From fb090bd3468f4a80a3aa7eb5c3e3c0b3d8b83ec1 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:20:14 -0400 Subject: [PATCH 001/216] Preregister native camera frame acquisition experiment --- jevdual/docs/experiments/NC1-native-camera.md | 27 +++++++++++++++++++ .../2026-10-10-native-camera-experiment.md | 8 ++++++ 2 files changed, 35 insertions(+) create mode 100644 jevdual/docs/experiments/NC1-native-camera.md create mode 100644 jevdual/docs/notebook/2026-10-10-native-camera-experiment.md diff --git a/jevdual/docs/experiments/NC1-native-camera.md b/jevdual/docs/experiments/NC1-native-camera.md new file mode 100644 index 0000000..3215362 --- /dev/null +++ b/jevdual/docs/experiments/NC1-native-camera.md @@ -0,0 +1,27 @@ +# NC1: Native Mac camera frame acquisition + +Mode: bounded engineering feasibility experiment, not a comparative product-value trial. + +## Hypothesis + +An isolated FFmpeg AVFoundation capture route can acquire a frame from the specifically observed built-in MacBook camera and retain a truthful operation/artifact record. + +## Predictions + +If supported and authorized, one capture yields a decodable saved PNG and matching receipt. Repeated client tokens retrieve that record without camera dispatch. Missing authorization, missing camera, missing receipt or corrupt bytes never become successful acquisition. + +If the hypothesis fails, permission/runtime acquisition or artifact verification cannot establish the requested frame; the failure remains explicit. + +## Design + +Use the installed FFmpeg and ffprobe binaries and Python standard library. Native permission inspection may use the installed Swift toolchain and AVFoundation. No new package install, provider call, microphone, screen capture, virtual-camera substitution, robot movement, or modification to jevdual production interfaces. Capture private images only in the experiment's ignored output. Use one fixed-operation ledger per run with conservative unresolved outcomes. + +Primary metric: successful bounded acquisition with independently decodable saved image and matching hash (binary feasibility result). + +Guardrails: exact physical device selection; bounded child lifetime; no microphone; no second dispatch for repeated tokens; artifact tamper/missing refusal; caller restart does not silently repeat an unresolved operation. + +Decision rule: advance only frame-acquisition feasibility when all required conformance checks pass and a real native-camera acquisition is verified. Report a permission or runtime prerequisite as unverified. This says nothing about exposure timestamps, scene interpretation, document quality, capture-to-page identity, shutter idempotency, power-loss recovery, exactly-once effects, or useful workflow comparisons. + +## Result + +Pending; source and notebook prediction must be committed before resolving checks. diff --git a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md new file mode 100644 index 0000000..452b176 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md @@ -0,0 +1,8 @@ +# Native camera capture experiment + +## NC1 · prediction · 2026-10-10 14:19 +Hypothesis: the installed FFmpeg AVFoundation route can acquire one bounded frame from the observed MacBook Pro Camera and persist an operation-bound artifact without introducing camera dependencies into Footwork's native runtime. +Test: isolated public CLI doctor and capture; explicit observed physical camera selection, no microphone or screen capture; inspect the saved image with ffprobe and hash readback. Conformance checks cover repeated tokens, changed arguments, interrupted capture and tampered/missing artifacts. Camera permission refusal remains a missing prerequisite, not successful acquisition. +Predicts: doctor distinguishes the built-in camera from OBS Virtual Camera; when access is granted, capture produces one decodable image with an operation-bound receipt; repeat lookup does not reacquire; uncertain operations remain blocked rather than replayed. +Against: camera selection broadens to screen/virtual sources, microphone opens, an unobserved device is accepted, capture claims success without decodable saved bytes, repeated lookup acquires a second frame, or permission/lost evidence is promoted to verified acquisition. +Refs: tools/camera-capture-experiment/; docs/experiments/NC1-native-camera.md; /Volumes/External SSD/referencerepos/libgphoto2/examples/sample-trigger-capture.c; /Volumes/External SSD/referencerepos/rerun/examples/python/live_camera_edge_detection/live_camera_edge_detection.py From 2bccd4510c7a5b23637a262fe6da8e97dab18626 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:29:42 -0400 Subject: [PATCH 002/216] Add isolated native camera frame acquisition experiment --- .../2026-10-10-native-camera-experiment.md | 6 + .../native-camera-20261010/conformance.json | 26 ++ .../native-camera-20261010/preflight.json | 16 + tools/camera-capture-experiment/.gitignore | 2 + tools/camera-capture-experiment/README.md | 106 +++++ tools/camera-capture-experiment/capture.py | 379 ++++++++++++++++++ .../permission.swift | 11 + .../camera-capture-experiment/test_capture.py | 305 ++++++++++++++ 8 files changed, 851 insertions(+) create mode 100644 jevdual/results/native-camera-20261010/conformance.json create mode 100644 jevdual/results/native-camera-20261010/preflight.json create mode 100644 tools/camera-capture-experiment/.gitignore create mode 100644 tools/camera-capture-experiment/README.md create mode 100644 tools/camera-capture-experiment/capture.py create mode 100644 tools/camera-capture-experiment/permission.swift create mode 100644 tools/camera-capture-experiment/test_capture.py diff --git a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md index 452b176..67d28dd 100644 --- a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md +++ b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md @@ -6,3 +6,9 @@ Test: isolated public CLI doctor and capture; explicit observed physical camera Predicts: doctor distinguishes the built-in camera from OBS Virtual Camera; when access is granted, capture produces one decodable image with an operation-bound receipt; repeat lookup does not reacquire; uncertain operations remain blocked rather than replayed. Against: camera selection broadens to screen/virtual sources, microphone opens, an unobserved device is accepted, capture claims success without decodable saved bytes, repeated lookup acquires a second frame, or permission/lost evidence is promoted to verified acquisition. Refs: tools/camera-capture-experiment/; docs/experiments/NC1-native-camera.md; /Volumes/External SSD/referencerepos/libgphoto2/examples/sample-trigger-capture.c; /Volumes/External SSD/referencerepos/rerun/examples/python/live_camera_edge_detection/live_camera_edge_detection.py + +## U-NCACCESS · update · 2026-10-10 14:22 +Observed: system camera inventory includes MacBook Pro Camera and OBS Virtual Camera; installed FFmpeg AVFoundation inventory matches exactly one MacBook Pro Camera. A separate Swift AVFoundation authorization query returns notDetermined. No camera has been opened and no image exists. +Inferred: built-in camera discovery is supported here; Swift permission state does not qualify the FFmpeg process identity or actual frame acquisition. +Next: complete isolated CLI conformance, freeze implementation, then explicit camera-only first-use capture under the user's authorized scope; OS permission and saved-image proof remain necessary. NC1 stays open. +Refs: results/native-camera-20261010/preflight.json; tools/camera-capture-experiment/ diff --git a/jevdual/results/native-camera-20261010/conformance.json b/jevdual/results/native-camera-20261010/conformance.json new file mode 100644 index 0000000..c7ecd25 --- /dev/null +++ b/jevdual/results/native-camera-20261010/conformance.json @@ -0,0 +1,26 @@ +{ + "source_sha256": { + "tools/camera-capture-experiment/capture.py": "5eb774018193a206e2fab836c801b5c10ec35d4d07170cb69967161d668c1c7b", + "tools/camera-capture-experiment/permission.swift": "71887f8fed0c51f4c539b2cce98c7c826a4b7c641c6ddbdc72f560f636161f56", + "tools/camera-capture-experiment/test_capture.py": "debef8d9115a87e2d0f93ac33c6c6b9f70f09adddb3e520cedfa3cc112171231", + "tools/camera-capture-experiment/README.md": "34108f3c8c5e378eaf314c6d9aec70e25bca5508098ef9d19e78c52b2ec95b5f" + }, + "preregistration_commit": "fb090bd", + "conformance": { + "command": "python3 -m unittest discover -s tools/camera-capture-experiment -p 'test_*.py' -v", + "exit_code": 0, + "tests": 18, + "runtime_boundary": "synthetic camera/process fixtures; real ffprobe on generated image, no live camera" + }, + "lint": { + "command": "uv run --no-sync ruff check ../tools/camera-capture-experiment", + "cwd": "jevdual", + "exit_code": 0 + }, + "notebook_check": { + "command": "uv run --no-sync python -m evals.notebook docs/notebook --check", + "cwd": "jevdual", + "exit_code": 0 + }, + "live_acquisition": "pending" +} diff --git a/jevdual/results/native-camera-20261010/preflight.json b/jevdual/results/native-camera-20261010/preflight.json new file mode 100644 index 0000000..c18a876 --- /dev/null +++ b/jevdual/results/native-camera-20261010/preflight.json @@ -0,0 +1,16 @@ +{ + "observed_at": "2026-10-10T14:22:07.709439-04:00", + "system_camera_names": [ + "MacBook Pro Camera", + "OBS Virtual Camera" + ], + "ffmpeg_exact_native_name_matches": [ + "MacBook Pro Camera" + ], + "ffmpeg_avfoundation_available": true, + "swift_video_authorization_raw": 0, + "swift_video_authorization": "not_determined", + "authorization_identity_limit": "Swift status is not a qualified FFmpeg permission result", + "camera_opened": false, + "frame_acquisition": "unverified" +} diff --git a/tools/camera-capture-experiment/.gitignore b/tools/camera-capture-experiment/.gitignore new file mode 100644 index 0000000..fd6aad7 --- /dev/null +++ b/tools/camera-capture-experiment/.gitignore @@ -0,0 +1,2 @@ +output/ +__pycache__/ diff --git a/tools/camera-capture-experiment/README.md b/tools/camera-capture-experiment/README.md new file mode 100644 index 0000000..de61a02 --- /dev/null +++ b/tools/camera-capture-experiment/README.md @@ -0,0 +1,106 @@ +# Native camera capture experiment + +Acquire one saved PNG from an exactly selected physical Mac camera. This is an isolated +Footwork experiment using Python's standard library and installed FFmpeg/ffprobe. It does +not change Footwork's runtime, TextEdit recovery, or production adapter interfaces. + +The experiment asks whether a requested frame can be acquired, decoded, and associated +with a retained operation record. It does not establish exposure freshness, scene meaning, +document quality, page identity, or exactly-once physical execution. + +## Inspect and capture + +Run from the repository root. Private run directories must be descendants of this package's +ignored `output/` directory. Directories use permissions 0700; records and diagnostics use 0600. +The program creates a missing run directory and refuses symlinked or publicly readable directories. + +```sh +python3 tools/camera-capture-experiment/capture.py doctor \ + --run-dir tools/camera-capture-experiment/output/desk-session +``` + +`doctor` reports model names from `system_profiler`, FFmpeg's AVFoundation video inventory, +their unique physical-name intersection, and camera authorization status. It excludes known +screen, virtual, OBS, and Continuity routes. Device IDs and microphone inventory are omitted. +Inventory is a selection aid, not authenticated hardware identity or proof of access. + +The optional Swift helper only queries `authorizationStatus(.video)`; it never requests +permission. Its status is specific to that process's privacy identity and does not prove +FFmpeg is authorized. An unavailable Swift query is reported explicitly. + +Use an exact name from `eligible_cameras`: + +```sh +python3 tools/camera-capture-experiment/capture.py capture \ + --run-dir tools/camera-capture-experiment/output/desk-session \ + --camera 'MacBook Pro Camera' --token frame-001 +``` + +If the status is undetermined or unavailable, an intentional first capture requires +`--allow-permission-prompt`. That lets FFmpeg's explicit camera acquisition trigger the +macOS authorization flow. `doctor` never opens the camera or requests access. A queried +denied/restricted status is refused; inspect macOS privacy settings before proceeding. + +Capture selects the observed device by name, explicitly disables microphone capture, +and saves one PNG without overwriting an existing artifact. It makes no frame-rate or +resolution assumption. Capture defaults to a 15-second timeout; `--timeout` accepts 1-60 +seconds. Inventory and permission inspection have separate bounded process lifetimes. +FFmpeg and its descendants are terminated on completion, timeout, or cancellation. + +## Read the result + +```sh +python3 tools/camera-capture-experiment/capture.py status \ + --run-dir tools/camera-capture-experiment/output/desk-session --token frame-001 +``` + +An `acquired` result means FFmpeg completed and ffprobe decoded one PNG frame, with +positive dimensions and a matching retained hash/byte count. `status` rechecks that saved +artifact without opening a camera. It provides no exposure timestamp or semantic claim. + +The ledger records intent before dispatch. Repeating the same token and arguments reads +the existing record, even in a fresh process. A token with changed camera, timeout, or +permission-prompt arguments is refused. A nonblocking process lock permits one owner per run. + +After dispatch, any incomplete capture or receipt produces `unknown`, including the first +CLI response. A pending ledger found after a restart remains unknown. A valid image without +a completed receipt cannot promote it to acquired. Unresolved operations block further +captures in that run; there is no automatic replay or reset command. + +If an acquired image later disappears or changes, current `state` becomes `unknown` and +claims are empty. `acquisition_outcome` and the persisted original receipt still retain the +historical acquisition; the current artifact is unusable. New captures in that run are blocked. + +FFmpeg stderr is retained in a private, bounded diagnostic file named in the record. It +is not printed by the CLI. Use it to distinguish permission, device-format, or runtime +failures. The experiment never retries by changing camera modes or selecting another device. +Inspect an unresolved run manually before deliberately beginning a new run. A new run is +a new operation, not proof that the earlier operation did not happen. + +Exit code 0 means the inventory completed, a retained acquisition is currently verifiable, +or a status token is absent. Exit code 2 means refusal, unknown outcome, or invalid retained +evidence. JSON `state` distinguishes those cases. This is process-restart testing; power-loss +recovery, hostile replacement, and cross-run camera exclusivity are not qualified. + +## Conformance checks + +```sh +python3 -m unittest discover -s tools/camera-capture-experiment -p 'test_*.py' -v +``` + +Tests use synthetic inventory and subprocess fixtures, never a live camera. One test uses +installed ffprobe to decode a tiny generated fixture. Live acquisition belongs to the +preregistered NC1 experiment and its engineering notebook. Private images, device diagnostics, +Swift module cache, and test scratch files remain under ignored `output/`. + +## Reference seams + +- Rerun's local `examples/python/live_camera_edge_detection/` illustrates camera acquisition + and visual inspection. A later exporter can project saved frames and operation events. +- libgphoto2's `examples/sample-trigger-capture.c` illustrates camera event and file handling. + A tethered still-camera transaction needs its own interface and qualification. +- Footwork's capability backend has validation, dispatch and readback seams. This experiment + deliberately keeps its acquisition ledger separate from native document recovery. + +Preregistration: `jevdual/docs/experiments/NC1-native-camera.md`. +Notebook: `jevdual/docs/notebook/2026-10-10-native-camera-experiment.md`. diff --git a/tools/camera-capture-experiment/capture.py b/tools/camera-capture-experiment/capture.py new file mode 100644 index 0000000..68e631b --- /dev/null +++ b/tools/camera-capture-experiment/capture.py @@ -0,0 +1,379 @@ +"""Bounded native-camera acquisition; no Footwork runtime dependencies.""" + +import argparse +import contextlib +import fcntl +import hashlib +import json +import os +import re +import shutil +import signal +import stat +import subprocess +import sys +import time +import uuid +from pathlib import Path + +BASE = Path(__file__).resolve().parent +OUTPUT = BASE / "output" +TOKEN = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.-]{0,127}\Z") +AV_DEVICE = re.compile(r"\[AVFoundation indev @ [^]]+\] \[(\d+)\] (.+)$") + + +class Refusal(Exception): + """An unmet prerequisite or unverifiable operation.""" + + def __init__(self, reason, private_stderr=None): + super().__init__(reason) + self.private_stderr = private_stderr + + +def run_process(argv, timeout): + """Start one owned process group; clean descendants on exit or interruption.""" + child = subprocess.Popen(argv, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, start_new_session=True, umask=0o077) + try: + stdout, stderr = child.communicate(timeout=timeout) + return child.returncode, stdout.decode(errors="replace"), stderr.decode(errors="replace") + except subprocess.TimeoutExpired as exc: + detail = exc.stderr or b"" + if isinstance(detail, bytes): + detail = detail.decode(errors="replace") + raise Refusal("child process exceeded its time limit", private_stderr=detail) from exc + finally: + # The group may outlive its leader (including pipe-holding grandchildren). + with contextlib.suppress(ProcessLookupError): + os.killpg(child.pid, signal.SIGKILL) + with contextlib.suppress(subprocess.TimeoutExpired): + child.communicate(timeout=2) + + +def private_directory(path): + """Create private directories without following caller-selected symlinks.""" + raw = Path(os.path.abspath(os.fspath(path))) + if raw == OUTPUT or OUTPUT not in raw.parents: + raise Refusal("run directory must be a subdirectory of the experiment's output directory") + current = OUTPUT + for part in (None, *raw.relative_to(OUTPUT).parts): + if part is not None: + current = current / part + try: + current.mkdir(mode=0o700) + except FileExistsError: + pass + info = current.lstat() + if not stat.S_ISDIR(info.st_mode) or info.st_uid != os.getuid(): + raise Refusal("run directory must contain only owned directories, without symlinks") + if info.st_mode & 0o077: + raise Refusal("run directories must be private (permissions 0700)") + return raw + + +@contextlib.contextmanager +def locked(root): + fd = os.open(root / "lock", os.O_RDWR | os.O_CREAT | os.O_NOFOLLOW, 0o600) + try: + if not stat.S_ISREG(os.fstat(fd).st_mode): + raise Refusal("invalid lock file") + try: + fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except BlockingIOError as exc: + raise Refusal("another process owns this run directory") from exc + yield + finally: + os.close(fd) + + +def read_json(path): + try: + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) + with os.fdopen(fd) as source: + if not stat.S_ISREG(os.fstat(source.fileno()).st_mode): + raise Refusal("ledger is not a regular file") + record = json.load(source) + if (not isinstance(record, dict) or record.get("state") not in {"pending", "unknown", "acquired"} + or not isinstance(record.get("token"), str) or not TOKEN.fullmatch(record["token"]) + or not isinstance(record.get("request"), dict)): + raise Refusal("ledger structure is invalid; inspect this run directory") + return record + except (OSError, ValueError) as exc: + raise Refusal("ledger cannot be read; inspect this run directory") from exc + + +def persist(path, record): + staging = path.with_name(f".{path.name}.{uuid.uuid4().hex}.tmp") + try: + fd = os.open(staging, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600) + with os.fdopen(fd, "w") as sink: + json.dump(record, sink, indent=2, sort_keys=True) + sink.write("\n") + sink.flush() + os.fsync(sink.fileno()) + os.replace(staging, path) + directory = os.open(path.parent, os.O_RDONLY) + try: + os.fsync(directory) + finally: + os.close(directory) + finally: + with contextlib.suppress(FileNotFoundError): + staging.unlink() + + +def private_diagnostic(path, stderr): + fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600) + with os.fdopen(fd, "wb") as sink: + sink.write(stderr.encode(errors="replace")[:65536]) + sink.flush() + os.fsync(sink.fileno()) + + +def parse_physical(data): + entries = data.get("SPCameraDataType") + if not isinstance(entries, list): + raise Refusal("system_profiler camera inventory is unavailable") + # The system inventory may include software cameras: require a model identifier. + result = [] + for item in entries: + name = item.get("_name", "") + model = item.get("spcamera_model-id", "") + if name and model and not re.search(r"virtual|screen|obs|continuity", name + " " + model, re.IGNORECASE): + result.append(name) + return result + + +def parse_avfoundation(stderr): + names = [] + in_video = False + for line in stderr.splitlines(): + if "AVFoundation video devices:" in line: + in_video = True + elif "AVFoundation audio devices:" in line: + in_video = False + elif in_video: + match = AV_DEVICE.search(line) + if match: + names.append(match.group(2).strip()) + return names + + +def binaries(): + found = {name: shutil.which(name) for name in ("ffmpeg", "ffprobe", "swift", "system_profiler")} + if not found["ffmpeg"] or not found["ffprobe"]: + raise Refusal("installed ffmpeg and ffprobe are required; nothing will be installed") + return found + + +def permission(root, programs): + if not programs["swift"]: + return "unavailable" + cache = root / "swift-module-cache" + if cache.is_symlink(): + raise Refusal("invalid Swift cache directory") + cache.mkdir(mode=0o700, exist_ok=True) + rc, stdout, _ = run_process([programs["swift"], "-module-cache-path", str(cache), + str(BASE / "permission.swift")], 20) + status = stdout.strip() + if rc or status not in {"authorized", "denied", "restricted", "not_determined", "unknown"}: + return "unavailable" + return status + + +def doctor(root): + programs = binaries() + if not programs["system_profiler"]: + raise Refusal("macOS system_profiler is required") + rc, stdout, _ = run_process([programs["system_profiler"], "SPCameraDataType", "-json"], 15) + if rc: + raise Refusal("physical camera inventory failed") + try: + physical = parse_physical(json.loads(stdout)) + except ValueError as exc: + raise Refusal("physical camera inventory was not valid JSON") from exc + # AVFoundation enumeration returns a nonzero code because no input is opened. + _, _, stderr = run_process([programs["ffmpeg"], "-hide_banner", "-nostdin", "-f", + "avfoundation", "-list_devices", "true", "-i", ""], 10) + video = parse_avfoundation(stderr) + if not video: + raise Refusal("FFmpeg AVFoundation video inventory was unavailable") + physical_unique = [name for name in physical if physical.count(name) == 1 and video.count(name) == 1] + return {"physical_cameras": physical, "avfoundation_video_devices": video, + "eligible_cameras": physical_unique, "permission_status": permission(root, programs), + "permission_query": "Swift AVFoundation authorizationStatus(.video); no request", + "programs": programs} + + +def select_camera(camera, inventory, allow_permission_prompt=False): + if not camera or ":" in camera or camera.startswith("-"): + raise Refusal("camera name is invalid") + if camera not in inventory["eligible_cameras"]: + raise Refusal("camera must exactly match one unique physical and AVFoundation device name") + if inventory["permission_status"] in {"denied", "restricted"}: + raise Refusal("camera permission query reports denied or restricted; inspect macOS privacy settings") + if inventory["permission_status"] != "authorized" and not allow_permission_prompt: + raise Refusal("camera permission is unestablished; explicit --allow-permission-prompt is required") + + +def artifact_info(path, ffprobe): + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) + with os.fdopen(fd, "rb") as source: + if not stat.S_ISREG(os.fstat(source.fileno()).st_mode): + raise Refusal("artifact is not a regular file") + digest = hashlib.sha256() + size = 0 + for chunk in iter(lambda: source.read(1024 * 1024), b""): + digest.update(chunk) + size += len(chunk) + if not size: + raise Refusal("artifact is empty") + rc, stdout, stderr = run_process([ffprobe, "-v", "error", "-count_frames", "-show_entries", + "stream=codec_name,width,height,nb_read_frames", "-of", "json", + str(path)], 10) + if rc or stderr.strip(): + raise Refusal("ffprobe could not decode the artifact") + try: + streams = json.loads(stdout)["streams"] + stream = streams[0] + if (len(streams) != 1 or stream["codec_name"] != "png" or + stream["width"] <= 0 or stream["height"] <= 0 or + str(stream["nb_read_frames"]) != "1"): + raise Refusal("artifact is not one decoded PNG frame") + except (KeyError, IndexError, ValueError, TypeError) as exc: + raise Refusal("ffprobe returned incomplete artifact evidence") from exc + return {"sha256": digest.hexdigest(), "bytes": size, "codec": "png", + "width": stream["width"], "height": stream["height"]} + + +def paths(root, token): + if not TOKEN.fullmatch(token): + raise Refusal("token must be 1-128 letters, digits, underscores, periods or hyphens") + key = hashlib.sha256(token.encode()).hexdigest() + return root / f"{key}.json", root / f"{key}.png", root / f"{key}.pending.png" + + +def status(root, token): + ledger, artifact, _ = paths(root, token) + if not ledger.exists() and not ledger.is_symlink(): + return {"token": token, "state": "absent"} + record = read_json(ledger) + if record.get("token") != token: + raise Refusal("ledger identity does not match requested operation") + result = dict(record) + if record.get("state") == "acquired": + result["acquisition_outcome"] = "acquired" + try: + observed = artifact_info(artifact, binaries()["ffprobe"]) + if observed != record["artifact"]: + raise Refusal("artifact no longer matches its receipt") + result["artifact_status"] = "verified" + except (OSError, KeyError, Refusal): + # Preserve historical acquisition; current artifact usability is unresolved. + result["state"] = "unknown" + result["artifact_status"] = "invalid_or_unverifiable" + result["reason"] = "retained artifact is missing, changed or unverifiable" + if result.get("state") == "pending": + result["state"] = "unknown" + result["reason"] = "dispatch was recorded without a complete persisted receipt; inspect manually" + result["claims"] = ["saved-frame acquisition", "retained artifact integrity"] if result["state"] == "acquired" else [] + return result + + +def capture(root, camera, token, timeout, allow_permission_prompt=False): + ledger, artifact, staging = paths(root, token) + diagnostic = ledger.with_suffix(".ffmpeg.stderr.log") + request = {"camera": camera, "format": "png", "timeout_seconds": timeout, + "allow_permission_prompt": allow_permission_prompt} + if ledger.exists() or ledger.is_symlink(): + record = read_json(ledger) + if record.get("request") != request: + raise Refusal("token already belongs to different capture arguments") + return status(root, token) + for existing in root.glob("*.json"): + record = read_json(existing) + if record.get("state") != "acquired": + raise Refusal("an unresolved operation blocks new captures; inspect this run directory") + # Invalid retained artifacts also block conflicting captures. + if status(root, record["token"])["state"] != "acquired": + raise Refusal("an unverifiable artifact blocks new captures; inspect this run directory") + if any(path.exists() or path.is_symlink() for path in (artifact, staging, diagnostic)): + raise Refusal("an unreceipted artifact already exists; it will not be overwritten") + inventory = doctor(root) + select_camera(camera, inventory, allow_permission_prompt) + programs = inventory["programs"] + record = {"version": 1, "token": token, "request": request, "state": "pending", + "intent_time_unix": time.time(), "artifact_name": artifact.name} + persist(ledger, record) + try: + rc, _, stderr = run_process([programs["ffmpeg"], "-hide_banner", "-loglevel", "error", + "-nostdin", "-n", "-f", "avfoundation", "-i", f"{camera}:none", + "-an", "-frames:v", "1", "-c:v", "png", str(staging)], timeout) + private_diagnostic(diagnostic, stderr) + record["diagnostic_name"] = diagnostic.name + if rc: + raise Refusal("FFmpeg capture failed; execution outcome remains unresolved") + info = artifact_info(staging, programs["ffprobe"]) + # Hard-link publication cannot replace an existing capture. + os.link(staging, artifact, follow_symlinks=False) + staging.unlink() + fd = os.open(artifact, os.O_RDONLY | os.O_NOFOLLOW) + try: + os.fsync(fd) + finally: + os.close(fd) + record.update(state="acquired", acquisition_outcome="acquired", artifact=info, + receipt_time_unix=time.time()) + persist(ledger, record) + # Every post-intent error must preserve uncertainty, including unexpected adapter errors. + except (Exception, KeyboardInterrupt) as exc: # noqa: BLE001 + if isinstance(exc, Refusal) and exc.private_stderr is not None: + with contextlib.suppress(OSError): + private_diagnostic(diagnostic, exc.private_stderr) + record["diagnostic_name"] = diagnostic.name + record["state"] = "unknown" + record["acquisition_outcome"] = "unknown" + record["reason"] = "capture or receipt did not complete; inspect artifacts before any further operation" + with contextlib.suppress(OSError): + persist(ledger, record) + # A first response after intent must expose uncertainty, never imply no dispatch. + return dict(record, claims=[]) + return status(root, token) + + +def main(argv=None): + parser = argparse.ArgumentParser(description=__doc__) + sub = parser.add_subparsers(dest="command", required=True) + for command in ("doctor", "capture", "status"): + child = sub.add_parser(command) + child.add_argument("--run-dir", required=True) + if command != "doctor": + child.add_argument("--token", required=True) + if command == "capture": + child.add_argument("--camera", required=True) + child.add_argument("--timeout", type=float, default=15) + child.add_argument("--allow-permission-prompt", action="store_true", + help="allow an explicit capture to trigger macOS camera authorization") + args = parser.parse_args(argv) + try: + if args.command == "capture" and not 1 <= args.timeout <= 60: + raise Refusal("capture timeout must be between 1 and 60 seconds") + root = private_directory(args.run_dir) + with locked(root): + if args.command == "doctor": + result = doctor(root) + elif args.command == "status": + result = status(root, args.token) + else: + result = capture(root, args.camera, args.token, args.timeout, args.allow_permission_prompt) + print(json.dumps(result, indent=2, sort_keys=True)) + return 0 if result.get("state", "acquired") in {"acquired", "absent"} else 2 + except (Refusal, OSError, KeyboardInterrupt) as exc: + # Do not print raw process output, personal images, or native device IDs. + reason = str(exc) if isinstance(exc, Refusal) else "operation interrupted or local resource unavailable" + print(json.dumps({"state": "refused", "reason": reason})) + return 2 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/camera-capture-experiment/permission.swift b/tools/camera-capture-experiment/permission.swift new file mode 100644 index 0000000..0e04048 --- /dev/null +++ b/tools/camera-capture-experiment/permission.swift @@ -0,0 +1,11 @@ +import AVFoundation + +// Inspection only: this helper never requests camera authorization. +let status = AVCaptureDevice.authorizationStatus(for: .video) +switch status { +case .authorized: print("authorized") +case .denied: print("denied") +case .restricted: print("restricted") +case .notDetermined: print("not_determined") +@unknown default: print("unknown") +} diff --git a/tools/camera-capture-experiment/test_capture.py b/tools/camera-capture-experiment/test_capture.py new file mode 100644 index 0000000..e7b1acc --- /dev/null +++ b/tools/camera-capture-experiment/test_capture.py @@ -0,0 +1,305 @@ +"""Conformance checks use fixtures, never a live camera.""" + +import base64 +import contextlib +import importlib.util +import json +import os +import shutil +import subprocess +import sys +import tempfile +import time +import unittest +from pathlib import Path +from string import Template +from unittest.mock import patch + +BASE = Path(__file__).resolve().parent +spec = importlib.util.spec_from_file_location("camera_capture", BASE / "capture.py") +capture = importlib.util.module_from_spec(spec) +spec.loader.exec_module(capture) +PNG = base64.b64decode( + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=" +) +CAMERA = "MacBook Pro Camera" +LISTING = """[AVFoundation indev @ 0x123] AVFoundation video devices: +[AVFoundation indev @ 0x123] [0] MacBook Pro Camera +[AVFoundation indev @ 0x123] [1] OBS Virtual Camera +[AVFoundation indev @ 0x123] [2] Capture screen 0 +[AVFoundation indev @ 0x123] AVFoundation audio devices: +[AVFoundation indev @ 0x123] [0] MacBook Pro Microphone +""" + + +class CaptureTests(unittest.TestCase): + def setUp(self): + capture.OUTPUT.mkdir(mode=0o700, exist_ok=True) + self.tmp = tempfile.TemporaryDirectory(prefix="conformance-", dir=capture.OUTPUT) + self.addCleanup(self.tmp.cleanup) + self.root = Path(self.tmp.name) + + def inventory(self, permission="authorized"): + return {"physical_cameras": [CAMERA], "avfoundation_video_devices": [CAMERA], + "eligible_cameras": [CAMERA], "permission_status": permission, + "programs": {"ffmpeg": "fixture-ffmpeg", "ffprobe": "fixture-ffprobe"}} + + def probe_result(self): + return 0, json.dumps({"streams": [{"codec_name": "png", "width": 1, "height": 1, + "nb_read_frames": "1"}]}), "" + + @contextlib.contextmanager + def working_device(self): + dispatched = [] + + def run(argv, timeout): + if argv[0] == "fixture-ffmpeg": + ledger, _, _ = capture.paths(self.root, "first") + self.assertEqual(capture.read_json(ledger)["state"], "pending") + dispatched.append(argv) + Path(argv[-1]).write_bytes(PNG) + return 0, "", "" + return self.probe_result() + + with patch.object(capture, "doctor", return_value=self.inventory()), \ + patch.object(capture, "binaries", return_value={"ffprobe": "fixture-ffprobe"}), \ + patch.object(capture, "run_process", side_effect=run): + yield dispatched + + def test_physical_inventory_rejects_virtual_and_continuity(self): + result = capture.parse_physical({"SPCameraDataType": [ + {"_name": CAMERA, "spcamera_model-id": CAMERA, "spcamera_unique-id": "private-id"}, + {"_name": "OBS Virtual Camera", "spcamera_model-id": "OBS"}, + {"_name": "Capture screen 0", "spcamera_model-id": "screen"}, + {"_name": "Phone", "spcamera_model-id": "Continuity Camera"}, + {"_name": "Incomplete device"}, + ]}) + self.assertEqual(result, [CAMERA]) + self.assertNotIn("private-id", repr(result)) + + def test_video_inventory_never_contains_microphone(self): + self.assertEqual(capture.parse_avfoundation(LISTING), + [CAMERA, "OBS Virtual Camera", "Capture screen 0"]) + + def test_doctor_exact_intersection_and_duplicate_refusal(self): + physical = {"SPCameraDataType": [{"_name": CAMERA, "spcamera_model-id": CAMERA}]} + listing = LISTING.replace("[1] OBS Virtual Camera", "[1] " + CAMERA) + with patch.object(capture, "binaries", return_value={"ffmpeg": "ffmpeg", "ffprobe": "ffprobe", + "swift": None, "system_profiler": "profiler"}), \ + patch.object(capture, "run_process", side_effect=[(0, json.dumps(physical), ""), + (1, "", listing)]): + inventory = capture.doctor(self.root) + self.assertEqual(inventory["eligible_cameras"], []) + with self.assertRaises(capture.Refusal): + capture.select_camera(CAMERA, inventory) + + def test_unobserved_virtual_screen_and_index_selection_refused(self): + for name in ("0", "OBS Virtual Camera", "Capture screen 0", "Another camera", CAMERA + ":none"): + with self.subTest(name=name), self.assertRaises(capture.Refusal): + capture.select_camera(name, self.inventory()) + + def test_permission_is_inspection_only_and_prompt_requires_opt_in(self): + for state in ("not_determined", "unknown", "unavailable"): + with self.assertRaises(capture.Refusal): + capture.select_camera(CAMERA, self.inventory(state)) + capture.select_camera(CAMERA, self.inventory(state), True) + for state in ("denied", "restricted"): + with self.assertRaises(capture.Refusal): + capture.select_camera(CAMERA, self.inventory(state), True) + source = (BASE / "permission.swift").read_text() + self.assertIn("authorizationStatus(for: .video)", source) + self.assertNotIn("requestAccess", source) + + def test_capture_persists_intent_and_uses_exact_camera_without_audio(self): + with self.working_device() as dispatched: + result = capture.capture(self.root, CAMERA, "first", 15) + repeat = capture.capture(self.root, CAMERA, "first", 15) + self.assertEqual(result["state"], "acquired") + self.assertEqual(repeat["artifact"], result["artifact"]) + self.assertEqual(len(dispatched), 1) + args = dispatched[0] + self.assertEqual(args[args.index("-i") + 1], CAMERA + ":none") + self.assertIn("-an", args) + self.assertIn("-nostdin", args) + self.assertIn("-n", args) + self.assertNotIn("-video_size", args) + + def test_changed_token_arguments_refused_before_second_dispatch(self): + with self.working_device() as dispatched: + capture.capture(self.root, CAMERA, "first", 15) + for camera, timeout, prompt in (("Other", 15, False), (CAMERA, 16, False), + (CAMERA, 15, True)): + with self.assertRaises(capture.Refusal): + capture.capture(self.root, camera, "first", timeout, prompt) + self.assertEqual(len(dispatched), 1) + + def test_unknown_and_valid_unreceipted_artifact_never_replay(self): + ledger, artifact, _ = capture.paths(self.root, "first") + request = {"camera": CAMERA, "format": "png", "timeout_seconds": 15, + "allow_permission_prompt": False} + capture.persist(ledger, {"token": "first", "request": request, "state": "pending"}) + artifact.write_bytes(PNG) + with patch.object(capture, "doctor") as doctor: + self.assertEqual(capture.capture(self.root, CAMERA, "first", 15)["state"], "unknown") + with self.assertRaises(capture.Refusal): + capture.capture(self.root, CAMERA, "second", 15) + doctor.assert_not_called() + + def test_corrupt_or_missing_image_invalidates_receipt_and_blocks_new_capture(self): + for mutate in (lambda p: p.write_bytes(b"changed"), lambda p: p.unlink()): + with self.subTest(mutate=mutate): + with self.working_device(): + capture.capture(self.root, CAMERA, "first", 15) + ledger, artifact, _ = capture.paths(self.root, "first") + mutate(artifact) + self.assertEqual(capture.status(self.root, "first")["state"], "unknown") + self.assertEqual(capture.status(self.root, "first")["acquisition_outcome"], "acquired") + self.assertEqual(capture.read_json(ledger)["state"], "acquired") + with self.assertRaises(capture.Refusal): + capture.capture(self.root, CAMERA, "second", 15) + for path in self.root.glob("*"): + path.unlink() + + def test_capture_timeout_retains_unknown(self): + with patch.object(capture, "doctor", return_value=self.inventory()), \ + patch.object(capture, "run_process", side_effect=capture.Refusal("timeout")): + self.assertEqual(capture.capture(self.root, CAMERA, "first", 1)["state"], "unknown") + self.assertEqual(capture.status(self.root, "first")["state"], "unknown") + + def test_lost_receipt_does_not_promote_valid_frame(self): + real_persist = capture.persist + + def fail_receipt(path, record): + if record["state"] != "pending": + raise OSError("injected persistence failure") + real_persist(path, record) + + with self.working_device(), patch.object(capture, "persist", side_effect=fail_receipt): + self.assertEqual(capture.capture(self.root, CAMERA, "first", 15)["state"], "unknown") + self.assertTrue(capture.paths(self.root, "first")[1].exists()) + self.assertEqual(capture.status(self.root, "first")["state"], "unknown") + + def test_arbitrary_or_symlinked_run_paths_and_tokens_refused(self): + with self.assertRaises(capture.Refusal): + capture.private_directory(BASE / "escape") + link = self.root / "link" + link.symlink_to(self.root, target_is_directory=True) + with self.assertRaises(capture.Refusal): + capture.private_directory(link / "child") + for token in ("../outside", "", "a" * 129): + with self.assertRaises(capture.Refusal): + capture.paths(self.root, token) + + def test_lock_blocks_another_process(self): + with capture.locked(self.root): + result = subprocess.run([sys.executable, str(BASE / "capture.py"), "status", "--run-dir", + str(self.root), "--token", "first"], capture_output=True, text=True, check=False) + self.assertEqual(result.returncode, 2) + self.assertIn("another process", result.stdout) + + def test_timeout_kills_pipe_holding_descendants(self): + marker = self.root / "survived" + grandchild = f"import pathlib,time;time.sleep(.4);pathlib.Path({str(marker)!r}).write_text('alive')" + parent = f"import subprocess,sys,time;subprocess.Popen([sys.executable,'-c',{grandchild!r}]);time.sleep(5)" + started = time.monotonic() + with self.assertRaises(capture.Refusal): + capture.run_process([sys.executable, "-c", parent], .15) + self.assertLess(time.monotonic() - started, 2) + time.sleep(.5) + self.assertFalse(marker.exists()) + + @unittest.skipUnless(shutil.which("ffprobe"), "installed ffprobe required for real fixture decoding") + def test_real_ffprobe_decodes_fixture_and_rejects_header_only_png(self): + image = self.root / "fixture.png" + image.write_bytes(PNG) + result = capture.artifact_info(image, shutil.which("ffprobe")) + self.assertEqual((result["width"], result["height"], result["codec"]), (1, 1, "png")) + image.write_bytes(PNG[:33]) + with self.assertRaises(capture.Refusal): + capture.artifact_info(image, shutil.which("ffprobe")) + + def test_cli_repeat_token_across_fresh_processes_without_camera(self): + bin_dir = self.root / "bin" + bin_dir.mkdir(mode=0o700) + marker = self.root / "dispatches" + fixture = Template("""#!/usr/bin/env python3 +import base64,json,pathlib,sys +name=pathlib.Path(sys.argv[0]).name +if name=='system_profiler': + print(json.dumps({'SPCameraDataType':[{'_name':'MacBook Pro Camera','spcamera_model-id':'MacBook Pro Camera'}]})) +elif name=='swift': print('authorized') +elif name=='ffmpeg': + if '-list_devices' in sys.argv: + print($listing,file=sys.stderr); sys.exit(1) + with open($marker,'a') as f: f.write('dispatch\\n') + pathlib.Path(sys.argv[-1]).write_bytes(base64.b64decode($png)) +elif name=='ffprobe': + print(json.dumps({'streams':[{'codec_name':'png','width':1,'height':1,'nb_read_frames':'1'}]})) +""").substitute(listing=repr(LISTING), marker=repr(str(marker)), png=repr(base64.b64encode(PNG).decode())) + for name in ("ffmpeg", "ffprobe", "swift", "system_profiler"): + program = bin_dir / name + program.write_text(fixture) + program.chmod(0o700) + env = dict(os.environ, PATH=str(bin_dir) + os.pathsep + os.environ["PATH"]) + args = [sys.executable, str(BASE / "capture.py"), "capture", "--run-dir", str(self.root / "run"), + "--camera", CAMERA, "--token", "fresh-process"] + for _ in range(2): + result = subprocess.run(args, env=env, capture_output=True, text=True, timeout=10, check=False) + self.assertEqual(result.returncode, 0, result.stdout + result.stderr) + self.assertEqual(json.loads(result.stdout)["state"], "acquired") + self.assertEqual(marker.read_text(), "dispatch\n") + status = subprocess.run([sys.executable, str(BASE / "capture.py"), "status", "--run-dir", + str(self.root / "run"), "--token", "fresh-process"], env=env, + capture_output=True, text=True, timeout=10, check=False) + self.assertEqual(status.returncode, 0, status.stdout + status.stderr) + self.assertEqual(json.loads(status.stdout)["state"], "acquired") + self.assertEqual(marker.read_text(), "dispatch\n") + + def test_public_cli_failed_or_timed_out_dispatch_reports_unknown_and_private_diagnostics(self): + for mode in ("failure", "timeout"): + with self.subTest(mode=mode): + bin_dir = self.root / mode + bin_dir.mkdir(mode=0o700) + fixture = Template("""#!/usr/bin/env python3 +import json,pathlib,sys,time +name=pathlib.Path(sys.argv[0]).name +if name=='system_profiler': + print(json.dumps({'SPCameraDataType':[{'_name':'MacBook Pro Camera','spcamera_model-id':'MacBook Pro Camera'}]})) +elif name=='swift': print('authorized') +elif name=='ffmpeg': + if '-list_devices' in sys.argv: + print($listing,file=sys.stderr); sys.exit(1) + print('PRIVATE_CAPTURE_DIAGNOSTIC',file=sys.stderr,flush=True) + if $mode == 'timeout': time.sleep(30) + sys.exit(1) +""").substitute(listing=repr(LISTING), mode=repr(mode)) + for name in ("ffmpeg", "ffprobe", "swift", "system_profiler"): + program = bin_dir / name + program.write_text(fixture) + program.chmod(0o700) + env = dict(os.environ, PATH=str(bin_dir) + os.pathsep + os.environ["PATH"]) + run_dir = self.root / (mode + "-run") + args = [sys.executable, str(BASE / "capture.py"), "capture", "--run-dir", str(run_dir), + "--camera", CAMERA, "--token", "failed-operation", "--timeout", "1"] + result = subprocess.run(args, env=env, capture_output=True, text=True, timeout=10, check=False) + self.assertEqual(result.returncode, 2, result.stdout + result.stderr) + record = json.loads(result.stdout) + self.assertEqual(record["state"], "unknown") + self.assertEqual(record["claims"], []) + self.assertNotIn("PRIVATE_CAPTURE_DIAGNOSTIC", result.stdout + result.stderr) + self.assertIn("PRIVATE_CAPTURE_DIAGNOSTIC", (run_dir / record["diagnostic_name"]).read_text()) + diagnostic = run_dir / record["diagnostic_name"] + self.assertEqual(diagnostic.stat().st_mode & 0o777, 0o600) + again = subprocess.run(args, env=env, capture_output=True, text=True, timeout=10, check=False) + self.assertEqual(json.loads(again.stdout)["state"], "unknown") + + def test_missing_permission_is_refused_without_ledger_or_dispatch(self): + with patch.object(capture, "doctor", return_value=self.inventory("not_determined")), \ + patch.object(capture, "run_process") as dispatch, self.assertRaises(capture.Refusal): + capture.capture(self.root, CAMERA, "first", 15) + dispatch.assert_not_called() + self.assertFalse(capture.paths(self.root, "first")[0].exists()) + + +if __name__ == "__main__": + unittest.main() From 4a086d3b5423de23fac8b3241509cd97795e9339 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:30:36 -0400 Subject: [PATCH 003/216] Record native camera mode failure and predict explicit 30 fps trial --- jevdual/docs/experiments/NC1-native-camera.md | 3 +++ .../notebook/2026-10-10-native-camera-experiment.md | 13 +++++++++++++ jevdual/results/native-camera-20261010/live-v1.json | 11 +++++++++++ 3 files changed, 27 insertions(+) create mode 100644 jevdual/results/native-camera-20261010/live-v1.json diff --git a/jevdual/docs/experiments/NC1-native-camera.md b/jevdual/docs/experiments/NC1-native-camera.md index 3215362..4f6f939 100644 --- a/jevdual/docs/experiments/NC1-native-camera.md +++ b/jevdual/docs/experiments/NC1-native-camera.md @@ -25,3 +25,6 @@ Decision rule: advance only frame-acquisition feasibility when all required conf ## Result Pending; source and notebook prediction must be committed before resolving checks. + +## Amendment · 2026-10-10 14:30 +Live-v1 on 2bccd45 found FFmpeg default 29.970030 fps unsupported; no PNG exists and its ledger remains unknown. Next frozen version will explicitly request device-reported 30 fps and record it as part of the request. Live-v2 is a distinct operation, without altering or replaying live-v1. Original scope and decision rule remain unchanged. diff --git a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md index 67d28dd..b3e1a9c 100644 --- a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md +++ b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md @@ -12,3 +12,16 @@ Observed: system camera inventory includes MacBook Pro Camera and OBS Virtual Ca Inferred: built-in camera discovery is supported here; Swift permission state does not qualify the FFmpeg process identity or actual frame acquisition. Next: complete isolated CLI conformance, freeze implementation, then explicit camera-only first-use capture under the user's authorized scope; OS permission and saved-image proof remain necessary. NC1 stays open. Refs: results/native-camera-20261010/preflight.json; tools/camera-capture-experiment/ + +## U-NCMODE · update · 2026-10-10 14:30 +Observed: frozen source 2bccd45 passed 18 conformance checks and Ruff. Live-v1 FFmpeg dispatch rejected its default 29.970030 fps; private diagnostic lists device modes spanning 15 to 30 fps, and no PNG was saved. Repeat of the identical token returns the original unknown operation without a new intent. NC1 remains open. +Inferred: a mode prerequisite, rather than saved-image verification, prevented acquisition; actual permission and acquisition remain unqualified. +Next: preregister explicit 30 fps and preserve live-v1 unchanged; a distinct trial is a new capture operation. +Refs: results/native-camera-20261010/conformance.json; results/native-camera-20261010/live-v1.json; tools/camera-capture-experiment/output/live-v1/ + +## NC2 · prediction · 2026-10-10 14:30 +Hypothesis: explicitly requesting the device-reported 30 fps eliminates the unsupported-default frame-rate failure while preserving capture argument binding and unknown outcomes. +Test: add a fixed 30 fps input option and bind it into the request; retain conformance checks, freeze amended source, and perform one distinct live-v2 native-camera operation. +Predicts: command requests 30 fps; live-v2 no longer fails with unsupported 29.970030 fps. Successful acquisition additionally requires permission and a decoded saved artifact; another failure remains unknown. +Against: FFmpeg still rejects 30 fps as unsupported, the request omits the mode, changing a retained mode replays an operation, or failure becomes a success without artifact proof. +Refs: results/native-camera-20261010/live-v1.json; docs/experiments/NC1-native-camera.md diff --git a/jevdual/results/native-camera-20261010/live-v1.json b/jevdual/results/native-camera-20261010/live-v1.json new file mode 100644 index 0000000..c4946b1 --- /dev/null +++ b/jevdual/results/native-camera-20261010/live-v1.json @@ -0,0 +1,11 @@ +{ + "source_commit": "2bccd45", + "run": "tools/camera-capture-experiment/output/live-v1", + "token": "native-frame-001", + "state": "unknown", + "png_count": 0, + "diagnosis": "FFmpeg default 29.970030 fps rejected; device reports 15.000000 to 30.000000 fps modes", + "repeat_same_request": "retained unknown record, no new intent or image", + "ledger_sha256": "2fa6e53a27e1ba460546c2f59f9f83543090edad2591efb4583950aa861de916", + "permission": "not qualified by frame acquisition" +} From 48b33a10080a3ca17b7600d204ea18c37a6034cb Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:31:21 -0400 Subject: [PATCH 004/216] Select observed 30 fps mode for native camera capture --- tools/camera-capture-experiment/README.md | 12 ++++++++---- tools/camera-capture-experiment/capture.py | 5 +++-- tools/camera-capture-experiment/test_capture.py | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/tools/camera-capture-experiment/README.md b/tools/camera-capture-experiment/README.md index de61a02..2adcbe8 100644 --- a/tools/camera-capture-experiment/README.md +++ b/tools/camera-capture-experiment/README.md @@ -42,8 +42,10 @@ macOS authorization flow. `doctor` never opens the camera or requests access. A denied/restricted status is refused; inspect macOS privacy settings before proceeding. Capture selects the observed device by name, explicitly disables microphone capture, -and saves one PNG without overwriting an existing artifact. It makes no frame-rate or -resolution assumption. Capture defaults to a 15-second timeout; `--timeout` accepts 1-60 +and saves one PNG without overwriting an existing artifact. It explicitly requests 30 fps, +a supported mode reported by this MacBook camera during NC1. It makes no resolution +assumption. Another device may reject this fixed mode; there is no mode fallback. +Capture defaults to a 15-second timeout; `--timeout` accepts 1-60 seconds. Inventory and permission inspection have separate bounded process lifetimes. FFmpeg and its descendants are terminated on completion, timeout, or cancellation. @@ -59,8 +61,10 @@ positive dimensions and a matching retained hash/byte count. `status` rechecks t artifact without opening a camera. It provides no exposure timestamp or semantic claim. The ledger records intent before dispatch. Repeating the same token and arguments reads -the existing record, even in a fresh process. A token with changed camera, timeout, or -permission-prompt arguments is refused. A nonblocking process lock permits one owner per run. +the existing record, even in a fresh process. The request binds the fixed `framerate_fps: 30` +alongside camera, timeout and permission-prompt arguments. Changed arguments or an older +request without that mode are refused by `capture`; `status` can still inspect the earlier +record. A nonblocking process lock permits one owner per run. After dispatch, any incomplete capture or receipt produces `unknown`, including the first CLI response. A pending ledger found after a restart remains unknown. A valid image without diff --git a/tools/camera-capture-experiment/capture.py b/tools/camera-capture-experiment/capture.py index 68e631b..a948355 100644 --- a/tools/camera-capture-experiment/capture.py +++ b/tools/camera-capture-experiment/capture.py @@ -283,7 +283,7 @@ def status(root, token): def capture(root, camera, token, timeout, allow_permission_prompt=False): ledger, artifact, staging = paths(root, token) diagnostic = ledger.with_suffix(".ffmpeg.stderr.log") - request = {"camera": camera, "format": "png", "timeout_seconds": timeout, + request = {"camera": camera, "format": "png", "framerate_fps": 30, "timeout_seconds": timeout, "allow_permission_prompt": allow_permission_prompt} if ledger.exists() or ledger.is_symlink(): record = read_json(ledger) @@ -307,7 +307,8 @@ def capture(root, camera, token, timeout, allow_permission_prompt=False): persist(ledger, record) try: rc, _, stderr = run_process([programs["ffmpeg"], "-hide_banner", "-loglevel", "error", - "-nostdin", "-n", "-f", "avfoundation", "-i", f"{camera}:none", + "-nostdin", "-n", "-f", "avfoundation", "-framerate", "30", + "-i", f"{camera}:none", "-an", "-frames:v", "1", "-c:v", "png", str(staging)], timeout) private_diagnostic(diagnostic, stderr) record["diagnostic_name"] = diagnostic.name diff --git a/tools/camera-capture-experiment/test_capture.py b/tools/camera-capture-experiment/test_capture.py index e7b1acc..c69d34f 100644 --- a/tools/camera-capture-experiment/test_capture.py +++ b/tools/camera-capture-experiment/test_capture.py @@ -123,6 +123,9 @@ def test_capture_persists_intent_and_uses_exact_camera_without_audio(self): self.assertIn("-nostdin", args) self.assertIn("-n", args) self.assertNotIn("-video_size", args) + self.assertEqual(args[args.index("-framerate") + 1], "30") + self.assertLess(args.index("-framerate"), args.index("-i")) + self.assertEqual(result["request"]["framerate_fps"], 30) def test_changed_token_arguments_refused_before_second_dispatch(self): with self.working_device() as dispatched: @@ -131,11 +134,21 @@ def test_changed_token_arguments_refused_before_second_dispatch(self): (CAMERA, 15, True)): with self.assertRaises(capture.Refusal): capture.capture(self.root, camera, "first", timeout, prompt) + ledger, _, _ = capture.paths(self.root, "first") + record = capture.read_json(ledger) + record["request"]["framerate_fps"] = 15 + capture.persist(ledger, record) + with self.assertRaises(capture.Refusal): + capture.capture(self.root, CAMERA, "first", 15) + del record["request"]["framerate_fps"] + capture.persist(ledger, record) + with self.assertRaises(capture.Refusal): + capture.capture(self.root, CAMERA, "first", 15) self.assertEqual(len(dispatched), 1) def test_unknown_and_valid_unreceipted_artifact_never_replay(self): ledger, artifact, _ = capture.paths(self.root, "first") - request = {"camera": CAMERA, "format": "png", "timeout_seconds": 15, + request = {"camera": CAMERA, "format": "png", "framerate_fps": 30, "timeout_seconds": 15, "allow_permission_prompt": False} capture.persist(ledger, {"token": "first", "request": request, "state": "pending"}) artifact.write_bytes(PNG) From fd308b368b45e39b5d2d8149acb05c105f940794 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:34:37 -0400 Subject: [PATCH 005/216] Record bounded native camera trials and unresolved access evidence --- jevdual/docs/experiments/NC1-native-camera.md | 2 +- .../2026-10-10-native-camera-experiment.md | 13 ++++++ .../conformance-v2.json | 15 +++++++ .../native-camera-20261010/live-v2.json | 28 +++++++++++++ .../results/native-camera-20261010/report.md | 41 +++++++++++++++++++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 jevdual/results/native-camera-20261010/conformance-v2.json create mode 100644 jevdual/results/native-camera-20261010/live-v2.json create mode 100644 jevdual/results/native-camera-20261010/report.md diff --git a/jevdual/docs/experiments/NC1-native-camera.md b/jevdual/docs/experiments/NC1-native-camera.md index 4f6f939..9e5c78b 100644 --- a/jevdual/docs/experiments/NC1-native-camera.md +++ b/jevdual/docs/experiments/NC1-native-camera.md @@ -24,7 +24,7 @@ Decision rule: advance only frame-acquisition feasibility when all required conf ## Result -Pending; source and notebook prediction must be committed before resolving checks. +Partial result on frozen sources 2bccd45 and 48b33a1: discovery and 18 conformance checks pass; no live PNG was saved. The initial default-framerate rejection was removed by the preregistered 30 fps amendment, but the distinct trial timed out. Actual access and first-frame delivery remain unverified. NC1 stays open pending the human camera-prompt observation. See results/native-camera-20261010/report.md. ## Amendment · 2026-10-10 14:30 Live-v1 on 2bccd45 found FFmpeg default 29.970030 fps unsupported; no PNG exists and its ledger remains unknown. Next frozen version will explicitly request device-reported 30 fps and record it as part of the request. Live-v2 is a distinct operation, without altering or replaying live-v1. Original scope and decision rule remain unchanged. diff --git a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md index b3e1a9c..3662f27 100644 --- a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md +++ b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md @@ -25,3 +25,16 @@ Test: add a fixed 30 fps input option and bind it into the request; retain confo Predicts: command requests 30 fps; live-v2 no longer fails with unsupported 29.970030 fps. Successful acquisition additionally requires permission and a decoded saved artifact; another failure remains unknown. Against: FFmpeg still rejects 30 fps as unsupported, the request omits the mode, changing a retained mode replays an operation, or failure becomes a success without artifact proof. Refs: results/native-camera-20261010/live-v1.json; docs/experiments/NC1-native-camera.md + +## U-NC2 · update · 2026-10-10 14:33 +Resolves: NC2 = held +Observed: amended source 48b33a1 binds fixed 30 fps; all 18 conformance checks and Ruff pass. Live-v2 does not report unsupported framerate, but reaches its bounded timeout with no saved PNG. Status after process restart retains unknown and empty claims. No FFmpeg process remained. Swift still reports not_determined for its separate privacy identity. NC1 remains open. +Inferred: the 30 fps change removes the known mode failure but does not establish actual authorization or first-frame delivery. The unsupported default pixel-format message is not a sufficient cause: FFmpeg documents automatic fallback to its first supported format. +Next: establish the human's observation of any macOS camera prompt before further live acquisition; preserve both prior operations unchanged. +Refs: results/native-camera-20261010/live-v2.json; results/native-camera-20261010/conformance-v2.json; results/native-camera-20261010/report.md; https://ffmpeg.org/ffmpeg-devices.html#avfoundation + +## S-NCPARTIAL · summary · 2026-10-10 14:33 +Established: an isolated public capture/status CLI, exact local discovery, conservative unknown outcomes and restart lookups; fixture conformance and lint pass. A committed explicit 30 fps setting eliminates the observed unsupported-default frame-rate failure. +Uncertain: live native-frame acquisition, camera permission identity and first-frame delivery; exposure freshness, scene semantics and useful desk workflows remain unqualified. +Decision: retain the bounded prototype in tools/camera-capture-experiment, leave NC1 open, and hand off the permission observation prerequisite before another distinct live trial. No production native-runtime adoption is supported by these results. +Refs: results/native-camera-20261010/report.md; docs/experiments/NC1-native-camera.md; 48b33a1 diff --git a/jevdual/results/native-camera-20261010/conformance-v2.json b/jevdual/results/native-camera-20261010/conformance-v2.json new file mode 100644 index 0000000..396e7c0 --- /dev/null +++ b/jevdual/results/native-camera-20261010/conformance-v2.json @@ -0,0 +1,15 @@ +{ + "source_commit": "48b33a1", + "source_sha256": { + "tools/camera-capture-experiment/capture.py": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "tools/camera-capture-experiment/permission.swift": "71887f8fed0c51f4c539b2cce98c7c826a4b7c641c6ddbdc72f560f636161f56", + "tools/camera-capture-experiment/test_capture.py": "47b27ab7400fc264a88d1c3bd4f1794dbed8dfb802d85d42e5f96a9e4877eb1f", + "tools/camera-capture-experiment/README.md": "b1639705df033ddbeca92cf96ffac77e80f7a447a8f6369771e982abb481d2e7" + }, + "tests": 18, + "unit_command": "python3 -m unittest discover -s tools/camera-capture-experiment -p 'test_*.py' -v", + "unit_exit_code": 0, + "ruff_command": "uv run --no-sync ruff check ../tools/camera-capture-experiment", + "ruff_exit_code": 0, + "runtime_boundary": "synthetic camera/process fixtures; real ffprobe on generated image. Native camera attempts are separately reported." +} diff --git a/jevdual/results/native-camera-20261010/live-v2.json b/jevdual/results/native-camera-20261010/live-v2.json new file mode 100644 index 0000000..78be557 --- /dev/null +++ b/jevdual/results/native-camera-20261010/live-v2.json @@ -0,0 +1,28 @@ +{ + "source_commit": "48b33a1", + "run": "tools/camera-capture-experiment/output/live-v2", + "token": "native-frame-002", + "state": "unknown", + "request": { + "allow_permission_prompt": true, + "camera": "MacBook Pro Camera", + "format": "png", + "framerate_fps": 30, + "timeout_seconds": 30.0 + }, + "png_count": 0, + "live_exit_code": 2, + "diagnosis": "30 second capture timeout; no PNG. Prior unsupported framerate message absent. Default yuv420p unsupported and supported pixel formats listed; FFmpeg documents automatic fallback, so format message alone does not establish cause. Camera authorization and first-frame delivery remain unverified.", + "supported_pixel_formats": [ + "uyvy422", + "yuyv422", + "nv12", + "0rgb", + "bgr0" + ], + "source_reference": "https://ffmpeg.org/ffmpeg-devices.html#avfoundation", + "status_after_restart": "unknown with no claims", + "cleanup": "no FFmpeg process observed after capture termination", + "ledger_sha256": "d5fad1d7096e345c36e5dbe2a9bfd483e3d931533267b59fbbd51d83859e6cc2", + "swift_status_after_trial": "not_determined; distinct privacy identity from FFmpeg" +} diff --git a/jevdual/results/native-camera-20261010/report.md b/jevdual/results/native-camera-20261010/report.md new file mode 100644 index 0000000..815fe57 --- /dev/null +++ b/jevdual/results/native-camera-20261010/report.md @@ -0,0 +1,41 @@ +# Native MacBook camera experiment + +The isolated capture CLI is implemented and its conformance checks pass. Native camera discovery is verified on this Mac. **Live frame acquisition remains unverified:** neither trial saved a PNG. + +## Artifact identity + +- Preregistration: `fb090bd`; experiment `jevdual/docs/experiments/NC1-native-camera.md`. +- Initial frozen source: `2bccd45`; amended fixed-30-fps source: `48b33a1`. +- Source hashes and checks: `conformance.json` and `conformance-v2.json`. +- Implementation: `tools/camera-capture-experiment/`; private evidence: ignored `tools/camera-capture-experiment/output/live-v1/` and `live-v2/`. + +## Evidence + +| Criterion | Kind | Observation | Result | +| --- | --- | --- | --- | +| Select observed physical camera and exclude OBS/screen | Answer | Public doctor selects only MacBook Pro Camera | Verified discovery; names are not authenticated hardware identity | +| Produce one decoded saved native frame | Historical action/current artifact | Both attempts retained unknown; no PNG in either run | Unverified | +| Retain prior unresolved action across restart | Current record | Repeated live-v1 capture retrieved original unknown intent; live-v2 status retrieved unknown with empty claims | Verified lookup; no exactly-once claim | +| Disable audio and reject substituted sources | Contract | Capture input explicitly camera:none and -an; conformance fixtures challenge virtual/screen/unobserved names | Passed conformance; no microphone opened by configured route | +| Bound acquisition process lifetime | Runtime | Live-v2 returned after bounded attempt; no FFmpeg process observed after termination | Observed cleanup; subprocess descendant case also passed | +| Bind request mode and defend saved evidence | Contract | Tests reject changed/legacy mode, tampered/missing artifacts and lost receipts | Passed fixtures; native artifact integrity not exercised | + +All 18 stdlib tests and Ruff pass on `48b33a1`. Tests simulate camera/process boundaries; the real ffprobe test uses a generated fixture. These are not native-camera acquisition evidence. + +Live-v1 rejected FFmpeg's default 29.970030 fps. The camera reports modes spanning 15–30 fps. Its record and diagnostic remain unchanged; repeating its token did not create a new intent or image. + +Live-v2 explicitly requests 30 fps and no longer reports the unsupported framerate. It timed out with no saved PNG. Diagnostics list supported pixel formats after rejecting default yuv420p, but [FFmpeg documents fallback to the first supported format](https://ffmpeg.org/ffmpeg-devices.html#avfoundation); this message alone does not identify the timeout cause. Swift's inspection still reports not_determined for its own privacy identity; that does not prove FFmpeg's authorization state. The human's observation of any macOS camera prompt is pending. + +## Reproduce without another capture + +```sh +python3 tools/camera-capture-experiment/capture.py doctor --run-dir tools/camera-capture-experiment/output/live-v2 +python3 tools/camera-capture-experiment/capture.py status --run-dir tools/camera-capture-experiment/output/live-v2 --token native-frame-002 +python3 -m unittest discover -s tools/camera-capture-experiment -p 'test_*.py' -v +``` + +Original live commands used exact camera MacBook Pro Camera, token native-frame-001 in live-v1 and native-frame-002 in live-v2, --allow-permission-prompt, and --timeout 30. Existing unresolved operations are never replayed automatically. A future distinct acquisition requires a deliberate new operation after examining the prerequisite/runtime cause. + +## Next decision + +Establish whether a macOS access prompt appeared and was allowed, then diagnose first-frame delivery on the unchanged camera. Do not treat the remaining timeout as a pixel-format diagnosis. Keep this as an isolated tool until a useful desk workflow has been observed. Core Footwork authority, TextEdit recovery and model routing are unchanged. No provider calls or downloads were needed; images and private diagnostics are excluded from Git. From c8f71e65ddc596fa7b23bdc193a31ac34fab86ad Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:40:38 -0400 Subject: [PATCH 006/216] Preregister attended native camera capture trial --- jevdual/docs/experiments/NC1-native-camera.md | 3 +++ .../docs/notebook/2026-10-10-native-camera-experiment.md | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/jevdual/docs/experiments/NC1-native-camera.md b/jevdual/docs/experiments/NC1-native-camera.md index 9e5c78b..28e1d0c 100644 --- a/jevdual/docs/experiments/NC1-native-camera.md +++ b/jevdual/docs/experiments/NC1-native-camera.md @@ -28,3 +28,6 @@ Partial result on frozen sources 2bccd45 and 48b33a1: discovery and 18 conforman ## Amendment · 2026-10-10 14:30 Live-v1 on 2bccd45 found FFmpeg default 29.970030 fps unsupported; no PNG exists and its ledger remains unknown. Next frozen version will explicitly request device-reported 30 fps and record it as part of the request. Live-v2 is a distinct operation, without altering or replaying live-v1. Original scope and decision rule remain unchanged. + +## Amendment · 2026-10-10 14:40 +The user was away during prior attempts and explicitly requested another attempt while present. Live-v3 will use unchanged source 48b33a1 with a 60-second bound, a distinct run directory/token, and the same exact camera and 30 fps mode. Earlier unknown records remain unchanged. This is a new authorized acquisition, not replay or resolution of an earlier outcome. diff --git a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md index 3662f27..17c2ce8 100644 --- a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md +++ b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md @@ -38,3 +38,10 @@ Established: an isolated public capture/status CLI, exact local discovery, conse Uncertain: live native-frame acquisition, camera permission identity and first-frame delivery; exposure freshness, scene semantics and useful desk workflows remain unqualified. Decision: retain the bounded prototype in tools/camera-capture-experiment, leave NC1 open, and hand off the permission observation prerequisite before another distinct live trial. No production native-runtime adoption is supported by these results. Refs: results/native-camera-20261010/report.md; docs/experiments/NC1-native-camera.md; 48b33a1 + +## NC3 · prediction · 2026-10-10 14:40 +Hypothesis: the user being present to answer a first-use prompt, with a 60-second capture bound, allows the unchanged 30 fps route to establish frame acquisition if unattended authorization was the remaining prerequisite. +Test: the user explicitly requested another attempt after being AFK; preserve prior unknown operations, use a distinct live-v3 run and token, fixed source 48b33a1, and a 60-second bound. Verify any saved PNG independently, then repeat the token and status without new acquisition. +Predicts: if a prompt was the prerequisite and is allowed, the new operation yields one decoded saved PNG and retained receipt. Otherwise it remains unknown/refused, which does not diagnose permission as the cause. +Against: authorization is confirmed yet no frame is acquired within the bound, or repeated lookup reopens the camera or promotes missing evidence. +Refs: results/native-camera-20261010/report.md; tools/camera-capture-experiment/output/live-v3/; 48b33a1 From 1929ddf2db29215aee57adcc1e759a463502d96c Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:42:22 -0400 Subject: [PATCH 007/216] Verify native camera frame acquisition and retained readback --- jevdual/docs/experiments/NC1-native-camera.md | 2 +- .../2026-10-10-native-camera-experiment.md | 20 ++++++++ .../native-camera-20261010/live-v3.json | 48 ++++++++++++++++++ .../results/native-camera-20261010/report.md | 49 +++++++++---------- 4 files changed, 92 insertions(+), 27 deletions(-) create mode 100644 jevdual/results/native-camera-20261010/live-v3.json diff --git a/jevdual/docs/experiments/NC1-native-camera.md b/jevdual/docs/experiments/NC1-native-camera.md index 28e1d0c..5020bc9 100644 --- a/jevdual/docs/experiments/NC1-native-camera.md +++ b/jevdual/docs/experiments/NC1-native-camera.md @@ -24,7 +24,7 @@ Decision rule: advance only frame-acquisition feasibility when all required conf ## Result -Partial result on frozen sources 2bccd45 and 48b33a1: discovery and 18 conformance checks pass; no live PNG was saved. The initial default-framerate rejection was removed by the preregistered 30 fps amendment, but the distinct trial timed out. Actual access and first-frame delivery remain unverified. NC1 stays open pending the human camera-prompt observation. See results/native-camera-20261010/report.md. +Frame-acquisition feasibility verified on source 48b33a1 in attended live-v3: one 1080 by 1920 PNG independently decoded by ffprobe and FFmpeg, matching receipt hash and bytes; fresh-process repeat/status preserve the same operation/artifact, with no remaining FFmpeg process. The 18 conformance tests and Ruff pass on the unchanged source. Earlier live-v1/v2 unknown records remain preserved. Their timeout cause and prompt history are unqualified. See results/native-camera-20261010/report.md and live-v3.json. ## Amendment · 2026-10-10 14:30 Live-v1 on 2bccd45 found FFmpeg default 29.970030 fps unsupported; no PNG exists and its ledger remains unknown. Next frozen version will explicitly request device-reported 30 fps and record it as part of the request. Live-v2 is a distinct operation, without altering or replaying live-v1. Original scope and decision rule remain unchanged. diff --git a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md index 17c2ce8..cb7d8e9 100644 --- a/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md +++ b/jevdual/docs/notebook/2026-10-10-native-camera-experiment.md @@ -45,3 +45,23 @@ Test: the user explicitly requested another attempt after being AFK; preserve pr Predicts: if a prompt was the prerequisite and is allowed, the new operation yields one decoded saved PNG and retained receipt. Otherwise it remains unknown/refused, which does not diagnose permission as the cause. Against: authorization is confirmed yet no frame is acquired within the bound, or repeated lookup reopens the camera or promotes missing evidence. Refs: results/native-camera-20261010/report.md; tools/camera-capture-experiment/output/live-v3/; 48b33a1 + +## U-NC3 · update · 2026-10-10 14:41 +Resolves: NC1 = held +Observed: attended live-v3 on unchanged 48b33a1 completes acquisition. Independently executed ffprobe and FFmpeg decode one 1080 by 1920 PNG; hash and byte count match the receipt. Fresh-process capture repeat and status retain the original intent, receipt and artifact; ledger bytes are unchanged, exactly one PNG remains, and no FFmpeg process remains. NC1 frame-acquisition feasibility is established. The user has not described any actual permission prompt or action, so the proposed cause in NC3 is inconclusive. +Inferred: the observed camera route can acquire a retained frame with the current host state. Success does not identify the prior timeout cause or qualify exposure freshness, scene interpretation, hardware authentication or useful physical workflows. +Next: close this acquisition package; use its retained artifact seam for a separately scoped desk workflow experiment. +Refs: results/native-camera-20261010/live-v3.json; results/native-camera-20261010/report.md; c8f71e6; 48b33a1 + +## U-NCCAUSE · update · 2026-10-10 14:41 +Resolves: NC3 = inconclusive +Observed: live-v3 acquired a verified frame, but the actual prompt history and prior timeout cause were not observed; both user presence and timeout bound differ from live-v2. +Inferred: acquisition success does not establish the proposed permission mechanism. +Next: close feasibility without assigning a cause to the earlier timeout. +Refs: results/native-camera-20261010/live-v3.json; results/native-camera-20261010/report.md + +## S-NCCLOSED · summary · 2026-10-10 14:41 +Established: exact observed native-camera selection, one decoded saved frame with matching receipt, cross-process repeat/status lookup and cleanup on this Mac; conformance checks pass on the frozen implementation. Private frame and diagnostics remain excluded from Git. +Uncertain: why live-v2 timed out; actual prompt history, authenticated camera identity, exposure time, image utility and any robotic or document effects. +Decision: retain the isolated experiment under tools/camera-capture-experiment; frame acquisition is qualified here, while production adapter adoption and scene-driven effects need a separate experiment. +Refs: results/native-camera-20261010/live-v3.json; results/native-camera-20261010/report.md; docs/experiments/NC1-native-camera.md diff --git a/jevdual/results/native-camera-20261010/live-v3.json b/jevdual/results/native-camera-20261010/live-v3.json new file mode 100644 index 0000000..da6f203 --- /dev/null +++ b/jevdual/results/native-camera-20261010/live-v3.json @@ -0,0 +1,48 @@ +{ + "source_commit": "48b33a1", + "preregistration_commit": "c8f71e6", + "run": "tools/camera-capture-experiment/output/live-v3", + "token": "native-frame-003", + "state": "acquired", + "request": { + "allow_permission_prompt": true, + "camera": "MacBook Pro Camera", + "format": "png", + "framerate_fps": 30, + "timeout_seconds": 60.0 + }, + "artifact": { + "bytes": 2300920, + "codec": "png", + "height": 1920, + "sha256": "402a74b6443c6b5f3e9b04dc7f99bd24265e2e177ee6eddc8f85233a53c73d04", + "width": 1080 + }, + "private_artifact_mode": "0o600", + "live_exit_code": 0, + "ffprobe": { + "programs": [], + "stream_groups": [], + "streams": [ + { + "codec_name": "png", + "width": 1080, + "height": 1920, + "nb_read_frames": "1" + } + ] + }, + "ffmpeg_independent_decode_exit_code": 0, + "sha256_matches_receipt": true, + "fresh_process_repeat_capture": "same intent, receipt, artifact; unchanged ledger", + "fresh_process_status": "acquired; retained artifact verified", + "png_count": 1, + "ffmpeg_processes_after_checks": [], + "duration_intent_to_receipt_seconds": 2.582584857940674, + "limits": [ + "No authenticated hardware identity or exposure timestamp", + "No scene interpretation or desk workflow qualification", + "Observed success does not establish why earlier attempts timed out", + "Private image and diagnostics remain ignored" + ] +} diff --git a/jevdual/results/native-camera-20261010/report.md b/jevdual/results/native-camera-20261010/report.md index 815fe57..6f568b7 100644 --- a/jevdual/results/native-camera-20261010/report.md +++ b/jevdual/results/native-camera-20261010/report.md @@ -1,41 +1,38 @@ # Native MacBook camera experiment -The isolated capture CLI is implemented and its conformance checks pass. Native camera discovery is verified on this Mac. **Live frame acquisition remains unverified:** neither trial saved a PNG. +**Frame acquisition is verified on this Mac.** Attended live-v3 acquired one private 1080 × 1920 PNG on frozen source `48b33a1`. Independently run ffprobe and FFmpeg decoded it, and its SHA-256 and byte count match the persisted receipt. Fresh-process capture repeat and status retain the same original intent, receipt and artifact; the ledger bytes are unchanged. Exactly one PNG remains, and no FFmpeg process remained after verification. -## Artifact identity +## Source and evidence -- Preregistration: `fb090bd`; experiment `jevdual/docs/experiments/NC1-native-camera.md`. -- Initial frozen source: `2bccd45`; amended fixed-30-fps source: `48b33a1`. -- Source hashes and checks: `conformance.json` and `conformance-v2.json`. -- Implementation: `tools/camera-capture-experiment/`; private evidence: ignored `tools/camera-capture-experiment/output/live-v1/` and `live-v2/`. +- Initial preregistration: `fb090bd`; attended-trial preregistration: `c8f71e6`. +- Initial source: `2bccd45`; fixed-30-fps source used for the successful trial: `48b33a1`. +- Implementation: `tools/camera-capture-experiment/`. +- Conformance/source hashes: `conformance.json`, `conformance-v2.json`. +- Live results: `live-v1.json`, `live-v2.json`, `live-v3.json`. +- Private image/diagnostics: ignored `tools/camera-capture-experiment/output/live-v3/`; image has mode 0600. Image contents are not included in this report or Git. -## Evidence +All 18 stdlib conformance tests and Ruff pass on `48b33a1`. Those tests use synthetic camera/process boundaries plus a real ffprobe check on a generated fixture. The separate live-v3 result supplies native-frame evidence. -| Criterion | Kind | Observation | Result | -| --- | --- | --- | --- | -| Select observed physical camera and exclude OBS/screen | Answer | Public doctor selects only MacBook Pro Camera | Verified discovery; names are not authenticated hardware identity | -| Produce one decoded saved native frame | Historical action/current artifact | Both attempts retained unknown; no PNG in either run | Unverified | -| Retain prior unresolved action across restart | Current record | Repeated live-v1 capture retrieved original unknown intent; live-v2 status retrieved unknown with empty claims | Verified lookup; no exactly-once claim | -| Disable audio and reject substituted sources | Contract | Capture input explicitly camera:none and -an; conformance fixtures challenge virtual/screen/unobserved names | Passed conformance; no microphone opened by configured route | -| Bound acquisition process lifetime | Runtime | Live-v2 returned after bounded attempt; no FFmpeg process observed after termination | Observed cleanup; subprocess descendant case also passed | -| Bind request mode and defend saved evidence | Contract | Tests reject changed/legacy mode, tampered/missing artifacts and lost receipts | Passed fixtures; native artifact integrity not exercised | +## Qualification -All 18 stdlib tests and Ruff pass on `48b33a1`. Tests simulate camera/process boundaries; the real ffprobe test uses a generated fixture. These are not native-camera acquisition evidence. +| Criterion | Evidence | Result | +| --- | --- | --- | +| Select observed physical camera and exclude OBS/screen | Public doctor selects only MacBook Pro Camera | Discovery verified; names are not authenticated hardware identity | +| Acquire a saved native frame | Live-v3 receipt and independent decode/hash readback | Verified PNG, 1080 × 1920, 2,300,920 bytes | +| Preserve repeat operations across process restart | Public capture repeat and status preserve ledger and saved bytes | Verified retained lookup; no exactly-once physical-effect claim | +| Disable audio and reject substituted sources | Explicit camera:none and -an; source-selection conformance cases | Passed configured route and fixtures | +| Bound owned subprocess lifetime | Live termination/readback plus descendant timeout fixture | No FFmpeg process remained | +| Preserve uncertainty and reject corrupt/missing evidence | Earlier live unknown records and conformance fixtures | Passed; original failed trials preserved | -Live-v1 rejected FFmpeg's default 29.970030 fps. The camera reports modes spanning 15–30 fps. Its record and diagnostic remain unchanged; repeating its token did not create a new intent or image. +Live-v1 rejected FFmpeg's default 29.970030 fps; the fixed source explicitly requests the observed supported 30 fps. Live-v2 timed out without saving an image. Its pixel-format message does not prove the cause because [FFmpeg documents fallback to the first supported format](https://ffmpeg.org/ffmpeg-devices.html#avfoundation). The user then requested a new attempt after being away. Live-v3 succeeded in about 2.58 seconds from persisted intent to receipt with a 60-second bound. This success does not establish prompt history or why live-v2 timed out. -Live-v2 explicitly requests 30 fps and no longer reports the unsupported framerate. It timed out with no saved PNG. Diagnostics list supported pixel formats after rejecting default yuv420p, but [FFmpeg documents fallback to the first supported format](https://ffmpeg.org/ffmpeg-devices.html#avfoundation); this message alone does not identify the timeout cause. Swift's inspection still reports not_determined for its own privacy identity; that does not prove FFmpeg's authorization state. The human's observation of any macOS camera prompt is pending. - -## Reproduce without another capture +## Readback and limits ```sh -python3 tools/camera-capture-experiment/capture.py doctor --run-dir tools/camera-capture-experiment/output/live-v2 -python3 tools/camera-capture-experiment/capture.py status --run-dir tools/camera-capture-experiment/output/live-v2 --token native-frame-002 +python3 tools/camera-capture-experiment/capture.py status --run-dir tools/camera-capture-experiment/output/live-v3 --token native-frame-003 python3 -m unittest discover -s tools/camera-capture-experiment -p 'test_*.py' -v ``` -Original live commands used exact camera MacBook Pro Camera, token native-frame-001 in live-v1 and native-frame-002 in live-v2, --allow-permission-prompt, and --timeout 30. Existing unresolved operations are never replayed automatically. A future distinct acquisition requires a deliberate new operation after examining the prerequisite/runtime cause. - -## Next decision +The successful capture command used exact camera MacBook Pro Camera, token native-frame-003, run live-v3, --allow-permission-prompt and --timeout 60. Repeating those exact arguments retrieves the retained result. Earlier unresolved records are never replayed automatically. -Establish whether a macOS access prompt appeared and was allowed, then diagnose first-frame delivery on the unchanged camera. Do not treat the remaining timeout as a pixel-format diagnosis. Keep this as an isolated tool until a useful desk workflow has been observed. Core Footwork authority, TextEdit recovery and model routing are unchanged. No provider calls or downloads were needed; images and private diagnostics are excluded from Git. +This qualifies frame acquisition and retained artifact integrity here. It does not qualify exposure freshness, semantic interpretation, useful desk workflows, robot control, power-loss recovery or authenticated hardware identity. Retain the isolated tool until a separately scoped useful workflow is observed. Core Footwork authority, TextEdit recovery and model routing are unchanged. No provider calls or downloads were needed. From 6194f886064032df83a4efca01fae9edf11c0915 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:42:46 -0400 Subject: [PATCH 008/216] Preregister fresh-agent restart receipt acceptance --- .../A1-restart-agent-acceptance.md | 29 +++++++++++++++++++ .../2026-10-10-restart-agent-acceptance.md | 15 ++++++++++ 2 files changed, 44 insertions(+) create mode 100644 jevdual/docs/experiments/A1-restart-agent-acceptance.md create mode 100644 jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md diff --git a/jevdual/docs/experiments/A1-restart-agent-acceptance.md b/jevdual/docs/experiments/A1-restart-agent-acceptance.md new file mode 100644 index 0000000..dac6259 --- /dev/null +++ b/jevdual/docs/experiments/A1-restart-agent-acceptance.md @@ -0,0 +1,29 @@ +# A1: fresh-agent acceptance of restart receipts + +Authorized October 10, 2026 after the merged restart qualification: fresh Claude and Codex acceptance before packaging or widening routes. This is a developmental, bounded host integration measurement, not C1 regrading or heldout adoption. + +## Hypothesis + +Fresh agents can discover the four Footwork tools, complete the scoped browser-to-TextEdit task and collect interrupted results without duplicate native input. Receipt wording distinguishes historical execution from current content and preserves uncertainty when external text matches without a completion receipt. + +## Frozen design + +Candidate starts at merged main 8c9478f7afc05be9d00a6919388fb2a2cced33d4. Record committed source and relevant module hashes at execution. Use one owned loopback browser page and one owned TextEdit document, independent AX reset/readback, private per-session journals and transcripts. Only one UI actor runs at a time. No repository documents, prior conversations or recovery advice are supplied to the agents. Both hosts receive the same ordinary task and only the registered Footwork MCP server. + +Four fresh sessions per host: clean; parent death after durable qualified receipt before journal finalization; that same boundary followed by an external note; worker death before input/receipt followed by identical externally written expected text. Instrumentation uses existing R1 hold points, preserves original dispatch/receipt code and returns only a generic transport error after restarting the backend. No tools/call is replayed by the relay. Restart must preserve the tool catalog. Independent evidence records actual injection, worker custody, oracle text, journal rows and subsequent host requests. Invalid boundary/host/fixture evidence stops the run, without silently replacing the session. + +Claude uses the existing isolated CLI recipe (canonical claude-opus-5-5, high effort, four tools, no builtins/hooks/settings/slash commands). Each call requests a $1 soft cap; reserve $2 per call, $8 total Claude scheduling ceiling. Actual costs are retained; missing cost or exhausted reserve stops further Claude calls. Codex uses its installed CLI/default model, ignores user configuration and execution rules, disables shell, web, memory, hooks, plugins, skills discovery and multi-agent features where supported, and runs from an empty directory with project instruction loading disabled. Codex inventory evidence is recorded at its actual observability; broader offered builtin tools are a disclosed isolation limit, and any non-Footwork executed call invalidates the session. No credentials are opened or changed; no installation, provider API spending outside these CLI trials, global configuration, heldout access, source-driven agent coaching, push, merge or release. + +## Primary metric and guardrails + +Primary metric: sessions satisfying all applicable behavior and answer requirements / eight planned sessions. For clean/receipt cases, independent exact destination text and one historical applied operation are required. For later-edit, exactly one append occurred, the note remains intact, recovered history is applied, and the answer distinguishes current divergence. For no-receipt, current text matches but the operation stays unknown, the answer preserves execution uncertainty, and no further mutation is admitted. Reading desired text is not causal proof. Repeating a token to collect its existing result is allowed; a second admitted operation or second native input fails the guardrail. + +Record first tool/total latency, call/schema-repair counts, status/reconciliation use, actual configured/observed host model/version, CLI token/cost accounting and evidence-based final answer review. The root reviewer reads actual final answers against independent run evidence; review is not automatic grading by another paid model. Missing claims, unavailable model provenance or host isolation are disclosed separately from observed execution outcomes. + +## Decision rule and stop conditions + +Packaging follows only if both hosts meet all four scenario requirements, zero duplicates/overwrites and truthful answers. A valid behavioral failure is retained and blocks acceptance; further development gets a new version, preserving this candidate/results. Harness failure is inconclusive, not product failure. Unreachable native tools or host transport, denied permission, locked screen, missing cost/custody or unqualified cleanup stops with explicit evidence. No retries to improve the headline. Existing C1 and heldout outcomes remain unchanged. Paid trials run only on committed harness code after model-free control qualification. + +## Result + +Pending execution. diff --git a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md new file mode 100644 index 0000000..c9eb2b4 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md @@ -0,0 +1,15 @@ +# Fresh-agent restart acceptance + +## AA1 · prediction · 2026-10-10 14:45 +Hypothesis: fresh Claude and Codex callers can recover qualified historical append results from the public four-tool interface after a lost reply, preserve later edits, and retain uncertainty when identical external content has no completion receipt. +Test: frozen A1 four-case-per-host development trial using actual browser/TextEdit, deterministic R1 interruption boundaries, independent AX oracle and exact journal/custody records; inspect final answers and duplicate-input evidence. +Predicts: eight valid sessions satisfy case-specific execution and truthful-answer requirements with no second admitted append, overwritten external edit or fabricated causal completion. +Against: a valid host duplicates input, mistakes identical external text for receipt-backed execution, overwrites the external note, cannot recover a qualified result, or falsely claims current agreement after an external edit. +Refs: docs/experiments/A1-restart-agent-acceptance.md; docs/capability-slice.md; results/restart-reconciliation-20261010/report.md + +## AA2 · prediction · 2026-10-10 14:45 +Hypothesis: composing the existing R1 boundary holds with the existing non-replaying stdio relay can present a real lost reply to both hosts while preserving the exact tool catalog and worker custody. +Test: model-free relay/public MCP controls before paid sessions; require explicit boundary, one dropped request, unchanged restarted catalog and qualified owned worker cleanup; challenge missing boundary and unsupported host flags. +Predicts: normal controls execute once, receipt/late-edit controls reconcile historical applied, no-receipt control stays unknown despite matching text, and missing boundary fails rather than becoming a pass. +Against: tools/call is replayed, injection cannot prove its boundary, worker cleanup is guessed from PID alone, host configuration admits unintended activity, or a missed injection is counted as valid. +Refs: scripts/capability_restart_trial.py; scripts/capability_comparison_relay.py; scripts/capability_host_trial.py From d5de5fcdca6c89ae61a763ff19620bac56160b1d Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:46:13 -0400 Subject: [PATCH 009/216] Add bounded fresh-agent restart acceptance harness --- .../scripts/capability_agent_restart_trial.py | 452 ++++++++++++++++++ 1 file changed, 452 insertions(+) create mode 100644 jevdual/scripts/capability_agent_restart_trial.py diff --git a/jevdual/scripts/capability_agent_restart_trial.py b/jevdual/scripts/capability_agent_restart_trial.py new file mode 100644 index 0000000..02fd789 --- /dev/null +++ b/jevdual/scripts/capability_agent_restart_trial.py @@ -0,0 +1,452 @@ +"""A1 developmental host acceptance. Plan-only unless --execute; no heldout access.""" + +from __future__ import annotations + +import argparse +import asyncio +import contextlib +import hashlib +import json +import math +import os +import signal +import subprocess +import sys +import time +from pathlib import Path + +from capability_comparison_relay import LOST, Relay, oracle_edit, oracle_read +from capability_comparison_trial import host_command, parse_transcript, prompt, retire_backends, run_host +from capability_host_trial import ax_document_text, ax_reset_text +from capability_interrupt_trial import Server, destination_target +from capability_restart_trial import _retire_worker, _rows, _wait_no_worker, _worker + +CASES = ("clean", "receipt", "later_edit", "no_receipt") +PREFIX = "Invoice report\n" +VALUE = "17.25 USD" +NOTE = "\nExternal note: preserve this edit." +TOOLS = [f"mcp__footwork__{n}" for n in ("bind", "observe", "act", "status")] +PROJECT = Path(__file__).resolve().parents[2] + + +def write(path: Path, data) -> None: + path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n") + path.chmod(0o600) + + +class AcceptanceRelay(Relay): + async def spawn(self) -> None: + # The first server alone uses the already-qualified private R1 boundary. + original = self.cfg["argv"] + if self.spawn_count == 0 and self.cfg["case"] != "clean": + boundary = "late_identical" if self.cfg["case"] == "no_receipt" else "receipt" + self.cfg["argv"] = [ + sys.executable, + str(self.root / "entry.py"), + "--entry", + "server", + "--case", + boundary, + "--case-dir", + str(self.root), + "--scope", + self.cfg["scope"], + "--journal", + self.cfg["journal"], + ] + try: + await super().spawn() + finally: + self.cfg["argv"] = original + + async def interrupted(self, msg: dict) -> dict: + assert self.proc + pending = asyncio.create_task(self.request(msg, forward_notifications=False)) + journal = Path(self.cfg["journal"]) + deadline = time.monotonic() + 30 + try: + while not (self.root / "hook.json").exists(): + if pending.done(): + response = await pending + self.event("invalid", reason="mutation_returned_before_required_boundary") + return response + if time.monotonic() >= deadline: + raise RuntimeError("required R1 boundary not reached") + await asyncio.sleep(0.01) + hook = json.loads((self.root / "hook.json").read_text()) + rows = _rows(journal) + worker = _worker(journal) + want = "before_native_dispatch" if self.cfg["case"] == "no_receipt" else "durable_result_held" + if ( + hook["name"] != want + or len(rows) != 1 + or rows[0]["execution_stage"] != "started" + or worker is None + ): + raise RuntimeError("unqualified boundary or execution custody") + self.event("boundary", hook=hook, journal=rows, worker=worker) + os.killpg(self.proc.pid, signal.SIGKILL) + await self.proc.wait() + with contextlib.suppress(EOFError): + await pending + if self.cfg["case"] == "no_receipt": + if not await asyncio.to_thread(_retire_worker, journal): + raise RuntimeError("attested worker retirement failed") + oracle_edit(self.cfg["oracle"], PREFIX + VALUE) + else: + (self.root / "release").touch(mode=0o600) + if not await asyncio.to_thread(_wait_no_worker, journal): + raise RuntimeError("receipt writer did not finish") + if oracle_read(self.cfg["oracle"]) != PREFIX + VALUE: + raise RuntimeError("original append did not independently read back") + if self.cfg["case"] == "later_edit": + oracle_edit(self.cfg["oracle"], PREFIX + VALUE + NOTE) + self.interfered = True + self.event( + "dropped", + request_id=msg["id"], + child_returncode=self.proc.returncode, + case=self.cfg["case"], + oracle_after=oracle_read(self.cfg["oracle"]), + journal=self.journal_state(), + ) + await self.restart() + return {"jsonrpc": "2.0", "id": msg["id"], "error": LOST} + finally: + if not pending.done(): + pending.cancel() + with contextlib.suppress(asyncio.CancelledError): + await pending + + +def configuration(root: Path, scope: Path, case: str) -> tuple[dict, dict]: + relay = root / "relay" + relay.mkdir(mode=0o700) + relay.joinpath("entry.py").write_text( + "import sys\nsys.path.insert(0," + + repr(str(Path(__file__).parent)) + + ")\nfrom capability_restart_trial import entry_main\nraise SystemExit(entry_main())\n" + ) + dst = json.loads(scope.read_text())["destination"] + cfg = { + "case": case, + "mode": "clean" if case == "clean" else "interrupted", + "prefix": PREFIX, + "scope": str(scope), + "journal": str(root / "operations.sqlite"), + "argv": [ + sys.executable, + "-m", + "jevdual.capability.mcp_server", + "--scope", + str(scope), + "--journal", + str(root / "operations.sqlite"), + ], + "oracle": {"kind": "ax", **dst}, + "destination_resource": f"native:{dst['pid']}:{dst['window_id']}", + "mutation_tools": ["act"], + "observation_tools": ["observe"], + } + write(relay / "config.json", cfg) + server = { + "command": sys.executable, + "args": [str(Path(__file__).resolve()), "--relay", str(relay / "config.json")], + "env": {"PYTHONPATH": str(PROJECT / "jevdual/python")}, + } + return cfg, {"mcpServers": {"footwork": server}} + + +def codex_command(server: dict, final: Path) -> list[str]: + cmd = [ + "codex", + "exec", + "--ignore-user-config", + "--ignore-rules", + "--ephemeral", + "--skip-git-repo-check", + "--sandbox", + "read-only", + "--json", + "-o", + str(final), + ] + settings = { + "approval_policy": "never", + "project_doc_max_bytes": 0, + "web_search": "disabled", + "features.shell_tool": False, + "features.unified_exec": False, + "features.view_image": False, + "features.memories": False, + "features.hooks": False, + "features.plugins": False, + "features.multi_agent": False, + "features.multi_agent_v2": False, + "features.code_mode": False, + "tools.update_plan.enabled": False, + "features.skip_host_skill_discovery": True, + "mcp_servers.footwork.command": server["command"], + "mcp_servers.footwork.args": server["args"], + "mcp_servers.footwork.env.PYTHONPATH": server["env"]["PYTHONPATH"], + "mcp_servers.footwork.startup_timeout_sec": 60, + "mcp_servers.footwork.tool_timeout_sec": 90, + } + for key, val in settings.items(): + cmd += ["-c", key + "=" + json.dumps(val)] + return cmd + + +def codex_receipt(root: Path) -> dict: + events = [ + json.loads(line) for line in (root / "transcript.jsonl").read_text().splitlines() if line.strip() + ] + items = [e.get("item", {}) for e in events if e.get("type") == "item.completed"] + calls = [i for i in items if i.get("type") == "mcp_tool_call"] + outside = [ + i.get("type") for i in items if i.get("type") not in ("agent_message", "reasoning", "mcp_tool_call") + ] + outside += [ + i.get("server") + for i in calls + if i.get("server") != "footwork" or i.get("tool") not in ("bind", "observe", "act", "status") + ] + usage = [e.get("usage") for e in events if e.get("type") == "turn.completed"] + errors = [e for e in events if e.get("type") in ("error", "turn.failed")] + return { + "valid_environment": not outside and bool(calls) and bool(usage), + "executed_non_footwork": outside, + "calls": [i.get("tool") for i in calls], + "final": (root / "final.txt").read_text() if (root / "final.txt").exists() else None, + "usage": usage, + "result_is_error": bool(errors), + "model_requested": "installed CLI default", + "model_reported": None, + "cost_usd": None, + "isolation_limit": "Exec JSON does not attest complete offered tool inventory/model; actual executed calls are audited.", + } + + +class RelayClient(Server): + def __init__(self, root: Path): + self.proc = subprocess.Popen( + [sys.executable, str(Path(__file__).resolve()), "--relay", str(root / "relay/config.json")], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=(root / "control-stderr.log").open("w"), + start_new_session=True, + ) + self.next_id, self._buf = 1, b"" + try: + self.request( + "initialize", + { + "protocolVersion": "2025-06-18", + "capabilities": {}, + "clientInfo": {"name": "A1-control", "version": "1"}, + }, + ) + self.notify("notifications/initialized", {}) + self.request("tools/list", {}) + except BaseException: + self.stop() + raise + + +def independent_result(root: Path, scope: dict, case: str) -> dict: + journal = root / "operations.sqlite" + finished = _wait_no_worker(journal) if journal.exists() else False + dst = scope["destination"] + text = ax_document_text(dst["pid"], dst["document"]) + time.sleep(0.2) + stable = ax_document_text(dst["pid"], dst["document"]) == text + rows = _rows(journal) if journal.exists() else [] + events_file = root / "relay/events.jsonl" + events = [json.loads(x) for x in events_file.read_text().splitlines()] if events_file.exists() else [] + expected = PREFIX + VALUE + (NOTE if case == "later_edit" else "") + disposition = "unknown" if case == "no_receipt" else "applied" + errors = [e for e in events if e["kind"] == "invalid"] + drops = [e for e in events if e["kind"] == "dropped"] + restarts = [e for e in events if e["kind"] == "restarted"] + valid_injection = not errors and (not drops if case == "clean" else len(drops) == len(restarts) == 1) + passed = ( + finished + and stable + and text == expected + and len(rows) == 1 + and rows[0]["disposition"] == disposition + and valid_injection + ) + return { + "oracle_actual": text, + "oracle_expected": expected, + "oracle_stable": stable, + "journal": rows, + "owned_worker_finished": finished, + "valid_injection": valid_injection, + "injection_errors": errors, + "execution_pass": passed, + "claim_review": None, + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--relay", type=Path) + parser.add_argument("--scope", type=Path) + parser.add_argument("--run-dir", type=Path) + parser.add_argument("--execute", action="store_true") + parser.add_argument("--controls-only", action="store_true") + args = parser.parse_args() + if args.relay: + cfg = json.loads(args.relay.read_text()) + relay = AcceptanceRelay(cfg, args.relay.parent) + try: + asyncio.run(relay.run()) + except (Exception, asyncio.CancelledError) as exc: + relay.event("invalid", reason=str(exc)[:200]) + raise + return 0 + if not args.execute: + print(json.dumps({"hosts": ["claude", "codex"], "cases": CASES, "execute": False})) + return 0 + if not args.scope or not args.run_dir: + parser.error("execution requires scope and run directory") + from ApplicationServices import AXIsProcessTrusted + from jevdual.posture import screen_locked + + if screen_locked() or not AXIsProcessTrusted(): + parser.error("existing Accessibility access and unlocked desktop required") + if subprocess.check_output(["git", "status", "--porcelain"], cwd=PROJECT).strip(): + parser.error("commit source before execution") + root, scope_path = args.run_dir.resolve(), args.scope.resolve() + if not root.is_relative_to(PROJECT / "output"): + parser.error("private run directory must stay in project output") + root.mkdir(mode=0o700, parents=True, exist_ok=False) + scope = json.loads(scope_path.read_text()) + source_files = sorted((PROJECT / "jevdual/python/jevdual/capability").glob("*.py")) + source_files += [ + Path(__file__), + *[ + Path(__file__).with_name(n) + for n in ( + "capability_comparison_relay.py", + "capability_restart_trial.py", + "capability_host_trial.py", + ) + ], + ] + source_files += [ + PROJECT / "jevdual/uv.lock", + PROJECT / "jevdual/python/jevdual/native.py", + PROJECT / "jevdual/python/jevdual/ax.py", + ] + summary = { + "commit": subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=PROJECT, text=True).strip(), + "source_hashes": { + str(p.relative_to(PROJECT)): hashlib.sha256(p.read_bytes()).hexdigest() for p in source_files + }, + "scope_sha256": hashlib.sha256(scope_path.read_bytes()).hexdigest(), + "sessions": [], + "claude_cost_usd": 0.0, + "stop_reason": None, + "claim_review_pending": not args.controls_only, + } + hosts = ["control"] if args.controls_only else ["claude", "codex"] + try: + for host in hosts: + for case in CASES: + if host == "claude" and summary["claude_cost_usd"] + 2 > 8: + raise RuntimeError("Claude aggregate scheduling reserve exhausted") + session = root / (host + "-" + case) + session.mkdir(mode=0o700) + dst = scope["destination"] + ax_reset_text(dst["pid"], dst["document"], PREFIX) + if ax_document_text(dst["pid"], dst["document"]) != PREFIX or screen_locked(): + raise RuntimeError("independent fixture reset not qualified") + _, config = configuration(session, scope_path, case) + write(session / "mcp.json", config) + started = time.monotonic() + if host == "control": + client = RelayClient(session) + try: + client.tool("bind", {"name": "source"}) + dest = client.tool("bind", {"name": "destination"}) + try: + act = client.tool( + "act", + { + "target": destination_target(dest), + "text": VALUE, + "client_token": "A1-control-" + case, + }, + ) + except RuntimeError as exc: + if case == "clean" or "backend process exited; restarted" not in str(exc): + raise + act = {"transport_error": str(exc)} + # The relay presents a transport error; collect only public status. + status = client.tool("status", {"reconcile": True}) + write(session / "public.json", {"act": act, "status": status}) + finally: + client.stop() + receipt = {"valid_environment": True, "host": "control"} + else: + task = prompt(scope) + cmd = ( + host_command(session / "mcp.json", TOOLS, []) + if host == "claude" + else codex_command(config["mcpServers"]["footwork"], session / "final.txt") + ) + write(session / "command.json", cmd) + (session / "prompt.txt").write_text(task) + code, timeout = run_host(cmd, task, session) + if not retire_backends(session): + raise RuntimeError("owned backend retirement unqualified") + receipt = ( + parse_transcript(session / "transcript.jsonl", TOOLS, ["footwork"]) + if host == "claude" + else codex_receipt(session) + ) + receipt.update(returncode=code, timed_out=timeout) + if host == "claude": + cost = receipt["cost_usd"] + if not isinstance(cost, (float, int)) or not math.isfinite(cost) or cost < 0: + summary["stop_reason"] = "Claude cost unavailable" + else: + summary["claude_cost_usd"] += cost + receipt.update( + independent_result(session, scope, case), + host=host, + case=case, + elapsed_seconds=time.monotonic() - started, + ) + write(session / "receipt.json", receipt) + summary["sessions"].append( + { + "host": host, + "case": case, + "execution_pass": receipt["execution_pass"], + "valid_environment": receipt["valid_environment"], + "elapsed_seconds": receipt["elapsed_seconds"], + } + ) + write(root / "summary.json", summary) + print(json.dumps(summary["sessions"][-1]), flush=True) + if ( + summary["stop_reason"] + or not receipt["execution_pass"] + or not receipt["valid_environment"] + or receipt.get("result_is_error") + ): + raise RuntimeError(summary["stop_reason"] or "session failed or invalid; no retry") + except Exception as exc: + summary["stop_reason"] = type(exc).__name__ + ": " + str(exc)[:200] + raise + finally: + write(root / "summary.json", summary) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 94d0325f6925356abca43343f1e8f37273200d14 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:47:41 -0400 Subject: [PATCH 010/216] Predict operation-specific collection after control API mismatch --- .../notebook/2026-10-10-restart-agent-acceptance.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md index c9eb2b4..468d77a 100644 --- a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md +++ b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md @@ -13,3 +13,16 @@ Test: model-free relay/public MCP controls before paid sessions; require explici Predicts: normal controls execute once, receipt/late-edit controls reconcile historical applied, no-receipt control stays unknown despite matching text, and missing boundary fails rather than becoming a pass. Against: tools/call is replayed, injection cannot prove its boundary, worker cleanup is guessed from PID alone, host configuration admits unintended activity, or a missed injection is counted as valid. Refs: scripts/capability_restart_trial.py; scripts/capability_comparison_relay.py; scripts/capability_host_trial.py + +## AAU1 · update · 2026-10-10 14:47 +Observed: d5de5fc control v1 completed clean, then correctly exposed one unknown row after the receipt boundary. The control requested task-wide status with reconcile=true but omitted operation; that API lists history and supplies a next operation-specific status call. The worker receipt, exact independent text, kill and restarted catalog were qualified. No paid host session ran. +Inferred: the control caller omitted the documented collection step; this is incomplete harness evidence, not a product reconciliation failure. +Next: correct only the scripted control to collect the operation ID from public task status, then call public operation status; preserve agent prompts without recovery coaching and retain v1. +Refs: output/agent-acceptance-controls-v1/control-receipt/public.json; output/agent-acceptance-controls-v1/control-receipt/receipt.json + +## AA3 · prediction · 2026-10-10 14:47 +Hypothesis: explicitly collecting the single operation identified by task status resolves the control's receipt case to historical applied; later-edit remains applied with current divergence, and missing receipt stays unknown despite matching text. +Test: fresh control v2 uses task status then the returned operation ID with reconcile=true; repeat the original token only to collect, and include a malformed-target negative control that must reject the missing interruption boundary. +Predicts: four positive controls meet their unchanged oracle/journal criteria, token collection preserves one row and exact text, and malformed-target control cannot manufacture a qualified interruption. +Against: operation-specific status cannot recover the qualified receipt, repeat adds an effect/row, matching text resolves without receipt, or an unobserved interruption is accepted. +Refs: scripts/capability_agent_restart_trial.py; output/agent-acceptance-controls-v1 From 600dacfe51640af832b8f33eda886d6a4a17face Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:48:06 -0400 Subject: [PATCH 011/216] Collect explicit operation status in acceptance controls --- .../scripts/capability_agent_restart_trial.py | 53 +++++++++++++++---- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/jevdual/scripts/capability_agent_restart_trial.py b/jevdual/scripts/capability_agent_restart_trial.py index 02fd789..8dbd778 100644 --- a/jevdual/scripts/capability_agent_restart_trial.py +++ b/jevdual/scripts/capability_agent_restart_trial.py @@ -372,22 +372,32 @@ def main() -> int: try: client.tool("bind", {"name": "source"}) dest = client.tool("bind", {"name": "destination"}) + arguments = { + "target": destination_target(dest), + "text": VALUE, + "client_token": "A1-control-" + case, + } try: - act = client.tool( - "act", - { - "target": destination_target(dest), - "text": VALUE, - "client_token": "A1-control-" + case, - }, - ) + act = client.tool("act", arguments) except RuntimeError as exc: if case == "clean" or "backend process exited; restarted" not in str(exc): raise act = {"transport_error": str(exc)} # The relay presents a transport error; collect only public status. - status = client.tool("status", {"reconcile": True}) - write(session / "public.json", {"act": act, "status": status}) + listing = client.tool("status", {}) + recent = listing.get("recent", []) + if len(recent) != 1: + raise RuntimeError("public status did not identify one operation") + status = client.tool( + "status", {"operation": recent[0]["operation_id"], "reconcile": True} + ) + repeat = client.tool("act", arguments) + if repeat.get("operation_id") != recent[0]["operation_id"]: + raise RuntimeError("token collection did not preserve operation identity") + write( + session / "public.json", + {"act": act, "listing": listing, "status": status, "repeat": repeat}, + ) finally: client.stop() receipt = {"valid_environment": True, "host": "control"} @@ -440,6 +450,29 @@ def main() -> int: or receipt.get("result_is_error") ): raise RuntimeError(summary["stop_reason"] or "session failed or invalid; no retry") + if args.controls_only: + negative = root / "control-missing-boundary" + negative.mkdir(mode=0o700) + ax_reset_text(dst["pid"], dst["document"], PREFIX) + if ax_document_text(dst["pid"], dst["document"]) != PREFIX: + raise RuntimeError("negative-control reset unqualified") + configuration(negative, scope_path, "receipt") + client = RelayClient(negative) + try: + result = client.tool("act", {"target": "not-an-offered-target", "text": VALUE}) + finally: + client.stop() + events = [json.loads(line) for line in (negative / "relay/events.jsonl").read_text().splitlines()] + rejected = ( + result.get("is_error") + and ax_document_text(dst["pid"], dst["document"]) == PREFIX + and any(e.get("reason") == "mutation_returned_before_required_boundary" for e in events) + and not any(e["kind"] == "dropped" for e in events) + ) + write(negative / "receipt.json", {"missing_boundary_rejected": bool(rejected), "public": result}) + summary["missing_boundary_rejected"] = bool(rejected) + if not rejected: + raise RuntimeError("missing boundary was not rejected") except Exception as exc: summary["stop_reason"] = type(exc).__name__ + ": " + str(exc)[:200] raise From be446d55011f8b1b426e35a478030c51df6b3316 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:49:15 -0400 Subject: [PATCH 012/216] Record native acceptance controls before fresh host trials --- .../docs/notebook/2026-10-10-restart-agent-acceptance.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md index 468d77a..eef8437 100644 --- a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md +++ b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md @@ -26,3 +26,9 @@ Test: fresh control v2 uses task status then the returned operation ID with reco Predicts: four positive controls meet their unchanged oracle/journal criteria, token collection preserves one row and exact text, and malformed-target control cannot manufacture a qualified interruption. Against: operation-specific status cannot recover the qualified receipt, repeat adds an effect/row, matching text resolves without receipt, or an unobserved interruption is accepted. Refs: scripts/capability_agent_restart_trial.py; output/agent-acceptance-controls-v1 + +## AAU2 · update · 2026-10-10 14:48 +Resolves: AA3 = held +Observed: frozen 600dacf control v2 passes clean, receipt, later-edit and no-receipt, each with one operation, independent stable exact text and repeated-token collection preserving the operation ID. The malformed target returned before the required boundary and was explicitly rejected without a dropped call. V1 remains retained. Product capability/native/AX source is unchanged from merged main; the existing compiled extension was copied with equal SHA256, without rebuilding. +Next: run eight fresh host sessions on the qualified harness; root reviews actual answers against independent evidence. AA1 and host-isolation portion of AA2 remain open. +Refs: output/agent-acceptance-controls-v2/summary.json; output/agent-acceptance-controls-v2/control-missing-boundary/receipt.json; 600dacf From e62fb475b07ecfce9757dc1094771b98a8c28fda Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:52:17 -0400 Subject: [PATCH 013/216] Preregister camera paper inbox and artifact verification experiment --- .../docs/experiments/DI1-desk-paper-inbox.md | 29 +++++++++++++++++++ .../notebook/2026-10-10-desk-paper-inbox.md | 8 +++++ 2 files changed, 37 insertions(+) create mode 100644 jevdual/docs/experiments/DI1-desk-paper-inbox.md create mode 100644 jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md diff --git a/jevdual/docs/experiments/DI1-desk-paper-inbox.md b/jevdual/docs/experiments/DI1-desk-paper-inbox.md new file mode 100644 index 0000000..c667c47 --- /dev/null +++ b/jevdual/docs/experiments/DI1-desk-paper-inbox.md @@ -0,0 +1,29 @@ +# DI1: Camera paper note to a Footwork-checked desk inbox + +Mode: bounded engineering/workflow feasibility. Not a model qualification or product-demand test. + +## Hypothesis + +An existing native-camera frame can supply a small paper note to local Apple Vision text recognition; an explicit review bound to the candidate digest can save exactly that text into a private inbox and Footwork can independently verify the saved bytes. + +## Predictions + +A known synthetic printed note yields expected text through the real Vision helper. A live paper note, when presented clearly and reviewed, can yield a saved note matching approved text. No text, altered candidates/source images, mismatched approval digests or invalid saved bytes cannot become verified notes. Repeating an accepted operation does not create duplicate notes. + +Against: a verified result without exact matching saved bytes, fabricated browser/native carries, unreviewed capture triggering an action, or a repeat creating another note. + +## Design + +Keep camera acquisition in the existing tools/camera-capture-experiment package and desk workflow in tools/desk-inbox-experiment. Use one native frame per deliberate operation; microphone disabled. Use installed Swift/Vision for local English OCR, with no cloud provider. Preserve OCR lines/confidence as fallible evidence, never execution authority. Explicit review approves a text digest; corrections are retained separately from original recognition. Keep images, recognized/private text, review pages, notes and per-operation receipts in ignored private output. + +Introduce a narrow provider-free read-only footwork check-artifact command and library boundary. It checks a digest-bound reviewed source and exact destination bytes. It supplies current artifact equality, not OCR correctness, native UI completion, authorization authentication or an exactly-once physical effect. Do not synthesize Footwork session carries or change native recovery/guard interfaces. + +Primary metric: one accepted note exists exactly once and matches its independently approved source bytes (binary feasibility), with source/candidate provenance retained. + +Checks: real Vision on a known generated printed note; public CLI whole workflow; repeat across processes; missing text; changed source/candidate; changed approval digest; missing/tampered destination; concurrency and interrupted write/receipt handling as appropriate. A human live note is a separate validation requiring positioning and review; if unavailable, report that gap explicitly. + +Decision rule: qualify only demonstrated source/OCR/file behavior. Advance toward a daily desk inbox only after one real note is reviewed and saved. Keep synthetic proof separate from live paper utility and semantic correctness. No model calls, UI automation, external task creation, publication or robot movement. + +## Result + +Pending. diff --git a/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md b/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md new file mode 100644 index 0000000..61f2153 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md @@ -0,0 +1,8 @@ +# Desk paper inbox experiment + +## DI1 · prediction · 2026-10-10 14:52 +Hypothesis: local Apple Vision OCR and an explicit digest-bound review can turn a small visible paper note into one private inbox artifact whose exact content Footwork independently verifies. +Test: implement isolated desk tool plus read-only Footwork artifact oracle, freeze source, run real OCR on known synthetic text, exercise the public prepare/review/accept/status boundaries, then attempt one real paper note if the user can position it. Preserve synthetic/live distinctions. +Predicts: accepted text is saved once and Footwork confirms exact bytes; repeats reuse one note; empty/changed/unapproved/tampered evidence refuses or reports unresolved without extra effects. No fake native/browser carries or provider calls. +Against: OCR alone dispatches an action, changed approval/candidate becomes saved text, bytes differ while verification passes, repeated token duplicates a note, or fixture proof is presented as live usefulness. +Refs: docs/experiments/DI1-desk-paper-inbox.md; tools/camera-capture-experiment/; /Volumes/External SSD/referencerepos/cua/libs/lume/src/Utils/VNCDriver.swift:272; /Volumes/External SSD/referencerepos/rerun/examples/python/live_camera_edge_detection/live_camera_edge_detection.py From 3e63656d6863327ca694b0fb0805bd8d43ebd738 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:54:37 -0400 Subject: [PATCH 014/216] Preregister explicit mirror orientation for paper note recognition --- jevdual/docs/experiments/DI1-desk-paper-inbox.md | 3 +++ jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/jevdual/docs/experiments/DI1-desk-paper-inbox.md b/jevdual/docs/experiments/DI1-desk-paper-inbox.md index c667c47..bc1e176 100644 --- a/jevdual/docs/experiments/DI1-desk-paper-inbox.md +++ b/jevdual/docs/experiments/DI1-desk-paper-inbox.md @@ -27,3 +27,6 @@ Decision rule: qualify only demonstrated source/OCR/file behavior. Advance towar ## Result Pending. + +## Amendment · 2026-10-10 14:54 +The user asks whether the camera mirrors. Preparation will expose an explicit --mirror-input option for OCR orientation and review display, bind it in request provenance, and retain original capture bytes. Mirroring is chosen from readable calibration text, not inferred from faces or OCR confidence. Normal/mirrored synthetic fixtures and the live LEFT 123 RIGHT line will assess orientation. diff --git a/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md b/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md index 61f2153..609c57d 100644 --- a/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md +++ b/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md @@ -6,3 +6,10 @@ Test: implement isolated desk tool plus read-only Footwork artifact oracle, free Predicts: accepted text is saved once and Footwork confirms exact bytes; repeats reuse one note; empty/changed/unapproved/tampered evidence refuses or reports unresolved without extra effects. No fake native/browser carries or provider calls. Against: OCR alone dispatches an action, changed approval/candidate becomes saved text, bytes differ while verification passes, repeated token duplicates a note, or fixture proof is presented as live usefulness. Refs: docs/experiments/DI1-desk-paper-inbox.md; tools/camera-capture-experiment/; /Volumes/External SSD/referencerepos/cua/libs/lume/src/Utils/VNCDriver.swift:272; /Volumes/External SSD/referencerepos/rerun/examples/python/live_camera_edge_detection/live_camera_edge_detection.py + +## DI2 · prediction · 2026-10-10 14:54 +Hypothesis: an explicit horizontal-mirror setting, applied to OCR orientation and review presentation while retaining the original source bytes, can handle a mirrored camera feed without silently changing capture evidence or operation identity. +Test: expose --mirror-input at preparation, bind it in source/request provenance, and test real Vision against known normal/mirrored printed fixtures. The user's live note will include LEFT 123 RIGHT to determine the feed's direction. +Predicts: the appropriate explicit orientation yields the original literal line order/text; a changed orientation cannot reuse a prior candidate as though it had the same source request. Original PNG/hash remain intact, and preview names the orientation. +Against: normal text is reversed under its matching setting, mirrored proof silently overwrites source bytes, OCR claims imply mirror classification, or candidate lookup ignores changed orientation. +Refs: docs/experiments/DI1-desk-paper-inbox.md; tools/desk-inbox-experiment/; https://developer.apple.com/documentation/vision/vnimagerequesthandler From ec89e6ec8cca4cadc4b416da148a1fd82086cdc1 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:55:13 -0400 Subject: [PATCH 015/216] Retain failed agent claims and predict bounded reporting repair --- .../notebook/2026-10-10-restart-agent-acceptance.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md index eef8437..aa6c6a0 100644 --- a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md +++ b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md @@ -32,3 +32,16 @@ Resolves: AA3 = held Observed: frozen 600dacf control v2 passes clean, receipt, later-edit and no-receipt, each with one operation, independent stable exact text and repeated-token collection preserving the operation ID. The malformed target returned before the required boundary and was explicitly rejected without a dropped call. V1 remains retained. Product capability/native/AX source is unchanged from merged main; the existing compiled extension was copied with equal SHA256, without rebuilding. Next: run eight fresh host sessions on the qualified harness; root reviews actual answers against independent evidence. AA1 and host-isolation portion of AA2 remain open. Refs: output/agent-acceptance-controls-v2/summary.json; output/agent-acceptance-controls-v2/control-missing-boundary/receipt.json; 600dacf + +## AAU3 · update · 2026-10-10 14:53 +Resolves: AA1 = failed +Observed: v1 Claude Opus5.5 executed all four scenarios safely with one operation each and $0.2771692 reported cost, but no-receipt final says "I added the total" and "so I appended" despite unknown history and an externally supplied value. Its separate uncertainty paragraph does not cure that causal assertion. It also infers unsaved disk state without a disk check. Receipt/later-edit executions recover and preserve external content. Codex clean is invalid: calls cancel before reaching the relay, an unsupported skip_host_skill_discovery flag warns, and global skill metadata was supplied. Remaining Codex sessions were not run. +Next: preserve v1 and freeze a separate v2 with clearer public reporting constraints and explicit scoped Codex tool approval/skill isolation. No original outcome will be regraded or replaced; packaging remains blocked by A1. +Refs: output/agent-acceptance-hosts-v1/summary.json; output/agent-acceptance-hosts-v1/claude-no_receipt/receipt.json; output/agent-acceptance-hosts-v1/codex-clean/transcript.jsonl; output/agent-acceptance-hosts-v1/codex-clean/host-stderr.log + +## AA4 · prediction · 2026-10-10 14:53 +Hypothesis: explicit operation reporting guidance (unknown execution cannot be attributed from matching text; disk persistence is not checked) improves truthful fresh-agent answers; narrow preapproved Footwork tools and disabled skill paths make Codex calls reach the scoped server without unrelated skills. +Test: first preserve a failing public reporting-contract check on unknown/no-receipt and applied/later-edit records; repair response wording without changing dispatch/reconciliation rules. Qualify v2 controls and repeat the same four cases per host in a new frozen directory, unchanged ordinary task; retain v1 costs against the $8 aggregate scheduling ceiling. +Predicts: both hosts meet the four case-specific answer/effect requirements, Codex actual calls reach the relay, and no unqualified causal or saved/unsaved assertion is made. Local configuration changes touch only the trial command and its already-authorized four tools. +Against: either host still falsely claims execution/save state, any caller duplicates input, Codex requires unrelated tools/skills or wider grants, or historical receipt behavior changes. +Refs: docs/experiments/A1-restart-agent-acceptance.md; python/jevdual/capability/service.py; scripts/capability_agent_restart_trial.py From 08f4cf867cc9c420f5094d5329c01443d68168f2 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 14:59:39 -0400 Subject: [PATCH 016/216] Clarify effect reporting and isolate authorized Codex trials --- .../A1-restart-agent-acceptance.md | 8 ++++ .../2026-10-10-restart-agent-acceptance.md | 5 +++ jevdual/python/jevdual/capability/service.py | 13 ++++++- .../scripts/capability_agent_restart_trial.py | 37 +++++++++++++++++-- jevdual/tests/test_capability_recovery.py | 32 ++++++++++++++++ 5 files changed, 90 insertions(+), 5 deletions(-) diff --git a/jevdual/docs/experiments/A1-restart-agent-acceptance.md b/jevdual/docs/experiments/A1-restart-agent-acceptance.md index dac6259..a7956b2 100644 --- a/jevdual/docs/experiments/A1-restart-agent-acceptance.md +++ b/jevdual/docs/experiments/A1-restart-agent-acceptance.md @@ -27,3 +27,11 @@ Packaging follows only if both hosts meet all four scenario requirements, zero d ## Result Pending execution. + +## Amendment · 2026-10-10 14:58 · before v2 + +V1 is retained: four Claude executions passed the native/journal checks, but the no-receipt final answer falsely attributed external text to its own action and asserted unchecked unsaved state. The first Codex session was invalid because host approvals cancelled calls before the relay and skill context was not isolated; remaining Codex sessions were not run. This is a failed acceptance candidate, not a passing headline based on execution alone. + +V2 keeps the same four scenarios and ordinary task. Public receipts add reporting.historical_effect, reporting.disk_persistence=not_checked and explicit guidance against causal attribution for unknown attempts or saved/unsaved claims without a check. No dispatch, receipt qualification, authority, current-agreement or reconciliation rule changes. The Codex command preapproves only the four tools on this fixture-scoped server, consistent with the user's existing trial authorization; no global config is changed. It disables actual discovered skill paths and automatic skills instructions, replacing the unsupported reference feature. Host warnings are classified separately from executed non-Footwork tools; neither can silently become a valid run. Full offered-tool/model inventory remains unavailable through installed exec JSON and stays disclosed. + +Run new native controls before v2 paid sessions on committed source. Carry $0.2771692 v1 Claude reported cost into the original $8 aggregate scheduling ceiling; no additional review/provider calls are authorized by this amendment. Retain invalid control scaffolds and original v1 evidence. Apply the original case-specific answer/effect requirements to v2 without relaxing uncertainty or disk-evidence rules. diff --git a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md index aa6c6a0..46b43d3 100644 --- a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md +++ b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md @@ -45,3 +45,8 @@ Test: first preserve a failing public reporting-contract check on unknown/no-rec Predicts: both hosts meet the four case-specific answer/effect requirements, Codex actual calls reach the relay, and no unqualified causal or saved/unsaved assertion is made. Local configuration changes touch only the trial command and its already-authorized four tools. Against: either host still falsely claims execution/save state, any caller duplicates input, Codex requires unrelated tools/skills or wider grants, or historical receipt behavior changes. Refs: docs/experiments/A1-restart-agent-acceptance.md; python/jevdual/capability/service.py; scripts/capability_agent_restart_trial.py + +## AAU4-local · update · 2026-10-10 14:58 +Observed: public receipt reporting baseline v4 fails four checks across receipt/no-receipt and matching/diverged current text; repaired service/recovery/MCP checks pass51 and Ruff passes. The first three baseline scaffolds were invalid due context-manager, teardown and lock misuse; corrected scaffold follows existing journal fixture closeout. All are retained. Durable English strings passed the human-writing hygiene pass with zero edits. CLI command disables518 discovered skill identities and preapproves only the four authorized fixture tools; host execution is still unqualified. +Next: freeze v2, run four fresh native controls and the missing-boundary rejection, then eight new host sessions with unchanged task and prior cost accounted. AA4 remains open until actual host answers and environment are checked. +Refs: output/agent-reporting-before.log; output/agent-reporting-before-v2.log; output/agent-reporting-before-v3.log; output/agent-reporting-before-v4.log; output/agent-reporting-after.log; output/reporting-language-hygiene.txt diff --git a/jevdual/python/jevdual/capability/service.py b/jevdual/python/jevdual/capability/service.py index 68de6ca..2bafdf2 100644 --- a/jevdual/python/jevdual/capability/service.py +++ b/jevdual/python/jevdual/capability/service.py @@ -318,7 +318,8 @@ def _receipt(op: Operation, *, repeat: bool, note: str | None = None) -> dict[st else: summary = ( f"Outcome unknown for {op.id}. Do not append again; call status with this operation " - "(reconcile=true) or have the operator inspect the document." + "(reconcile=true) or have the operator inspect the document. " + "Matching text does not confirm this attempt wrote it. Report the attempted append as unknown." ) next_step = {"tool": "status", "operation": op.id, "reconcile": True} result: dict[str, Any] = { @@ -330,6 +331,16 @@ def _receipt(op: Operation, *, repeat: bool, note: str | None = None) -> dict[st "summary": summary, "repeat": repeat, "evidence": op.evidence, + "reporting": { + "historical_effect": op.disposition or "unknown", + "disk_persistence": "not_checked", + "guidance": "Disk persistence was not checked. Do not claim the file is saved or unsaved." + + ( + " This attempt is unconfirmed even if the text matches. Do not claim that you appended it." + if op.state != "final" + else " Report the retained execution result separately from current document agreement." + ), + }, } if op.client_token is not None: result["client_token"] = op.client_token diff --git a/jevdual/scripts/capability_agent_restart_trial.py b/jevdual/scripts/capability_agent_restart_trial.py index 8dbd778..846716d 100644 --- a/jevdual/scripts/capability_agent_restart_trial.py +++ b/jevdual/scripts/capability_agent_restart_trial.py @@ -185,7 +185,7 @@ def codex_command(server: dict, final: Path) -> list[str]: "features.multi_agent_v2": False, "features.code_mode": False, "tools.update_plan.enabled": False, - "features.skip_host_skill_discovery": True, + "skills.include_instructions": False, "mcp_servers.footwork.command": server["command"], "mcp_servers.footwork.args": server["args"], "mcp_servers.footwork.env.PYTHONPATH": server["env"]["PYTHONPATH"], @@ -194,6 +194,23 @@ def codex_command(server: dict, final: Path) -> list[str]: } for key, val in settings.items(): cmd += ["-c", key + "=" + json.dumps(val)] + # The installed CLI does not support skip_host_skill_discovery. Disable + # actual discovered skill identities using the supported skills config. + paths = set() + for base in (Path.home() / ".codex/skills", Path.home() / ".agents/skills"): + if base.exists(): + for directory in base.iterdir(): + skill = directory / "SKILL.md" + if skill.is_file(): + paths.update((str(skill), str(skill.resolve()))) + paths.update(str(p) for p in base.rglob("SKILL.md")) + cache = Path.home() / ".codex/plugins/cache" + if cache.exists(): + paths.update(str(p) for p in cache.rglob("SKILL.md")) + entries = ["{path=" + json.dumps(p) + ",enabled=false}" for p in sorted(paths)] + cmd += ["-c", "skills.config=[" + ",".join(entries) + "]"] + for tool in ("bind", "observe", "act", "status"): + cmd += ["-c", f'mcp_servers.footwork.tools.{tool}.approval_mode="approve"'] return cmd @@ -204,7 +221,9 @@ def codex_receipt(root: Path) -> dict: items = [e.get("item", {}) for e in events if e.get("type") == "item.completed"] calls = [i for i in items if i.get("type") == "mcp_tool_call"] outside = [ - i.get("type") for i in items if i.get("type") not in ("agent_message", "reasoning", "mcp_tool_call") + i.get("type") + for i in items + if i.get("type") not in ("agent_message", "reasoning", "mcp_tool_call", "error") ] outside += [ i.get("server") @@ -213,9 +232,15 @@ def codex_receipt(root: Path) -> dict: ] usage = [e.get("usage") for e in events if e.get("type") == "turn.completed"] errors = [e for e in events if e.get("type") in ("error", "turn.failed")] + stderr = (root / "host-stderr.log").read_text() + isolation_errors = [i.get("message", "") for i in items if i.get("type") == "error"] + isolation_errors += [ + line for line in stderr.splitlines() if "unknown feature key" in line or "patch rejected" in line + ] return { - "valid_environment": not outside and bool(calls) and bool(usage), + "valid_environment": not outside and not isolation_errors and bool(calls) and bool(usage), "executed_non_footwork": outside, + "isolation_errors": isolation_errors, "calls": [i.get("tool") for i in calls], "final": (root / "final.txt").read_text() if (root / "final.txt").exists() else None, "usage": usage, @@ -297,6 +322,7 @@ def main() -> int: parser.add_argument("--run-dir", type=Path) parser.add_argument("--execute", action="store_true") parser.add_argument("--controls-only", action="store_true") + parser.add_argument("--prior-claude-cost", type=float, default=0.0) args = parser.parse_args() if args.relay: cfg = json.loads(args.relay.read_text()) @@ -312,6 +338,8 @@ def main() -> int: return 0 if not args.scope or not args.run_dir: parser.error("execution requires scope and run directory") + if not math.isfinite(args.prior_claude_cost) or not 0 <= args.prior_claude_cost < 8: + parser.error("prior Claude cost must be finite and within the aggregate ceiling") from ApplicationServices import AXIsProcessTrusted from jevdual.posture import screen_locked @@ -349,6 +377,7 @@ def main() -> int: "scope_sha256": hashlib.sha256(scope_path.read_bytes()).hexdigest(), "sessions": [], "claude_cost_usd": 0.0, + "prior_claude_cost_usd": args.prior_claude_cost, "stop_reason": None, "claim_review_pending": not args.controls_only, } @@ -356,7 +385,7 @@ def main() -> int: try: for host in hosts: for case in CASES: - if host == "claude" and summary["claude_cost_usd"] + 2 > 8: + if host == "claude" and args.prior_claude_cost + summary["claude_cost_usd"] + 2 > 8: raise RuntimeError("Claude aggregate scheduling reserve exhausted") session = root / (host + "-" + case) session.mkdir(mode=0o700) diff --git a/jevdual/tests/test_capability_recovery.py b/jevdual/tests/test_capability_recovery.py index 0351010..a4515b3 100644 --- a/jevdual/tests/test_capability_recovery.py +++ b/jevdual/tests/test_capability_recovery.py @@ -94,6 +94,38 @@ def test_private_immutable_packet_and_receipt_roundtrip(prepared): assert store.read_result(op) == result +@pytest.mark.asyncio +@pytest.mark.parametrize("completed", [False, True]) +@pytest.mark.parametrize("matching_text", [False, True]) +async def test_public_reporting_separates_execution_current_text_and_persistence( + prepared, monkeypatch, completed, matching_text +): + from jevdual.capability.service import CapabilityService + + journal, store, op, packet = prepared + journal.start(op.id) + if completed: + store.write_record(op.id, "result", _applied(packet)) + journal.close() + monkeypatch.setattr(journal, "close", lambda: None) + + class CurrentOnly: + async def current_recovery(self, recovery): + return {"agreement": "yes" if matching_text else "no", "persistence": "not_checked"} + + restarted = Journal(journal.path) + try: + reply = await CapabilityService(restarted, CurrentOnly()).status( + task=op.task, operation=op.id, reconcile=True + ) + assert reply["disposition"] == ("applied" if completed else "unknown") + assert reply["current"]["agreement"] == ("yes" if matching_text else "no") + assert reply["reporting"]["historical_effect"] == ("applied" if completed else "unknown") + assert reply["reporting"]["disk_persistence"] == "not_checked" + finally: + restarted.close() + + @pytest.mark.parametrize("field", ["operation_id", "request_digest", "nonce", "packet_digest", "version"]) def test_receipt_binding_mismatch_is_never_accepted(prepared, field): _, store, op, packet = prepared From 6e93c35a1e34c24e5d9def09c37f3beee5669c1c Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 15:00:00 -0400 Subject: [PATCH 017/216] Add local paper inbox and read-only Footwork artifact check --- jevdual/python/jevdual/artifacts.py | 67 ++++ jevdual/python/jevdual/cli.py | 14 + tools/desk-inbox-experiment/.gitignore | 2 + tools/desk-inbox-experiment/inbox.py | 337 ++++++++++++++++++++ tools/desk-inbox-experiment/recognize.swift | 44 +++ 5 files changed, 464 insertions(+) create mode 100644 jevdual/python/jevdual/artifacts.py create mode 100644 tools/desk-inbox-experiment/.gitignore create mode 100644 tools/desk-inbox-experiment/inbox.py create mode 100644 tools/desk-inbox-experiment/recognize.swift diff --git a/jevdual/python/jevdual/artifacts.py b/jevdual/python/jevdual/artifacts.py new file mode 100644 index 0000000..3be7d17 --- /dev/null +++ b/jevdual/python/jevdual/artifacts.py @@ -0,0 +1,67 @@ +"""Read-only, digest-bound equality of external artifact bytes; no session provenance.""" + +from __future__ import annotations + +import hashlib +import os +import re +import stat +from pathlib import Path + +MAX_ARTIFACT_BYTES = 1024 * 1024 +_DIGEST = re.compile(r"[0-9a-f]{64}\Z") + + +class ArtifactError(Exception): + """A file cannot supply stable, bounded evidence.""" + + +def read_regular(path: Path, *, limit: int = MAX_ARTIFACT_BYTES) -> bytes: + """Read a regular file without following a final symlink; detect concurrent mutation.""" + try: + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK) + with os.fdopen(fd, "rb") as source: + before = os.fstat(source.fileno()) + if not stat.S_ISREG(before.st_mode): + raise ArtifactError("not a regular file") + if before.st_size > limit: + raise ArtifactError(f"file exceeds {limit} byte limit") + data = source.read(limit + 1) + after = os.fstat(source.fileno()) + if len(data) > limit: + raise ArtifactError(f"file exceeds {limit} byte limit") + if (before.st_size, before.st_mtime_ns, before.st_ctime_ns) != ( + after.st_size, after.st_mtime_ns, after.st_ctime_ns + ): + raise ArtifactError("file changed during read") + return data + except OSError as exc: + raise ArtifactError("file is missing, symlinked or unreadable") from exc + + +def check_artifact(path: Path, expected_file: Path, expected_sha256: str) -> dict: + """Compare exact current bytes to a digest-bound source; never print artifact text.""" + result = {"ok": False, "path": str(path), "expected_file": str(expected_file), + "expected_sha256": expected_sha256, + "claims": [], "limit_bytes": MAX_ARTIFACT_BYTES} + if not isinstance(expected_sha256, str) or not _DIGEST.fullmatch(expected_sha256): + return {**result, "detail": "expected SHA256 must contain 64 lowercase hexadecimal characters"} + try: + expected = read_regular(expected_file) + source_sha = hashlib.sha256(expected).hexdigest() + result["source_sha256"] = source_sha + result["expected_bytes"] = len(expected) + if source_sha != expected_sha256: + return {**result, "detail": "expected source no longer matches its bound digest"} + observed = read_regular(path) + result["observed_sha256"] = hashlib.sha256(observed).hexdigest() + result["observed_bytes"] = len(observed) + if observed != expected: + return {**result, "detail": "destination bytes differ from the bound expected source"} + # Recheck the source after destination read; mutable source cannot silently change approval. + if hashlib.sha256(read_regular(expected_file)).hexdigest() != expected_sha256: + return {**result, "detail": "expected source changed during verification"} + return {**result, "ok": True, "detail": "current bytes equal the digest-bound expected source", + "claims": ["current_artifact_byte_equality"]} + except ArtifactError as exc: + return {**result, "detail": str(exc)} diff --git a/jevdual/python/jevdual/cli.py b/jevdual/python/jevdual/cli.py index a509b4b..02837e5 100644 --- a/jevdual/python/jevdual/cli.py +++ b/jevdual/python/jevdual/cli.py @@ -57,6 +57,15 @@ async def cmd_apps(_: argparse.Namespace) -> int: return 0 +async def cmd_check_artifact(args: argparse.Namespace) -> int: + """External-artifact equality needs no Driver, model, session, or carried value.""" + from jevdual.artifacts import check_artifact + + result = check_artifact(Path(args.path), Path(args.expected_file), args.expected_sha256) + print(json.dumps(result, sort_keys=True)) + return 0 if result["ok"] else 6 + + async def cmd_menu(args: argparse.Namespace) -> int: from cua_driver import CuaDriver @@ -413,6 +422,11 @@ def common(sp: argparse.ArgumentParser) -> None: ) common(cf) cf.set_defaults(fn=S.cmd_check_file) + artifact = sub.add_parser("check-artifact", help="read-only exact bytes against a digest-bound expected file") + artifact.add_argument("path") + artifact.add_argument("--expected-file", required=True) + artifact.add_argument("--expected-sha256", required=True) + artifact.set_defaults(fn=cmd_check_artifact) gr = sub.add_parser("grant", help="allow one exact effect on one resource (the words `do` takes)") gr.add_argument("words", nargs="+") gr.add_argument("--uses", type=int, default=1) diff --git a/tools/desk-inbox-experiment/.gitignore b/tools/desk-inbox-experiment/.gitignore new file mode 100644 index 0000000..fd6aad7 --- /dev/null +++ b/tools/desk-inbox-experiment/.gitignore @@ -0,0 +1,2 @@ +output/ +__pycache__/ diff --git a/tools/desk-inbox-experiment/inbox.py b/tools/desk-inbox-experiment/inbox.py new file mode 100644 index 0000000..f5e8058 --- /dev/null +++ b/tools/desk-inbox-experiment/inbox.py @@ -0,0 +1,337 @@ +"""Local saved-frame OCR, explicit review, and Footwork-checked private desk notes.""" + +import argparse +import contextlib +import hashlib +import html +import importlib.util +import json +import os +import re +import shutil +import stat +import sys +import time +from pathlib import Path + +BASE = Path(__file__).resolve().parent +PROJECT = BASE.parents[1] +OUTPUT = BASE / "output" +FOOTWORK = PROJECT / "jevdual" / ".venv" / "bin" / "footwork" +SPEC = importlib.util.spec_from_file_location("camera_capture", BASE.parent / "camera-capture-experiment" / "capture.py") +camera = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(camera) +Refusal = camera.Refusal +MAX_IMAGE_BYTES = 32 * 1024 * 1024 +MAX_NOTE_BYTES = 128 * 1024 +STATES = {"preparing", "needs_text", "needs_review", "accepting", "saved", "unknown"} +DIGEST = re.compile(r"[0-9a-f]{64}\Z") + + +def digest(data): + return hashlib.sha256(data).hexdigest() + + +def private_directory(path): + raw = Path(os.path.abspath(os.fspath(path))) + if raw == OUTPUT or OUTPUT not in raw.parents: + raise Refusal("run directory must be a subdirectory of the desk experiment's output directory") + current = OUTPUT + for part in (None, *raw.relative_to(OUTPUT).parts): + if part is not None: + current = current / part + try: + current.mkdir(mode=0o700) + except FileExistsError: + pass + info = current.lstat() + if not stat.S_ISDIR(info.st_mode) or info.st_uid != os.getuid() or info.st_mode & 0o077: + raise Refusal("run directories must be owned, private and free of symlinks") + return raw + + +def read_regular(path, limit): + try: + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK) + with os.fdopen(fd, "rb") as source: + before = os.fstat(source.fileno()) + if not stat.S_ISREG(before.st_mode) or before.st_size > limit: + raise Refusal("input must be a regular file within the declared size limit") + data = source.read(limit + 1) + after = os.fstat(source.fileno()) + if len(data) > limit or (before.st_size, before.st_mtime_ns, before.st_ctime_ns) != ( + after.st_size, after.st_mtime_ns, after.st_ctime_ns + ): + raise Refusal("input exceeds its limit or changed during read") + return data + except OSError as exc: + raise Refusal("input is missing, symlinked or unreadable") from exc + + +def create_file(path, data): + fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600) + with os.fdopen(fd, "wb") as sink: + sink.write(data) + sink.flush() + os.fsync(sink.fileno()) + + +def load(root): + try: + record = json.loads(read_regular(root / "manifest.json", MAX_NOTE_BYTES)) + except ValueError as exc: + raise Refusal("manifest is not valid JSON") from exc + if not isinstance(record, dict) or record.get("state") not in STATES: + raise Refusal("manifest state is invalid; inspect the run") + return record + + +def persist(root, record): + camera.persist(root / "manifest.json", record) + + +def source_request(capture_run=None, capture_token=None, fixture_image=None, mirror_input=False): + if fixture_image: + if capture_run or capture_token: + raise Refusal("fixture and native capture sources cannot be combined") + path = Path(os.path.abspath(fixture_image)) + request = {"source_kind": "synthetic_fixture", "source_path": str(path), "mirror_input": mirror_input} + else: + if not capture_run or not capture_token: + raise Refusal("prepare requires a capture run and token, or an explicit PNG fixture") + capture_root = camera.private_directory(capture_run) + with camera.locked(capture_root): + retained = camera.status(capture_root, capture_token) + if retained.get("state") != "acquired": + raise Refusal("source camera operation has no currently verifiable acquired frame") + path = camera.paths(capture_root, capture_token)[1] + request = {"source_kind": "native_camera_frame", "source_path": str(path), + "capture_run": str(capture_root), "capture_token": capture_token, + "mirror_input": mirror_input} + data = read_regular(path, MAX_IMAGE_BYTES) + if not data.startswith(b"\x89PNG\r\n\x1a\n"): + raise Refusal("source must be a saved PNG") + request["source_sha256"] = digest(data) + return request, data + + +def recognize(root, mirror_input): + swift = shutil.which("swift") + if not swift: + raise Refusal("installed Swift and Apple Vision are required; nothing will be installed") + cache = root / "swift-module-cache" + if cache.exists() or cache.is_symlink(): + raise Refusal("a prior OCR cache indicates an interrupted preparation; inspect the run") + cache.mkdir(mode=0o700) + orientation = "up_mirrored" if mirror_input else "up" + rc, stdout, stderr = camera.run_process([swift, "-module-cache-path", str(cache), + str(BASE / "recognize.swift"), str(root / "source.png"), + orientation], 45) + create_file(root / "vision.stderr.log", stderr.encode(errors="replace")[:65536]) + if rc: + raise Refusal("local Vision recognition failed; private diagnostics retained") + try: + result = json.loads(stdout) + if not isinstance(result["lines"], list): + raise TypeError("lines") + for line in result["lines"]: + if not isinstance(line["text"], str) or not isinstance(line["confidence"], (int, float)): + raise TypeError("line schema") + return result + except (ValueError, KeyError, TypeError) as exc: + raise Refusal("Vision returned invalid recognition evidence") from exc + + +def note_text(data): + try: + text = data.decode("utf-8") + except UnicodeError as exc: + raise Refusal("reviewed text must be UTF-8") from exc + if not text.strip() or "\x00" in text or len(data) > MAX_NOTE_BYTES: + raise Refusal("reviewed text must be nonempty, bounded UTF-8 without NUL bytes") + return text + + +def preview(root, record, text): + mirror = record["request"]["mirror_input"] + label = "Horizontal mirror correction (explicit)" if mirror else "Original orientation (explicit)" + transform = "transform:scaleX(-1);" if mirror else "" + content = f"""Review desk note + +

Review the paper and recognized text

{html.escape(label)}

+

Source kind: {html.escape(record['request']['source_kind'])}

+

Source: {html.escape(record['request']['source_path'])}

+Retained source frame

OCR candidate

{html.escape(text)}
+

Candidate SHA256: {html.escape(record['candidate_sha256'])}

+

Compare against the paper. Correct a copy if needed. Approval authorizes saving text only; +the note's words are data and will never execute as commands.

""" + create_file(root / "review.html", content.encode()) + + +def source_valid(root, record): + request = record["request"] + expected = request["source_sha256"] + if digest(read_regular(Path(request["source_path"]), MAX_IMAGE_BYTES)) != expected: + raise Refusal("original source bytes changed") + if digest(read_regular(root / "source.png", MAX_IMAGE_BYTES)) != expected: + raise Refusal("retained source image changed") + if request["source_kind"] == "native_camera_frame": + capture_root = camera.private_directory(request["capture_run"]) + with camera.locked(capture_root): + retained = camera.status(capture_root, request["capture_token"]) + if retained.get("state") != "acquired": + raise Refusal("native frame receipt is no longer verifiable") + if record.get("candidate_sha256") and digest(read_regular(root / "candidate.txt", MAX_NOTE_BYTES)) != record["candidate_sha256"]: + raise Refusal("original OCR candidate changed") + + +def check_note(root, sha): + if not FOOTWORK.is_file(): + raise Refusal("existing Footwork environment is unavailable; no install is attempted") + rc, stdout, _ = camera.run_process([str(FOOTWORK), "check-artifact", str(root / "inbox" / "note.txt"), + "--expected-file", str(root / "approved.txt"), + "--expected-sha256", sha], 20) + try: + result = json.loads(stdout) + if rc not in (0, 6) or not isinstance(result.get("ok"), bool) or result["ok"] != (rc == 0): + raise ValueError("checker result") + return result + except (ValueError, TypeError) as exc: + raise Refusal("Footwork artifact checker returned an invalid result") from exc + + +def status(root): + if not (root / "manifest.json").exists() and not (root / "manifest.json").is_symlink(): + return {"state": "absent", "claims": []} + record = load(root) + result = dict(record, claims=[]) + if record["state"] in {"preparing", "accepting"}: + return {**result, "state": "unknown", "reason": "interrupted intent; inspect without retrying"} + if record["state"] == "unknown": + return result + try: + source_valid(root, record) + if record["state"] == "saved": + checked = check_note(root, record["approval"]["sha256"]) + result["current_artifact_check"] = checked + if not checked["ok"]: + raise Refusal("saved note or approval source is currently unverifiable") + result["claims"] = ["current_note_equals_digest_bound_reviewed_bytes"] + except (Refusal, OSError, KeyError) as exc: + result["state"] = "unknown" + result["reason"] = str(exc) if isinstance(exc, Refusal) else "retained evidence is incomplete" + return result + + +def prepare(root, capture_run=None, capture_token=None, fixture_image=None, mirror_input=False): + request, image = source_request(capture_run, capture_token, fixture_image, mirror_input) + if (root / "manifest.json").exists() or (root / "manifest.json").is_symlink(): + record = load(root) + if record["request"] != request: + raise Refusal("run already belongs to different source bytes or orientation") + return status(root) + record = {"version": 1, "state": "preparing", "request": request, "prepare_time_unix": time.time(), + "ocr_helper_sha256": digest((BASE / "recognize.swift").read_bytes())} + persist(root, record) + try: + create_file(root / "source.png", image) + ocr = recognize(root, mirror_input) + if digest(read_regular(Path(request["source_path"]), MAX_IMAGE_BYTES)) != request["source_sha256"]: + raise Refusal("original source changed during recognition") + if digest(read_regular(root / "source.png", MAX_IMAGE_BYTES)) != request["source_sha256"]: + raise Refusal("retained source changed during recognition") + create_file(root / "ocr.json", (json.dumps(ocr, indent=2, ensure_ascii=False) + "\n").encode()) + text = "\n".join(line["text"] for line in ocr["lines"] if line["text"].strip()) + if not text.strip(): + record["state"] = "needs_text" + record["reason"] = "Vision found no text; no candidate or note was saved" + else: + candidate = (text + "\n").encode("utf-8") + note_text(candidate) + create_file(root / "candidate.txt", candidate) + record.update(state="needs_review", candidate_sha256=digest(candidate), + candidate_bytes=len(candidate), preview_name="review.html") + preview(root, record, text) + persist(root, record) + except (Exception, KeyboardInterrupt): # noqa: BLE001 - never replay interrupted preparation + record.update(state="unknown", reason="preparation did not complete; inspect private artifacts") + with contextlib.suppress(OSError): + persist(root, record) + return status(root) + + +def accept(root, approved_sha256, reviewed_file=None): + if not DIGEST.fullmatch(approved_sha256): + raise Refusal("approval must be an exact lowercase SHA256 digest") + record = load(root) + approved = {"sha256": approved_sha256, + "reviewed_input_path": str(Path(os.path.abspath(reviewed_file))) if reviewed_file else None} + if record["state"] in {"saved", "accepting", "unknown"}: + if record.get("approval") != approved: + raise Refusal("run already has a different or incomplete approval") + return status(root) + if record["state"] != "needs_review": + raise Refusal("no reviewed-text candidate is available") + source_valid(root, record) + data = read_regular(Path(approved["reviewed_input_path"]) if reviewed_file else root / "candidate.txt", MAX_NOTE_BYTES) + note_text(data) + if digest(data) != approved_sha256: + raise Refusal("reviewed text no longer matches the explicitly approved digest") + if reviewed_file is None and approved_sha256 != record["candidate_sha256"]: + raise Refusal("candidate digest changed") + record.update(state="accepting", approval=approved, review_kind="corrected_text" if reviewed_file else "original_ocr", + approval_time_unix=time.time()) + persist(root, record) + try: + create_file(root / "approved.txt", data) + (root / "inbox").mkdir(mode=0o700) + create_file(root / "inbox" / "note.txt", data) + checked = check_note(root, approved_sha256) + if not checked["ok"]: + raise Refusal("saved note did not match approved bytes") + record.update(state="saved", historical_save_outcome="saved", saved_time_unix=time.time(), + saved_artifact_check=checked, note_name="inbox/note.txt") + persist(root, record) + except (Exception, KeyboardInterrupt): # noqa: BLE001 - a partial publication is never retried + record.update(state="unknown", historical_save_outcome="unknown", + reason="publication or receipt did not complete; inspect without replay") + with contextlib.suppress(OSError): + persist(root, record) + return status(root) + + +def main(argv=None): + parser = argparse.ArgumentParser(description=__doc__) + sub = parser.add_subparsers(dest="command", required=True) + for command in ("prepare", "accept", "status"): + child = sub.add_parser(command) + child.add_argument("--run-dir", required=True) + if command == "prepare": + child.add_argument("--capture-run") + child.add_argument("--capture-token") + child.add_argument("--fixture-image") + child.add_argument("--mirror-input", action="store_true") + elif command == "accept": + child.add_argument("--approved-sha256", required=True) + child.add_argument("--reviewed-file") + args = parser.parse_args(argv) + try: + root = private_directory(args.run_dir) + with camera.locked(root): + if args.command == "prepare": + result = prepare(root, args.capture_run, args.capture_token, args.fixture_image, args.mirror_input) + elif args.command == "accept": + result = accept(root, args.approved_sha256, args.reviewed_file) + else: + result = status(root) + print(json.dumps(result, sort_keys=True, indent=2)) + return 0 if result["state"] in {"needs_review", "saved", "absent"} else 2 + except (Refusal, OSError, KeyError, KeyboardInterrupt) as exc: + reason = str(exc) if isinstance(exc, Refusal) else "operation interrupted or local evidence unavailable" + print(json.dumps({"state": "refused", "reason": reason, "claims": []})) + return 2 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/desk-inbox-experiment/recognize.swift b/tools/desk-inbox-experiment/recognize.swift new file mode 100644 index 0000000..d69e1a8 --- /dev/null +++ b/tools/desk-inbox-experiment/recognize.swift @@ -0,0 +1,44 @@ +import Foundation +import ImageIO +import Vision + +guard CommandLine.arguments.count == 3, + ["up", "up_mirrored"].contains(CommandLine.arguments[2]) else { + fputs("expected saved image path and explicit orientation\n", stderr) + exit(2) +} +let url = URL(fileURLWithPath: CommandLine.arguments[1]) +guard let source = CGImageSourceCreateWithURL(url as CFURL, nil), + let image = CGImageSourceCreateImageAtIndex(source, 0, nil) else { + fputs("saved image could not be decoded\n", stderr) + exit(2) +} +let request = VNRecognizeTextRequest() +request.recognitionLevel = .accurate +request.recognitionLanguages = ["en-US"] +request.usesLanguageCorrection = false +do { + let orientation: CGImagePropertyOrientation = CommandLine.arguments[2] == "up_mirrored" ? .upMirrored : .up + try VNImageRequestHandler(cgImage: image, orientation: orientation, options: [:]).perform([request]) + let observations = (request.results ?? []).sorted { + if $0.boundingBox.midY == $1.boundingBox.midY { + return $0.boundingBox.minX < $1.boundingBox.minX + } + return $0.boundingBox.midY > $1.boundingBox.midY + } + let lines: [[String: Any]] = observations.compactMap { observation in + guard let candidate = observation.topCandidates(1).first else { return nil } + let box = observation.boundingBox + return ["text": candidate.string, "confidence": Double(candidate.confidence), + "bounds": ["x": box.minX, "y": box.minY, "width": box.width, "height": box.height]] + } + let result: [String: Any] = ["engine": "Apple Vision", "recognition_level": "accurate", + "languages": ["en-US"], "language_correction": false, "lines": lines, + "request_revision": request.revision, "orientation": CommandLine.arguments[2]] + let data = try JSONSerialization.data(withJSONObject: result, options: [.sortedKeys]) + FileHandle.standardOutput.write(data) + FileHandle.standardOutput.write(Data([10])) +} catch { + fputs("local Vision recognition failed\n", stderr) + exit(2) +} From b178ff33aa732c99e067a08882162f6ce0d0368d Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 15:02:29 -0400 Subject: [PATCH 018/216] Record full checks and retain unavailable fixture prerequisite --- .../docs/notebook/2026-10-10-restart-agent-acceptance.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md index 46b43d3..7e3e8c7 100644 --- a/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md +++ b/jevdual/docs/notebook/2026-10-10-restart-agent-acceptance.md @@ -50,3 +50,9 @@ Refs: docs/experiments/A1-restart-agent-acceptance.md; python/jevdual/capability Observed: public receipt reporting baseline v4 fails four checks across receipt/no-receipt and matching/diverged current text; repaired service/recovery/MCP checks pass51 and Ruff passes. The first three baseline scaffolds were invalid due context-manager, teardown and lock misuse; corrected scaffold follows existing journal fixture closeout. All are retained. Durable English strings passed the human-writing hygiene pass with zero edits. CLI command disables518 discovered skill identities and preapproves only the four authorized fixture tools; host execution is still unqualified. Next: freeze v2, run four fresh native controls and the missing-boundary rejection, then eight new host sessions with unchanged task and prior cost accounted. AA4 remains open until actual host answers and environment are checked. Refs: output/agent-reporting-before.log; output/agent-reporting-before-v2.log; output/agent-reporting-before-v3.log; output/agent-reporting-before-v4.log; output/agent-reporting-after.log; output/reporting-language-hygiene.txt + +## AAU5 · update · 2026-10-10 15:02 +Observed: frozen08f4cf8 full suite passes1433 with27skips. Controls-v3 stopped before its first action because the independent AX oracle found zero matching owned windows; a later identity-only probe found the same PID and owned document. No v2 model session ran and no action was admitted. Fixture-v1 owner exited normally after exact document/browser cleanup; a fresh owned fixture-v2 is being established. +Inferred: this is an unavailable prerequisite snapshot with unverified cause, not evidence against the reporting change. +Next: run unchanged-source controls in a fresh directory on fixture-v2, then v2 host sessions only if all controls qualify. Retain the empty/inconclusive v3 and original v1 outcomes. +Refs: output/agent-acceptance-full-tests.log; output/agent-acceptance-controls-v3/summary.json; output/agent-acceptance-fixture-v1/scope.json; output/agent-acceptance-fixture-v2 From a2b35b9aa117cb94e55a2a4b40541cfd09774d41 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 15:05:57 -0400 Subject: [PATCH 019/216] Verify reviewed live paper inbox and preserve OCR evidence --- README.md | 5 + .../docs/experiments/DI1-desk-paper-inbox.md | 2 +- .../notebook/2026-10-10-desk-paper-inbox.md | 20 ++ .../desk-inbox-20261010/environment.json | 14 + .../results/desk-inbox-20261010/fixtures.json | 30 ++ jevdual/results/desk-inbox-20261010/report.md | 48 ++++ .../results/desk-inbox-20261010/source.json | 14 + .../desk-inbox-20261010/verification.json | 57 ++++ jevdual/tests/test_artifacts.py | 91 ++++++ tools/desk-inbox-experiment/README.md | 145 ++++++++++ tools/desk-inbox-experiment/test_inbox.py | 272 ++++++++++++++++++ 11 files changed, 697 insertions(+), 1 deletion(-) create mode 100644 jevdual/results/desk-inbox-20261010/environment.json create mode 100644 jevdual/results/desk-inbox-20261010/fixtures.json create mode 100644 jevdual/results/desk-inbox-20261010/report.md create mode 100644 jevdual/results/desk-inbox-20261010/source.json create mode 100644 jevdual/results/desk-inbox-20261010/verification.json create mode 100644 jevdual/tests/test_artifacts.py create mode 100644 tools/desk-inbox-experiment/README.md create mode 100644 tools/desk-inbox-experiment/test_inbox.py diff --git a/README.md b/README.md index cc588bf..5b1fd84 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,11 @@ timestamped evidence through an existing tab/CDP adapter. They are dependency-fr separate from the Python driver and verification gates. Their contract is tested offline; live capture fidelity must be calibrated on the selected browser. +The optional [desk paper inbox](tools/desk-inbox-experiment/README.md) connects a saved +camera frame to local text recognition and a reviewed inbox note. Its private review keeps +the original image and OCR text. `footwork check-artifact` checks the saved note against +the approved source bytes without a model call; it does not judge recognition accuracy. + ## Drive it ```sh diff --git a/jevdual/docs/experiments/DI1-desk-paper-inbox.md b/jevdual/docs/experiments/DI1-desk-paper-inbox.md index bc1e176..c3ac6bd 100644 --- a/jevdual/docs/experiments/DI1-desk-paper-inbox.md +++ b/jevdual/docs/experiments/DI1-desk-paper-inbox.md @@ -26,7 +26,7 @@ Decision rule: qualify only demonstrated source/OCR/file behavior. Advance towar ## Result -Pending. +Reviewed live note handoff verified on frozen source 6e93c35: user-confirmed corrected text saved once and independently matched by Footwork; original frame/raw OCR retained. All 31 focused tests and Ruff pass. Known printed/normal/mirrored OCR matches expected text; blank and adversarial cases remain explicit. Raw live handwriting OCR required correction, so autonomous transcription and daily utility are unqualified. See results/desk-inbox-20261010/report.md and verification.json. ## Amendment · 2026-10-10 14:54 The user asks whether the camera mirrors. Preparation will expose an explicit --mirror-input option for OCR orientation and review display, bind it in request provenance, and retain original capture bytes. Mirroring is chosen from readable calibration text, not inferred from faces or OCR confidence. Normal/mirrored synthetic fixtures and the live LEFT 123 RIGHT line will assess orientation. diff --git a/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md b/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md index 609c57d..ce560ed 100644 --- a/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md +++ b/jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md @@ -13,3 +13,23 @@ Test: expose --mirror-input at preparation, bind it in source/request provenance Predicts: the appropriate explicit orientation yields the original literal line order/text; a changed orientation cannot reuse a prior candidate as though it had the same source request. Original PNG/hash remain intact, and preview names the orientation. Against: normal text is reversed under its matching setting, mirrored proof silently overwrites source bytes, OCR claims imply mirror classification, or candidate lookup ignores changed orientation. Refs: docs/experiments/DI1-desk-paper-inbox.md; tools/desk-inbox-experiment/; https://developer.apple.com/documentation/vision/vnimagerequesthandler + +## U-DI1 · update · 2026-10-10 15:05 +Resolves: DI1 = held +Observed: frozen source 6e93c35 passes 31 focused tests and Ruff. Real Vision exactly recognizes the known printed fixture; blank fixture yields no candidate/note. The user positioned a live handwritten paper, confirmed a separately corrected transcription after seeing raw OCR errors, and authorized saving it. Public Footwork check-artifact independently confirms all 187 approved bytes; fresh-process accept/status preserve the same manifest and one note. Raw OCR and source remain unchanged. Wrong digest refuses; a tampered saved fixture retains historical save but current unknown and repeat acceptance does not overwrite it. +Inferred: reviewed physical-to-digital note feasibility is established on this Mac and one real note; unreviewed handwriting accuracy and daily utility remain unqualified. +Next: close DI1; assess capture/review friction before further workflow expansion. +Refs: results/desk-inbox-20261010/verification.json; results/desk-inbox-20261010/source.json; results/desk-inbox-20261010/report.md; tools/desk-inbox-experiment/output/live-paper-v1/ + +## U-DI2 · update · 2026-10-10 15:05 +Resolves: DI2 = held +Observed: real Vision on normal and horizontally mirrored known fixtures yields the same exact expected three lines under explicit up/upMirrored settings. Original source hashes remain intact; changed mirror request refuses reuse. The live calibration line reads normally in the raw captured frame, so no flip was selected. +Inferred: explicit orientation handling works on these fixtures and the observed feed; this does not classify arbitrary camera mirror state or infer direction from confidence. +Next: keep mirror choice explicit and tied to retained calibration evidence. +Refs: results/desk-inbox-20261010/verification.json; results/desk-inbox-20261010/fixtures.json; tools/desk-inbox-experiment/recognize.swift + +## S-DICLOSED · summary · 2026-10-10 15:05 +Established: one complete live capture/OCR/review/save/readback handoff, exact approved bytes, repeat lookup and preserved source/corrections; real printed/mirror/blank OCR proof remains distinct from fixture conformance. +Uncertain: raw handwriting quality, daily usefulness, capture-to-page identity, exposure freshness, authenticated review and any autonomous or robotic actions. +Decision: keep an isolated desk tool plus read-only Footwork artifact checker; prioritize image/word review and legibility before task execution. No native recovery, guard threshold or model-default changes were made. +Refs: results/desk-inbox-20261010/report.md; docs/experiments/DI1-desk-paper-inbox.md; 6e93c35 diff --git a/jevdual/results/desk-inbox-20261010/environment.json b/jevdual/results/desk-inbox-20261010/environment.json new file mode 100644 index 0000000..04c37a6 --- /dev/null +++ b/jevdual/results/desk-inbox-20261010/environment.json @@ -0,0 +1,14 @@ +{ + "macos_version": "26.5.1", + "machine": "arm64", + "python_version": "3.14.5", + "ocr": "Apple Vision via installed Swift; actual request revision captured by helper", + "reference_seams": [ + "/Volumes/External SSD/referencerepos/cua/libs/lume/src/Utils/VNCDriver.swift:272", + "/Volumes/External SSD/referencerepos/rerun/examples/python/live_camera_edge_detection/live_camera_edge_detection.py" + ], + "source_references": [ + "https://developer.apple.com/documentation/vision/recognizing-text-in-images", + "https://developer.apple.com/documentation/imageio/cgimagepropertyorientation/upmirrored" + ] +} diff --git a/jevdual/results/desk-inbox-20261010/fixtures.json b/jevdual/results/desk-inbox-20261010/fixtures.json new file mode 100644 index 0000000..a640d17 --- /dev/null +++ b/jevdual/results/desk-inbox-20261010/fixtures.json @@ -0,0 +1,30 @@ +{ + "source_kind": "synthetic_fixture", + "generator_sha256": "3f1d8d8d6a369709429f71da3449f9b69fc27dfe644a27be847a7e7d07080d6a", + "images": { + "printed-note.png": "740cfe0c4055553b732356cbee75c7797919fc3f3624d9e8f9459a626609edeb", + "blank.png": "a6c04d1da5a290c892b9aa0a837cdbb19c7015bf5a744512754578c4bc06f2b7", + "normal-calibration.png": "8cf6377c803c75b66500bfa7c1364e852320f8f50becca5e60e04398574f081a", + "mirror-note.png": "c01b5aa2d71bfd4f895af215c6e01eb4baf722a45a0226b175e36ce02faad121" + }, + "expected_lines": { + "printed-note.png": [ + "Buy coffee", + "Measure desk", + "Fix camera" + ], + "normal-calibration.png": [ + "LEFT 123 RIGHT", + "Buy coffee", + "Measure desk" + ], + "mirror-note.png": [ + "LEFT 123 RIGHT", + "Buy coffee", + "Measure desk" + ], + "blank.png": [] + }, + "fixture_directory": "jevdual/output/desk-inbox-verification", + "live_camera_evidence": false +} diff --git a/jevdual/results/desk-inbox-20261010/report.md b/jevdual/results/desk-inbox-20261010/report.md new file mode 100644 index 0000000..aff7309 --- /dev/null +++ b/jevdual/results/desk-inbox-20261010/report.md @@ -0,0 +1,48 @@ +# Camera paper inbox: first desk experiment + +**The live physical-to-digital handoff worked after review.** A deliberately captured handwritten note was recognized locally, corrected in a separate file, confirmed by the user, saved once and independently checked through the real Footwork CLI. The saved note equals all 187 approved bytes. A fresh-process accept/status repeat preserves the same manifest and one note. The original frame and 180-byte raw OCR candidate remain unchanged. + +## What was built + +- `tools/desk-inbox-experiment/`: saved-frame preparation, local Apple Vision OCR, private review HTML, explicit digest-bound acceptance and status. +- `footwork check-artifact DEST --expected-file REVIEWED --expected-sha256 DIGEST`: a provider-free, read-only exact-byte check. It uses no fabricated native/browser Carry and does not grant action or native-completion authority. +- Original capture stays in `tools/camera-capture-experiment/`; the new tool reads acquired receipts without reopening the camera. + +Frozen implementation: `6e93c35`; preregistration: `e62fb47`, mirror amendment: `3e63656`. Source identity and commands are in `source.json`. All 31 focused tests and scoped Ruff passed. Existing CLI/carry tests are included. No provider calls or downloads were needed. + +## Observed evidence + +| Check | Evidence | Result | +| --- | --- | --- | +| Printed note, real Vision | Independently drawn known three-line fixture | Exact text match | +| Normal and mirrored text | Known calibration fixtures; explicit up/upMirrored | Same expected text and candidate digest; source bytes retained | +| Blank image | Real Vision | needs_text; no note; acceptance refused | +| Wrong approval digest | Public accept | Refused before writing a note | +| Tampered saved fixture | Public status and repeat accept | Current unknown, historical save retained; no overwrite/replay | +| Live handwritten note | User-positioned physical paper and actual camera receipt | Acquired, recognized and reviewed | +| Live mirror direction | Readable calibration line in original frame | Not mirrored; explicit up used | +| Saved text | User-confirmed correction and independent public Footwork check | Exact bytes match, one note | +| Restart/repeat | Public fresh-process accept/status and unchanged manifest | Existing note reused; raw OCR preserved | + +Private live output is under `tools/desk-inbox-experiment/output/live-paper-v1/`; camera output is under `tools/camera-capture-experiment/output/desk-paper-v1/`. Images, OCR, candidate/corrected text and note contents are ignored and excluded from this report. `verification.json` records hashes, byte counts, checks and limits. Fixture identities are in `fixtures.json`; fixtures prove synthetic behavior rather than human handwriting quality. + +## What the handwriting test showed + +Raw OCR contained missing spaces, casing/punctuation differences and word substitutions. It did not match the user's note cleanly. The separate corrected text was explicitly confirmed before saving, with the original header retained. This qualifies a reviewed workflow on one note, not autonomous transcription or calibrated handwriting accuracy. + +The helper uses [Apple Vision text recognition](https://developer.apple.com/documentation/vision/vnrecognizetextrequest) in accurate mode, en-US, with language correction disabled. An explicit --mirror-input chooses [upMirrored orientation](https://developer.apple.com/documentation/imageio/cgimagepropertyorientation/upmirrored); it never rewrites the original PNG or classifies direction from confidence. Lines retain confidence and bounds, which do not establish correctness. + +Local reference seams: Cua `libs/lume/src/Utils/VNCDriver.swift:272` for Vision recognition; Rerun `examples/python/live_camera_edge_detection/` for acquisition/visual inspection. Footwork's existing Carry semantics were preserved because they require real native/browser observations. + +## Readback + +```sh +python3 tools/desk-inbox-experiment/inbox.py status --run-dir tools/desk-inbox-experiment/output/live-paper-v1 +jevdual/.venv/bin/footwork check-artifact tools/desk-inbox-experiment/output/live-paper-v1/inbox/note.txt --expected-file tools/desk-inbox-experiment/output/live-paper-v1/reviewed.txt --expected-sha256 6d4fb067193c2c1f48d3e57c130fee9cf9540651c7b77946e020b13a8e71847c +``` + +## Decision + +Keep the workflow isolated in Footwork's tools directory. The integration proves exact saved-artifact equality to an explicitly reviewed source. It does not establish exposure freshness, authenticated physical page/hardware/review identity, exactly-once physical effects, power-loss recovery or native UI completion. + +Improve capture/review friction next: paper-region selection, a legibility check and word-level review against the image. Compare this with ordinary note entry before adding automated task creation. The technical opportunity is a source-preserving physical observation that can support a later bounded digital action; demand and daily utility remain unvalidated. diff --git a/jevdual/results/desk-inbox-20261010/source.json b/jevdual/results/desk-inbox-20261010/source.json new file mode 100644 index 0000000..367fed1 --- /dev/null +++ b/jevdual/results/desk-inbox-20261010/source.json @@ -0,0 +1,14 @@ +{ + "source_commit": "6e93c35", + "source_sha256": { + "jevdual/python/jevdual/artifacts.py": "f2d52806bef26654aa733fc1a8a02079088a08c2c4d4f05f6594880fc648ef8a", + "jevdual/python/jevdual/cli.py": "a397139e56a7ba576f51344131e859e3a9c2c3fcaad5d04bc46f15a2d66f5d7c", + "tools/desk-inbox-experiment/inbox.py": "13aeee66b25cd11b6a741e6798206c5f154bcb4d1605fd41dd44f6b99776e51b", + "tools/desk-inbox-experiment/recognize.swift": "340d9969f84f4bc892483c2a7fd4786f6bf4a6fef964f9cf6ba9b956389d2b85" + }, + "test_command": "uv run --no-sync pytest tests/test_artifacts.py tests/test_cli.py tests/test_carry.py ../tools/desk-inbox-experiment/test_inbox.py -q", + "test_cwd": "jevdual", + "tests_passed": 31, + "test_exit_code": 0, + "ruff_exit_code": 0 +} diff --git a/jevdual/results/desk-inbox-20261010/verification.json b/jevdual/results/desk-inbox-20261010/verification.json new file mode 100644 index 0000000..8190584 --- /dev/null +++ b/jevdual/results/desk-inbox-20261010/verification.json @@ -0,0 +1,57 @@ +{ + "source_commit": "6e93c35", + "preregistration_commits": [ + "e62fb47", + "3e63656" + ], + "conformance": { + "tests": 31, + "pytest_exit_code": 0, + "ruff_exit_code": 0 + }, + "synthetic_real_vision": { + "printed_three_lines": "exact match", + "normal_calibration_three_lines": "exact match with up", + "mirrored_calibration_three_lines": "exact match with upMirrored; same resulting text digest as normal", + "blank": "needs_text; acceptance refused; no note", + "wrong_approval_digest": "refused before note creation", + "tampered_saved_fixture": "current unknown; historical saved preserved; repeated accept did not overwrite/replay" + }, + "live_paper": { + "source_kind": "native_camera_frame", + "capture_run": "tools/camera-capture-experiment/output/desk-paper-v1", + "desk_run": "tools/desk-inbox-experiment/output/live-paper-v1", + "camera_sha256": "afd69ee24f1252dccbabd9956717106447927db2044ce596f769c53f61a5327c", + "raw_ocr_sha256": "9e86fa8843213b560211b2d9fe43e5983c5de0fc0c10f77fd97880967525dc3d", + "raw_ocr_bytes": 180, + "reviewed_sha256": "6d4fb067193c2c1f48d3e57c130fee9cf9540651c7b77946e020b13a8e71847c", + "reviewed_bytes": 187, + "user_review": "explicitly confirmed corrected transcription; retained original header", + "mirror_observation": "calibration text reads normally in raw frame; no mirror correction used", + "ocr_accuracy": "raw handwritten OCR contained spacing, punctuation/case and word errors; separate correction required", + "state": "saved", + "fresh_process_repeat_accept_status": "same manifest; one note; candidate retained unchanged", + "independent_footwork_check": { + "claims": [ + "current_artifact_byte_equality" + ], + "detail": "current bytes equal the digest-bound expected source", + "expected_bytes": 187, + "expected_file": "/Users/thomasmain/projects/footwork/tools/desk-inbox-experiment/output/live-paper-v1/reviewed.txt", + "expected_sha256": "6d4fb067193c2c1f48d3e57c130fee9cf9540651c7b77946e020b13a8e71847c", + "limit_bytes": 1048576, + "observed_bytes": 187, + "observed_sha256": "6d4fb067193c2c1f48d3e57c130fee9cf9540651c7b77946e020b13a8e71847c", + "ok": true, + "path": "/Users/thomasmain/projects/footwork/tools/desk-inbox-experiment/output/live-paper-v1/inbox/note.txt", + "source_sha256": "6d4fb067193c2c1f48d3e57c130fee9cf9540651c7b77946e020b13a8e71847c" + }, + "changed_mirror_request": "refused without manifest change" + }, + "limits": [ + "No paid provider or robot control", + "No calibrated handwriting accuracy or automatic task execution", + "No authenticated review identity, hardware identity, or exposure freshness", + "Images and note contents stay private/ignored" + ] +} diff --git a/jevdual/tests/test_artifacts.py b/jevdual/tests/test_artifacts.py new file mode 100644 index 0000000..f8f2bca --- /dev/null +++ b/jevdual/tests/test_artifacts.py @@ -0,0 +1,91 @@ +"""External artifacts never acquire native/browser session provenance.""" + +from __future__ import annotations + +import hashlib +import json +import os +import subprocess +import sys + +from jevdual.artifacts import MAX_ARTIFACT_BYTES, check_artifact +from jevdual.cli import main + + +def test_exact_multiline_bytes_and_no_normalization(tmp_path): + expected = tmp_path / "reviewed.txt" + target = tmp_path / "note.txt" + text = b"PRIVATE_NOTE_LINE\nsecond line\n" + expected.write_bytes(text) + target.write_bytes(text) + digest = hashlib.sha256(text).hexdigest() + result = check_artifact(target, expected, digest) + assert result["ok"] and result["claims"] == ["current_artifact_byte_equality"] + assert "PRIVATE_NOTE_LINE" not in json.dumps(result) + for changed in (text.replace(b"\n", b"\r\n"), text[:-1], text + b" "): + target.write_bytes(changed) + assert not check_artifact(target, expected, digest)["ok"] + + +def test_source_digest_change_and_invalid_digest_fail_closed(tmp_path): + expected = tmp_path / "reviewed.txt" + target = tmp_path / "note.txt" + expected.write_bytes(b"before\n") + digest = hashlib.sha256(expected.read_bytes()).hexdigest() + expected.write_bytes(b"after\n") + target.write_bytes(expected.read_bytes()) + result = check_artifact(target, expected, digest) + assert not result["ok"] and "bound digest" in result["detail"] + for bad in ("invalid", "a" * 63, "A" * 64): + assert not check_artifact(target, expected, bad)["ok"] + + +def test_missing_symlink_nonregular_and_oversize_files(tmp_path): + expected = tmp_path / "expected" + target = tmp_path / "target" + expected.write_bytes(b"same") + digest = hashlib.sha256(b"same").hexdigest() + assert not check_artifact(target, expected, digest)["ok"] + target.symlink_to(expected) + assert not check_artifact(target, expected, digest)["ok"] + target.unlink() + target.mkdir() + assert not check_artifact(target, expected, digest)["ok"] + target.rmdir() + os.mkfifo(target) + assert not check_artifact(target, expected, digest)["ok"] + target.unlink() + target.write_bytes(b"x" * (MAX_ARTIFACT_BYTES + 1)) + assert not check_artifact(target, expected, digest)["ok"] + expected.write_bytes(target.read_bytes()) + digest = hashlib.sha256(expected.read_bytes()).hexdigest() + assert not check_artifact(target, expected, digest)["ok"] + + +def test_public_cli_exit_codes_and_output_do_not_contain_text(tmp_path, capsys): + expected, target = tmp_path / "expected", tmp_path / "target" + expected.write_bytes(b"PRIVATE_NOTE\n") + target.write_bytes(expected.read_bytes()) + digest = hashlib.sha256(expected.read_bytes()).hexdigest() + args = ["check-artifact", str(target), "--expected-file", str(expected), "--expected-sha256", digest] + assert main(args) == 0 + output = capsys.readouterr().out + assert json.loads(output)["ok"] and "PRIVATE_NOTE" not in output + target.write_bytes(b"different") + assert main(args) == 6 + assert not json.loads(capsys.readouterr().out)["ok"] + assert not (tmp_path / "session.json").exists() + + +def test_cli_fresh_process_without_credentials_or_native_driver(tmp_path): + expected, target = tmp_path / "expected", tmp_path / "target" + expected.write_bytes(b"multiline\nartifact\n") + target.write_bytes(expected.read_bytes()) + digest = hashlib.sha256(expected.read_bytes()).hexdigest() + code = "from jevdual.cli import main; import sys; sys.exit(main(sys.argv[1:]))" + # No credentials are read by this command and no Driver/model is constructed. + result = subprocess.run([sys.executable, "-c", code, "check-artifact", str(target), "--expected-file", + str(expected), "--expected-sha256", digest], capture_output=True, + text=True, check=False, timeout=15) + assert result.returncode == 0, result.stderr + assert json.loads(result.stdout)["ok"] diff --git a/tools/desk-inbox-experiment/README.md b/tools/desk-inbox-experiment/README.md new file mode 100644 index 0000000..e657047 --- /dev/null +++ b/tools/desk-inbox-experiment/README.md @@ -0,0 +1,145 @@ +# Paper note to a private desk inbox + +Turn a saved camera frame into locally recognized text, review it against the paper, +then save one note whose bytes Footwork checks independently. The note is data: its +words never become commands, tasks, or agent instructions. + +This isolated experiment uses installed Swift and Apple Vision for English OCR. It +needs no cloud model, microphone, browser automation, or new package installation. +The real Footwork `check-artifact` command verifies the file; no native/browser session +or carried value is fabricated. + +## 1. Capture, then prepare + +Run from the repository root. Acquire a deliberate frame using the existing camera tool, +or select an already acquired run and token. Use the exact eligible camera name: + +```sh +python3 tools/camera-capture-experiment/capture.py capture \ + --run-dir tools/camera-capture-experiment/output/paper-001 \ + --camera 'MacBook Pro Camera' --token paper-001 \ + --allow-permission-prompt --timeout 60 + +python3 tools/desk-inbox-experiment/inbox.py prepare \ + --capture-run tools/camera-capture-experiment/output/paper-001 \ + --capture-token paper-001 \ + --run-dir tools/desk-inbox-experiment/output/paper-001 +``` + +Preparation reads the original frame through the camera tool's private-directory, +lock, receipt and artifact checks. It does not acquire another frame. An unknown camera +operation cannot supply a note. + +Vision uses accurate recognition, `en-US`, and disabled language correction. The result +retains each recognized line, confidence and normalized bounds. OCR remains fallible: +confidence does not establish correctness or authorize saving. + +For a known horizontally mirrored frame, add `--mirror-input` to `prepare`. This chooses +Vision's `upMirrored` orientation and mirrors the review display. It retains the original +PNG and hash. The default explicitly uses `up`. Determine direction from readable calibration +text such as `LEFT 123 RIGHT`; the tool does not classify mirror state or choose a setting +from confidence. A different orientation is a different preparation request. + +An explicit developer fixture route is available: + +```sh +python3 tools/desk-inbox-experiment/inbox.py prepare \ + --fixture-image /absolute/path/to/printed-note.png \ + --run-dir tools/desk-inbox-experiment/output/fixture-001 +``` + +That run is labeled `synthetic_fixture`, including when real Vision processes its image. +It supplies no native-camera acquisition evidence. Inputs must be saved PNGs at most 32 MiB. + +## 2. Review the image and text + +```sh +open tools/desk-inbox-experiment/output/paper-001/review.html +``` + +The local page shows the retained image, explicit orientation, original source path, +recognized text and candidate SHA256. All text and paths are HTML-escaped. It has no +scripts, upload route or automatic acceptance. Compare the text with the paper. + +The original OCR stays in `ocr.json`; `candidate.txt` joins recognized nonblank lines with +LF and adds one final LF. No text means `needs_text`, with no candidate or inbox note. +Preparation repeats reuse the existing candidate. Changed source bytes or orientation +refuse reuse. An interrupted preparation stays unknown and does not rerun OCR. + +If corrections are needed, write a separate reviewed UTF-8 file inside the private run, +then obtain its digest with `shasum -a 256`. Keep `candidate.txt` unchanged. Corrections retain +their exact bytes, including any CRLF or missing terminal newline, and are limited to 128 KiB. +Empty text and NUL bytes are refused. This experiment stores notes, rather than interpreting +their meaning or deciding what should be done. + +## 3. Accept and verify + +After review, use the exact digest shown for the candidate: + +```sh +python3 tools/desk-inbox-experiment/inbox.py accept \ + --run-dir tools/desk-inbox-experiment/output/paper-001 \ + --approved-sha256 REPLACE_WITH_THE_REVIEWED_SHA256 + +python3 tools/desk-inbox-experiment/inbox.py status \ + --run-dir tools/desk-inbox-experiment/output/paper-001 +``` + +For a corrected file, supply `--reviewed-file /absolute/path/to/reviewed.txt` and its +own approved SHA256. The manifest distinguishes corrected text from original OCR. +Digest approval is the caller's explicit review assertion; it does not authenticate a human +or prove that someone compared the paper. + +Acceptance records intent before creating `approved.txt` and `inbox/note.txt`, both private +and create-only. It calls the installed public Footwork CLI: + +```sh +jevdual/.venv/bin/footwork check-artifact DESTINATION \ + --expected-file REVIEWED_SOURCE --expected-sha256 APPROVED_DIGEST +``` + +The checker reads the source, validates its approved SHA256, compares the destination's +raw bytes and rechecks the source. It returns hashes, sizes and a verdict without note +contents. Its 1 MiB limit applies independently to both files; final file symlinks and +nonregular files are rejected. It does not authenticate ancestor directories or provenance. +The desk tool separately requires owned private run directories without symlinks. + +Repeating acceptance reads the original operation. It never overwrites or recreates a +missing or altered note. A partial write, lost receipt, interrupted acceptance or failed +checker leaves the operation unknown and blocks replay. There is no reset command. + +Status rechecks original/retained image hashes, candidate integrity, approved text and +the note. A later failure leaves the historical saved receipt intact while current state +is unknown with empty claims. Preserve source files and the original capture run so their +retained evidence remains checkable. + +The result establishes current file equality to reviewed bytes. It does not establish OCR +accuracy, physical page identity, exposure freshness, native UI completion, exactly-once +camera effects, human-review authentication, or power-loss recovery. + +## Files and checks + +Each run lives under ignored `tools/desk-inbox-experiment/output/`. Images, OCR, candidate +and approved text, HTML review, Swift cache and diagnostics remain private. Run directories +use 0700; created files use 0600. JSON responses contain paths, hashes and operation state, +but no recognized text. One nonblocking process lock permits one owner per run. + +`prepare`, `accept` and `status` return 0 for `needs_review`, `saved` or `absent`; other +states return 2. Footwork `check-artifact` returns 0 for equality and 6 for invalid/mismatched +evidence. Read JSON state as well as the exit code. + +```sh +cd jevdual +uv run --no-sync pytest tests/test_artifacts.py tests/test_cli.py tests/test_carry.py \ + ../tools/desk-inbox-experiment/test_inbox.py -q +uv run --no-sync ruff check python/jevdual/artifacts.py python/jevdual/cli.py \ + tests/test_artifacts.py ../tools/desk-inbox-experiment +``` + +Conformance tests use OCR/process fixtures and the real Footwork file checker. Real Vision +against independently generated normal/mirrored/blank images, and a human's live paper note, +are separate preregistered validations. Neither fixture conformance nor printed-fixture OCR +establishes live handwriting usefulness. + +Preregistration: `jevdual/docs/experiments/DI1-desk-paper-inbox.md`. +Notebook: `jevdual/docs/notebook/2026-10-10-desk-paper-inbox.md`. diff --git a/tools/desk-inbox-experiment/test_inbox.py b/tools/desk-inbox-experiment/test_inbox.py new file mode 100644 index 0000000..f34e9a6 --- /dev/null +++ b/tools/desk-inbox-experiment/test_inbox.py @@ -0,0 +1,272 @@ +"""Desk conformance at file and process boundaries; real Vision is a separate run.""" + +import base64 +import importlib.util +import json +import os +import subprocess +import sys +import tempfile +import unittest +from pathlib import Path +from unittest.mock import patch + +BASE = Path(__file__).resolve().parent +SPEC = importlib.util.spec_from_file_location("desk_inbox", BASE / "inbox.py") +inbox = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(inbox) +PNG = base64.b64decode( + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=" +) +OCR = {"engine": "fixture", "orientation": "up", "lines": [ + {"text": "First note", "confidence": .8, "bounds": {"x": .1, "y": .8, "width": .5, "height": .1}}, + {"text": "Second note", "confidence": .7, "bounds": {"x": .1, "y": .6, "width": .5, "height": .1}}, +]} + + +class InboxTests(unittest.TestCase): + def setUp(self): + inbox.OUTPUT.mkdir(mode=0o700, exist_ok=True) + self.tmp = tempfile.TemporaryDirectory(prefix="conformance-", dir=inbox.OUTPUT) + self.addCleanup(self.tmp.cleanup) + self.work = Path(self.tmp.name) + self.root = inbox.private_directory(self.work / "run") + self.image = self.work / "printed<&>.png" + self.image.write_bytes(PNG) + + def prepare(self, result=OCR, mirror=False): + with patch.object(inbox, "recognize", return_value=result) as recognize: + prepared = inbox.prepare(self.root, fixture_image=str(self.image), mirror_input=mirror) + return prepared, recognize + + def test_prepare_and_accept_use_real_footwork_checker_without_text_output(self): + prepared, _ = self.prepare() + self.assertEqual(prepared["state"], "needs_review") + self.assertEqual(prepared["request"]["source_kind"], "synthetic_fixture") + self.assertEqual((self.root / "candidate.txt").read_bytes(), b"First note\nSecond note\n") + result = inbox.accept(self.root, prepared["candidate_sha256"]) + self.assertEqual(result["state"], "saved") + self.assertTrue(result["current_artifact_check"]["ok"]) + self.assertNotIn("First note", json.dumps(result)) + self.assertEqual((self.root / "inbox" / "note.txt").read_bytes(), (self.root / "candidate.txt").read_bytes()) + self.assertFalse((self.root / "session.json").exists()) + self.assertFalse((self.root / "carries.json").exists()) + + def test_repeated_prepare_and_accept_do_not_rewrite(self): + prepared, _ = self.prepare() + before = (self.root / "manifest.json").read_bytes() + with patch.object(inbox, "recognize") as recognize: + again = inbox.prepare(self.root, fixture_image=str(self.image)) + recognize.assert_not_called() + self.assertEqual(again["candidate_sha256"], prepared["candidate_sha256"]) + self.assertEqual((self.root / "manifest.json").read_bytes(), before) + inbox.accept(self.root, prepared["candidate_sha256"]) + before = (self.root / "manifest.json").read_bytes() + note_before = (self.root / "inbox" / "note.txt").stat() + again = inbox.accept(self.root, prepared["candidate_sha256"]) + self.assertEqual(again["state"], "saved") + self.assertEqual((self.root / "manifest.json").read_bytes(), before) + self.assertEqual((self.root / "inbox" / "note.txt").stat().st_mtime_ns, note_before.st_mtime_ns) + self.assertEqual(len(list((self.root / "inbox").iterdir())), 1) + + def test_mirror_is_bound_explicit_and_preview_escapes_text(self): + malicious = {"lines": [{"text": " & commands", "confidence": .9}]} + prepared, recognize = self.prepare(malicious, mirror=True) + self.assertTrue(prepared["request"]["mirror_input"]) + recognize.assert_called_once_with(self.root, True) + page = (self.root / "review.html").read_text() + self.assertNotIn("" + self.caller["interpretation"] = "" + self.sha = self.write_record() + self.link() + md = (self.root / "record.md").read_text() + self.assertNotIn(" + + diff --git a/tools/physical-workcell/order_app.py b/tools/physical-workcell/order_app.py new file mode 100644 index 0000000..5cea4af --- /dev/null +++ b/tools/physical-workcell/order_app.py @@ -0,0 +1,549 @@ +"""Loopback browser orders with SQLite revision leases and independently checked fulfillment.""" + +import argparse +import contextlib +import importlib.util +import json +import os +import signal +import sqlite3 +import stat +import sys +import threading +import time +import uuid +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from pathlib import Path +from urllib.parse import unquote, urlsplit + +BASE = Path(__file__).resolve().parent +sys.path.insert(0, str(BASE)) +import order_protocol as protocol + +Refusal = protocol.Refusal +DB_NAME = "orders.sqlite3" +SOURCES = ("order_app.py", "order_protocol.py", "order_app.html", "controller.py", "episode_runner.py", + "workcell.py", "image_guided.py", "episode_cases.py", "proposal.schema.json", "scene.xml") + + +def fingerprints(): + return {name: protocol.sha(protocol.read_bytes(BASE / name)) for name in SOURCES} + + +def work_order(order): + return {key: order[key] for key in ("version", "order_id", "project", "part_id", "target_zone")} + + +def sqlite_file(path): + info = path.lstat() + if not stat.S_ISREG(info.st_mode) or info.st_uid != os.getuid() or info.st_mode & 0o077: + raise Refusal("application store must be an owned private regular file") + return [info.st_dev, info.st_ino] + + +def initialize(app_dir, order_file, order_sha256): + if not isinstance(order_sha256, str) or not protocol.DIGEST.fullmatch(order_sha256): + raise Refusal("order SHA256 must be exact lowercase hexadecimal") + content = protocol.read_bytes(Path(order_file)) + if protocol.sha(content) != order_sha256: + raise Refusal("order input differs from its bound digest") + order = protocol.validate_order(protocol.decode(content)) + if order["state"] == "fulfilled": + raise Refusal("a seeded order cannot invent a fulfillment receipt") + binding_path = app_dir / "app-binding.json" + if binding_path.exists() or binding_path.is_symlink(): + store = Store(app_dir) + if store.binding["seed_sha256"] != order_sha256: + raise Refusal("application already belongs to a different seed order") + return {"app_id": store.app_id, "app_dir": str(app_dir), "phase": "initialized", "order": store.order(order["order_id"])} + if any(path.name != "app.lock" for path in app_dir.iterdir()): + raise Refusal("unreceipted app files exist; implicit initialization/reset is forbidden") + app_id, store_id = uuid.uuid4().hex, uuid.uuid4().hex + protocol.create_file(app_dir / "seed-order.json", content) + database = app_dir / DB_NAME + protocol.create_file(database, b"") + binding = {"version": 1, "app_id": app_id, "store_id": store_id, "app_dir": str(app_dir), + "database": DB_NAME, "database_identity": sqlite_file(database), "seed_sha256": order_sha256, + "source_fingerprints": fingerprints()} + with contextlib.closing(sqlite3.connect(database)) as connection: + connection.execute("PRAGMA synchronous=FULL") + connection.executescript(""" + CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT NOT NULL); + CREATE TABLE orders (order_id TEXT PRIMARY KEY, revision INTEGER NOT NULL, + state TEXT NOT NULL, work_order_json TEXT NOT NULL); + CREATE TABLE leases (lease_id TEXT PRIMARY KEY, order_id TEXT NOT NULL, + revision INTEGER NOT NULL, lease_json TEXT NOT NULL); + CREATE UNIQUE INDEX one_lease_per_revision ON leases(order_id, revision); + CREATE TABLE operations (operation_id TEXT PRIMARY KEY, kind TEXT NOT NULL, + order_id TEXT NOT NULL, lease_id TEXT NOT NULL, + request_json TEXT NOT NULL, receipt_json TEXT NOT NULL); + """) + connection.execute("INSERT INTO meta VALUES ('binding', ?)", (protocol.encoded(binding).decode(),)) + connection.execute("INSERT INTO orders VALUES (?,?,?,?)", ( + order["order_id"], order["revision"], order["state"], protocol.encoded(work_order(order)).decode())) + connection.commit() + protocol.sync_directory(app_dir) + protocol.create_file(binding_path, protocol.encoded(binding)) + protocol.directory(app_dir / "workcells", create=True) + return {"app_id": app_id, "app_dir": str(app_dir), "phase": "initialized", "order": order} + + +class Store: + def __init__(self, app_dir): + self.app_dir = app_dir + self.binding = protocol.decode(protocol.read_bytes(app_dir / "app-binding.json")) + protocol.fields(self.binding, ("version", "app_id", "store_id", "app_dir", "database", "database_identity", + "seed_sha256", "source_fingerprints"), "application binding") + if (self.binding["version"] != 1 or self.binding["app_dir"] != str(app_dir) or + self.binding["database"] != DB_NAME or not protocol.UUID.fullmatch(self.binding["app_id"]) or + not protocol.UUID.fullmatch(self.binding["store_id"])): + raise Refusal("application identity or store binding is invalid") + self.app_id = self.binding["app_id"] + self.database = app_dir / DB_NAME + self.validate_current() + with self.connection() as connection: + if connection.execute("PRAGMA quick_check").fetchone()[0] != "ok": + raise Refusal("application SQLite store failed integrity check") + + @contextlib.contextmanager + def connection(self): + sqlite_file(self.database) + connection = sqlite3.connect(self.database, timeout=2, isolation_level=None) + connection.row_factory = sqlite3.Row + try: + connection.execute("PRAGMA synchronous=FULL") + yield connection + finally: + connection.close() + + @contextlib.contextmanager + def transaction(self): + self.validate_current() + with self.connection() as connection: + connection.execute("BEGIN IMMEDIATE") + try: + yield connection + connection.commit() + except BaseException: + connection.rollback() + raise + + def validate_current(self): + if (protocol.decode(protocol.read_bytes(self.app_dir / "app-binding.json")) != self.binding or + self.binding["source_fingerprints"] != fingerprints() or + self.binding["database_identity"] != sqlite_file(self.app_dir / DB_NAME) or + protocol.sha(protocol.read_bytes(self.app_dir / "seed-order.json")) != self.binding["seed_sha256"]): + raise Refusal("application source, seed or store binding changed") + with self.connection() as connection: + row = connection.execute("SELECT value FROM meta WHERE key='binding'").fetchone() + if row is None or protocol.decode(row[0].encode()) != self.binding: + raise Refusal("SQLite application identity does not match its owned store") + origin = connection.execute("SELECT value FROM meta WHERE key='origin'").fetchone() + origin_path = self.app_dir / "origin.json" + if ((origin is not None or origin_path.exists() or origin_path.is_symlink()) and + (origin is None or protocol.decode(protocol.read_bytes(origin_path)) != { + "app_id": self.app_id, "origin": origin[0]})): + raise Refusal("application origin identity changed") + + def origin(self): + with self.connection() as connection: + row = connection.execute("SELECT value FROM meta WHERE key='origin'").fetchone() + return row[0] if row else None + + def bind_origin(self, origin): + prior = self.origin() + if prior is not None: + if prior != origin: + raise Refusal("application restart must preserve its exact loopback origin") + return + with self.transaction() as connection: + protocol.create_file(self.app_dir / "origin.json", protocol.encoded({"app_id": self.app_id, "origin": origin})) + connection.execute("INSERT INTO meta VALUES ('origin', ?)", (origin,)) + + def order(self, order_id, connection=None): + protocol.identity(order_id) + if connection is None: + with self.connection() as opened: + return self.order(order_id, opened) + row = connection.execute("SELECT * FROM orders WHERE order_id=?", (order_id,)).fetchone() + if row is None: + raise LookupError("order identity is unavailable") + order = protocol.decode(row["work_order_json"].encode()) + order.update(revision=row["revision"], state=row["state"]) + return protocol.validate_order(order) + + def lease(self, lease_id, connection=None): + if not isinstance(lease_id, str) or not protocol.UUID.fullmatch(lease_id): + raise Refusal("lease identity must be an exact UUID") + if connection is None: + with self.connection() as opened: + return self.lease(lease_id, opened) + row = connection.execute("SELECT * FROM leases WHERE lease_id=?", (lease_id,)).fetchone() + if row is None: + raise LookupError("lease identity is unavailable") + lease = protocol.decode(row["lease_json"].encode()) + protocol.fields(lease, ("app_id", "lease_id", "order_id", "expected_revision", "work_order", "work_order_sha256", + "binding_operation_id", "physical_completion_id", "completion_operation_id", "origin", + "app_dir", "workspace_dir", "run_dir", "controller_dir", "handoff_dir"), "retained lease") + expected_paths = protocol.paths_for(self.app_dir, lease_id) + if (lease["app_id"] != self.app_id or lease["lease_id"] != lease_id or + lease["order_id"] != row["order_id"] or lease["expected_revision"] != row["revision"] or + lease["work_order"]["order_id"] != row["order_id"] or + any(lease[key] != value for key, value in expected_paths.items()) or + lease["origin"] != self.origin() or + protocol.sha(protocol.encoded(protocol.validate_work_order(lease["work_order"]))) != lease["work_order_sha256"]): + raise Refusal("retained lease identity, origin, order or assigned paths changed") + return lease + + def operation(self, operation_id, connection=None): + protocol.identity(operation_id) + if connection is None: + with self.connection() as opened: + return self.operation(operation_id, opened) + row = connection.execute("SELECT * FROM operations WHERE operation_id=?", (operation_id,)).fetchone() + if row is None: + raise LookupError("application operation is unavailable") + return row + + def bind(self, order_id, request): + protocol.fields(request, ("expected_revision", "binding_operation_id"), "bind request") + protocol.revision(request["expected_revision"]) + operation_id = protocol.identity(request["binding_operation_id"]) + exact = {"order_id": order_id, **request} + with self.transaction() as connection: + previous = connection.execute("SELECT * FROM operations WHERE operation_id=?", (operation_id,)).fetchone() + if previous: + if previous["kind"] != "bind" or protocol.decode(previous["request_json"].encode()) != exact: + raise Refusal("binding operation ID belongs to different arguments") + return {"app_id": self.app_id, "lease": self.lease(previous["lease_id"], connection), + "order": self.order(order_id, connection), "historical": True} + order = self.order(order_id, connection) + if order["state"] != "open" or order["revision"] != request["expected_revision"]: + raise Refusal("only the exact current open revision can be bound") + if connection.execute("SELECT 1 FROM leases WHERE order_id=? AND revision=?", (order_id, order["revision"])).fetchone(): + raise Refusal("this order revision already has a lease; reuse its original binding operation") + lease_id = uuid.uuid4().hex + snapshot = work_order(order) + lease = {"app_id": self.app_id, "lease_id": lease_id, "order_id": order_id, + "expected_revision": order["revision"], "work_order": snapshot, + "work_order_sha256": protocol.sha(protocol.encoded(snapshot)), + "binding_operation_id": operation_id, "physical_completion_id": "stage-" + uuid.uuid4().hex, + "completion_operation_id": "fulfill-" + uuid.uuid4().hex, "origin": self.origin(), + **protocol.paths_for(self.app_dir, lease_id)} + protocol.directory(Path(lease["workspace_dir"]), create=True) + connection.execute("INSERT INTO leases VALUES (?,?,?,?)", ( + lease_id, order_id, order["revision"], protocol.encoded(lease).decode())) + connection.execute("INSERT INTO operations VALUES (?,?,?,?,?,?)", ( + operation_id, "bind", order_id, lease_id, protocol.encoded(exact).decode(), protocol.encoded(lease).decode())) + return {"app_id": self.app_id, "lease": lease, "order": order, "historical": False} + + def mutate(self, order_id, request, cancel=False): + protocol.fields(request, ("expected_revision",) if cancel else ("expected_revision", "target_zone"), "order mutation") + protocol.revision(request["expected_revision"]) + if not cancel: + protocol.validate_zone(request["target_zone"]) + with self.transaction() as connection: + order = self.order(order_id, connection) + if order["state"] != "open" or order["revision"] != request["expected_revision"]: + raise Refusal("order changed or is no longer open") + order["revision"] = protocol.revision(order["revision"] + 1) + if cancel: + order["state"] = "cancelled" + else: + order["target_zone"] = request["target_zone"] + connection.execute("UPDATE orders SET revision=?,state=?,work_order_json=? WHERE order_id=?", ( + order["revision"], order["state"], protocol.encoded(work_order(order)).decode(), order_id)) + return {"app_id": self.app_id, "order": order} + + def fulfilled_repeat(self, row, exact, connection): + if row["kind"] != "fulfill" or protocol.decode(row["request_json"].encode()) != exact: + raise Refusal("completion operation ID belongs to different arguments") + return {"app_id": self.app_id, "receipt": protocol.decode(row["receipt_json"].encode()), + "current_order": self.order(row["order_id"], connection), "historical": True} + + def fulfill(self, order_id, request): + protocol.fields(request, ("lease_id", "completion_operation_id"), "fulfillment request") + operation_id = protocol.identity(request["completion_operation_id"]) + exact = {"order_id": order_id, **request} + # Reconcile a committed reply before consulting possibly unavailable physical evidence. + with self.connection() as connection: + previous = connection.execute("SELECT * FROM operations WHERE operation_id=?", (operation_id,)).fetchone() + if previous: + return self.fulfilled_repeat(previous, exact, connection) + lease = self.lease(request["lease_id"], connection) + order = self.order(order_id, connection) + if (lease["order_id"] != order_id or lease["completion_operation_id"] != operation_id or + order["state"] != "open" or order["revision"] != lease["expected_revision"]): + raise Refusal("completion must reference the assigned operation and unchanged open leased order") + proof = verify_physical(lease) + with self.transaction() as connection: + previous = connection.execute("SELECT * FROM operations WHERE operation_id=?", (operation_id,)).fetchone() + if previous: + return self.fulfilled_repeat(previous, exact, connection) + current_lease = self.lease(request["lease_id"], connection) + current = self.order(order_id, connection) + if (current_lease != lease or current["state"] != "open" or + current["revision"] != lease["expected_revision"] or work_order(current) != lease["work_order"]): + raise Refusal("order or lease changed after physical verification; fulfillment refused") + new_revision = protocol.revision(current["revision"] + 1) + changed = connection.execute("UPDATE orders SET state='fulfilled', revision=? WHERE order_id=? AND revision=? AND state='open'", + (new_revision, order_id, lease["expected_revision"])).rowcount + if changed != 1: + raise Refusal("current order no longer matches the leased revision") + receipt = {"app_id": self.app_id, "order_id": order_id, "lease_id": lease["lease_id"], + "completion_operation_id": operation_id, "physical_completion_id": lease["physical_completion_id"], + "leased_revision": lease["expected_revision"], "fulfilled_revision": new_revision, + "work_order_sha256": lease["work_order_sha256"], "state": "fulfilled", + "committed_time_unix": time.time(), "physical_proof": {"historical": True, **proof}} + connection.execute("INSERT INTO operations VALUES (?,?,?,?,?,?)", ( + operation_id, "fulfill", order_id, lease["lease_id"], protocol.encoded(exact).decode(), protocol.encoded(receipt).decode())) + return {"app_id": self.app_id, "receipt": receipt, "current_order": self.order(order_id, connection), "historical": True} + + +def controller_module(): + spec = importlib.util.spec_from_file_location("order_frozen_controller", BASE / "controller.py") + module = importlib.util.module_from_spec(spec) + try: + spec.loader.exec_module(module) + except ImportError as exc: + raise Refusal("pinned physical controller dependencies are unavailable") from exc + return module + + +def controller_query(controller, control, request): + try: + return controller.client(control, request) + except (controller.Refusal, OSError, ValueError, TypeError, KeyError) as exc: + raise Refusal("assigned live controller evidence is unavailable") from exc + + +def controller_observe(lease): + controller = controller_module() + control = protocol.directory(Path(lease["controller_dir"])) + observed = controller_query(controller, control, {"command": "observe"}) + if observed.get("phase") != "ready" or observed.get("current_health") != "ready": + raise Refusal("assigned controller has no current supported observation") + packet = observed["observation"] + expected = {key: lease["work_order"][key] for key in ("order_id", "project", "part_id", "target_zone")} + if (packet["task_intent"] != expected or packet["run_dir"] != lease["run_dir"] or + packet["binding"]["work_order_sha256"] != lease["work_order_sha256"]): + raise Refusal("controller observation does not belong to the leased order") + return controller, observed, packet + + +def verify_physical(lease): + controller = controller_module() + control = protocol.directory(Path(lease["controller_dir"])) + goal = controller_query(controller, control, {"command": "status", "operation_id": lease["physical_completion_id"]}) + if (goal.get("operation_id") != lease["physical_completion_id"] or goal.get("historical_outcome") != "staged" or + goal.get("phase") != "staged" or goal.get("current_health") != "ready" or + not goal.get("current_software_artifact_check", {}).get("ok")): + raise Refusal("assigned physical completion has no staged history and current verified artifact") + _, observed, packet = controller_observe(lease) + receipt = goal["receipt"] + if (receipt["decision"] != "complete" or receipt["token"] != lease["physical_completion_id"] or + receipt["phase"] != "staged" or receipt["image_generation"] != packet["generation"] or + receipt["after_generation"] != packet["generation"] or receipt["after_state_sha256"] != packet["state_sha256"] or + receipt["image_sha256"] != packet["image_sha256"] or packet["perception"]["state"] != "recognized" or + packet["calibration"]["valid"] is not True or not observed.get("current_software_artifact_check", {}).get("ok") or + receipt.get("historical_visual_check", {}).get("inside_with_margin") is not True or + goal["current_incarnation"] != observed["current_incarnation"]): + raise Refusal("current RGB, calibration, controller history or software evidence is unsupported") + content = protocol.read_bytes(Path(lease["run_dir"]) / "order.json") + artifact_sha = protocol.sha(content) + for checked in (goal["current_software_artifact_check"], observed["current_software_artifact_check"]): + if checked.get("expected_sha256") != artifact_sha or checked.get("observed_sha256") != artifact_sha: + raise Refusal("saved physical artifact bytes do not match the live checker") + artifact = protocol.decode(content) + expected = lease["work_order"] + if (artifact.get("source_kind") != "mujoco_simulation" or artifact.get("state") != "staged" or + artifact.get("work_order_sha256") != lease["work_order_sha256"] or + any(artifact.get(key) != expected[key] for key in ("order_id", "project", "part_id", "target_zone")) or + artifact.get("simulator_generation") != packet["generation"] or + artifact.get("simulator_state_sha256") != packet["state_sha256"]): + raise Refusal("saved physical artifact identity differs from the leased task") + return {"source_kind": "mujoco_simulation", "operation_id": lease["physical_completion_id"], + "controller_incarnation": goal["current_incarnation"], "accepted_incarnation": goal["accepted_incarnation"], + "generation": packet["generation"], "state_sha256": packet["state_sha256"], + "image_sha256": packet["image_sha256"], "artifact_sha256": artifact_sha, "verified_time_unix": time.time()} + + +class Server(ThreadingHTTPServer): + daemon_threads = False + block_on_close = True + + def __init__(self, store, port): + super().__init__(("127.0.0.1", port), Handler) + self.store = store + self.origin = f"http://127.0.0.1:{self.server_address[1]}" + self.incarnation = uuid.uuid4().hex + self.timeout = .2 + + +class Handler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + + def setup(self): + super().setup() + self.connection.settimeout(3) + + def log_message(self, *_): + pass + + def send(self, value, status=200, content_type="application/json; charset=utf-8", extra_headers=None): + content = value if isinstance(value, bytes) else protocol.encoded(value) + self.send_response(status) + self.send_header("Content-Type", content_type) + self.send_header("Content-Length", str(len(content))) + self.send_header("Cache-Control", "no-store") + self.send_header("X-Content-Type-Options", "nosniff") + self.send_header("Content-Security-Policy", "default-src 'self'; img-src 'self' blob:; style-src 'unsafe-inline'; script-src 'unsafe-inline'; frame-ancestors 'none'") + for key, header in (extra_headers or {}).items(): + self.send_header(key, str(header)) + self.end_headers() + self.wfile.write(content) + + def gate(self, writing=False): + expected_host = urlsplit(self.server.origin).netloc + if self.client_address[0] != "127.0.0.1" or self.headers.get_all("Host") != [expected_host]: + raise Refusal("request must target the exact loopback application host") + if writing and self.headers.get_all("Origin") != [self.server.origin]: + raise Refusal("write requires the exact application Origin") + if writing and self.headers.get_all("X-Footwork-App-ID") != [self.server.store.app_id]: + raise Refusal("write requires the exact immutable application identity") + self.server.store.validate_current() + + def route(self): + parsed = urlsplit(self.path) + if parsed.scheme or parsed.netloc or parsed.query or parsed.fragment: + raise Refusal("request path must be an exact local route") + return [unquote(part) for part in parsed.path.split("/") if part] + + def execute(self, writing=False): + try: + self.gate(writing) + route = self.route() + store = self.server.store + if not writing: + if not route: + return self.send(protocol.read_bytes(BASE / "order_app.html"), content_type="text/html; charset=utf-8") + if route == ["api", "health"]: + return self.send({"app_id": store.app_id, "app_dir": str(store.app_dir), "origin": self.server.origin, + "server_incarnation": self.server.incarnation, "phase": "ready", + "source_fingerprints": store.binding["source_fingerprints"]}) + if route == ["api", "orders"]: + with store.connection() as connection: + orders = [store.order(row[0], connection) for row in connection.execute("SELECT order_id FROM orders ORDER BY order_id")] + return self.send({"app_id": store.app_id, "orders": orders}) + if len(route) == 3 and route[:2] == ["api", "orders"]: + return self.send({"app_id": store.app_id, "order": store.order(route[2])}) + if len(route) == 3 and route[:2] == ["api", "leases"]: + return self.send({"app_id": store.app_id, "lease": store.lease(route[2])}) + if len(route) == 4 and route[:2] == ["api", "leases"] and route[3] == "frame": + lease = store.lease(route[2]) + _, _, packet = controller_observe(lease) + expected_path = Path(lease["run_dir"]) / f"vision-frame-{packet['generation']:06d}.png" + if packet["image_path"] != str(expected_path): + raise Refusal("controller frame path differs from its assigned run") + content = protocol.read_bytes(expected_path, maximum=1024 * 1024) + if protocol.sha(content) != packet["image_sha256"] or not content.startswith(b"\x89PNG\r\n\x1a\n"): + raise Refusal("current rendered frame bytes do not match controller evidence") + return self.send(content, content_type="image/png", extra_headers={ + "X-Image-Generation": packet["generation"], "X-Image-SHA256": packet["image_sha256"], + "X-Perception-State": packet["perception"]["state"], + "X-Calibration-Valid": str(packet["calibration"]["valid"]).lower()}) + if len(route) == 3 and route[:2] == ["api", "operations"]: + row = store.operation(route[2]) + return self.send({"app_id": store.app_id, "receipt": protocol.decode(row["receipt_json"].encode()), + "current_order": store.order(row["order_id"]), "historical": True}) + raise LookupError("application route is unavailable") + if (self.headers.get_all("Content-Type") != ["application/json"] or + len(self.headers.get_all("Content-Length") or []) != 1 or self.headers.get("Transfer-Encoding") is not None): + raise Refusal("write requires bounded exact JSON framing") + length = int(self.headers["Content-Length"]) + if not 0 < length <= protocol.MAX_BYTES: + raise Refusal("JSON request size is outside its bound") + content = self.rfile.read(length) + if len(content) != length: + raise Refusal("JSON request ended before its declared length") + request = protocol.decode(content) + if len(route) != 4 or route[:2] != ["api", "orders"]: + raise LookupError("application write route is unavailable") + order_id, action = protocol.identity(route[2]), route[3] + if action == "bind": + result = store.bind(order_id, request) + elif action in {"edit", "cancel"}: + result = store.mutate(order_id, request, cancel=action == "cancel") + elif action == "fulfill": + result = store.fulfill(order_id, request) + else: + raise LookupError("application write route is unavailable") + return self.send(result) + except LookupError as exc: + return self.send({"app_id": self.server.store.app_id, "phase": "unavailable", "reason": str(exc)}, 404) + except (Refusal, OSError, ValueError, KeyError, TypeError, sqlite3.Error) as exc: + reason = str(exc) if isinstance(exc, Refusal) else "application input or current evidence is unavailable" + return self.send({"app_id": self.server.store.app_id, "phase": "refused", "reason": reason}, 409) + + def do_GET(self): + self.execute() + + def do_POST(self): + self.execute(writing=True) + + +def serve(app_dir, port): + if type(port) is not int or not 0 <= port <= 65535: + raise Refusal("port must be a bounded integer") + store = Store(app_dir) + prior = store.origin() + if prior is not None and port != urlsplit(prior).port: + raise Refusal("restart requires the exact prior loopback port; origin changes are unsupported") + with Server(store, port) as server: + store.bind_origin(server.origin) + ready = {"app_id": store.app_id, "app_dir": str(app_dir), "origin": server.origin, "pid": os.getpid(), + "server_incarnation": server.incarnation, "phase": "ready", "source_fingerprints": fingerprints()} + protocol.persist(app_dir / "readiness.json", ready) + stop = threading.Event() + prior_handlers = {sig: signal.signal(sig, lambda *_: stop.set()) for sig in (signal.SIGTERM, signal.SIGINT)} + try: + while not stop.is_set(): + server.handle_request() + finally: + # server_close joins request threads before the app ownership lock can unwind. + server.server_close() + ready.update(phase="stopped", stopped_time_unix=time.time()) + protocol.persist(app_dir / "readiness.json", ready) + for sig, handler in prior_handlers.items(): + signal.signal(sig, handler) + + +def main(argv=None): + parser = argparse.ArgumentParser(description=__doc__) + commands = parser.add_subparsers(dest="command", required=True) + for command in ("init", "serve"): + child = commands.add_parser(command) + child.add_argument("--app-dir", required=True) + if command == "init": + child.add_argument("--order-file", required=True) + child.add_argument("--order-sha256", required=True) + else: + child.add_argument("--port", type=int, default=0) + args = parser.parse_args(argv) + try: + app_dir = protocol.directory(args.app_dir, create=args.command == "init") + with protocol.locked(app_dir): + if args.command == "init": + result = initialize(app_dir, args.order_file, args.order_sha256) + print(json.dumps(result, sort_keys=True, indent=2)) + else: + serve(app_dir, args.port) + return 0 + except (Refusal, OSError, ValueError, TypeError, KeyError, sqlite3.Error, KeyboardInterrupt) as exc: + reason = str(exc) if isinstance(exc, Refusal) else "application or owned store is unavailable" + print(json.dumps({"phase": "refused", "reason": reason})) + return 2 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/physical-workcell/order_protocol.py b/tools/physical-workcell/order_protocol.py new file mode 100644 index 0000000..00f729f --- /dev/null +++ b/tools/physical-workcell/order_protocol.py @@ -0,0 +1,191 @@ +"""Bounded stdlib schemas and owned paths for the local versioned order app.""" + +import contextlib +import fcntl +import hashlib +import json +import math +import os +import re +import stat +from pathlib import Path + +BASE = Path(__file__).resolve().parent +OUTPUT = BASE / "output" +MAX_BYTES = 64 * 1024 +DIGEST = re.compile(r"[0-9a-f]{64}\Z") +IDENTITY = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}\Z") +UUID = re.compile(r"[0-9a-f]{32}\Z") + + +class Refusal(ValueError): + pass + + +def sha(content): + return hashlib.sha256(content).hexdigest() + + +def encoded(value): + return (json.dumps(value, sort_keys=True, indent=2, allow_nan=False) + "\n").encode() + + +def decode(content): + def unique(pairs): + result = {} + for key, value in pairs: + if key in result: + raise Refusal("duplicate JSON key") + result[key] = value + return result + + def nonfinite(_): + raise Refusal("nonfinite JSON value") + + if len(content) > MAX_BYTES: + raise Refusal("JSON exceeds its bounded size") + try: + return json.loads(content, object_pairs_hook=unique, parse_constant=nonfinite) + except (UnicodeError, json.JSONDecodeError) as exc: + raise Refusal("invalid UTF-8 JSON") from exc + + +def fields(value, keys, label): + if not isinstance(value, dict) or set(value) != set(keys): + raise Refusal(f"{label} has invalid fields") + + +def identity(value): + if not isinstance(value, str) or not IDENTITY.fullmatch(value): + raise Refusal("identity must be an exact bounded safe string") + return value + + +def revision(value): + if type(value) is not int or not 1 <= value <= 2147483647: + raise Refusal("revision must be a positive bounded integer") + return value + + +def finite(value): + if type(value) not in (int, float) or not math.isfinite(value): + raise Refusal("target coordinates must be finite numbers") + return float(value) + + +def validate_zone(zone): + fields(zone, ("x_min", "x_max", "y_min", "y_max"), "target zone") + for value in zone.values(): + finite(value) + if not (-.35 <= zone["x_min"] < zone["x_max"] <= .35 and -.2 <= zone["y_min"] < zone["y_max"] <= .2): + raise Refusal("target zone must be a bounded nonempty tabletop rectangle") + return zone + + +def validate_work_order(order): + fields(order, ("version", "order_id", "project", "part_id", "target_zone"), "work order") + if type(order["version"]) is not int or order["version"] != 1 or order["part_id"] != "block": + raise Refusal("only version 1 block work orders are supported") + fields(order["project"], ("namespace", "project_id"), "project identity") + for value in (order["order_id"], *order["project"].values()): + identity(value) + validate_zone(order["target_zone"]) + return order + + +def validate_order(order): + fields(order, ("version", "order_id", "project", "part_id", "target_zone", "revision", "state"), "application order") + validate_work_order({key: value for key, value in order.items() if key not in {"revision", "state"}}) + revision(order["revision"]) + if order["state"] not in {"open", "cancelled", "fulfilled"}: + raise Refusal("application order state is invalid") + return order + + +def directory(path, create=False): + root = Path(os.path.abspath(os.fspath(path))) + if root == OUTPUT or OUTPUT not in root.parents: + raise Refusal("owned directory must be under physical-workcell/output") + current = OUTPUT + for part in (None, *root.relative_to(OUTPUT).parts): + if part is not None: + current /= part + if create: + try: + current.mkdir(mode=0o700) + except FileExistsError: + pass + info = current.lstat() + if not stat.S_ISDIR(info.st_mode) or info.st_uid != os.getuid() or info.st_mode & 0o077: + raise Refusal("owned directories must be private and free of symlinks") + return root + + +def read_bytes(path, maximum=MAX_BYTES): + try: + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK) + with os.fdopen(fd, "rb") as source: + before = os.fstat(source.fileno()) + if not stat.S_ISREG(before.st_mode) or before.st_size > maximum: + raise Refusal("input must be a bounded regular file") + content = source.read(maximum + 1) + after = os.fstat(source.fileno()) + if len(content) > maximum or (before.st_size, before.st_mtime_ns, before.st_ctime_ns) != ( + after.st_size, after.st_mtime_ns, after.st_ctime_ns): + raise Refusal("input changed while reading") + return content + except OSError as exc: + raise Refusal("input is missing, symlinked or unreadable") from exc + + +def create_file(path, content): + fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_WRONLY | os.O_NOFOLLOW, 0o600) + with os.fdopen(fd, "wb") as sink: + sink.write(content) + sink.flush() + os.fsync(sink.fileno()) + sync_directory(path.parent) + + +def sync_directory(path): + fd = os.open(path, os.O_RDONLY) + try: + os.fsync(fd) + finally: + os.close(fd) + + +def persist(path, value): + import uuid + + staging = path.with_name("." + path.name + "." + uuid.uuid4().hex) + try: + create_file(staging, encoded(value)) + os.replace(staging, path) + sync_directory(path.parent) + finally: + with contextlib.suppress(FileNotFoundError): + staging.unlink() + + +@contextlib.contextmanager +def locked(root): + fd = os.open(root / "app.lock", os.O_RDWR | os.O_CREAT | os.O_NOFOLLOW, 0o600) + try: + if not stat.S_ISREG(os.fstat(fd).st_mode): + raise Refusal("invalid application lock") + try: + fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except BlockingIOError as exc: + raise Refusal("another process owns this application directory") from exc + yield + finally: + os.close(fd) + + +def paths_for(app_dir, lease_id): + if not isinstance(lease_id, str) or not UUID.fullmatch(lease_id): + raise Refusal("lease identity must be an exact UUID") + workspace = app_dir / "workcells" / lease_id + return {"app_dir": str(app_dir), "workspace_dir": str(workspace), "run_dir": str(workspace / "r"), + "controller_dir": str(workspace / "c"), "handoff_dir": str(workspace / "h")} diff --git a/tools/physical-workcell/qualify_order_handoff.py b/tools/physical-workcell/qualify_order_handoff.py new file mode 100644 index 0000000..ccb5c4a --- /dev/null +++ b/tools/physical-workcell/qualify_order_handoff.py @@ -0,0 +1,358 @@ +"""Seven independent SIM5 API/adapter/native diagnostics after an explicit source freeze. + +Uses identified backend fixture transport helpers, never calls unit-test methods. +Planning uses public RGB only. SQLite scoring is separately labelled and read-only. +Actual browser read/bind/fulfill is separately driven by the parent. +""" +import argparse +import hashlib +import json +import os +import shutil +import socket +import sqlite3 +import subprocess +import time +import traceback +import urllib.parse +from pathlib import Path + +from test_order_app import BASE, CONTROLLER, OrderApplicationTests, encoded, sha + +HANDOFF = BASE / 'app_handoff.py' +SOURCE_FILES = ('qualify_order_handoff.py', 'test_order_app.py', 'order_app.py', 'order_protocol.py', + 'order_app.html', 'app_handoff.py', 'controller.py', 'episode_runner.py', + 'workcell.py', 'image_guided.py', 'episode_cases.py', 'proposal.schema.json', 'scene.xml') + + +class Fixture(OrderApplicationTests): + def initialize(self, directory, name): + self.setUp() + self.directory.rename(directory) + self.directory = directory + self.app = directory / 'app' + self.order_id = 'qualification-' + name + self.work_order['order_id'] = self.order_id + self.work_order['project'] = {'namespace': 'diagnostic', 'project_id': 'sim5-independent'} + self.work_order['target_zone'] = {'x_min': .12, 'x_max': .20, 'y_min': -.035, 'y_max': .035} + self.seed = {**self.work_order, 'revision': 3, 'state': 'open'} + self.expected_native_pid = None + self.adapter_stopped = False + + def bind(self): + code, reply = self.http('POST', self.order_path('bind'), { + 'expected_revision': 3, 'binding_operation_id': 'bind-' + self.order_id}) + self.assertEqual(code, 200, reply) + self.lease = reply['lease'] + self.assertEqual(self.lease['app_id'], self.app_id) + self.assertEqual(self.lease['work_order'], self.work_order) + return self.lease + + def handoff(self, command, *args): + return self.command([str(BASE / '.venv/bin/python'), HANDOFF, command, + '--handoff-dir', self.lease['handoff_dir'], *args]) + + def prepare(self, *, placed=False, pace=0): + scene = {'block_xy': [.163, .004] if placed else [-.117, .004], + 'illumination_scale': 1, 'occlusion_fraction': 0, 'camera_offset_x_m': 0} + path = self.retain(self.directory / 'scene.json', scene) + prepared = self.command([str(BASE / '.venv/bin/python'), HANDOFF, 'prepare', '--app-url', self.origin, + '--expected-app-id', self.app_id, '--lease-id', self.lease['lease_id'], '--scene-file', path, + '--scene-sha256', sha(path.read_bytes()), '--pace-s', pace]) + self.assertEqual(prepared['phase'], 'prepared', prepared) + self.assertEqual(prepared['ownership'], 'owned') + self.control = Path(self.lease['controller_dir']) + self.incarnation = prepared['controller']['current_incarnation'] + self.expected_native_pid = prepared['controller']['pid'] + return prepared + + def observe(self): + reply = self.handoff('observe') + self.assertEqual(reply['phase'], 'ready', reply) + packet = reply['observation'] + self.event({'kind': 'public_rgb_planning_basis', 'generation': packet['generation'], + 'image_sha256': packet['image_sha256'], 'image_path': packet['image_path'], + 'state_sha256': packet['state_sha256'], 'task_intent': packet['task_intent']}) + return packet + + def submit(self, ident, proposal): + reply = self.handoff('submit', '--operation-id', ident, '--proposal-file', proposal[0], + '--proposal-sha256', proposal[1]) + self.assertIn(reply['phase'], {'accepted', 'running', 'executed', 'staged'}, reply) + return reply + + def stop_adapter(self): + stopped = self.handoff('stop') + self.assertTrue(stopped['process_termination_observed'], stopped) + self.adapter_stopped = True + return stopped + + def scoring(self): + # Scorer role begins here. No native poses or private controller journals are read. + order, count = self.db_rows() + database = self.app / 'orders.sqlite3' + with sqlite3.connect('file:' + str(database) + '?mode=ro', uri=True) as connection: + binding = json.loads(connection.execute("SELECT value FROM meta WHERE key='binding'").fetchone()[0]) + receipts = [dict(zip(('operation_id', 'order_id', 'lease_id', 'receipt_json'), row, strict=True)) + for row in connection.execute("SELECT operation_id,order_id,lease_id,receipt_json FROM operations WHERE kind='fulfill'")] + self.assertEqual(binding['app_id'], self.app_id) + self.assertEqual(binding['app_dir'], str(self.app)) + self.assertEqual(binding['database_identity'], [database.stat().st_dev, database.stat().st_ino]) + score = {'role': 'read_only_sqlite_scorer', 'order_row': order, 'fulfillment_count': count, + 'app_id': binding['app_id'], 'store_id': binding['store_id'], + 'database_identity': binding['database_identity'], 'source_fingerprints': binding['source_fingerprints'], + 'fulfillment_receipts': receipts} + self.event({'kind': 'separate_persisted_application_score', **score}) + return score + + def cleanup(self): + errors = [] + if self.expected_native_pid is not None and not self.adapter_stopped: + try: + self.stop_adapter() + except (AssertionError, KeyError, OSError, ValueError, subprocess.TimeoutExpired) as exc: + errors.append(str(exc)) + self.event({'kind': 'adapter_cleanup_unconfirmed', 'expected_owned_pid': self.expected_native_pid, + 'reason': str(exc), 'unconfirmed_process_not_blindly_signalled': True}) + for process in reversed(self.processes): + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=8) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=4) + for handle in self.handles: + handle.close() + self.event({'kind': 'owned_process_cleanup', + 'processes': [{'pid': p.pid, 'exit_code': p.poll()} for p in self.processes], + 'all_parent_handles_exited': all(p.poll() is not None for p in self.processes), + 'adapter_stop_observed': self.adapter_stopped, + 'socket_exists': bool(self.control and (BASE / 'output/.s' / + (sha(str(self.control).encode())[:20] + '.sock')).exists())}) + if errors: + raise RuntimeError('adapter cleanup unconfirmed: ' + '; '.join(errors)) + + +def normal(f): + f.start() + f.bind() + f.prepare() + staged, contacts = f.stage() + f.assertGreater(contacts, 0) + code, fulfilled = f.fulfill() + f.assertEqual(code, 200, fulfilled) + reconciled = f.handoff('reconcile') + f.assertEqual(reconciled['phase'], 'fulfilled', reconciled) + f.assertEqual(reconciled['receipt'], fulfilled['receipt']) + score = f.scoring() + f.assertEqual((score['order_row'][1], score['order_row'][2], score['fulfillment_count']), (4, 'fulfilled', 1)) + return {'expected_outcome': 'fulfilled', 'contact_samples': contacts, 'physical_receipt': staged, + 'application_receipt': fulfilled, 'sqlite_score': score, 'browser_scope': 'HTTP-only; parent owns actual browser case'} + + +def changed(f, *, cancelled=False): + f.start() + f.bind() + f.prepare(pace=.003) + packet = f.observe() + ident = 'admitted-before-app-change' + f.submit(ident, f.proposal(packet, ident)) + f.until(ident, {'running'}) + time.sleep(.4) + action = 'cancel' if cancelled else 'edit' + mutation = {'expected_revision': 3} + if not cancelled: + mutation['target_zone'] = {'x_min': .15, 'x_max': .23, 'y_min': -.035, 'y_max': .035} + code, app = f.http('POST', f.order_path(action), mutation) + f.assertEqual(code, 200, app) + guard = f.handoff('guard') + f.assertFalse(guard['guard_current']) + f.assertTrue(guard['physical_effects_may_be_partial']) + f.assertFalse(guard['rollback_claim']) + stopped = f.until(ident) + f.assertEqual(stopped['phase'], 'cancelled', stopped) + f.assertTrue(stopped['stop_evidence']['stop_verified']) + f.assertTrue(stopped['stop_evidence']['state_retained']) + f.assertGreater(stopped['stop_evidence']['native_steps_before_cancel'], 0) + current_packet = f.controller('observe')['observation'] + f.assertEqual(stopped['stop_evidence']['retained_generation'], current_packet['generation']) + f.assertEqual(stopped['stop_evidence']['retained_state_sha256'], current_packet['state_sha256']) + f.event({'kind': 'read_only_cancel_stop_scoring', 'generation': current_packet['generation'], + 'state_sha256': current_packet['state_sha256'], 'after_application_guard': 'withheld'}) + blocked = f.handoff('submit', '--operation-id', 'after-change', '--proposal-file', + f.proposal(packet, 'after-change')[0], '--proposal-sha256', + sha((f.directory / 'proposal-after-change.json').read_bytes())) + f.assertTrue(blocked['new_submissions_withheld'], blocked) + f.assertNotEqual(f.fulfill()[0], 200) + score = f.scoring() + f.assertEqual((score['order_row'][1], score['order_row'][2], score['fulfillment_count']), + (4, 'cancelled' if cancelled else 'open', 0)) + return {'expected_outcome': 'stale_fulfillment_refused', 'app_mutation': app, + 'guard': guard, 'retained_cancelled_receipt': stopped, 'sqlite_score': score} + + +def lost_reply(f): + f.start() + f.bind() + f.prepare(placed=True) + f.stage() + content = encoded({'lease_id': f.lease['lease_id'], 'completion_operation_id': f.lease['completion_operation_id']}) + port = urllib.parse.urlsplit(f.origin).port + request = (f'POST {f.order_path("fulfill")} HTTP/1.1\r\nHost: 127.0.0.1:{port}\r\nOrigin: {f.origin}\r\n' + f'X-Footwork-App-ID: {f.app_id}\r\nContent-Type: application/json\r\nContent-Length: {len(content)}\r\n' + 'Connection: close\r\n\r\n').encode() + content + with socket.create_connection(('127.0.0.1', port), timeout=5) as caller: + caller.sendall(request) + f.event({'kind': 'actual_http_socket_closed_before_reply', 'reply_consumed': False, + 'app_id': f.app_id, 'completion_operation_id': f.lease['completion_operation_id']}) + deadline = time.monotonic() + 6 + while time.monotonic() < deadline: + code, saved = f.http('GET', '/api/operations/' + f.lease['completion_operation_id']) + if code == 200: + break + time.sleep(.05) + f.assertEqual(code, 200, saved) + f.stop_adapter() + code, repeated = f.fulfill() + f.assertEqual(code, 200, repeated) + f.assertEqual(saved['receipt'], repeated['receipt']) + f.assertEqual(f.handoff('reconcile')['receipt'], saved['receipt']) + conflicting_code, conflicting = f.fulfill(lease_id='0' * 32) + f.assertNotEqual(conflicting_code, 200, conflicting) + score = f.scoring() + f.assertEqual((score['order_row'][1], score['fulfillment_count']), (4, 1)) + return {'expected_outcome': 'one_effect_historical_reconciliation', 'readback': saved, + 'repeat_after_controller_stop': repeated, 'sqlite_score': score} + + +def identities(f): + f.start() + f.bind() + f.assertNotEqual(f.fulfill()[0], 200) # No physical controller/evidence exists. + f.prepare(placed=True) + f.stage() + original = f.app, f.origin, f.app_id, f.lease + f.app = f.directory / 'foreign-app' + f.initialize_app() + f.serve_app() + foreign = f.bind() + foreign_app_id = f.app_id + f.app, f.origin, f.app_id, f.lease = original + f.assertNotEqual(f.fulfill(lease_id=foreign['lease_id'])[0], 200) + for fields in ({'success': True}, {'receipt_path': '/tmp/unassigned-receipt'}, + {'completion_operation_id': f.lease['binding_operation_id']}, + {'completion_operation_id': 'wrong-assigned-operation'}): + f.assertNotEqual(f.fulfill(**fields)[0], 200) + for identity in ('', foreign_app_id): + code, _ = f.http('POST', f.order_path('fulfill'), { + 'lease_id': f.lease['lease_id'], 'completion_operation_id': f.lease['completion_operation_id']}, + extra_headers={'X-Footwork-App-ID': identity}) + f.assertNotEqual(code, 200) + wrong_order, _ = f.http('POST', f.order_path().replace(f.order_id, f.order_id + '-other') + '/fulfill', { + 'lease_id': f.lease['lease_id'], 'completion_operation_id': f.lease['completion_operation_id']}) + f.assertNotEqual(wrong_order, 200) + score = f.scoring() + f.assertEqual((score['order_row'][1], score['order_row'][2], score['fulfillment_count']), (3, 'open', 0)) + return {'expected_outcome': 'wrong_identity_flags_paths_and_unsupported_evidence_refused', 'sqlite_score': score} + + +def restart(f): + app_process, initial_app = f.start() + f.bind() + prepared = f.prepare() + staged, _ = f.stage() + before = f.observe() + f.stop_adapter() + app_process.terminate() + app_process.wait(timeout=8) + _, current_app = f.serve_app(restart=True) + f.assertEqual(initial_app['app_id'], current_app['app_id']) + f.native = f.spawn([str(BASE / '.venv/bin/python'), CONTROLLER, 'serve', '--run-dir', f.lease['run_dir'], + '--controller-dir', f.control], 'independent-controller-restart') + current = f.native_ready() + f.assertNotEqual(current['current_incarnation'], prepared['controller']['current_incarnation']) + retained = f.controller('status', '--operation-id', f.lease['physical_completion_id']) + f.assertEqual(retained['receipt'], staged['receipt']) + after = f.controller('observe')['observation'] + f.assertEqual((before['generation'], before['state_sha256']), (after['generation'], after['state_sha256'])) + code, fulfilled = f.fulfill() + f.assertEqual(code, 200, fulfilled) + score = f.scoring() + f.assertEqual((score['order_row'][1], score['fulfillment_count']), (4, 1)) + return {'expected_outcome': 'same_identity_history_no_redispatch', 'before_packet': before, + 'after_packet': after, 'retained_physical': retained, 'app_receipt': fulfilled, 'sqlite_score': score} + + +def artifact(f): + f.start() + f.bind() + f.prepare(placed=True) + staged, _ = f.stage() + current_file = Path(f.lease['run_dir']) / 'order.json' + preserved = f.directory / 'original-physical-order.json' + shutil.copyfile(current_file, preserved) + preserved.chmod(0o600) + with current_file.open('ab') as sink: + sink.write(b' ') + f.event({'kind': 'controlled_current_artifact_byte_fault', 'path': str(current_file), + 'preserved_original': str(preserved), 'native_state_not_modified': True}) + current = f.controller('status', '--operation-id', f.lease['physical_completion_id']) + f.assertEqual(current['phase'], 'staged') + f.assertEqual(current['receipt'], staged['receipt']) + f.assertEqual(current['current_health'], 'blocked') + f.assertNotEqual(f.fulfill()[0], 200) + score = f.scoring() + f.assertEqual((score['order_row'][1], score['order_row'][2], score['fulfillment_count']), (3, 'open', 0)) + return {'expected_outcome': 'historical_stage_current_artifact_refuses_new_fulfillment', + 'current_physical_status': current, 'sqlite_score': score} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--output-dir', required=True) + parser.add_argument('--source-commit', required=True) + args = parser.parse_args() + output = Path(os.path.abspath(args.output_dir)) + if BASE / 'output' not in output.parents or output.exists(): + raise ValueError('qualification needs a new owned output directory; no episode rerun') + commit = subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=BASE).decode().strip() + if commit != args.source_commit: + raise ValueError('requested source freeze differs from current HEAD') + output.mkdir(mode=0o700) + sources = {name: hashlib.sha256((BASE / name).read_bytes()).hexdigest() for name in SOURCE_FILES} + result = {'source_commit': commit, 'source_sha256': sources, 'fixture_source': 'test_order_app.OrderApplicationTests transport helpers', + 'classification': 'independent public API/adapter/native integration diagnostics; no AI benchmark', + 'browser_scope': 'parent separately owns actual browser evidence', 'cases': []} + scenarios = [('01-normal-http-native', normal), ('02-edit-during-motion', changed), + ('03-cancel-during-motion', lambda f: changed(f, cancelled=True)), ('04-lost-app-reply', lost_reply), + ('05-identity-and-authority', identities), ('06-restart-history', restart), ('07-current-artifact', artifact)] + for name, scenario in scenarios: + fixture = Fixture('test_real_contact_fulfillment_commits_exact_version_and_receipt') + case = {'case_id': name, 'passed': False} + try: + fixture.initialize(output / name, name) + case['evidence'] = scenario(fixture) + case['passed'] = True + except Exception as exc: # noqa: BLE001 - retain each failed attempt, no effect retry + case.update(error=str(exc), traceback=traceback.format_exc()) + finally: + try: + fixture.cleanup() + except Exception as exc: # noqa: BLE001 - retain owned-resource cleanup failure + case.update(passed=False, cleanup_error=str(exc)) + case['events'] = fixture.events + fixture.retain(output / name / 'case-result.json', case) + result['cases'].append(case) + result['passed'] = sum(item['passed'] for item in result['cases']) + result['attempted'] = len(result['cases']) + fixture.retain(output / 'qualification.json', result) + print(json.dumps({'case_id': name, 'passed': case['passed'], 'error': case.get('error')}), flush=True) + result['final_source_sha256'] = {name: hashlib.sha256((BASE / name).read_bytes()).hexdigest() for name in SOURCE_FILES} + result['source_unchanged'] = result['final_source_sha256'] == sources + fixture.retain(output / 'qualification.json', result) + return 0 if result['passed'] == 7 and result['source_unchanged'] else 1 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/tools/physical-workcell/test_app_handoff.py b/tools/physical-workcell/test_app_handoff.py new file mode 100644 index 0000000..4ffd1bb --- /dev/null +++ b/tools/physical-workcell/test_app_handoff.py @@ -0,0 +1,436 @@ +"""Actual local app/controller adapter conformance; independent private development inputs.""" + +import copy +import importlib.util +import json +import os +import signal +import socket +import sqlite3 +import subprocess +import time +import unittest +import urllib.error +import urllib.parse +import urllib.request +import uuid +from pathlib import Path + +BASE = Path(__file__).resolve().parent +SPEC = importlib.util.spec_from_file_location("handoff_test", BASE / "app_handoff.py") +handoff = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(handoff) +protocol = handoff.protocol +PYTHON = BASE / ".venv/bin/python" + + +class HandoffTests(unittest.TestCase): + def setUp(self): + self.work = protocol.directory(protocol.OUTPUT / ("h5" + uuid.uuid4().hex[:6]), create=True) + self.app_dir = protocol.directory(self.work / "a", create=True) + self.evidence = [] + self.processes = [] + self.handles = [] + self.owned_controllers = [] + self.order = {"version": 1, "order_id": "handoff-private-order", + "project": {"namespace": "test", "project_id": "handoff-development"}, "part_id": "block", + "target_zone": {"x_min": .18, "x_max": .26, "y_min": -.04, "y_max": .04}, + "revision": 1, "state": "open"} + self.scene = {"block_xy": [-.17, 0], "illumination_scale": 1, + "occlusion_fraction": 0, "camera_offset_x_m": 0} + self.scene_path = self.work / "scene.json" + self.handoff_dir = None + self.counter = 0 + + def tearDown(self): + for controller_dir, pid, incarnation in self.owned_controllers: + reply = self.raw_controller(controller_dir, "health", allow_failure=True) + if reply.get("pid") == pid and reply.get("current_incarnation") == incarnation: + with self.subTest(cleanup_pid=pid): + os.kill(pid, signal.SIGTERM) + for process in self.processes: + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=6) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=4) + for handle in self.handles: + handle.close() + result = self._outcome.result + failed = any(test is self or getattr(test, "test_case", None) is self + for test, _ in (*result.failures, *result.errors)) + protocol.create_file(self.work / "conformance.json", protocol.encoded({ + "test_id": self.id(), "passed": not failed, "events": self.evidence, + "scope": "actual_local_process_adapter; mechanical HTTP use is not browser evidence"})) + + def command(self, script, command, *args, allow_failure=False, timeout=25): + result = subprocess.run([str(PYTHON), str(BASE / script), command, *map(str, args)], + capture_output=True, timeout=timeout, check=False) + try: + value = protocol.decode(result.stdout) + except protocol.Refusal as exc: + self.fail(f"public CLI returned no bounded JSON: {result.stdout!r}; {result.stderr!r}; {exc}") + self.evidence.append({"script": script, "command": command, "exit_code": result.returncode, "reply": value}) + self.no_oracle(value) + if not allow_failure: + self.assertEqual(result.returncode, 0, value) + return value + + def no_oracle(self, value): + serialized = json.dumps(value) + for forbidden in ("block_xyz", "pusher_xyz", "physical_condition_verified", "block_center_in_zone", "qpos", "xpos"): + self.assertNotIn(forbidden, serialized) + + def start_app(self, *, restart=False): + if not restart: + source = self.work / "order.json" + content = protocol.encoded(self.order) + protocol.create_file(source, content) + initialized = self.command("order_app.py", "init", "--app-dir", self.app_dir, + "--order-file", source, "--order-sha256", protocol.sha(content)) + self.app_id = initialized["app_id"] + port = 0 + else: + port = urllib.parse.urlsplit(self.url).port + logfile = open(self.work / f"app-{len(self.processes)}.log", "xb") # noqa: SIM115 - owned until tearDown + os.chmod(logfile.name, 0o600) + self.handles.append(logfile) + process = subprocess.Popen([str(PYTHON), str(BASE / "order_app.py"), "serve", "--app-dir", str(self.app_dir), + "--port", str(port)], stdout=logfile, stderr=subprocess.STDOUT) + self.processes.append(process) + deadline = time.monotonic() + 5 + while time.monotonic() < deadline: + if process.poll() is not None: + self.fail(f"app startup failed; private logs: {self.work}") + readiness = self.app_dir / "readiness.json" + if readiness.exists(): + value = protocol.decode(readiness.read_bytes()) + if value.get("phase") == "ready" and value.get("pid") == process.pid: + self.url = value["origin"] + self.assertEqual(value["app_id"], self.app_id) + return process + time.sleep(.02) + self.fail("app readiness timeout") + + def http(self, route, value=None, *, allow_failure=False): + request = urllib.request.Request(self.url + route, data=None if value is None else protocol.encoded(value), + headers={"Content-Type": "application/json", "Origin": self.url, + "X-Footwork-App-ID": self.app_id}) + opener = urllib.request.build_opener(urllib.request.ProxyHandler({})) + try: + response = opener.open(request, timeout=5) + except urllib.error.HTTPError as exc: + response = exc + with response: + code = response.code + reply = protocol.decode(response.read(protocol.MAX_BYTES + 1)) + self.evidence.append({"http": route, "method": "GET" if value is None else "POST", "code": code, "reply": reply}) + self.no_oracle(reply) + if not allow_failure: + self.assertEqual(code, 200, reply) + return code, reply + + def bind(self): + _, value = self.http(f"/api/orders/{self.order['order_id']}/bind", { + "expected_revision": 1, "binding_operation_id": "private-binding"}) + self.lease = value["lease"] + self.handoff_dir = Path(self.lease["handoff_dir"]) + + def prepare(self, *, pace=0, delay=0): + if not hasattr(self, "lease"): + self.start_app() + self.bind() + if not self.scene_path.exists(): + protocol.create_file(self.scene_path, protocol.encoded(self.scene)) + self.scene_sha = protocol.sha(self.scene_path.read_bytes()) + value = self.command("app_handoff.py", "prepare", "--app-url", self.url, "--expected-app-id", self.app_id, + "--lease-id", self.lease["lease_id"], "--scene-file", self.scene_path, + "--scene-sha256", self.scene_sha, "--pace-s", pace, "--dispatch-delay-s", delay) + self.assertEqual(value["phase"], "prepared", value) + controller = value["controller"] + ownership = (self.lease["controller_dir"], controller["pid"], controller["current_incarnation"]) + if ownership not in self.owned_controllers: + self.owned_controllers.append(ownership) + return value + + def adapter(self, command, *args, allow_failure=False): + return self.command("app_handoff.py", command, "--handoff-dir", self.handoff_dir, + *args, allow_failure=allow_failure) + + def raw_controller(self, control, command, *args, allow_failure=False): + return self.command("controller.py", command, "--controller-dir", control, *args, allow_failure=allow_failure) + + def packet(self): + value = self.adapter("observe") + self.assertEqual(value["phase"], "ready", value) + return value["observation"] + + def proposal(self, packet, token, *, complete=False, noncanonical=False): + value = {"version": 1, "run_dir": self.lease["run_dir"], "generation": packet["generation"], + "image_sha256": packet["image_sha256"], "token": token, + "block_box": packet["perception"]["block_box"], "decision": "complete" if complete else "move"} + if not complete: + value["target"] = {"x": min(.17, packet["perception"]["pusher_center_xy"][0] + .10), "y": 0} + content = json.dumps(value, indent=4).encode() if noncanonical else protocol.encoded(value) + path = self.work / f"proposal-{token}.json" + protocol.create_file(path, content) + return path, protocol.sha(content) + + def submit(self, operation_id, proposal, *, allow_failure=False): + return self.adapter("submit", "--operation-id", operation_id, "--proposal-file", proposal[0], + "--proposal-sha256", proposal[1], allow_failure=allow_failure) + + def until(self, operation_id, phases=("executed", "staged", "cancelled", "refused", "unknown")): + deadline = time.monotonic() + 12 + while time.monotonic() < deadline: + value = self.adapter("status", "--operation-id", operation_id, allow_failure=True) + if value.get("phase") in phases: + return value + time.sleep(.02) + self.fail("controller phase timeout") + + def states(self): + return {path.name: path.read_bytes() for path in Path(self.lease["run_dir"]).glob("state-*.json")} + + def test_prepare_submit_fresh_caller_repeat_and_exact_raw_proposal_digest(self): + prepared = self.prepare() + packet = self.packet() + proposal = self.proposal(packet, "first-move", noncanonical=True) + self.submit("first-move", proposal) + final = self.until("first-move") + self.assertEqual(final["phase"], "executed", final) + before = self.states() + repeated = self.prepare() + self.assertEqual(repeated["controller"]["pid"], prepared["controller"]["pid"]) + self.assertEqual(repeated["controller"]["current_incarnation"], prepared["controller"]["current_incarnation"]) + self.assertEqual(self.submit("first-move", proposal)["phase"], "executed") + self.assertEqual(self.states(), before) + changed = self.proposal(self.packet(), "conflict") + self.assertEqual(self.submit("first-move", changed, allow_failure=True)["phase"], "refused") + self.assertEqual(self.states(), before) + + def changed_during_motion(self, action): + self.prepare(pace=.003) + self.submit("contact", self.proposal(self.packet(), "contact")) + first = self.until("contact") + self.assertEqual(first["phase"], "executed") + self.assertGreater(first["receipt"]["contact_statistics"]["pusher_block_contact_samples"], 0) + packet = self.packet() + self.submit("active", self.proposal(packet, "active")) + self.until("active", phases=("running",)) + time.sleep(.18) + mutation = {"expected_revision": 1} + if action == "edit": + mutation["target_zone"] = {"x_min": .16, "x_max": .24, "y_min": -.04, "y_max": .04} + self.http(f"/api/orders/{self.order['order_id']}/{action}", mutation) + guarded = self.adapter("guard", allow_failure=True) + self.assertFalse(guarded["guard_current"]) + self.assertTrue(guarded["physical_effects_may_be_partial"]) + self.assertFalse(guarded["rollback_claim"]) + terminal = self.until("active") + self.assertEqual(terminal["phase"], "cancelled", terminal) + self.assertGreater(terminal["stop_evidence"]["native_steps_before_cancel"], 0) + self.assertTrue(terminal["stop_evidence"]["stop_verified"]) + before = self.states() + blocked_proposal = self.proposal(packet, "withheld") + self.assertIn(self.submit("withheld", blocked_proposal, allow_failure=True)["phase"], {"withheld", "unknown"}) + self.assertEqual(self.states(), before) + record = handoff.load(self.handoff_dir) + self.assertNotIn("withheld", record["operations"]) + _, order = self.http(f"/api/orders/{self.order['order_id']}") + self.assertEqual(order["order"]["revision"], 2) + self.assertEqual(order["order"]["state"], "cancelled" if action == "cancel" else "open") + self.assertEqual(self.adapter("reconcile", allow_failure=True)["phase"], "unknown") + + def test_order_edit_during_native_progress_guards_and_cancels(self): + self.changed_during_motion("edit") + + def test_order_cancel_during_native_progress_guards_and_cancels(self): + self.changed_during_motion("cancel") + + def test_exact_committed_app_effect_reconciles_after_lost_reply(self): + self.scene["block_xy"] = [.195, .006] + self.prepare() + completion_id = self.lease["physical_completion_id"] + wrong = self.proposal(self.packet(), "wrong-stage", complete=True) + self.assertEqual(self.submit("wrong-stage", wrong, allow_failure=True)["phase"], "refused") + self.submit(completion_id, self.proposal(self.packet(), completion_id, complete=True)) + self.assertEqual(self.until(completion_id)["phase"], "staged") + content = protocol.encoded({"lease_id": self.lease["lease_id"], + "completion_operation_id": self.lease["completion_operation_id"]}) + parsed = urllib.parse.urlsplit(self.url) + header = (f"POST /api/orders/{self.order['order_id']}/fulfill HTTP/1.1\r\nHost: {parsed.netloc}\r\n" + f"Origin: {self.url}\r\nX-Footwork-App-ID: {self.app_id}\r\nContent-Type: application/json\r\n" + f"Content-Length: {len(content)}\r\n\r\n").encode() + with socket.create_connection(("127.0.0.1", parsed.port), timeout=3) as client: + client.sendall(header + content) + self.evidence.append({"scenario": "actual_fulfillment_client_closed_before_reply", "blind_resubmissions": 0}) + deadline = time.monotonic() + 8 + while time.monotonic() < deadline: + reconciled = self.adapter("reconcile", allow_failure=True) + if reconciled["phase"] == "fulfilled": + break + time.sleep(.02) + self.assertEqual(reconciled["phase"], "fulfilled", reconciled) + self.assertEqual(reconciled["receipt"]["completion_operation_id"], self.lease["completion_operation_id"]) + self.assertEqual(reconciled["receipt"]["lease_id"], self.lease["lease_id"]) + before = self.states() + self.assertEqual(self.adapter("reconcile")["receipt"], reconciled["receipt"]) + self.assertEqual(self.states(), before) + self.assertFalse(self.adapter("guard", allow_failure=True)["guard_current"]) + + def test_app_restart_same_origin_reconnects_without_native_replay(self): + prepared = self.prepare() + self.submit("restart-history", self.proposal(self.packet(), "restart-history")) + self.assertEqual(self.until("restart-history")["phase"], "executed") + before = self.states() + self.processes[0].terminate() + self.processes[0].wait(timeout=5) + self.start_app(restart=True) + repeated = self.prepare() + self.assertEqual(repeated["controller"]["pid"], prepared["controller"]["pid"]) + self.assertEqual(self.adapter("status", "--operation-id", "restart-history")["historical_outcome"], "executed") + self.assertEqual(self.states(), before) + + def test_malformed_retained_receipt_actual_api_readback_never_claims_effect(self): + self.scene["block_xy"] = [.195, .006] + self.prepare() + physical_id = self.lease["physical_completion_id"] + self.submit(physical_id, self.proposal(self.packet(), physical_id, complete=True)) + self.assertEqual(self.until(physical_id)["phase"], "staged") + self.http(f"/api/orders/{self.order['order_id']}/fulfill", { + "lease_id": self.lease["lease_id"], "completion_operation_id": self.lease["completion_operation_id"]}) + self.assertEqual(self.adapter("reconcile")["phase"], "fulfilled") + database = self.app_dir / "orders.sqlite3" + with sqlite3.connect(database) as connection: + original_receipt = connection.execute("SELECT receipt_json FROM operations WHERE operation_id=?", ( + self.lease["completion_operation_id"],)).fetchone()[0] + original_order = connection.execute("SELECT revision,state,work_order_json FROM orders WHERE order_id=?", ( + self.order["order_id"],)).fetchone() + protocol.create_file(self.work / "original-application-receipt.json", original_receipt.encode()) + before = self.states() + variants = (("receipt_state", {"state": "open"}, {}), + ("boolean_leased_revision", {"leased_revision": True}, {}), + ("fulfilled_revision", {"fulfilled_revision": 4}, {}), + ("terminal_current_state", {}, {"state": "cancelled"}), + ("current_revision_before_receipt", {}, {"revision": 1}), + ("current_order_identity", {}, {"order_id": "another-order"})) + for name, receipt_changes, order_changes in variants: + with self.subTest(fault=name): + receipt = protocol.decode(original_receipt.encode()) + receipt.update(receipt_changes) + order_json = protocol.decode(original_order[2].encode()) + if "order_id" in order_changes: + order_json["order_id"] = order_changes["order_id"] + with sqlite3.connect(database) as connection: + connection.execute("UPDATE operations SET receipt_json=? WHERE operation_id=?", ( + protocol.encoded(receipt).decode(), self.lease["completion_operation_id"])) + connection.execute("UPDATE orders SET revision=?,state=?,work_order_json=? WHERE order_id=?", ( + order_changes.get("revision", original_order[0]), order_changes.get("state", original_order[1]), + protocol.encoded(order_json).decode(), self.order["order_id"])) + self.evidence.append({"scenario": "labeled_retained_store_readback_fault", "fault": name, + "source_store_identity_and_native_history_unchanged": True}) + result = self.adapter("reconcile", allow_failure=True) + self.assertEqual(result["phase"], "refused", result) + self.assertFalse(result.get("application_effect_confirmed", False)) + self.assertEqual(self.states(), before) + with sqlite3.connect(database) as connection: + connection.execute("UPDATE operations SET receipt_json=? WHERE operation_id=?", ( + original_receipt, self.lease["completion_operation_id"])) + connection.execute("UPDATE orders SET revision=?,state=?,work_order_json=? WHERE order_id=?", ( + *original_order, self.order["order_id"])) + self.assertEqual(self.adapter("reconcile")["phase"], "fulfilled") + + def test_external_controller_restart_allows_history_but_no_ownership_takeover(self): + self.prepare() + self.submit("external-history", self.proposal(self.packet(), "external-history")) + self.assertEqual(self.until("external-history")["phase"], "executed") + stopped = self.adapter("stop") + self.assertTrue(stopped["process_termination_observed"]) + logfile = open(self.work / "external-controller.log", "xb") # noqa: SIM115 - owned until tearDown + os.chmod(logfile.name, 0o600) + self.handles.append(logfile) + process = subprocess.Popen([str(PYTHON), str(BASE / "controller.py"), "serve", "--run-dir", self.lease["run_dir"], + "--controller-dir", self.lease["controller_dir"]], stdout=logfile, stderr=subprocess.STDOUT) + self.processes.append(process) + deadline = time.monotonic() + 5 + while time.monotonic() < deadline: + health = self.raw_controller(self.lease["controller_dir"], "health", allow_failure=True) + if health.get("pid") == process.pid: + break + time.sleep(.02) + before = self.states() + self.assertEqual(self.adapter("status", "--operation-id", "external-history")["historical_outcome"], "executed") + proposal = self.proposal(self.packet(), "unowned-submit") + self.assertEqual(self.submit("unowned-submit", proposal, allow_failure=True)["phase"], "refused") + self.assertEqual(self.adapter("stop", allow_failure=True)["phase"], "refused") + self.assertIsNone(process.poll()) + self.assertEqual(self.states(), before) + + def test_wrong_app_lease_scene_digest_and_retained_paths_refuse(self): + self.start_app() + self.bind() + protocol.create_file(self.scene_path, protocol.encoded(self.scene)) + digest = protocol.sha(self.scene_path.read_bytes()) + for app_id, lease_id, scene_sha in (("wrong-app", self.lease["lease_id"], digest), + (self.app_id, "0" * 32, digest), + (self.app_id, self.lease["lease_id"], "0" * 64)): + with self.subTest(app_id=app_id, lease_id=lease_id): + result = self.command("app_handoff.py", "prepare", "--app-url", self.url, "--expected-app-id", app_id, + "--lease-id", lease_id, "--scene-file", self.scene_path, "--scene-sha256", scene_sha, + allow_failure=True) + self.assertEqual(result["phase"], "refused") + self.assertFalse((self.handoff_dir / "handoff.json").exists()) + health = handoff.api(self.url, self.app_id, "/api/health") + changed = copy.deepcopy(self.lease) + changed["run_dir"] = str(self.work / "arbitrary-proof") + with self.assertRaises(protocol.Refusal): + handoff.lease_schema(changed, health, self.url, self.app_id, self.lease["lease_id"]) + + def test_scene_change_repeat_never_reinitializes_or_replaces_controller(self): + self.prepare() + before = self.states() + original = self.scene_path.read_bytes() + self.scene_path.write_bytes(original + b" ") + result = self.command("app_handoff.py", "prepare", "--app-url", self.url, "--expected-app-id", self.app_id, + "--lease-id", self.lease["lease_id"], "--scene-file", self.scene_path, + "--scene-sha256", protocol.sha(self.scene_path.read_bytes()), allow_failure=True) + self.assertEqual(result["phase"], "refused") + self.assertEqual(self.states(), before) + self.scene_path.write_bytes(original) + + def test_missing_app_readback_stays_unknown_and_guard_withholds(self): + self.prepare() + self.assertEqual(self.adapter("reconcile", allow_failure=True)["phase"], "unknown") + proposal = self.proposal(self.packet(), "app-down") + before = self.states() + self.processes[0].terminate() + self.processes[0].wait(timeout=5) + guarded = self.adapter("guard", allow_failure=True) + self.assertFalse(guarded["guard_current"]) + self.assertEqual(guarded["phase"], "unknown") + self.assertEqual(self.submit("app-down", proposal, allow_failure=True)["phase"], "unknown") + self.assertEqual(self.states(), before) + self.assertNotIn("app-down", handoff.load(self.handoff_dir)["operations"]) + + def test_loopback_origin_strict_and_scene_symlink_refusal(self): + for url in ("https://127.0.0.1:1234", "http://localhost:1234", "http://127.0.0.1:1234/", + "http://user:secret@127.0.0.1:1234", "http://127.0.0.1:1234?other=1"): + with self.subTest(url=url), self.assertRaises(protocol.Refusal): + handoff.origin(url) + self.start_app() + self.bind() + protocol.create_file(self.scene_path, protocol.encoded(self.scene)) + linked = self.work / "linked-scene.json" + linked.symlink_to(self.scene_path) + result = self.command("app_handoff.py", "prepare", "--app-url", self.url, "--expected-app-id", self.app_id, + "--lease-id", self.lease["lease_id"], "--scene-file", linked, + "--scene-sha256", protocol.sha(self.scene_path.read_bytes()), allow_failure=True) + self.assertEqual(result["phase"], "refused") + self.assertFalse((self.handoff_dir / "handoff.json").exists()) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/physical-workcell/test_order_app.py b/tools/physical-workcell/test_order_app.py new file mode 100644 index 0000000..2d0f520 --- /dev/null +++ b/tools/physical-workcell/test_order_app.py @@ -0,0 +1,654 @@ +"""SIM5 actual HTTP/SQLite/native-controller backend conformance. + +Private application cases and owned processes are retained under output. +Public controller RGB supplies targets; server verifies real staged evidence. +""" +import hashlib +import json +import socket +import sqlite3 +import subprocess +import sys +import threading +import time +import unittest +import urllib.error +import urllib.parse +import urllib.request +import uuid +from http.client import HTTPConnection +from pathlib import Path + +BASE = Path(__file__).resolve().parent +APP = BASE / 'order_app.py' +CONTROLLER = BASE / 'controller.py' +TERMINAL = {'executed', 'staged', 'cancelled', 'refused', 'unknown'} + + +def encoded(value): + return (json.dumps(value, indent=2, sort_keys=True, allow_nan=False) + '\n').encode() + + +def sha(content): + return hashlib.sha256(content).hexdigest() + + +class OrderApplicationTests(unittest.TestCase): + def setUp(self): + self.directory = BASE / 'output' / ('a5' + uuid.uuid4().hex[:7]) + self.directory.mkdir(mode=0o700) + self.app = self.directory / 'app' + self.processes = [] + self.handles = [] + self.events = [] + self.origin = None + self.app_id = None + self.order_id = 'order-' + uuid.uuid4().hex[:8] + self.work_order = {'version': 1, 'order_id': self.order_id, + 'project': {'namespace': 'test', 'project_id': 'application-conformance'}, + 'part_id': 'block', 'target_zone': {'x_min': .14, 'x_max': .22, 'y_min': -.04, 'y_max': .04}} + self.seed = {**self.work_order, 'revision': 1, 'state': 'open'} + self.native = None + self.control = None + self.incarnation = None + self.lease = None + + def tearDown(self): + cleanup = [] + for process in reversed(self.processes): + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=8) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=4) + cleanup.append({'pid': process.pid, 'exit_code': process.poll()}) + for handle in self.handles: + handle.close() + failed = any(test is self or getattr(test, 'test_case', None) is self + for test, _ in (*self._outcome.result.failures, *self._outcome.result.errors)) + self.retain(self.directory / 'conformance.json', {'test_id': self.id(), 'passed': not failed, + 'events': self.events, 'owned_process_cleanup': cleanup, + 'classification': 'actual HTTP/SQLite/native controller diagnostic, not browser or AI benchmark'}) + + def retain(self, path, value): + path.write_bytes(encoded(value)) + path.chmod(0o600) + return path + + def event(self, value): + self.events.append({'time_unix': time.time(), **value}) + + def command(self, argv): + argv = list(map(str, argv)) + result = subprocess.run(argv, capture_output=True, text=True, timeout=12, check=False) + try: + body = json.loads(result.stdout) + except ValueError: + self.fail(f'non-JSON CLI reply {result.stdout!r} stderr={result.stderr!r}; retained {self.directory}') + self.event({'kind': 'public_cli', 'command': argv, 'exit_code': result.returncode, + 'reply': body, 'stderr': result.stderr}) + return body + + def spawn(self, argv, name): + path = self.directory / (name + '.log') + handle = path.open('xb') + path.chmod(0o600) + self.handles.append(handle) + argv = list(map(str, argv)) + process = subprocess.Popen(argv, stdout=handle, stderr=subprocess.STDOUT) + self.processes.append(process) + self.event({'kind': 'owned_process', 'command': argv, 'pid': process.pid, 'log': str(path)}) + return process + + def initialize_app(self): + path = self.retain(self.directory / 'seed.json', self.seed) + result = self.command([sys.executable, APP, 'init', '--app-dir', self.app, + '--order-file', path, '--order-sha256', sha(path.read_bytes())]) + self.assertNotEqual(result.get('phase'), 'refused', result) + + def serve_app(self, *, restart=False, fault_script=None): + port = urllib.parse.urlsplit(self.origin).port if restart else 0 + process = self.spawn([sys.executable, fault_script or APP, 'serve', '--app-dir', self.app, + '--port', port], 'app-' + str(len(self.processes))) + deadline = time.monotonic() + 8 + while time.monotonic() < deadline: + if process.poll() is not None: + self.fail(f'app startup failed {process.returncode}; retained {self.directory}') + readiness = self.app / 'readiness.json' + if readiness.exists(): + info = json.loads(readiness.read_bytes()) + if info.get('pid') == process.pid: + self.origin = info['origin'] + code, health = self.http('GET', '/api/health') + if code == 200: + self.app_id = health['app_id'] + return process, health + time.sleep(.04) + self.fail(f'app readiness timed out; retained {self.directory}') + + def http(self, method, path, body=None, *, origin=True, extra_headers=None): + headers = {'Accept': 'application/json'} + content = None if body is None else encoded(body) + if content is not None: + headers['Content-Type'] = 'application/json' + if method == 'POST': + headers['X-Footwork-App-ID'] = self.app_id + if origin: + headers['Origin'] = self.origin + headers.update(extra_headers or {}) + request = urllib.request.Request(self.origin + path, data=content, headers=headers, method=method) + try: + response = urllib.request.urlopen(request, timeout=10) + except urllib.error.HTTPError as exc: + response = exc + with response: + status = response.status + value = json.loads(response.read()) + self.event({'kind': 'http', 'method': method, 'path': path, 'request': body, + 'headers': headers, 'status': status, 'reply': value}) + return status, value + + def order_path(self, action=''): + return '/api/orders/' + self.order_id + (('/' + action) if action else '') + + def start(self): + self.initialize_app() + return self.serve_app() + + def bind(self): + code, reply = self.http('POST', self.order_path('bind'), + {'expected_revision': 1, 'binding_operation_id': 'bind-' + uuid.uuid4().hex}) + self.assertEqual(code, 200, reply) + self.assertEqual(reply['app_id'], self.app_id) + self.lease = reply['lease'] + self.assertEqual(self.lease['work_order'], self.work_order) + self.assertEqual(self.lease['expected_revision'], 1) + return self.lease + + def start_native(self, *, pace=0, placed=False, altered_order=None): + lease = self.lease + self.control = Path(lease['controller_dir']) + case = {'version': 1, 'case_id': lease['lease_id'], 'max_actions': 8, + 'scene': {'block_xy': [.175, .004] if placed else [-.138, .004], + 'illumination_scale': 1, 'occlusion_fraction': 0, 'camera_offset_x_m': 0}, + 'work_order': altered_order or lease['work_order']} + path = self.retain(self.directory / ('case-' + lease['lease_id'] + '.json'), case) + result = self.command([sys.executable, BASE / 'episode_runner.py', 'init', '--case-file', path, + '--case-sha256', sha(path.read_bytes()), '--run-dir', lease['run_dir']]) + self.assertEqual(result['phase'], 'active', result) + self.native = self.spawn([sys.executable, CONTROLLER, 'serve', '--run-dir', lease['run_dir'], + '--controller-dir', self.control, '--pace-s', pace], + 'native-' + str(len(self.processes))) + return self.native_ready() + + def native_ready(self): + deadline = time.monotonic() + 8 + while time.monotonic() < deadline: + if self.native.poll() is not None: + self.fail(f'native startup failed; retained {self.directory}') + result = self.controller('health') + if result.get('phase') != 'refused' and result.get('current_incarnation'): + self.incarnation = result['current_incarnation'] + return result + time.sleep(.04) + self.fail('native readiness timed out') + + def controller(self, command, *args): + return self.command([sys.executable, CONTROLLER, command, '--controller-dir', self.control, *args]) + + def observe(self): + result = self.controller('observe') + self.assertEqual(result['phase'], 'ready', result) + return result['observation'] + + def proposal(self, packet, token, *, complete=False, advance=.105): + value = {'version': 1, 'run_dir': self.lease['run_dir'], 'generation': packet['generation'], + 'image_sha256': packet['image_sha256'], 'token': token, + 'block_box': packet['perception']['block_box'], 'decision': 'complete' if complete else 'move'} + if not complete: + value['target'] = {'x': packet['perception']['pusher_center_xy'][0] + advance, 'y': .004} + path = self.retain(self.directory / ('proposal-' + token + '.json'), value) + return path, sha(path.read_bytes()) + + def submit(self, ident, proposal): + result = self.controller('submit', '--operation-id', ident, '--proposal-file', proposal[0], + '--proposal-sha256', proposal[1], '--expected-incarnation', self.incarnation) + self.assertIn(result['phase'], {'accepted', 'running', 'executed', 'staged'}, result) + return result + + def until(self, ident, phases=TERMINAL): + deadline = time.monotonic() + 10 + while time.monotonic() < deadline: + result = self.controller('status', '--operation-id', ident) + if result.get('phase') in phases: + return result + time.sleep(.05) + self.fail(f'controller status timed out for {ident}') + + def stage(self): + contacts = 0 + for index in range(7): + packet = self.observe() + zone = packet['task_intent']['target_zone'] + block = packet['perception']['block_center_xy'] + pusher = packet['perception']['pusher_center_xy'] + inside = (zone['x_min'] + .005 <= block[0] <= zone['x_max'] - .005 and + zone['y_min'] + .005 <= block[1] <= zone['y_max'] - .005) + ident = self.lease['physical_completion_id'] if inside else 'move-' + str(index) + gap = max(0, block[0] - pusher[0] - .055) + advance = min(.105, max(.015, gap + (zone['x_min'] + zone['x_max']) / 2 - block[0])) + self.submit(ident, self.proposal(packet, ident, complete=inside, advance=advance)) + final = self.until(ident) + if inside: + self.assertEqual(final['phase'], 'staged', final) + return final, contacts + self.assertEqual(final['phase'], 'executed', final) + contacts += final['receipt']['contact_statistics']['pusher_block_contact_samples'] + self.fail('RGB feedback did not stage with completion slot reserved') + + def fulfill(self, **changes): + value = {'lease_id': self.lease['lease_id'], + 'completion_operation_id': self.lease['completion_operation_id'], **changes} + return self.http('POST', self.order_path('fulfill'), value) + + def db_rows(self): + db = sqlite3.connect('file:' + str(self.app / 'orders.sqlite3') + '?mode=ro', uri=True) + try: + order = db.execute('SELECT order_id,revision,state,work_order_json FROM orders WHERE order_id=?', + (self.order_id,)).fetchone() + count = db.execute("SELECT COUNT(*) FROM operations WHERE kind='fulfill'").fetchone()[0] + finally: + db.close() + self.event({'kind': 'independent_sqlite_readback', 'order_row': order, 'fulfillment_effect_count': count}) + return order, count + + def test_real_contact_fulfillment_commits_exact_version_and_receipt(self): + self.start() + code, order = self.http('GET', self.order_path()) + self.assertEqual(code, 200) + self.assertEqual(order['order']['revision'], 1) + self.bind() + self.start_native() + physical, contacts = self.stage() + self.assertGreater(contacts, 0) + code, receipt = self.fulfill() + self.assertEqual(code, 200, receipt) + saved, count = self.db_rows() + self.assertEqual((saved[1], saved[2], count), (2, 'fulfilled', 1)) + read_code, readback = self.http('GET', '/api/operations/' + self.lease['completion_operation_id']) + self.assertEqual(read_code, 200) + self.assertEqual(readback['receipt'], receipt['receipt']) + self.assertEqual(physical['receipt']['token'], self.lease['physical_completion_id']) + + def test_concurrent_bind_allocates_one_workspace_per_order_revision(self): + self.start() + barrier = threading.Barrier(3) + replies = [] + errors = [] + requests = [{'expected_revision': 1, 'binding_operation_id': 'parallel-' + uuid.uuid4().hex} + for _ in range(2)] + + def bind_in_parallel(payload): + try: + barrier.wait(timeout=5) + code, reply = self.http('POST', self.order_path('bind'), payload) + replies.append((payload, code, reply)) + except (OSError, ValueError, threading.BrokenBarrierError) as exc: + errors.append(str(exc)) + + threads = [threading.Thread(target=bind_in_parallel, args=(payload,)) for payload in requests] + for thread in threads: + thread.start() + barrier.wait(timeout=5) + for thread in threads: + thread.join(timeout=8) + self.assertTrue(all(not thread.is_alive() for thread in threads)) + self.assertFalse(errors, errors) + self.assertEqual(len(replies), 2) + accepted = [reply for reply in replies if reply[1] == 200] + self.assertEqual(len(accepted), 1, replies) + payload, _, winner = accepted[0] + repeated_code, repeated = self.http('POST', self.order_path('bind'), payload) + self.assertEqual(repeated_code, 200, repeated) + self.assertEqual(repeated['lease'], winner['lease']) + self.assertTrue(repeated['historical']) + conflicting_code, _ = self.http('POST', self.order_path('bind'), {**payload, 'expected_revision': 2}) + self.assertNotEqual(conflicting_code, 200) + extra_code, _ = self.http('POST', self.order_path('bind'), { + 'expected_revision': 1, 'binding_operation_id': 'client-path-' + uuid.uuid4().hex, + 'run_dir': str(self.directory / 'client-picked-workspace')}) + self.assertNotEqual(extra_code, 200) + db = sqlite3.connect('file:' + str(self.app / 'orders.sqlite3') + '?mode=ro', uri=True) + try: + count = db.execute('SELECT COUNT(*) FROM leases WHERE order_id=? AND revision=1', + (self.order_id,)).fetchone()[0] + bind_count = db.execute("SELECT COUNT(*) FROM operations WHERE kind='bind'").fetchone()[0] + finally: + db.close() + self.assertEqual((count, bind_count), (1, 1)) + self.event({'kind': 'independent_sqlite_lease_allocation_readback', + 'lease_count_at_revision': count, 'binding_effect_count': bind_count, + 'server_assigned_workspace': winner['lease']['workspace_dir']}) + + def test_edit_during_actual_motion_refuses_stale_fulfillment(self): + self.changed_during_motion(cancelled=False) + + def test_cancel_during_actual_motion_keeps_cancelled_app_truth(self): + self.changed_during_motion(cancelled=True) + + def changed_during_motion(self, *, cancelled): + self.start() + self.bind() + self.start_native(pace=.003) + ident = 'active-before-order-change' + self.submit(ident, self.proposal(self.observe(), ident)) + self.until(ident, {'running'}) + time.sleep(.3) + action = 'cancel' if cancelled else 'edit' + change = {'expected_revision': 1} + if not cancelled: + change['target_zone'] = {'x_min': .16, 'x_max': .24, 'y_min': -.04, 'y_max': .04} + code, changed = self.http('POST', self.order_path(action), change) + self.assertEqual(code, 200, changed) + self.controller('cancel', '--operation-id', ident, '--expected-incarnation', self.incarnation) + stopped = self.until(ident) + self.assertIn(stopped['phase'], {'cancelled', 'unknown'}) + code, refused = self.fulfill() + self.assertNotEqual(code, 200, refused) + saved, count = self.db_rows() + self.assertEqual(saved[1], 2) + self.assertEqual(saved[2], 'cancelled' if cancelled else 'open') + self.assertEqual(count, 0) + + def test_actual_lost_http_reply_has_one_sqlite_effect_and_historical_repeat(self): + self.start() + self.bind() + self.start_native(placed=True) + self.stage() + content = encoded({'lease_id': self.lease['lease_id'], + 'completion_operation_id': self.lease['completion_operation_id']}) + parsed = urllib.parse.urlsplit(self.origin) + request = (f'POST {self.order_path("fulfill")} HTTP/1.1\r\nHost: 127.0.0.1:{parsed.port}\r\n' + f'Origin: {self.origin}\r\nX-Footwork-App-ID: {self.app_id}\r\n' + f'Content-Type: application/json\r\nContent-Length: {len(content)}\r\n' + 'Connection: close\r\n\r\n').encode() + content + with socket.create_connection(('127.0.0.1', parsed.port), timeout=5) as caller: + caller.sendall(request) + self.event({'kind': 'actual_http_socket_closed_before_reply', 'path': self.order_path('fulfill'), + 'reply_consumed': False, 'body_sha256': sha(content)}) + deadline = time.monotonic() + 6 + while time.monotonic() < deadline: + code, original = self.http('GET', '/api/operations/' + self.lease['completion_operation_id']) + if code == 200: + break + time.sleep(.05) + self.assertEqual(code, 200, original) + self.native.terminate() + self.native.wait(timeout=8) + repeated_code, repeated = self.fulfill() + self.assertEqual(repeated_code, 200, repeated) + self.assertEqual(repeated['receipt'], original['receipt']) + self.assertTrue(repeated['historical']) + saved, count = self.db_rows() + self.assertEqual((saved[1], saved[2], count), (2, 'fulfilled', 1)) + wrong_code, _ = self.fulfill(lease_id=uuid.uuid4().hex) + self.assertNotEqual(wrong_code, 200) + self.assertEqual(self.db_rows()[1], 1) + + def test_client_flags_paths_wrong_ids_and_missing_physical_evidence_refuse(self): + self.start() + self.bind() + for extra in ({'success': True}, {'receipt_path': '/tmp/fake.json'}, + {'app_id': uuid.uuid4().hex}, {'lease_id': uuid.uuid4().hex}, + {'completion_operation_id': 'fulfill-' + uuid.uuid4().hex}): + with self.subTest(extra=extra): + self.assertNotEqual(self.fulfill(**extra)[0], 200) + self.assertNotEqual(self.fulfill()[0], 200) + saved, count = self.db_rows() + self.assertEqual((saved[1], saved[2], count), (1, 'open', 0)) + + def test_other_application_lease_cannot_alias_same_order_and_real_physical_proof(self): + self.start() + self.bind() + self.start_native(placed=True) + self.stage() + original = self.app, self.origin, self.app_id, self.lease + self.app = self.directory / 'other-app' + self.initialize_app() + self.serve_app() + other = self.bind() + self.assertNotEqual(self.app_id, original[2]) + self.assertEqual(other['work_order'], original[3]['work_order']) + self.app, self.origin, self.app_id, self.lease = original + foreign_code, foreign = self.fulfill(lease_id=other['lease_id']) + self.assertNotEqual(foreign_code, 200, foreign) + missing, _ = self.http('GET', '/api/leases/' + other['lease_id']) + self.assertNotEqual(missing, 200) + self.assertEqual(self.db_rows()[1], 0) + own_code, own = self.fulfill() + self.assertEqual(own_code, 200, own) + self.assertEqual(self.db_rows()[1], 1) + + def test_valid_staging_for_wrong_task_cannot_fulfill_lease(self): + self.start() + self.bind() + altered = {**self.work_order, 'target_zone': {'x_min': .16, 'x_max': .24, 'y_min': -.04, 'y_max': .04}} + self.start_native(placed=True, altered_order=altered) + self.assertEqual(self.stage()[0]['phase'], 'staged') + self.assertNotEqual(self.fulfill()[0], 200) + self.assertEqual(self.db_rows()[1], 0) + + def test_valid_staging_for_wrong_order_identity_cannot_fulfill_lease(self): + self.start() + self.bind() + self.start_native(placed=True, altered_order={**self.work_order, 'order_id': self.order_id + '-different'}) + self.assertEqual(self.stage()[0]['phase'], 'staged') + self.assertNotEqual(self.fulfill()[0], 200) + self.assertEqual(self.db_rows()[1], 0) + + def test_executed_motion_under_completion_id_does_not_invent_staging(self): + self.start() + self.bind() + self.start_native() + ident = self.lease['physical_completion_id'] + self.submit(ident, self.proposal(self.observe(), ident)) + moved = self.until(ident) + self.assertEqual(moved['phase'], 'executed') + self.assertGreater(moved['receipt']['contact_statistics']['native_steps'], 0) + self.assertNotEqual(self.fulfill()[0], 200) + self.assertEqual(self.db_rows()[1], 0) + + def test_changed_source_binding_and_exact_store_replacement_refuse_restart(self): + process, _ = self.start() + self.bind() + process.terminate() + process.wait(timeout=8) + port = urllib.parse.urlsplit(self.origin).port + binding = self.app / 'app-binding.json' + original = binding.read_bytes() + saved_binding = self.directory / 'original-app-binding.json' + saved_binding.write_bytes(original) + saved_binding.chmod(0o600) + changed = json.loads(original) + changed['source_fingerprints']['order_app.py'] = '0' * 64 + self.retain(binding, changed) + refusal = self.command([sys.executable, APP, 'serve', '--app-dir', self.app, '--port', port]) + self.assertEqual(refusal['phase'], 'refused', refusal) + self.event({'kind': 'controlled_retained_binding_fault', 'fault': 'changed_app_source_fingerprint', + 'original_path': str(saved_binding), 'runtime_source_changed': False}) + binding.write_bytes(original) + database = self.app / 'orders.sqlite3' + original_database = self.directory / 'original-orders.sqlite3' + old_identity = [database.stat().st_dev, database.stat().st_ino] + database.rename(original_database) + database.write_bytes(original_database.read_bytes()) + database.chmod(0o600) + new_identity = [database.stat().st_dev, database.stat().st_ino] + self.assertNotEqual(new_identity, old_identity) + refusal = self.command([sys.executable, APP, 'serve', '--app-dir', self.app, '--port', port]) + self.assertEqual(refusal['phase'], 'refused', refusal) + self.event({'kind': 'controlled_retained_store_fault', 'fault': 'byte_identical_store_new_file_identity', + 'original_path': str(original_database), 'old_identity': old_identity, 'new_identity': new_identity}) + + def test_staged_history_with_tampered_current_artifact_refuses_first_fulfillment(self): + self.start() + self.bind() + self.start_native(placed=True) + final, _ = self.stage() + artifact = Path(self.lease['run_dir']) / 'order.json' + original = artifact.read_bytes() + saved = self.directory / 'original-physical-order.json' + saved.write_bytes(original) + saved.chmod(0o600) + artifact.write_bytes(original + b' ') + self.event({'kind': 'controlled_current_artifact_fault', 'path': str(artifact), 'original_path': str(saved), + 'original_sha256': sha(original)}) + status = self.controller('status', '--operation-id', self.lease['physical_completion_id']) + self.assertEqual(status['phase'], 'staged') + self.assertEqual(status['current_health'], 'blocked') + self.assertEqual(status['receipt'], final['receipt']) + self.assertNotEqual(self.fulfill()[0], 200) + self.assertEqual(self.db_rows()[1], 0) + + def test_application_controller_restart_retains_exact_store_and_no_redispatch(self): + app_process, first = self.start() + self.bind() + self.start_native(placed=True) + final, _ = self.stage() + before = self.observe() + old_incarnation = self.incarnation + self.native.terminate() + self.native.wait(timeout=8) + app_process.terminate() + app_process.wait(timeout=8) + _, current = self.serve_app(restart=True) + self.assertEqual(current['app_id'], first['app_id']) + self.assertNotEqual(current['server_incarnation'], first['server_incarnation']) + self.native = self.spawn([sys.executable, CONTROLLER, 'serve', '--run-dir', self.lease['run_dir'], + '--controller-dir', self.control], 'native-restart') + self.native_ready() + self.assertNotEqual(self.incarnation, old_incarnation) + retained = self.controller('status', '--operation-id', self.lease['physical_completion_id']) + self.assertEqual(retained['receipt'], final['receipt']) + after = self.observe() + self.assertEqual((after['generation'], after['state_sha256']), + (before['generation'], before['state_sha256'])) + self.assertEqual(self.fulfill()[0], 200) + self.assertEqual(self.db_rows()[1], 1) + + def test_loopback_browser_origin_and_exact_schema_protect_mutations(self): + self.start() + payload = {'expected_revision': 1, 'binding_operation_id': 'origin-' + uuid.uuid4().hex} + for headers, origin in (({'Origin': 'http://example.com'}, True), ({}, False), + ({'Host': 'example.com'}, True)): + with self.subTest(headers=headers, origin=origin): + code, reply = self.http('POST', self.order_path('bind'), payload, origin=origin, extra_headers=headers) + self.assertNotEqual(code, 200, reply) + self.assertEqual(self.db_rows()[1], 0) + + def test_mutations_require_pre_effect_exact_application_identity(self): + self.start() + original = self.app, self.origin, self.app_id + self.app = self.directory / 'foreign-app' + self.initialize_app() + self.serve_app() + foreign_id = self.app_id + self.assertNotEqual(foreign_id, original[2]) + self.app, self.origin, self.app_id = original + for expected_id, action in ((None, 'edit'), (foreign_id, 'cancel')): + with self.subTest(expected_id=expected_id, action=action): + before, before_count = self.db_rows() + payload = {'expected_revision': before[1]} + if action == 'edit': + payload['target_zone'] = {'x_min': .16, 'x_max': .24, 'y_min': -.04, 'y_max': .04} + headers = {'Origin': self.origin, 'Content-Type': 'application/json'} + if expected_id is not None: + headers['X-Footwork-App-ID'] = expected_id + parsed = urllib.parse.urlsplit(self.origin) + connection = HTTPConnection('127.0.0.1', parsed.port, timeout=8) + try: + connection.request('POST', self.order_path(action), body=encoded(payload), headers=headers) + response = connection.getresponse() + code, reply = response.status, json.loads(response.read()) + finally: + connection.close() + after, after_count = self.db_rows() + self.event({'kind': 'expected_app_identity_pre_effect_regression', 'action': action, + 'headers': headers, 'valid_foreign_app_id': foreign_id, + 'request': payload, 'status': code, 'reply': reply, + 'before_row': before, 'after_row': after}) + self.assertNotEqual(code, 200, reply) + self.assertEqual((after, after_count), (before, before_count)) + + def test_real_verified_proof_then_concurrent_edit_loses_version_cas(self): + self.initialize_app() + marker = self.directory / 'real-proof-ready' + release = self.directory / 'allow-cas' + script = self.directory / 'after-real-verification-timing-fault.py' + content = f'''import importlib.util +import sys +import time +from pathlib import Path +sys.path.insert(0, {str(BASE)!r}) +spec = importlib.util.spec_from_file_location("order_app_real_cas_fault", {str(APP)!r}) +app = importlib.util.module_from_spec(spec) +spec.loader.exec_module(app) +original = app.verify_physical +marker = Path({str(marker)!r}) +release = Path({str(release)!r}) +def delayed(lease): + proof = original(lease) + marker.write_bytes(b"real native/controller/artifact proof obtained\\n") + deadline = time.monotonic() + 5 + while not release.exists(): + if time.monotonic() > deadline: + raise RuntimeError("bounded verification/CAS timing fault timed out") + time.sleep(.02) + return proof +app.verify_physical = delayed +sys.exit(app.main()) +''' + script.write_text(content) + script.chmod(0o600) + self.serve_app(fault_script=script) + self.bind() + self.start_native(placed=True) + self.stage() + replies = [] + failures = [] + + def fulfill_in_parallel(): + try: + replies.append(self.fulfill()) + except (OSError, ValueError) as exc: + failures.append(str(exc)) + + thread = threading.Thread(target=fulfill_in_parallel) + thread.start() + try: + deadline = time.monotonic() + 5 + while not marker.exists() and time.monotonic() < deadline: + time.sleep(.03) + self.assertTrue(marker.exists(), f'no real proof marker; retained {self.directory}') + changed_zone = {'x_min': .16, 'x_max': .24, 'y_min': -.04, 'y_max': .04} + code, changed = self.http('POST', self.order_path('edit'), + {'expected_revision': 1, 'target_zone': changed_zone}) + self.assertEqual(code, 200, changed) + self.event({'kind': 'actual_process_with_labeled_timing_fault', + 'fault': 'real_physical_verification_complete_before_cas_release', + 'verification_success_mocked': False, 'marker': str(marker), 'release': str(release)}) + finally: + release.write_bytes(b'continue real CAS after actual edit\n') + thread.join(timeout=8) + self.assertFalse(thread.is_alive()) + self.assertFalse(failures, failures) + self.assertEqual(len(replies), 1) + self.assertNotEqual(replies[0][0], 200, replies) + saved, count = self.db_rows() + self.assertEqual((saved[1], saved[2], count), (2, 'open', 0)) + + +if __name__ == '__main__': + unittest.main() From 83266c17600d1b502045d95e1537cb97b01fe45c Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sat, 10 Oct 2026 19:47:03 -0400 Subject: [PATCH 081/216] Record verified browser physical fulfillment and independent SIM5 results --- .../SIM5-versioned-application-fulfillment.md | 11 +- ...10-10-versioned-application-fulfillment.md | 13 ++ .../browser-fulfilled.jpg | Bin 0 -> 76030 bytes .../browser-result.json | 58 +++++++++ .../report.md | 111 +++++++++++++++++ .../source-freeze.json | 30 +++++ .../summary.json | 112 ++++++++++++++++++ .../verification.json | 59 +++++++++ 8 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 jevdual/results/versioned-application-fulfillment-20261010/browser-fulfilled.jpg create mode 100644 jevdual/results/versioned-application-fulfillment-20261010/browser-result.json create mode 100644 jevdual/results/versioned-application-fulfillment-20261010/report.md create mode 100644 jevdual/results/versioned-application-fulfillment-20261010/source-freeze.json create mode 100644 jevdual/results/versioned-application-fulfillment-20261010/summary.json create mode 100644 jevdual/results/versioned-application-fulfillment-20261010/verification.json diff --git a/jevdual/docs/experiments/SIM5-versioned-application-fulfillment.md b/jevdual/docs/experiments/SIM5-versioned-application-fulfillment.md index f18ebb8..f29cd06 100644 --- a/jevdual/docs/experiments/SIM5-versioned-application-fulfillment.md +++ b/jevdual/docs/experiments/SIM5-versioned-application-fulfillment.md @@ -80,7 +80,16 @@ Hardware transfer, real operator demand and production adapter promotion remain ## Result -Pending. +The first implementation failed the wrong-app mutation requirement in development; +the failure is retained and notebook SIM5-R revises its prediction. Corrected frozen +implementation `bd896e1` passed the actual isolated-browser read/bind, image-guided native +contact, verified browser fulfillment and persisted readback. All seven independent +public-API integration scenarios passed on first attempts with unchanged source. +The 95 affected checks, source fingerprints, failed development attempts, separate +browser evidence, SQLite effect counts and cleanup are recorded under +`results/versioned-application-fulfillment-20261010/`. Adopt the bounded local experimental +handoff; hardware, persistent shared-body orders and production capability promotion +remain outside this result. ## Amendment · 2026-10-10 19:38 · before independent qualification diff --git a/jevdual/docs/notebook/2026-10-10-versioned-application-fulfillment.md b/jevdual/docs/notebook/2026-10-10-versioned-application-fulfillment.md index 1057929..331d529 100644 --- a/jevdual/docs/notebook/2026-10-10-versioned-application-fulfillment.md +++ b/jevdual/docs/notebook/2026-10-10-versioned-application-fulfillment.md @@ -50,3 +50,16 @@ Changes: the adapter now requires an integer leased revision, exact fulfilled re Inferred: assigned IDs alone are insufficient for typed historical application-effect claims. This is a conformance fault on owned persisted data, not a hardware/security qualification. Next: finish final-source adapter/backend suites, freeze all measured source, then run independent SIM5-R trials. Refs: tools/physical-workcell/output/h5-receipt-before-type-fix-v2/unittest.log; tools/physical-workcell/test_app_handoff.py + +## SIM5-R-U1 · update · 2026-10-10 19:46 +Resolves: SIM5-R = held +Observed: frozen bd896e1 completed the isolated-browser order binding, four image-guided native-contact moves, staged artifact verification and browser fulfillment. Separate HTTP/SQLite scoring found exactly one receipt at fulfilled revision 2; browser reload preserved it. Independent public-API trials passed all seven first attempts with unchanged source, including native-step-confirmed edit/cancel stops, lost-reply reconciliation, identity/conflict refusals, restart history and current artifact tampering. +Inferred: the corrected bounded local handoff connects physical evidence to saved application state while preserving explicit stale/current/history boundaries. It does not establish general visual-policy performance or hardware transfer. +Next: close this package with retained failures, evidence and owned-process cleanup; consider persistent body identity across successive work orders separately. +Refs: bd896e1; results/versioned-application-fulfillment-20261010/report.md; results/versioned-application-fulfillment-20261010/summary.json; results/versioned-application-fulfillment-20261010/browser-result.json + +## SIM5-S · summary · 2026-10-10 19:46 +Established: Python/SQLite application revision leases and a public controller adapter completed a real browser/native-image/software loop, with 95 affected checks and seven independent diagnostic scenarios supporting the corrected implementation. Wrong-app mutation and malformed reconciliation development failures are preserved; all trial-owned processes/sockets and the temporary browser tab were cleaned up. +Uncertain: physical/application proof is not atomic; the host must invoke guard to interrupt stale jobs; each lease currently owns a separate simulated episode. General robotics, a physical shared-body scheduler, camera/hardware calibration, operator demand and production capability governance are unqualified. +Decision: keep the bounded local app/handoff as an experimental Footwork tool, with deterministic authority and host planning. A subsequent package should separate persistent body/resource ownership from changing task identity. +Refs: results/versioned-application-fulfillment-20261010/; docs/experiments/SIM5-versioned-application-fulfillment.md; tools/physical-workcell/ORDER_APP.md diff --git a/jevdual/results/versioned-application-fulfillment-20261010/browser-fulfilled.jpg b/jevdual/results/versioned-application-fulfillment-20261010/browser-fulfilled.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f1224e55b2009f941c08e53e144bb23f14790898 GIT binary patch literal 76030 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 O|J(kLJ^_KR!~YBZU!ElZ literal 0 HcmV?d00001 diff --git a/jevdual/results/versioned-application-fulfillment-20261010/browser-result.json b/jevdual/results/versioned-application-fulfillment-20261010/browser-result.json new file mode 100644 index 0000000..1e15a26 --- /dev/null +++ b/jevdual/results/versioned-application-fulfillment-20261010/browser-result.json @@ -0,0 +1,58 @@ +{ + "source_commit": "bd896e1786406dc06cab65dcb9255934fd5ad196", + "classification": "actual isolated browser + root image-guided host proposals + native simulation + separate persisted SQLite readback", + "app_id": "609f629c251e40a29b2db363cb2d9f32", + "order_id": "desk-stage-001", + "leased_revision": 1, + "fulfilled_revision": 2, + "effect_count": 1, + "moves": 4, + "admitted_actions": 5, + "native_steps": 3484, + "native_contact_samples": 9890, + "public_rgb_generations": [ + 0, + 1, + 2, + 3, + 4 + ], + "final_rgb_center_m": [ + 0.19583333333333333, + 0.005833333333333333 + ], + "application_receipt": { + "app_id": "609f629c251e40a29b2db363cb2d9f32", + "committed_time_unix": 1791675824.074699, + "completion_operation_id": "fulfill-3e04eadf0a0e49cdb0a129db756ed781", + "fulfilled_revision": 2, + "lease_id": "24d56730083145d59b07fa1f4bcf2d4e", + "leased_revision": 1, + "order_id": "desk-stage-001", + "physical_completion_id": "stage-22a96ebafcb4404eb13478fb966f848b", + "physical_proof": { + "accepted_incarnation": "172b048b98204a3487c6902368b424c0", + "artifact_sha256": "6b9e6edded2471349354bec3d632bf81e186ea9c191d582ea68f2c22615f4d9d", + "controller_incarnation": "172b048b98204a3487c6902368b424c0", + "generation": 4, + "historical": true, + "image_sha256": "0f943c8669de3e35d64936bc01afef80a792095df2233592d567086edf6584c9", + "operation_id": "stage-22a96ebafcb4404eb13478fb966f848b", + "source_kind": "mujoco_simulation", + "state_sha256": "95f9c3e2c3c6113f12f5eb486443b8010a9382b3f8972d3e2450b4a1130ca495", + "verified_time_unix": 1791675824.0734122 + }, + "state": "fulfilled", + "work_order_sha256": "3f93b8004097cd730b72a4d9a78523d42f0cf6057d5e1a4a0e1b8b8eb98baada" + }, + "browser_reload_persisted": true, + "evidence_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/b5-browser-20261010", + "screenshot": "browser-fulfilled.jpg", + "cleanup": { + "app_stopped": true, + "controller_process_stopped": true, + "controller_socket_absent": true, + "tab_closed": true, + "native_stop_claim": false + } +} diff --git a/jevdual/results/versioned-application-fulfillment-20261010/report.md b/jevdual/results/versioned-application-fulfillment-20261010/report.md new file mode 100644 index 0000000..08d6a61 --- /dev/null +++ b/jevdual/results/versioned-application-fulfillment-20261010/report.md @@ -0,0 +1,111 @@ +# SIM5: Versioned application and simulated physical fulfillment + +The corrected implementation completed the actual browser/physical/application loop and +all seven independent integration scenarios on frozen commit `bd896e1`. The affected +95 checks passed. This is a local diagnostic, not hardware, production browser governance +or autonomous policy qualification. Source, outcomes and verification are recorded in +`source-freeze.json`, `summary.json`, `browser-result.json` and `verification.json`. + +## What connects + +A Python/SQLite loopback app records an order and its revision. The browser binds one +immutable lease for that revision, including the exact task and stable physical/application +completion identities. A separate handoff CLI owns or reconnects the assigned controller +through public commands. The agent observes rendered RGB and supplies bounded proposals. +The app verifies the assigned staged history, current image/task binding and saved artifact, +then updates the same still-open revision and saves one fulfillment receipt in a transaction. + +Editing or cancelling advances the revision. A guard withholds subsequent submissions and +requests cooperative cancellation of an owned active operation. Previously admitted motion +can be partial. The guard must be called by the host; this package has no background watcher +or atomic transaction joining native motion and application state. + +## Development evidence + +The earlier controller/body/vision files retain their SIM4 hashes. Their 68 affected tests +passed: 18 process/controller tests and 50 workcell, image-guided, case and episode tests. +Commands and timings are recorded in `verification.json`. + +Root source review found that a cached browser checked the responding app identity after +POST, leaving same-origin replacement writes unbound to the original app. Prediction +`46aa8f4` preceded the real mutation regression. Both pre-fix subcases failed: an absent +expected app identity edited the row, and a valid foreign app identity cancelled it. Private +before/after rows and the failed parent result remain at +`tools/physical-workcell/output/a56bb315a/conformance.json`. + +The corrected server requires one exact `X-Footwork-App-ID` before every mutation. The +browser sends its retained app identity. Valid order/lease references and exact Origin/Host +are separate requirements. + +The first malformed-receipt attempt stopped before its intended check when an overlapping +UI change invalidated the bound source. A fresh fixture then exposed three falsely accepted +reconciliation variants after controlled private-store corruption: boolean leased revision, +cancelled current order and a current revision older than the receipt. Both logs remain under +`output/h5-receipt-before-type-fix*/`. The final adapter requires strict typed receipt fields, +the same canonical task and a fulfilled current order at or after the recorded revision. + +Final app conformance passed 16 tests in 38.746 seconds; final adapter conformance passed +11 tests in 37.086 seconds. Their exact source/evidence paths are in `verification.json`. +Earlier controller regressions account for the other 68 checks and retain the unchanged +SIM4 hashes. Ruff, JavaScript syntax and notebook checks passed. + +## Independent evidence + +Root drove an isolated in-app browser against the frozen local app. It read and bound +`desk-stage-001` revision 1. Root inspected native RGB generations 0 through 4 and chose +four bounded moves from the public visual packet. Native receipts recorded 9,890 contact +samples over 3,484 steps. The final image-derived block center was approximately +(0.196, 0.006) m inside the requested region. A fifth admitted completion action staged +the digest-bound software artifact and passed Footwork's current saved-byte check. + +The browser's **Verify and fulfill** action then independently checked physical evidence +and saved fulfilled revision 2. Separate HTTP and read-only SQLite verification found +exactly one application receipt for the same app/order/lease/operation. Browser reload +preserved fulfilled revision 2. The screenshot shows the result and actual rendered RGB; +it is evidence from the completed trial, not a current live camera feed. + +![Verified browser fulfillment](browser-fulfilled.jpg) + +The independent driver used public app/controller/handoff APIs, a deterministic RGB planner +and separate read-only SQLite scoring. It reused identified frozen transport helpers but +did not call unit-test scenarios. Its seven first attempts passed with unchanged source: + +| Scenario | Persisted outcome | Fulfillment effects | +| --- | --- | ---: | +| Normal RGB contact and fulfillment | Revision 4, fulfilled | 1 | +| Edit during admitted motion | Revision 4, open; stale completion refused | 0 | +| Cancel during admitted motion | Revision 4, cancelled | 0 | +| Lost HTTP reply after commit | Original receipt reconciled and repeated after controller stop | 1 | +| Wrong identities, conflicting IDs, client flags/paths, unsupported evidence | Revision 3, open; refused | 0 | +| Same-origin app and controller restart | Unchanged physical generation/state, retained history, revision 4 fulfilled | 1 | +| Changed current artifact with staged history | Revision 3, open; new fulfillment refused | 0 | + +Edit/cancel stopped after 179/186 native steps respectively; each verified retained state +matched a fresh public observation. The driver preserved the actual lost-reply socket event +and conflicting committed-ID refusal. Raw evidence remains in +`tools/physical-workcell/output/s5-independent-20261010-v1/qualification.json`, with its SHA256 +in `summary.json`. Root's separate browser evidence remains in `output/b5-browser-20261010/`. + +All trial-owned app/controller processes exited and owned controller sockets disappeared. +The temporary browser tab closed; persisted order state and screenshots remain. Process +exit is a cleanup observation, separate from the verified native cancellation stop checks. + +## Limits and next boundary + +Physical proof is checked before the application transaction. Its verification timestamp +and the application's commit timestamp describe that boundary; a later physical/artifact +change cannot be excluded atomically. Historical application receipts remain separate from +current physical integrity. Same-app restart preserves its exact port; origin rebinding and +automatic takeover of externally restarted controllers are unsupported. + +The controller still operates one known-color block and pusher in a bounded MuJoCo scene. +Native camera perception, general robot manipulation, multiple agents sharing real hardware, +production capability governance and demand from an operator remain untested. + +Each lease owns a separate simulated episode. Successive orders or edited targets on one +persistent physical body, with resource ownership independent of task identity, are the next +useful boundary. This run does not qualify that transition or automatically continue an +interrupted physical job under a new order revision. + +Preregistration: `../../docs/experiments/SIM5-versioned-application-fulfillment.md`. +Notebook: `../../docs/notebook/2026-10-10-versioned-application-fulfillment.md`. diff --git a/jevdual/results/versioned-application-fulfillment-20261010/source-freeze.json b/jevdual/results/versioned-application-fulfillment-20261010/source-freeze.json new file mode 100644 index 0000000..4f53e27 --- /dev/null +++ b/jevdual/results/versioned-application-fulfillment-20261010/source-freeze.json @@ -0,0 +1,30 @@ +{ + "source_commit": "bd896e1786406dc06cab65dcb9255934fd5ad196", + "corrected_prediction_commit": "71600c1", + "original_prediction_commit": "07346c0", + "freeze_time": "2026-10-10T19:41:25-04:00", + "screen_before_browser_trial": { + "IOConsoleLocked": false, + "on_console": true + }, + "python": "3.12.6", + "mujoco": "3.15.0", + "sha256": { + "order_app.py": "006939326f54c76fea99c6c73f98692efb5fdc27e4f0615181013f7d27f2c5f7", + "order_protocol.py": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "order_app.html": "c8c286cad1d5d1aa795d48c8d9ae39f20292d7a3f08cb9f85fbc5789adfcc56a", + "app_handoff.py": "1af6b2bd78021d96632e51aa1bb5b5c8ccbb2ed84568fa05690369b2583bb187", + "controller.py": "29131e49c0b19ec59b957cf52a56aa573242ea3d3ee6851ebf4627c52a8c1bfd", + "workcell.py": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "image_guided.py": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961", + "episode_runner.py": "530c8e65d2b4c613e3c02c8dcc5e9f8d56559e5f119b011bb3e138667b1474e7", + "episode_cases.py": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "scene.xml": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "proposal.schema.json": "4f632336093c6b9d81741a4deff879b07eea7c9290eb34cbfa75ed84359b90e6", + "qualify_order_handoff.py": "bae7d9d668422d3f77b9390aa3e6fa4497fca2cbac90b5f5d1e6f65ec54eda08", + "test_order_app.py": "a8257e6b8572ace9721bddaeff037996e58a7e18637e674d00688d530434047a", + "test_app_handoff.py": "2ebabb984d75543adf5044551a78bc799ffb34157eeaea10cfaf9b7e13a71865", + "ORDER_APP.md": "75ae4263e16e1d6eda6974e6010141dc4eddbf2c766baf4391b42a2459e9b168", + "README.md": "1b01239948d1aa72496fc1f28ff379433217111d30831ccdf79c9ec46b141b5e" + } +} diff --git a/jevdual/results/versioned-application-fulfillment-20261010/summary.json b/jevdual/results/versioned-application-fulfillment-20261010/summary.json new file mode 100644 index 0000000..c093ffa --- /dev/null +++ b/jevdual/results/versioned-application-fulfillment-20261010/summary.json @@ -0,0 +1,112 @@ +{ + "source_commit": "bd896e1786406dc06cab65dcb9255934fd5ad196", + "attempted": 7, + "passed": 7, + "source_unchanged": true, + "raw_evidence": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/s5-independent-20261010-v1/qualification.json", + "raw_sha256": "647d6dab77eff0d5225d5df5802e58c83a076e2500d01da395c5911c4ee73df4", + "classification": "independent public API/adapter/native integration diagnostics; no AI benchmark", + "cases": [ + { + "case_id": "01-normal-http-native", + "passed": true, + "expected_outcome": "fulfilled", + "app_revision": 4, + "app_state": "fulfilled", + "effect_count": 1, + "native_steps_before_cancel": null, + "verified_stop": null, + "all_parent_handles_exited": true, + "adapter_stop_observed": true, + "socket_absent": true + }, + { + "case_id": "02-edit-during-motion", + "passed": true, + "expected_outcome": "stale_fulfillment_refused", + "app_revision": 4, + "app_state": "open", + "effect_count": 0, + "native_steps_before_cancel": 179, + "verified_stop": true, + "all_parent_handles_exited": true, + "adapter_stop_observed": true, + "socket_absent": true + }, + { + "case_id": "03-cancel-during-motion", + "passed": true, + "expected_outcome": "stale_fulfillment_refused", + "app_revision": 4, + "app_state": "cancelled", + "effect_count": 0, + "native_steps_before_cancel": 186, + "verified_stop": true, + "all_parent_handles_exited": true, + "adapter_stop_observed": true, + "socket_absent": true + }, + { + "case_id": "04-lost-app-reply", + "passed": true, + "expected_outcome": "one_effect_historical_reconciliation", + "app_revision": 4, + "app_state": "fulfilled", + "effect_count": 1, + "native_steps_before_cancel": null, + "verified_stop": null, + "all_parent_handles_exited": true, + "adapter_stop_observed": true, + "socket_absent": true + }, + { + "case_id": "05-identity-and-authority", + "passed": true, + "expected_outcome": "wrong_identity_flags_paths_and_unsupported_evidence_refused", + "app_revision": 3, + "app_state": "open", + "effect_count": 0, + "native_steps_before_cancel": null, + "verified_stop": null, + "all_parent_handles_exited": true, + "adapter_stop_observed": true, + "socket_absent": true + }, + { + "case_id": "06-restart-history", + "passed": true, + "expected_outcome": "same_identity_history_no_redispatch", + "app_revision": 4, + "app_state": "fulfilled", + "effect_count": 1, + "native_steps_before_cancel": null, + "verified_stop": null, + "all_parent_handles_exited": true, + "adapter_stop_observed": true, + "socket_absent": true + }, + { + "case_id": "07-current-artifact", + "passed": true, + "expected_outcome": "historical_stage_current_artifact_refuses_new_fulfillment", + "app_revision": 3, + "app_state": "open", + "effect_count": 0, + "native_steps_before_cancel": null, + "verified_stop": null, + "all_parent_handles_exited": true, + "adapter_stop_observed": true, + "socket_absent": true + } + ], + "actual_browser": { + "passed": true, + "effect_count": 1, + "fulfilled_revision": 2 + }, + "failures_preserved": [ + "tools/physical-workcell/output/a56bb315a/conformance.json", + "tools/physical-workcell/output/h5-receipt-before-type-fix/unittest.log", + "tools/physical-workcell/output/h5-receipt-before-type-fix-v2/unittest.log" + ] +} diff --git a/jevdual/results/versioned-application-fulfillment-20261010/verification.json b/jevdual/results/versioned-application-fulfillment-20261010/verification.json new file mode 100644 index 0000000..2159e7b --- /dev/null +++ b/jevdual/results/versioned-application-fulfillment-20261010/verification.json @@ -0,0 +1,59 @@ +{ + "phase": "complete", + "prior_controller_regressions": { + "controller_tests": 18, + "controller_seconds": 34.144, + "other_physical_tests": 50, + "other_seconds": 15.742, + "result": "passed" + }, + "prior_runtime_hashes_unchanged": true, + "commands": [ + { + "command": "tools/physical-workcell/.venv/bin/python -m unittest discover -s tools/physical-workcell -p test_controller.py", + "cwd": "/Users/thomasmain/projects/footwork" + }, + { + "command": ".venv/bin/python -m unittest test_workcell test_image_guided test_episode_cases test_episode_runner", + "cwd": "/Users/thomasmain/projects/footwork/tools/physical-workcell" + } + ], + "browser_trial": "passed", + "independent_trials": "7/7 passed", + "backend_conformance": { + "corrected_full_suite_tests": 16, + "seconds": 37.054, + "result": "passed", + "pre_fix_identity_regression": "tools/physical-workcell/output/a56bb315a/conformance.json", + "pre_fix_identity_regression_result": "failed; two effects before app identity checking", + "final_suite_tests": 16, + "final_seconds": 38.746, + "final_source_suite": "tools/physical-workcell/output/s5backend-final-f2190c5/suite-result.json" + }, + "adapter_conformance": { + "final_suite_tests": 11, + "seconds": 37.086, + "result": "passed", + "log": "tools/physical-workcell/output/h5-adapter-final-suite/unittest.log", + "previous_failed_attempts": [ + "tools/physical-workcell/output/h5-receipt-before-type-fix/unittest.log", + "tools/physical-workcell/output/h5-receipt-before-type-fix-v2/unittest.log" + ] + }, + "total_affected_checks": 95, + "lint": "Ruff passed", + "browser_cleanup": { + "app_stopped": true, + "controller_process_stopped": true, + "controller_socket_absent": true, + "tab_closed": true, + "native_stop_claim": false + }, + "notebook_check_exit_code": 0, + "result_redaction_files_changed": 0, + "runtime_source_unchanged": true, + "screen_at_close": { + "IOConsoleLocked": false, + "on_console": true + } +} From 161e4398a32bfb82d518db569823bf66a2f70d26 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 13:41:25 -0400 Subject: [PATCH 082/216] Register standalone onboarding review remediation before testing --- .../docs/notebook/2026-10-11-onboarding-remediation.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 jevdual/docs/notebook/2026-10-11-onboarding-remediation.md diff --git a/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md b/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md new file mode 100644 index 0000000..ff56b72 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md @@ -0,0 +1,8 @@ +# Standalone packet review remediation + +## UOR1 · prediction · 2026-10-11 13:43 +Hypothesis: resolving provenance from the packet manifest before installation or native actions removes Git/Command Line Tools dependence and prevents a completed native trial from losing its receipt at the provenance stage. +Test: preserve the old packet's installer failure outside a repository with Git denied; test both receipt paths against a frozen unpacked v3 packet with Git denied, plus invalid manifest and checkout fallback cases. Exercise the guest member-verification command and refuse modified, extra and symlinked members. Rebuild twice and verify immutable source binding. No independent Mac/TCC claims from these checks. +Predicts: standalone receipt provenance equals the frozen manifest, no Git subprocess occurs in packet mode, bad provenance refuses before effects, and altered extracted payloads fail guest verification. +Against: either receipt still invokes Git, accepts an enclosing foreign checkout, fails after native effects for provenance, or guest verification accepts modified payloads. +Refs: Claude review1791739896683034000; scripts/capability_clean_install.py; scripts/capability_installed_trial.py; docs/independent-onboarding.md From aab323288ffc40e02f6787facc910c45e2073d53 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 13:42:46 -0400 Subject: [PATCH 083/216] Record merge and independent VM provisioning scope --- jevdual/docs/notebook/2026-10-11-onboarding-remediation.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md b/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md index ff56b72..6eb2212 100644 --- a/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md +++ b/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md @@ -6,3 +6,8 @@ Test: preserve the old packet's installer failure outside a repository with Git Predicts: standalone receipt provenance equals the frozen manifest, no Git subprocess occurs in packet mode, bad provenance refuses before effects, and altered extracted payloads fail guest verification. Against: either receipt still invokes Git, accepts an enclosing foreign checkout, fails after native effects for provenance, or guest verification accepts modified payloads. Refs: Claude review1791739896683034000; scripts/capability_clean_install.py; scripts/capability_installed_trial.py; docs/independent-onboarding.md + +## UORU0 · update · 2026-10-11 13:43 +Observed: the prediction heading was entered13:43 while the terminal clock showed13:41. Its committed161e439 precedes the resolving tests; the prediction text is retained. PR2 merged exact7669d3d into268f0fc after four passing checks and an empty review-thread audit. User selected and authorized disposable VM provisioning on External SSD, including launcher/image downloads. +Next: reproduce the packet receipt defect, remediate and freezev3; independently provision a SIP-enabled guest without inherited grants. +Refs: https://github.com/Tom-R-Main/Footwork/pull/2; Claude review1791739896683034000 From f5e91d31340ce39881df019f18373230f9f38856 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 13:43:53 -0400 Subject: [PATCH 084/216] Register disposable SIP-enabled VM provisioning before execution --- jevdual/docs/notebook/2026-10-11-u2-vm-provision.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 jevdual/docs/notebook/2026-10-11-u2-vm-provision.md diff --git a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md new file mode 100644 index 0000000..a46ca02 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md @@ -0,0 +1,8 @@ +# U2 disposable macOS provisioning + +## VM1 · prediction · 2026-10-11 13:42 +Hypothesis: a pinned upstream Lume launcher running with all configuration, cache, restore-image and VM storage under the approved External SSD folder can install a fresh Apple restore image without a global install, shared host credentials or pregranted guest permissions. +Test: inspect upstream installer/release and launcher help, verify downloaded release provenance, then create a 4 CPU/8 GB/64 GB SIP-default guest from the recorded Apple IPSW and launch its visible Setup Assistant; preserve paths, hashes, logs and status in output/u2-vm-provision-20261011. +Predicts: the release and image are identifiable, provisioning writes stay in the approved folders, the guest reaches initial Setup Assistant, and no unattended seed, host permission change or guest permission grant is needed for provisioning. +Against: the launcher requires a global service or writes elsewhere, hardware/storage blocks install, the image cannot be verified/provisioned, or the guest arrives pregranted instead of pristine. +Refs: docs/experiments/U2-independent-onboarding.md; docs/onboarding-vm-plan.md; output/u2-vm-provision-20261011 From 33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 13:45:20 -0400 Subject: [PATCH 085/216] Remove guest Git dependency and verify standalone packet members --- jevdual/docs/independent-onboarding.md | 12 +- jevdual/scripts/build_onboarding_packet.py | 1 + jevdual/scripts/capability_clean_install.py | 22 ++- jevdual/scripts/capability_installed_trial.py | 7 +- jevdual/scripts/verify_onboarding_packet.py | 80 ++++++++++ jevdual/tests/test_onboarding_packet.py | 150 ++++++++++++++++++ 6 files changed, 263 insertions(+), 9 deletions(-) create mode 100644 jevdual/scripts/verify_onboarding_packet.py create mode 100644 jevdual/tests/test_onboarding_packet.py diff --git a/jevdual/docs/independent-onboarding.md b/jevdual/docs/independent-onboarding.md index ff82e74..9b77765 100644 --- a/jevdual/docs/independent-onboarding.md +++ b/jevdual/docs/independent-onboarding.md @@ -15,13 +15,21 @@ Open an interactive guest Terminal and define the packet directory: ~~~sh cd /absolute/extracted/footwork PACKET_ROOT="$(pwd -P)" +QUALIFICATION_PYTHON=/absolute/python3.12 +command -v python3 uv +"$QUALIFICATION_PYTHON" --version +uv --version +"$QUALIFICATION_PYTHON" -I "$PACKET_ROOT/jevdual/scripts/verify_onboarding_packet.py" \ + --packet-root "$PACKET_ROOT" cd jevdual -python3 scripts/capability_clean_install.py \ - --python /absolute/python3.12 \ +"$QUALIFICATION_PYTHON" -E -s scripts/capability_clean_install.py \ + --python "$QUALIFICATION_PYTHON" \ --wheel "$PACKET_ROOT/artifacts/jevdual-0.0.1-py3-none-any.whl" \ --run-dir "$PACKET_ROOT/output/install-v1" ~~~ +Set QUALIFICATION_PYTHON to the absolute executable installed for this run, not /usr/bin/python3. The system Python and Git commands can trigger a developer-tools installation dialog on a fresh Mac. The standalone helpers read their source commit from MANIFEST.json and do not need Git. Record the command paths and version output above. Verify members before installation creates output directories; stop on a nonzero verification exit. The archive hash from the accompanying report authenticates the manifest; member hashes detect changes after extraction. + The installer uses a fresh environment, empty cache, private state and public binary packages. Preserve failures as their own version; a new attempt needs a new run directory. Existing dependencies, source code, Rust and model accounts must not satisfy missing prerequisites. ## Record denied first use diff --git a/jevdual/scripts/build_onboarding_packet.py b/jevdual/scripts/build_onboarding_packet.py index d693200..324b49d 100644 --- a/jevdual/scripts/build_onboarding_packet.py +++ b/jevdual/scripts/build_onboarding_packet.py @@ -14,6 +14,7 @@ PROJECT = Path(__file__).resolve().parents[2] HELPERS = ( + "verify_onboarding_packet.py", "capability_clean_install.py", "capability_fixture.py", "capability_fixture_config.py", diff --git a/jevdual/scripts/capability_clean_install.py b/jevdual/scripts/capability_clean_install.py index 54ee253..fa0a1ac 100644 --- a/jevdual/scripts/capability_clean_install.py +++ b/jevdual/scripts/capability_clean_install.py @@ -11,6 +11,7 @@ import json import os import platform +import re import shutil import subprocess from pathlib import Path @@ -18,6 +19,22 @@ PROJECT = Path(__file__).resolve().parents[2] +def source_commit(project: Path) -> str: + """Packet provenance never calls Git or the macOS developer-tools shim.""" + manifest = project / "MANIFEST.json" + if manifest.exists() or manifest.is_symlink(): + if manifest.is_symlink() or not manifest.is_file(): + raise ValueError("Packet manifest must be a regular file") + payload = json.loads(manifest.read_text()) + commit = payload.get("source_commit") if isinstance(payload, dict) else None + if not isinstance(commit, str) or not re.fullmatch(r"[0-9a-f]{40}", commit): + raise ValueError("Packet manifest requires a full immutable source commit") + return commit + if (project / ".git").exists(): + return subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=project, text=True).strip() + return "unavailable" + + def isolated_environment(state_root: Path | None = None) -> dict[str, str]: env = {} for name, value in os.environ.items(): @@ -61,6 +78,7 @@ def main() -> int: root, wheel = args.run_dir.resolve(), args.wheel.resolve() if not root.is_relative_to(PROJECT / "output") or not wheel.is_file(): parser.error("owned output run and existing wheel required") + provenance = source_commit(PROJECT) root.mkdir(parents=True, exist_ok=False, mode=0o700) cwd, cache, venv = root / "outside-source", root / "empty-cache", root / "venv" cwd.mkdir(mode=0o700) @@ -74,9 +92,7 @@ def main() -> int: interpreter = os.path.abspath(args.python) common = [uv, "--no-config", "--no-progress", "--cache-dir", str(cache), "--no-python-downloads"] receipt = { - "source_commit": subprocess.check_output( - ["git", "rev-parse", "HEAD"], cwd=PROJECT, text=True - ).strip(), + "source_commit": provenance, "host": {"platform": platform.system(), "machine": platform.machine()}, "interpreter_requested": interpreter, "wheel": str(wheel), diff --git a/jevdual/scripts/capability_installed_trial.py b/jevdual/scripts/capability_installed_trial.py index b978012..4312637 100644 --- a/jevdual/scripts/capability_installed_trial.py +++ b/jevdual/scripts/capability_installed_trial.py @@ -14,7 +14,7 @@ from pathlib import Path import psutil -from capability_clean_install import isolated_environment +from capability_clean_install import isolated_environment, source_commit from capability_host_trial import ax_document_text, ax_reset_text from capability_interrupt_trial import Server, destination_target from capability_restart_trial import _rows, _wait_no_worker @@ -99,6 +99,7 @@ def main() -> int: root = args.run_dir.resolve() if not root.is_relative_to(PROJECT / "output"): parser.error("owned output directory required") + provenance = source_commit(PROJECT) root.mkdir(parents=True, mode=0o700, exist_ok=False) cwd = root / "outside-source" cwd.mkdir(mode=0o700) @@ -326,9 +327,7 @@ def watch(): ) result = { "passed": True, - "source_commit": subprocess.check_output( - ["git", "rev-parse", "HEAD"], cwd=PROJECT, text=True - ).strip(), + "source_commit": provenance, "origins": origins, "actual_runtime_contexts": actual_contexts, "emitted_configuration_checked": configured is not None, diff --git a/jevdual/scripts/verify_onboarding_packet.py b/jevdual/scripts/verify_onboarding_packet.py new file mode 100644 index 0000000..5dea792 --- /dev/null +++ b/jevdual/scripts/verify_onboarding_packet.py @@ -0,0 +1,80 @@ +"""Verify extracted packet members before creating any qualification output.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import re +from pathlib import Path, PurePosixPath + + +def verify(root: Path) -> dict: + root = root.resolve() + manifest_path = root / "MANIFEST.json" + if manifest_path.is_symlink() or not manifest_path.is_file(): + raise ValueError("Manifest must be a regular file") + manifest = json.loads(manifest_path.read_text()) + if not isinstance(manifest, dict) or not re.fullmatch( + r"[0-9a-f]{40}", str(manifest.get("source_commit", "")) + ): + raise ValueError("Manifest requires a full immutable source commit") + members = manifest.get("members") + if not isinstance(members, dict) or not members: + raise ValueError("Manifest requires payload member hashes") + expected = {"MANIFEST.json"} + for name, digest in members.items(): + relative = PurePosixPath(name) + if ( + not relative.parts + or relative.parts[0] != "footwork" + or len(relative.parts) < 2 + or relative.is_absolute() + or ".." in relative.parts + or relative.as_posix() != name + or not isinstance(digest, str) + or not re.fullmatch(r"[0-9a-f]{64}", digest) + ): + raise ValueError("Invalid packet member or hash") + path = root.joinpath(*relative.parts[1:]) + if any(parent.is_symlink() for parent in (path, *path.parents) if parent != root.parent): + raise ValueError("Symlinked packet member") + if not path.is_file() or not path.resolve().is_relative_to(root): + raise ValueError("Missing or nonregular packet member") + if hashlib.sha256(path.read_bytes()).hexdigest() != digest: + raise ValueError("Packet member hash mismatch: " + name) + expected.add(path.relative_to(root).as_posix()) + actual = { + path.relative_to(root).as_posix() for path in root.rglob("*") if path.is_file() or path.is_symlink() + } + if actual != expected: + raise ValueError("Extracted packet inventory differs from manifest") + wheels = [ + digest + for name, digest in members.items() + if name.startswith("footwork/artifacts/") and name.endswith(".whl") + ] + if wheels != [manifest.get("wheel_sha256")]: + raise ValueError("Manifest wheel hash differs") + return { + "verified": True, + "members": len(actual), + "source_commit": manifest["source_commit"], + "wheel_sha256": manifest["wheel_sha256"], + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--packet-root", type=Path, required=True) + args = parser.parse_args() + try: + result = verify(args.packet_root) + except (ValueError, OSError, TypeError) as exc: + parser.exit(1, "Packet verification failed: " + str(exc) + "\n") + print(json.dumps(result)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/jevdual/tests/test_onboarding_packet.py b/jevdual/tests/test_onboarding_packet.py new file mode 100644 index 0000000..96babe3 --- /dev/null +++ b/jevdual/tests/test_onboarding_packet.py @@ -0,0 +1,150 @@ +"""Standalone qualification receipts must not require a guest Git installation.""" + +from __future__ import annotations + +import hashlib +import importlib.util +import json +import subprocess +import sys +from pathlib import Path +from types import SimpleNamespace + +import pytest + +SCRIPTS = Path(__file__).resolve().parents[1] / "scripts" +COMMIT = "a" * 40 + + +def installer(): + spec = importlib.util.spec_from_file_location("packet_installer", SCRIPTS / "capability_clean_install.py") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def test_packet_installer_writes_receipt_without_git(tmp_path, monkeypatch): + module = installer() + project = tmp_path / "footwork" + project.mkdir() + (project / "MANIFEST.json").write_text(json.dumps({"source_commit": COMMIT})) + wheel = project / "fixture.whl" + wheel.write_bytes(b"qualification fixture") + monkeypatch.setattr(module, "PROJECT", project) + monkeypatch.setattr(module.shutil, "which", lambda name: "fixture-uv") + + def no_git(*args, **kwargs): + raise RuntimeError("Guest Git must never be invoked") + + monkeypatch.setattr(module.subprocess, "check_output", no_git) + # Stop at the external uv boundary; execute the real installer receipt path. + monkeypatch.setattr(module.subprocess, "run", lambda *args, **kwargs: SimpleNamespace(returncode=17)) + monkeypatch.setattr( + sys, + "argv", + [ + "install", + "--python", + sys.executable, + "--wheel", + str(wheel), + "--run-dir", + str(project / "output/install"), + ], + ) + assert module.main() == 1 + receipt = json.loads((project / "output/install/receipt.json").read_text()) + assert receipt["source_commit"] == COMMIT + assert receipt["commands"][0]["stage"] == "venv" + assert receipt["commands"][0]["returncode"] == 17 + + +def test_manifest_overrides_enclosing_repository(tmp_path): + subprocess.run(["git", "init", "--quiet", str(tmp_path)], check=True) + project = tmp_path / "footwork" + project.mkdir() + (project / "MANIFEST.json").write_text(json.dumps({"source_commit": COMMIT})) + assert installer().source_commit(project) == COMMIT + + +@pytest.mark.parametrize("value", ["bad", None, 123, "a" * 39]) +def test_bad_packet_provenance_refuses_without_git(tmp_path, monkeypatch, value): + module = installer() + (tmp_path / "MANIFEST.json").write_text(json.dumps({"source_commit": value})) + monkeypatch.setattr(module.subprocess, "check_output", lambda *a, **k: pytest.fail("Git was invoked")) + with pytest.raises(ValueError, match="source commit"): + module.source_commit(tmp_path) + + +def test_no_manifest_or_owned_git_returns_unavailable(tmp_path, monkeypatch): + module = installer() + monkeypatch.setattr(module.subprocess, "check_output", lambda *a, **k: pytest.fail("Git was invoked")) + assert module.source_commit(tmp_path) == "unavailable" + + +def test_checkout_provenance_remains_available(): + project = SCRIPTS.parents[1] + expected = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=project, text=True).strip() + assert installer().source_commit(project) == expected + + +def test_native_bad_manifest_refuses_before_resource_creation(tmp_path, monkeypatch): + monkeypatch.syspath_prepend(str(SCRIPTS)) + import capability_installed_trial as trial + + (tmp_path / "MANIFEST.json").write_text(json.dumps({"source_commit": "invalid"})) + monkeypatch.setattr(trial, "PROJECT", tmp_path) + monkeypatch.setattr(trial, "InstalledServer", lambda *a, **k: pytest.fail("Server must not start")) + monkeypatch.setattr( + sys, + "argv", + [ + "trial", + "--python", + sys.executable, + "--scope", + str(tmp_path / "absent-scope.json"), + "--run-dir", + str(tmp_path / "output/native"), + ], + ) + with pytest.raises(ValueError, match="source commit"): + trial.main() + assert not (tmp_path / "output").exists() + + +@pytest.mark.parametrize("mutation", [None, "modified", "extra", "symlink", "escape"]) +def test_guest_verifier_checks_extracted_payload(tmp_path, mutation): + root = tmp_path / "footwork" + (root / "artifacts").mkdir(parents=True) + wheel = root / "artifacts/fixture.whl" + wheel.write_bytes(b"fixture wheel") + digest = hashlib.sha256(wheel.read_bytes()).hexdigest() + manifest = { + "source_commit": COMMIT, + "wheel_sha256": digest, + "members": {"footwork/artifacts/fixture.whl": digest}, + } + if mutation == "modified": + wheel.write_bytes(b"modified wheel") + elif mutation == "extra": + (root / "unexpected.txt").write_text("extra") + elif mutation == "symlink": + outside = tmp_path / "outside.whl" + wheel.rename(outside) + wheel.symlink_to(outside) + elif mutation == "escape": + manifest["members"]["footwork/../outside.whl"] = digest + (root / "MANIFEST.json").write_text(json.dumps(manifest)) + run = subprocess.run( + [sys.executable, "-I", str(SCRIPTS / "verify_onboarding_packet.py"), "--packet-root", str(root)], + capture_output=True, + text=True, + check=False, + ) + if mutation is None: + assert run.returncode == 0, run.stderr + assert json.loads(run.stdout)["source_commit"] == COMMIT + else: + assert run.returncode == 1 + assert "verification failed" in run.stderr From 507fe855cb56336e1bd4c23e65410e91474b2600 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 13:48:51 -0400 Subject: [PATCH 086/216] Preserve packet v3 regression evidence and PR2 merge readback --- .../2026-10-11-onboarding-remediation.md | 6 ++ .../onboarding-remediation-20261011/report.md | 14 +++ .../summary.json | 95 +++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 jevdual/results/onboarding-remediation-20261011/report.md create mode 100644 jevdual/results/onboarding-remediation-20261011/summary.json diff --git a/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md b/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md index 6eb2212..abe4be0 100644 --- a/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md +++ b/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md @@ -11,3 +11,9 @@ Refs: Claude review1791739896683034000; scripts/capability_clean_install.py; scr Observed: the prediction heading was entered13:43 while the terminal clock showed13:41. Its committed161e439 precedes the resolving tests; the prediction text is retained. PR2 merged exact7669d3d into268f0fc after four passing checks and an empty review-thread audit. User selected and authorized disposable VM provisioning on External SSD, including launcher/image downloads. Next: reproduce the packet receipt defect, remediate and freezev3; independently provision a SIP-enabled guest without inherited grants. Refs: https://github.com/Tom-R-Main/Footwork/pull/2; Claude review1791739896683034000 + +## UORU1 · update · 2026-10-11 13:48 +Resolves: UOR1 = held +Observed: the baseline installer fails at trapped Git; v3 unpacks and retains manifest provenance without Git on installed3.12.6/3.14.7. Both guest verifier invocations pass; both native invalid-manifest paths refuse before resources.23 focused tests and Ruff pass, repeated14member builds match frozen33e1afb, with the reviewed wheel unchanged. The smoke stops at an intentional uv boundary and does not establish dependency installation or native effects. Initial headings ran ahead of terminal clock by one or two minutes; committed prediction order is authoritative. +Next: request Claude exact-artifact review and keep UO2 open for independent guest runtime/permission evidence. +Refs: results/onboarding-remediation-20261011; output/u2-remediation-smoke-v3/receipt.json; PR2 merge268f0fc diff --git a/jevdual/results/onboarding-remediation-20261011/report.md b/jevdual/results/onboarding-remediation-20261011/report.md new file mode 100644 index 0000000..1dc83a5 --- /dev/null +++ b/jevdual/results/onboarding-remediation-20261011/report.md @@ -0,0 +1,14 @@ +# Standalone packet v3 review remediation + +Frozen helper/doc commit: `33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d`. +Packet: `output/u2-packet-v3/footwork-onboarding-u2.zip`. +SHA256: `769c08c89061731368db33d78b180e7c8c96d531190f43bee44263642a76fd0f`. +Two builds match at14members. The product wheel remains the PR2-reviewed9bb0440d artifact, byte for byte. + +Claude B1/N1/N2 are addressed: both receipt paths obtain manifest provenance before resource creation; checkout fallback runs Git only at an owned .git marker; the runbook uses one explicit Python executable and records paths/versions; a stdlib guest command verifies every extracted payload and rejects extra members. + +23 focused tests pass, plus Ruff and notebook validation. `output/u2-remediation-smoke-v3/receipt.json` records actual unpacked installer invocations on existing installed3.12.6 and3.14.7 interpreters. Git is trapped and uv intentionally exits17 at the external environment-creation boundary: v2 invokes Git and loses its receipt; v3 does not invoke Git and preserves its frozen source commit in a failed-stage receipt. This is a receipt-path smoke, not a fresh dependency installation. Both profiles run the guest verifier successfully and native entry refuses an invalid manifest before output creation or scope access. Native effects and the final successful native receipt have not been rerun here; U2 will exercise them in the independent guest. Tamper/symlink/escape/extra-member cases are covered by CLI tests. + +The checkout development .venv disappeared between checks and was recreated empty by uv; no cause was established. The repeated23tests and Ruff used the main checkout's existing development environment with the isolated checkout's source/tests. Packet tests used the retained separate full-dependency environments. No new host dependencies were installed for these checks. + +PR2 merged exact7669d3d at268f0fc; both post-merge workflows passed (38160734302,38160734323). The new packet changes remain on the local independent-onboarding branch. Claude's v3 review is requested. The user approved SSD VM launcher/image provisioning; actual clean-Mac permission qualification remains unexecuted. diff --git a/jevdual/results/onboarding-remediation-20261011/summary.json b/jevdual/results/onboarding-remediation-20261011/summary.json new file mode 100644 index 0000000..e67012f --- /dev/null +++ b/jevdual/results/onboarding-remediation-20261011/summary.json @@ -0,0 +1,95 @@ +{ + "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", + "packet_sha256": "769c08c89061731368db33d78b180e7c8c96d531190f43bee44263642a76fd0f", + "members": 14, + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7", + "reproducible": true, + "focused_tests_passed": 23, + "ruff": "passed", + "profiles": { + "312": { + "v2": { + "returncode": 1, + "git_invoked": true, + "receipt_source_commit": null, + "external_stage": null + }, + "member_verification": { + "verified": true, + "members": 14, + "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7" + }, + "v3": { + "returncode": 1, + "git_invoked": false, + "receipt_source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", + "external_stage": [ + { + "stage": "venv", + "argv": [ + "/Users/thomasmain/.codex/worktrees/restart-agent-acceptance/footwork/output/u2-remediation-smoke-v3/312-v3/stub-bin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/thomasmain/.codex/worktrees/restart-agent-acceptance/footwork/output/u2-remediation-smoke-v3/312-v3/footwork/output/install-provenance/empty-cache", + "--no-python-downloads", + "venv", + "--python", + "/Users/thomasmain/.codex/worktrees/restart-agent-acceptance/footwork/output/delivery-dependencies-py312-v1/venv/bin/python", + "/Users/thomasmain/.codex/worktrees/restart-agent-acceptance/footwork/output/u2-remediation-smoke-v3/312-v3/footwork/output/install-provenance/venv" + ], + "returncode": 17 + } + ] + }, + "native_bad_provenance_refuses_before_resources": true + }, + "314": { + "v2": { + "returncode": 1, + "git_invoked": true, + "receipt_source_commit": null, + "external_stage": null + }, + "member_verification": { + "verified": true, + "members": 14, + "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7" + }, + "v3": { + "returncode": 1, + "git_invoked": false, + "receipt_source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", + "external_stage": [ + { + "stage": "venv", + "argv": [ + "/Users/thomasmain/.codex/worktrees/restart-agent-acceptance/footwork/output/u2-remediation-smoke-v3/314-v3/stub-bin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/thomasmain/.codex/worktrees/restart-agent-acceptance/footwork/output/u2-remediation-smoke-v3/314-v3/footwork/output/install-provenance/empty-cache", + "--no-python-downloads", + "venv", + "--python", + "/Users/thomasmain/.codex/worktrees/restart-agent-acceptance/footwork/output/delivery-dependencies-py314-v1/venv/bin/python", + "/Users/thomasmain/.codex/worktrees/restart-agent-acceptance/footwork/output/u2-remediation-smoke-v3/314-v3/footwork/output/install-provenance/venv" + ], + "returncode": 17 + } + ] + }, + "native_bad_provenance_refuses_before_resources": true + } + }, + "first_use_qualification": "not_performed", + "claude_review": "requested", + "pr2": { + "state": "merged", + "merge_commit": "268f0fc940a76e1fb071faeeb94ef12799176df2", + "post_merge_ci": "passed" + }, + "limits": "stopped_at_external_uv_boundary; native actions not performed; source unit checks use existing dev environment, packet checks use separately installed dependency environments." +} From 7af5b73ce1ea624b755046aed44fe06ab5d9afa5 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 13:51:33 -0400 Subject: [PATCH 087/216] Record Claude approval of immutable packet v3 --- jevdual/docs/notebook/2026-10-11-onboarding-remediation.md | 6 ++++++ jevdual/results/onboarding-remediation-20261011/report.md | 2 ++ .../results/onboarding-remediation-20261011/summary.json | 7 ++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md b/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md index abe4be0..4ea1a56 100644 --- a/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md +++ b/jevdual/docs/notebook/2026-10-11-onboarding-remediation.md @@ -17,3 +17,9 @@ Resolves: UOR1 = held Observed: the baseline installer fails at trapped Git; v3 unpacks and retains manifest provenance without Git on installed3.12.6/3.14.7. Both guest verifier invocations pass; both native invalid-manifest paths refuse before resources.23 focused tests and Ruff pass, repeated14member builds match frozen33e1afb, with the reviewed wheel unchanged. The smoke stops at an intentional uv boundary and does not establish dependency installation or native effects. Initial headings ran ahead of terminal clock by one or two minutes; committed prediction order is authoritative. Next: request Claude exact-artifact review and keep UO2 open for independent guest runtime/permission evidence. Refs: results/onboarding-remediation-20261011; output/u2-remediation-smoke-v3/receipt.json; PR2 merge268f0fc + +## UORS1 · summary · 2026-10-11 13:51 +Established: packetv3 is frozen, reproducible and independently approved by Claude1791740993609795000 for preparation; all three review findings closed. PR2 merged268f0fc and both postmerge workflows passed. +Uncertain: independent guest permission transition, final native receipt and cleanup remain unexecuted; verified SIP-on guest provisioning is underway in the user-approved SSD folder. +Decision: retain immutablev3 and execute UO2 only on the new guest after real setup, denied baseline and explicit permission transition. +Refs: results/onboarding-remediation-20261011; output/u2-vm-provision-20261011/provision-state.json diff --git a/jevdual/results/onboarding-remediation-20261011/report.md b/jevdual/results/onboarding-remediation-20261011/report.md index 1dc83a5..2fbffa0 100644 --- a/jevdual/results/onboarding-remediation-20261011/report.md +++ b/jevdual/results/onboarding-remediation-20261011/report.md @@ -12,3 +12,5 @@ Claude B1/N1/N2 are addressed: both receipt paths obtain manifest provenance bef The checkout development .venv disappeared between checks and was recreated empty by uv; no cause was established. The repeated23tests and Ruff used the main checkout's existing development environment with the isolated checkout's source/tests. Packet tests used the retained separate full-dependency environments. No new host dependencies were installed for these checks. PR2 merged exact7669d3d at268f0fc; both post-merge workflows passed (38160734302,38160734323). The new packet changes remain on the local independent-onboarding branch. Claude's v3 review is requested. The user approved SSD VM launcher/image provisioning; actual clean-Mac permission qualification remains unexecuted. + +Claude approved the exact v3 archive in mailbox1791740993609795000 after independent outside-repository extraction, trapped-Git provenance checks and guest-verifier modification/extra/symlink negatives. B1/N1/N2 are closed; U2runtime success remains unproven. diff --git a/jevdual/results/onboarding-remediation-20261011/summary.json b/jevdual/results/onboarding-remediation-20261011/summary.json index e67012f..1bcdcff 100644 --- a/jevdual/results/onboarding-remediation-20261011/summary.json +++ b/jevdual/results/onboarding-remediation-20261011/summary.json @@ -85,7 +85,12 @@ } }, "first_use_qualification": "not_performed", - "claude_review": "requested", + "claude_review": { + "verdict": "approved_for_preparation", + "message": "1791740993609795000", + "artifact_sha256": "769c08c89061731368db33d78b180e7c8c96d531190f43bee44263642a76fd0f", + "runtime_success": false + }, "pr2": { "state": "merged", "merge_commit": "268f0fc940a76e1fb071faeeb94ef12799176df2", From 30d36e3028d1276fd7e25b0be71fc729707108e5 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 13:58:09 -0400 Subject: [PATCH 088/216] Register clipboard-isolated Tart provisioning after Lume viewer audit --- jevdual/docs/notebook/2026-10-11-u2-vm-provision.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md index a46ca02..8dd6c98 100644 --- a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md +++ b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md @@ -6,3 +6,16 @@ Test: inspect upstream installer/release and launcher help, verify downloaded re Predicts: the release and image are identifiable, provisioning writes stay in the approved folders, the guest reaches initial Setup Assistant, and no unattended seed, host permission change or guest permission grant is needed for provisioning. Against: the launcher requires a global service or writes elsewhere, hardware/storage blocks install, the image cannot be verified/provisioned, or the guest arrives pregranted instead of pristine. Refs: docs/experiments/U2-independent-onboarding.md; docs/onboarding-vm-plan.md; output/u2-vm-provision-20261011 + +## VMU1 · update · 2026-10-11 13:57 +Observed: Lume0.6.1 asset digest/signature/notarization and SSD-only configuration checks passed. Source inspection found its native viewer unconditionally reads the host clipboard before guest SSH is available, and its VNC CLI exposes no bind-address control; the queued controller was stopped before any VM create. The fresh Apple26.6.2/25G83 IPSW download remains active and its advertised SHA256 is recorded. +Inferred: a supported privacy-bounded native viewer requires a different launcher; launch proof and VM1 remain open. +Next: qualify pinned Tart with its supported --no-clipboard flag, then reuse the Apple image only after full SHA256 verification. +Refs: output/u2-vm-provision-20261011/launcher-provenance.json; output/u2-vm-provision-20261011/provision-state.json + +## VM2 · prediction · 2026-10-11 13:57 +Hypothesis: pinned upstream Tart2.40.1 with TART_HOME and temporary state on the approved SSD and --no-clipboard can provision a pristine macOS guest and show Setup Assistant without host clipboard access, VNC listener, folder sharing, guest SSH or pregranted permissions. +Test: verify official release digest/signature/license and actual CLI help/source flags, create from the fully verified Apple IPSW, configure4CPU/8GB/64GB, and run its native viewer with clipboard/audio/USB passthrough disabled and no directory/SSH/guest-agent setup; root observes the GUI and owns any human-dependent setup. +Predicts: CLI/source and runtime state confirm the supported disabled clipboard route and isolated storage, guest installation succeeds, and a real visible Setup Assistant is available before permission grants. +Against: the flags are unsupported or still read host clipboard, Tart requires unapproved global paths or paid terms, installation fails, or Setup Assistant/host isolation cannot be established. +Refs: output/u2-vm-provision-20261011/tart-release.json; output/u2-vm-provision-20261011/tart-run-pinned.swift; docs/experiments/U2-independent-onboarding.md From f966e7264c55d47a233a552f1f7a4a79520146c0 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 13:58:49 -0400 Subject: [PATCH 089/216] Preregister successive simulated bench cycles and disturbance recovery --- .../docs/experiments/SIM6-reusable-bench.md | 35 +++++++++++++++++++ .../notebook/2026-10-11-reusable-bench.md | 8 +++++ 2 files changed, 43 insertions(+) create mode 100644 jevdual/docs/experiments/SIM6-reusable-bench.md create mode 100644 jevdual/docs/notebook/2026-10-11-reusable-bench.md diff --git a/jevdual/docs/experiments/SIM6-reusable-bench.md b/jevdual/docs/experiments/SIM6-reusable-bench.md new file mode 100644 index 0000000..5ea7bb5 --- /dev/null +++ b/jevdual/docs/experiments/SIM6-reusable-bench.md @@ -0,0 +1,35 @@ +# SIM6: successive physical-computer experiments on one simulated bench + +## Question + +Can one persistent MuJoCo body support image-guided preparation, a separately executed computer measurement, contact-driven reset, and a subsequent job, including recovery from an unexpected block movement? + +## Hypothesis + +Separating persistent bench identity and state generation from job identity, and requiring fresh image-bound effects, permits successive jobs without reinitializing the body. A color-specific RGB host can reobserve after a diagnostic force disturbance and resume preparation instead of acting on stale placement evidence. + +## Predictions + +If true, two successive jobs retain one bench ID, monotonic native time and generations, each record one independently readable image measurement, and reset through native actuator/contact steps before the next job. A stale move or measurement following a disturbance refuses without its requested effect, then fresh RGB guidance completes and resets the disturbed job. + +If false, reset requires state assignment/reinitialization, a disturbed job cannot recover within its bounded action budget, a stale packet authorizes measurement or motion, or job two loses the state/history of job one. + +## Design + +Add an isolated persistent bench under `tools/physical-workcell/`, reusing the pinned MuJoCo model, bounded native motion, PNG codec and color-specific RGB detector. Preserve the older episode/controller/application experiments. The host sees image packets and task intent, never private native pose guidance. Job phases separate preparation, measured result, resetting, and completed reset. A measurement subprocess computes the orange silhouette footprint and centroid from the exact image and records an idempotent job-bound SQLite result. This is a simulated optical measurement, not a calibrated physical instrument. + +Reset routes the pusher around the block, pushes it back to the home region through contacts, then returns the pusher home. Initialization is allowed once; no reset may assign block pose or call `mj_resetData`. A bounded native external-force diagnostic produces an unexpected displacement, persists a new state generation, and is separately labeled intervention rather than planner motion. + +Use private development runs and focused conformance tests. Freeze source before an independent public-interface qualification. Retain all attempts and cleanup evidence. No paid models, hardware, real camera access, cloud deployment or broad UI change. + +## Primary metric + +Number of successful complete job cycles in the preregistered sequence: ordinary job, disturbed job. Success requires exact measurement receipt, independently scored placement and home reset, continuous retained body identity/state, and no unsupported effect replay. Required result: 2/2 cycles and stale-evidence rejection in the disturbed cycle. + +## Guardrails + +One active job and exclusive bench writer; exact source, bench, job, generation and image identity; bounded motion/force/steps and action budget; historical measurement distinguished from current placement; unknown interrupted effects block new dispatch. Duplicate exact effect requests read history, conflicting IDs refuse. No implicit reset on restart or corruption. The independent scorer may inspect native state; the planner may not. + +## Decision rule + +Adopt only as an isolated experimental tool if the primary metric and guardrails hold. A recovery failure is retained and narrows the supported disturbance envelope. This qualification does not establish model-driven planning, arbitrary manipulation, hardware transfer, power-loss safety or production Footwork capability governance. diff --git a/jevdual/docs/notebook/2026-10-11-reusable-bench.md b/jevdual/docs/notebook/2026-10-11-reusable-bench.md new file mode 100644 index 0000000..9dcc293 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-11-reusable-bench.md @@ -0,0 +1,8 @@ +# Reusable simulated bench + +## SIM6-P1 · prediction · 2026-10-11 13:57 +Hypothesis: a persistent integration state and image-bound job transitions can support two prepare-measure-contact-reset cycles, including recovery after a bounded external-force disturbance, without recreating the block. +Test: implement an isolated bench and RGB host; run focused development checks, then freeze and independently exercise two successive jobs, stale evidence after disturbance, measurement readback and native reset scoring. +Predicts: one bench identity and increasing generations/native time span both cycles; each job has one measurement, physical contact reset, and the disturbed job rejects stale evidence before fresh observation guides recovery. +Against: stale evidence dispatches an effect, reset assigns body pose, job two begins before reset verification, the body is recreated, or disturbance recovery fails within the declared budget. +Refs: docs/experiments/SIM6-reusable-bench.md; tools/physical-workcell/; results/reusable-bench-20261011/ From 3cf268f0bc55be22cd769f4d13be0a4dc96bddc4 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 14:07:33 -0400 Subject: [PATCH 090/216] Register read-only guest asset transfer before ISO test --- jevdual/docs/notebook/2026-10-11-u2-vm-provision.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md index 8dd6c98..ec872be 100644 --- a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md +++ b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md @@ -19,3 +19,10 @@ Test: verify official release digest/signature/license and actual CLI help/sourc Predicts: CLI/source and runtime state confirm the supported disabled clipboard route and isolated storage, guest installation succeeds, and a real visible Setup Assistant is available before permission grants. Against: the flags are unsupported or still read host clipboard, Tart requires unapproved global paths or paid terms, installation fails, or Setup Assistant/host isolation cannot be established. Refs: output/u2-vm-provision-20261011/tart-release.json; output/u2-vm-provision-20261011/tart-run-pinned.swift; docs/experiments/U2-independent-onboarding.md + +## VM3 · prediction · 2026-10-11 14:07 +Hypothesis: hdiutil makehybrid can produce an ISO containing only the approved packet and downloaded prerequisite assets without attaching a host volume, and Tart's supported --disk path:ro route can expose that immutable image inside the pristine guest without host clipboard or directory sharing. +Test: stage exactly packetv3, Python3.14.7, uv0.12.5, ChromeDMG and their manifest/checksums, build an ISO under the approved SSD folder, verify its inventory/hash, and attach read-only on the first isolated Tart run; root later observes guest volume and verifies payload hashes. +Predicts: ISO creation does not require hostmount or global changes, contains the five declared source files plus checksum/provenance metadata, and Tart's CLI/source passes readOnly=true for the attachment. +Against: ISO creation fails like host DMG attach, unexpectedly includes other hostfiles, or the supported attachment cannot be made/readback as read-only inside the guest. +Refs: output/u2-vm-provision-20261011/tart-run-help.txt; output/u2-vm-provision-20261011/tart-run-pinned.swift; output/u2-vm-provision-20261011/prerequisite-provenance.json From 0091e5f832a3aef24ef73fdc9f1ee76bd64b7e46 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 14:09:35 -0400 Subject: [PATCH 091/216] Add persistent image-guided bench with measurement and contact reset --- .../notebook/2026-10-11-reusable-bench.md | 6 + tools/physical-workcell/BENCH.md | 63 +++ tools/physical-workcell/README.md | 4 + tools/physical-workcell/bench.py | 459 ++++++++++++++++++ tools/physical-workcell/bench_runner.py | 170 +++++++ tools/physical-workcell/measurement.py | 150 ++++++ tools/physical-workcell/qualify_bench.py | 169 +++++++ tools/physical-workcell/test_bench.py | 290 +++++++++++ 8 files changed, 1311 insertions(+) create mode 100644 tools/physical-workcell/BENCH.md create mode 100644 tools/physical-workcell/bench.py create mode 100644 tools/physical-workcell/bench_runner.py create mode 100644 tools/physical-workcell/measurement.py create mode 100644 tools/physical-workcell/qualify_bench.py create mode 100644 tools/physical-workcell/test_bench.py diff --git a/jevdual/docs/notebook/2026-10-11-reusable-bench.md b/jevdual/docs/notebook/2026-10-11-reusable-bench.md index 9dcc293..d63fab5 100644 --- a/jevdual/docs/notebook/2026-10-11-reusable-bench.md +++ b/jevdual/docs/notebook/2026-10-11-reusable-bench.md @@ -6,3 +6,9 @@ Test: implement an isolated bench and RGB host; run focused development checks, Predicts: one bench identity and increasing generations/native time span both cycles; each job has one measurement, physical contact reset, and the disturbed job rejects stale evidence before fresh observation guides recovery. Against: stale evidence dispatches an effect, reset assigns body pose, job two begins before reset verification, the body is recreated, or disturbance recovery fails within the declared budget. Refs: docs/experiments/SIM6-reusable-bench.md; tools/physical-workcell/; results/reusable-bench-20261011/ + +## SIM6-DEV-U1 · update · 2026-10-11 14:05 +Observed: the first source-stable development sequence completed two cycles on bench df2c545a1cee4405b9ce2bd3eedfc149. Generations advanced from 0 to 29 to 70. A native external-force intervention displaced the RGB block center by 0.1333 m; stale motion and measurement refused before fresh observations guided recovery. Both resets retained native contact evidence and both measurement results were independently persisted by separate processes. +Inferred: the axial RGB routing and contact reset mechanism work in this development fixture. This is not the frozen independent qualification and does not yet resolve SIM6-P1. +Next: complete retained measurement-integrity and reset evidence guards, run focused conformance, freeze source, then qualify a fresh two-job sequence with separate native/SQLite scoring. +Refs: tools/physical-workcell/output/sim6-root-dev1/ordinary-journal/; tools/physical-workcell/output/sim6-root-dev1/disturbed-journal/; tools/physical-workcell/output/sim6-root-dev1/ordinary.stdout.json; tools/physical-workcell/output/sim6-root-dev1/disturbed.stdout.json diff --git a/tools/physical-workcell/BENCH.md b/tools/physical-workcell/BENCH.md new file mode 100644 index 0000000..802ed18 --- /dev/null +++ b/tools/physical-workcell/BENCH.md @@ -0,0 +1,63 @@ +# A reusable simulated experiment bench + +Prepare the block in the measurement region, run an optical measurement on the computer, return the block and pusher home, then accept another job. The bench retains one identity and a single continuous native integration state across jobs. Job identity changes; body identity does not. + +This is an isolated Footwork experiment. It reuses the pinned MuJoCo model, native contact controller, PNG codec and color-specific RGB detector. It preserves the older single-order routes and uses a deterministic image-guided host. It makes no language-model calls and controls no hardware. + +## Run two jobs + +Use a new private directory below `tools/physical-workcell/output`. Run from the repository root with the existing pinned environment: + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/bench.py \ + --root tools/physical-workcell/output/my-bench/body init --diagnostic-enabled + +tools/physical-workcell/.venv/bin/python tools/physical-workcell/bench_runner.py \ + --bench-dir tools/physical-workcell/output/my-bench/body \ + --journal-dir tools/physical-workcell/output/my-bench/job-1 --job-id job-1 + +tools/physical-workcell/.venv/bin/python tools/physical-workcell/bench_runner.py \ + --bench-dir tools/physical-workcell/output/my-bench/body \ + --journal-dir tools/physical-workcell/output/my-bench/job-2 --job-id job-2 --disturb + +tools/physical-workcell/.venv/bin/python tools/physical-workcell/bench.py \ + --root tools/physical-workcell/output/my-bench/body status +``` + +Initialization only accepts an empty owned directory. It never clears an existing bench. Each job and journal needs a new identity. Omit `--diagnostic-enabled` and `--disturb` for ordinary use. The diagnostic flag authorizes a bounded simulated external force, separate from planner-controlled actuator motion. + +The host positions the orange block near x=0.07 m, clears the blue pusher, and calls the measurement worker. It then routes the pusher around the block at y=0.135 m, pushes the block back near x=-0.12 m, and parks the pusher at x=-0.30 m, y=0. Reset uses contact dynamics; it never assigns block position or resets native data. + +With `--disturb`, a simulated force moves the block after preparation. The host deliberately submits its old image for a move and a measurement. Both must refuse. It reads a new image, detects displacement, repositions the block, and resumes measurement and reset. Recovery supports one known block near y=0, reachable positions and recognizable silhouettes. Unsupported placements stop the host and retain the partial job. + +## The computer action + +`measurement.py` runs in a separate process. It reads the exact image bound to the job and computes the orange silhouette's pixel count, centroid and apparent footprint area using simulated camera calibration. It writes a SQLite row with bench ID, job ID, image and state digests, generation, native time and worker identity. The controller reads that row back independently and recomputes the image result before accepting it. + +The result is a simulated optical measurement. It is not a physical mass, volume, material-quality or calibrated instrument measurement. A future adapter could replace this worker with an instrument or measurement application while retaining preparation and verification. + +Read the retained results separately: + +```sh +sqlite3 -readonly tools/physical-workcell/output/my-bench/body/measurements.sqlite \ + 'SELECT job_id,generation,receipt_json FROM measurements ORDER BY job_id;' +``` + +## Control and evidence + +Jobs progress through `prepare`, `measured`, `resetting`, and `completed`. Only one job may be active. Another cannot start until the block and pusher home positions and retained reset-contact steps have been verified. Measurement history describes an earlier measurement; current placement requires a new observation. + +Each effect binds its operation ID to exact arguments. An identical repeat reads history; conflicting arguments refuse. Fresh effects require exact bench, job, phase, generation, state, image, calibration and source identity. Modified state, source, image or measurement evidence blocks further work. Interrupted dispatch stays unknown and blocks new effects; it is not automatically replayed or repaired. + +The bench holds an exclusive writer lock during actions and the measurement subprocess. Each command restores the same integration state and saves its successor. Simulation time pauses between commands; this is not a continuously running hardware controller. Physical verification and computer persistence are separate steps, not an atomic physical/software transaction. + +The host's `event-*.json` files retain observations, targets, action receipts, stale refusals, measurement reconciliation and reset. They contain no native pose guidance. Native state belongs to the separate qualification scorer. An unsuccessful run retains its partial journal and active or unknown job. Use a fresh diagnostic bench when testing changed source. + +## Qualification + +Preregistration: [SIM6](../../jevdual/docs/experiments/SIM6-reusable-bench.md). +Notebook: [reusable bench](../../jevdual/docs/notebook/2026-10-11-reusable-bench.md). + +`qualify_bench.py --output PRIVATE_OUTPUT --source-commit COMMIT` verifies that every measured source file matches the named Git commit. It runs ordinary and disturbed jobs in separate host processes on one bench. Separate read-only SQLite/native scoring checks historical measurement placement, contact reset, retained state continuity and receipt identity. All attempts and failed output are retained. See the [results](../../jevdual/results/reusable-bench-20261011/report.md) for the frozen run and limits. + +Local references: MuJoCo simulation/state documentation and integration-state APIs at commit `0696cdc85fc3741fdf71a97dec09467d19105e75` in `/Volumes/External SSD/referencerepos/mujoco`; LeRobot policy/client separation in `docs/source/async.mdx` at commit `b9cb121cb7d4e3e26ec5c906d08dda68d151ba52`. This loop uses MuJoCo directly and introduces no LeRobot dependency or network controller. diff --git a/tools/physical-workcell/README.md b/tools/physical-workcell/README.md index 4ed57f6..6369d85 100644 --- a/tools/physical-workcell/README.md +++ b/tools/physical-workcell/README.md @@ -27,6 +27,10 @@ physical staging before fulfillment, and saves the application result in SQLite. cancelling the order invalidates its old lease; the agent must call the guard to request cancellation of active motion. This remains a local simulated application experiment. +The [reusable bench](BENCH.md) keeps one simulated body across successive jobs: RGB-guided +preparation, a separately executed computer measurement, contact-driven reset, and recovery +from a bounded unexpected block displacement. + ## One work order The package uses pinned `mujoco==3.15.0` in its own ignored `.venv`. The existing Footwork diff --git a/tools/physical-workcell/bench.py b/tools/physical-workcell/bench.py new file mode 100644 index 0000000..97538f2 --- /dev/null +++ b/tools/physical-workcell/bench.py @@ -0,0 +1,459 @@ +"""Persistent image-guided MuJoCo bench: prepare, computer measurement, contact reset.""" +import argparse +import json +import os +import sqlite3 +import subprocess +import sys +import uuid +import xml.etree.ElementTree as ET +from pathlib import Path + +import image_guided as vision +import measurement +import mujoco +import numpy as np +import order_protocol as protocol +import workcell as body + +Refusal = body.Refusal +BASE = Path(__file__).resolve().parent +HOME_ZONE = {"x_min": -.16, "x_max": -.08, "y_min": -.03, "y_max": .03} +TARGET_BOUNDS = {"x_min": .02, "x_max": .12, "y_min": -.03, "y_max": .03} +MAX_MOVES_PER_JOB = 64 +OBSERVATION_FIELDS = {"version", "source_kind", "bench_id", "job_id", "phase", "generation", "native_time_s", + "state_sha256", "image_path", "image_sha256", "calibration", "source_fingerprints"} + + +def fingerprints(): + return {**body.fingerprints(), "bench_sha256": body.sha(body.read_bytes(BASE / "bench.py")), + "measurement_sha256": body.sha(body.read_bytes(BASE / "measurement.py")), + "vision_sha256": body.sha(body.read_bytes(BASE / "image_guided.py")), + "protocol_sha256": body.sha(body.read_bytes(BASE / "order_protocol.py")), + "capture_utility_sha256": body.sha(body.read_bytes(BASE.parent / "camera-capture-experiment" / "capture.py"))} + + +def in_zone(xy, zone): + return zone["x_min"] <= xy[0] <= zone["x_max"] and zone["y_min"] <= xy[1] <= zone["y_max"] + + +def validate_zone(zone): + protocol.validate_zone(zone) + if not (.02 <= zone["x_min"] < zone["x_max"] <= .12 and + -.03 <= zone["y_min"] < zone["y_max"] <= .03 and + zone["x_max"] - zone["x_min"] >= .04 and zone["y_max"] - zone["y_min"] >= .04): + raise Refusal("job zone exceeds the qualified reachable center region") + return dict(zone) + + +def initialize(root, diagnostic_enabled=False): + root = protocol.directory(root, create=True) + if type(diagnostic_enabled) is not bool: + raise Refusal("diagnostic flag must be boolean") + with protocol.locked(root): + if any(path.name != "app.lock" for path in root.iterdir()): + raise Refusal("bench initialization requires an empty owned directory") + source = fingerprints() + tree = ET.fromstring(body.read_bytes(body.SCENE)) + ET.SubElement(tree.find("worldbody"), "camera", {"name": "vision_top", "projection": "orthographic", + "fovy": "0.6", "pos": "0 0 1", "xyaxes": "1 0 0 0 1 0"}) + model_bytes = ET.tostring(tree, encoding="utf-8") + body.create_file(root / "model.xml", model_bytes) + for name in ("images", "operations", "requests", "jobs"): + (root / name).mkdir(mode=0o700) + model = mujoco.MjModel.from_xml_path(str(root / "model.xml")) + data = mujoco.MjData(model) + for _ in range(500): + mujoco.mj_step(model, data) + state_sha = body.save_state(root, model, data, 0) + manifest = {"version": 1, "source_kind": body.SOURCE_KIND, "bench_id": uuid.uuid4().hex, + "source_fingerprints": source, "model_sha256": body.sha(model_bytes), "generation": 0, + "state_sha256": state_sha, "native_time_s": float(data.time), "diagnostic_enabled": diagnostic_enabled, + "active_job": None, "jobs": {}, "operations": {}, "busy": None} + protocol.persist(root / "bench.json", manifest) + return Bench(root).status() + + +class Bench: + def __init__(self, root): + self.root = protocol.directory(root) + + def _load(self, allow_busy=False): + m = body.decoded(body.read_bytes(self.root / "bench.json")) + if (not isinstance(m, dict) or (type(m.get("version")) is not int or m["version"] != 1) or m.get("source_kind") != body.SOURCE_KIND or + m.get("source_fingerprints") != fingerprints() or type(m.get("generation")) is not int or + not 0 <= m["generation"] <= 999999): + raise Refusal("bench manifest or source fingerprint changed") + if body.sha(body.read_bytes(self.root / "model.xml")) != m["model_sha256"]: + raise Refusal("retained native model changed") + content = body.read_bytes(body.state_path(self.root, m["generation"])) + if body.sha(content) != m["state_sha256"]: + raise Refusal("retained native state changed; implicit reset is forbidden") + state = body.decoded(content) + body.fields(state, ("source_kind", "state_spec", "values"), "native state") + model = mujoco.MjModel.from_xml_path(str(self.root / "model.xml")) + spec = mujoco.mjtState.mjSTATE_INTEGRATION + if state["state_spec"] != int(spec) or state["source_kind"] != body.SOURCE_KIND: + raise Refusal("native state specification changed") + values = np.array([body.number(v) for v in state["values"]], dtype=float) + if len(values) != mujoco.mj_stateSize(model, spec): + raise Refusal("native state size changed") + data = mujoco.MjData(model) + mujoco.mj_setState(model, data, values, spec) + mujoco.mj_forward(model, data) + if data.time != m["native_time_s"]: + raise Refusal("retained native time changed") + if m["busy"] is not None and not allow_busy: + raise Refusal("interrupted effect is unknown; new dispatch is blocked") + if not allow_busy: + self._verify_measurements(m) + return m, model, data + + def _verify_measurements(self, m): + jobs = list(m["jobs"].values()) + ([m["active_job"]] if m["active_job"] else []) + for job in jobs: + if "measurement_receipt" in job: + recorded = measurement.read_result(self.root, job["measurement_operation_id"]) + if recorded != job["measurement_receipt"]: + raise Refusal("retained computer measurement changed") + packet_path = self.root / "requests" / (body.sha(job["measurement_operation_id"].encode()) + ".json") + packet = body.decoded(body.read_bytes(packet_path)) + if (packet["bench_id"] != m["bench_id"] or packet["job_id"] != job["job_id"] or + any(packet[k] != recorded[k] for k in ("generation", "state_sha256", "image_sha256"))): + raise Refusal("historical measurement packet binding changed") + image_path = Path(packet["image_path"]) + if image_path.parent != self.root / "images": + raise Refusal("historical measurement image is not bench-owned") + if body.sha(body.read_bytes(body.state_path(self.root, packet["generation"]))) != packet["state_sha256"]: + raise Refusal("historical measurement native state changed") + if measurement.compute(packet, body.read_bytes(image_path)) != recorded["measurement"]: + raise Refusal("historical optical measurement changed") + + def _persist(self, m): + protocol.persist(self.root / "bench.json", m) + + def _public(self, m): + return {k: m[k] for k in ("version", "source_kind", "bench_id", "generation", "native_time_s", + "source_fingerprints", "active_job", "jobs", "diagnostic_enabled")} | { + "state": "unknown" if m["busy"] else "ready", "unresolved_effect": m["busy"]} + + def status(self): + with protocol.locked(self.root): + m, _, _ = self._load(allow_busy=True) + public = self._public(m) + try: + self._verify_measurements(m) + except (Refusal, OSError, sqlite3.Error, KeyError, TypeError, ValueError) as exc: + public.update(state="unknown", unresolved_effect={"reason": str(exc), "kind": "measurement_integrity"}) + return public + + def start_job(self, job_id, target_zone): + protocol.identity(job_id) + zone = validate_zone(target_zone) + with protocol.locked(self.root): + m, _, _ = self._load() + if m["active_job"] is not None or job_id in m["jobs"]: + raise Refusal("one active job is allowed; job identity cannot be reused") + job = {"job_id": job_id, "target_zone": zone, "phase": "prepare", "moves": 0, + "started_generation": m["generation"], "started_native_time_s": m["native_time_s"]} + body.create_file(self.root / "jobs" / (body.sha(job_id.encode()) + ".json"), body.encoded(job)) + m["active_job"] = job + self._persist(m) + return self._public(m) + + def _observation(self, m, model, data): + job = m["active_job"] + zone = job["target_zone"] if job else HOME_ZONE + marker = model.geom("inspection_zone") + marker.pos[:2] = [(zone["x_min"] + zone["x_max"]) / 2, (zone["y_min"] + zone["y_max"]) / 2] + marker.size[:2] = [(zone["x_max"] - zone["x_min"]) / 2, (zone["y_max"] - zone["y_min"]) / 2] + mujoco.mj_forward(model, data) + try: + with mujoco.Renderer(model, height=360, width=640) as renderer: + renderer.update_scene(data, camera="vision_top") + content = body.png_bytes(renderer.render().copy()) + except Exception as exc: + raise Refusal("native RGB renderer unavailable; no image was fabricated") from exc + name = f"{m['generation']:06d}-{body.sha(body.encoded(job))[:16]}.png" + image_path = self.root / "images" / name + if image_path.exists() or image_path.is_symlink(): + if body.read_bytes(image_path) != content: + raise Refusal("retained observation image changed") + else: + body.create_file(image_path, content) + return {"version": 1, "source_kind": body.SOURCE_KIND, "bench_id": m["bench_id"], + "job_id": job["job_id"] if job else None, "phase": job["phase"] if job else "idle", + "generation": m["generation"], "native_time_s": m["native_time_s"], "state_sha256": m["state_sha256"], + "image_path": str(image_path), "image_sha256": body.sha(content), + "calibration": vision.calibration(), "source_fingerprints": m["source_fingerprints"]} + + def observe(self): + with protocol.locked(self.root): + return self._observation(*self._load()) + + def _fresh(self, observation, loaded): + body.fields(observation, OBSERVATION_FIELDS, "observation") + if type(observation["generation"]) is not int or type(observation["version"]) is not int: + raise Refusal("observation versions must be exact integers") + current = self._observation(*loaded) + if observation != current: + raise Refusal("observation is stale or foreign; no requested effect dispatched") + return current + + def _operation(self, m, operation_id, request): + protocol.identity(operation_id) + path = self.root / "operations" / (body.sha(operation_id.encode()) + ".json") + if operation_id in m["operations"]: + content = body.read_bytes(path) + if body.sha(content) != m["operations"][operation_id]: + raise Refusal("historical operation receipt changed") + record = body.decoded(content) + if record["request"] != request: + raise Refusal("operation identity conflicts with its retained request") + return record["receipt"] + if path.exists() or path.is_symlink(): + raise Refusal("unresolved operation record exists") + return None + + def _intent(self, m, operation_id, kind): + m["busy"] = {"operation_id": operation_id, "kind": kind, "generation": m["generation"]} + self._persist(m) + + def _finish(self, m, operation_id, request, receipt): + content = body.encoded({"request": request, "receipt": receipt}) + body.create_file(self.root / "operations" / (body.sha(operation_id.encode()) + ".json"), content) + m["operations"][operation_id] = body.sha(content) + m["busy"] = None + self._persist(m) + return receipt + + def _advance(self, m, model, data): + if m["generation"] >= 999999 or data.time <= m["native_time_s"]: + raise Refusal("native time/generation did not advance") + m["generation"] += 1 + m["state_sha256"] = body.save_state(self.root, model, data, m["generation"]) + m["native_time_s"] = float(data.time) + block = data.xpos[model.body("block").id] + if not (-.35 <= block[0] <= .35 and -.2 <= block[1] <= .2 and .02 <= block[2] <= .08): + self._persist(m) + raise Refusal("block left the bounded tabletop envelope; bench is unknown") + + def move(self, operation_id, observation, target_x, target_y): + x, y = body.number(target_x), body.number(target_y) + if not (-.32 <= x <= .18 and -.15 <= y <= .15): + raise Refusal("pusher target exceeds native bounds") + request = {"kind": "move", "observation": observation, "target_x": x, "target_y": y} + with protocol.locked(self.root): + loaded = self._load() + m, model, data = loaded + old = self._operation(m, operation_id, request) + if old is not None: + return old + self._fresh(observation, loaded) + job = m["active_job"] + if job is None or job["phase"] not in {"prepare", "resetting"} or job["moves"] >= MAX_MOVES_PER_JOB: + raise Refusal("job phase or motion budget does not allow motion") + self._intent(m, operation_id, "move") + native = body.motion(model, data, x, y) + self._advance(m, model, data) + job["moves"] += 1 + receipt = {"operation_id": operation_id, "kind": "move", "bench_id": m["bench_id"], + "job_id": job["job_id"], "generation": m["generation"], "native_time_s": m["native_time_s"], + "state_sha256": m["state_sha256"], "target_xy": [x, y], **native} + return self._finish(m, operation_id, request, receipt) + + def _placement(self, m, model, data, packet, zone): + _, located = measurement.image_and_location(body.read_bytes(Path(packet["image_path"]))) + image_center = vision.image_world_center(located["block"]["box"]) + block = data.xpos[model.body("block").id] + if not in_zone(image_center, zone) or not in_zone(block[:2], zone) or not .02 <= block[2] <= .08: + raise Refusal("fresh image and native placement do not satisfy the job region") + + def measure(self, operation_id, observation): + request = {"kind": "measure", "observation": observation} + with protocol.locked(self.root): + loaded = self._load() + m, model, data = loaded + old = self._operation(m, operation_id, request) + if old is not None: + retained = measurement.read_result(self.root, operation_id) + if retained != old["measurement_receipt"]: + raise Refusal("historical computer measurement changed") + return old + packet = self._fresh(observation, loaded) + job = m["active_job"] + if job is None or job["phase"] != "prepare": + raise Refusal("measurement requires an active preparation phase") + self._placement(m, model, data, packet, job["target_zone"]) + self._intent(m, operation_id, "measure") + path = self.root / "requests" / (body.sha(operation_id.encode()) + ".json") + content = body.encoded(packet) + body.create_file(path, content) + result = subprocess.run([sys.executable, str(BASE / "measurement.py"), "--root", str(self.root), + "--operation-id", operation_id, "--packet-file", str(path), + "--packet-sha256", body.sha(content)], capture_output=True, timeout=30, check=False) + body.create_file(self.root / "requests" / (body.sha(operation_id.encode()) + ".worker.json"), + body.encoded({"returncode": result.returncode, "stdout": result.stdout.decode(), + "stderr": result.stderr.decode()})) + if result.returncode != 0: + raise Refusal("computer measurement worker failed; dispatch outcome is unknown") + recorded = measurement.read_result(self.root, operation_id) + expected = {"operation_id": operation_id, "bench_id": m["bench_id"], "job_id": job["job_id"], + "generation": m["generation"], "image_sha256": packet["image_sha256"], + "state_sha256": m["state_sha256"]} + if any(recorded.get(k) != value for k, value in expected.items()) or recorded["worker_pid"] == os.getpid(): + raise Refusal("independent measurement readback does not match the dispatched job") + recomputed = measurement.compute(packet, body.read_bytes(Path(packet["image_path"]))) + if recorded["measurement"] != recomputed: + raise Refusal("independent image measurement recomputation disagrees") + job.update(phase="measured", measurement_operation_id=operation_id, measurement_receipt=recorded) + receipt = {"operation_id": operation_id, "kind": "measure", **expected, "measurement_receipt": recorded} + return self._finish(m, operation_id, request, receipt) + + def begin_reset(self, job_id): + protocol.identity(job_id) + with protocol.locked(self.root): + m, _, _ = self._load() + job = m["active_job"] + if job is None or job["job_id"] != job_id or job["phase"] not in {"measured", "resetting"}: + raise Refusal("reset requires the exact measured active job") + if job["phase"] == "measured": + job["reset_started_generation"] = m["generation"] + job["phase"] = "resetting" + self._persist(m) + return self._public(m) + + def finish_reset(self, operation_id, observation): + request = {"kind": "finish_reset", "observation": observation} + with protocol.locked(self.root): + loaded = self._load() + m, model, data = loaded + old = self._operation(m, operation_id, request) + if old is not None: + return old + packet = self._fresh(observation, loaded) + job = m["active_job"] + if job is None or job["phase"] != "resetting": + raise Refusal("reset completion requires the resetting phase") + self._placement(m, model, data, packet, HOME_ZONE) + pusher = data.xpos[model.body("pusher").id] + _, located = measurement.image_and_location(body.read_bytes(Path(packet["image_path"]))) + image_pusher = vision.image_world_center(located["pusher"]["box"]) + if (abs(pusher[0] + .3) > .005 or abs(pusher[1]) > .005 or + abs(image_pusher[0] + .3) > .005 or abs(image_pusher[1]) > .005): + raise Refusal("fresh image and native pusher must verify its home position") + reset_native_steps, reset_contacts = 0, 0 + for token, digest in m["operations"].items(): + content = body.read_bytes(self.root / "operations" / (body.sha(token.encode()) + ".json")) + if body.sha(content) != digest: + raise Refusal("reset operation history changed") + record = body.decoded(content) + receipt = record["receipt"] + if (receipt.get("kind") == "move" and receipt.get("job_id") == job["job_id"] and + record["request"]["observation"]["phase"] == "resetting" and + receipt["generation"] > job["reset_started_generation"]): + reset_native_steps += receipt["native_steps"] + reset_contacts += receipt["pusher_block_contact_samples"] + if reset_native_steps <= 0 or reset_contacts <= 0: + raise Refusal("reset requires retained native contact-motion evidence") + self._intent(m, operation_id, "finish_reset") + receipt = {"operation_id": operation_id, "kind": "finish_reset", "bench_id": m["bench_id"], + "job_id": job["job_id"], "generation": m["generation"], "native_time_s": m["native_time_s"], + "state_sha256": m["state_sha256"], "image_sha256": packet["image_sha256"], + "block_home_verified": True, "pusher_home_verified": True, + "reset_native_steps": reset_native_steps, "reset_contact_samples": reset_contacts} + job.update(phase="completed", reset_receipt=receipt, completed_generation=m["generation"], + completed_native_time_s=m["native_time_s"]) + m["jobs"][job["job_id"]] = job + m["active_job"] = None + return self._finish(m, operation_id, request, receipt) + + def disturb(self, operation_id, force_x_n, steps): + force = body.number(force_x_n) + if not 0 < abs(force) <= 2 or type(steps) is not int or not 1 <= steps <= 150: + raise Refusal("diagnostic force or native step budget exceeds bounds") + request = {"kind": "disturb", "force_x_n": force, "steps": steps} + with protocol.locked(self.root): + m, model, data = self._load() + old = self._operation(m, operation_id, request) + if old is not None: + return old + if not m["diagnostic_enabled"] or m["active_job"] is None or m["active_job"]["phase"] != "prepare": + raise Refusal("diagnostic intervention requires explicit enabled preparation") + self._intent(m, operation_id, "disturb") + body_id = model.body("block").id + for _ in range(steps): + data.xfrc_applied[body_id, 0] = force + mujoco.mj_step(model, data) + data.xfrc_applied[body_id, :] = 0 + for _ in range(500): + mujoco.mj_step(model, data) + mujoco.mj_forward(model, data) + self._advance(m, model, data) + receipt = {"operation_id": operation_id, "kind": "diagnostic_external_force", "bench_id": m["bench_id"], + "job_id": m["active_job"]["job_id"], "generation": m["generation"], + "native_time_s": m["native_time_s"], "state_sha256": m["state_sha256"], + "force_x_n": force, "forced_steps": steps, "native_steps": steps + 500} + return self._finish(m, operation_id, request, receipt) + + +def read_packet(path, expected_sha256): + content = body.read_bytes(Path(path)) + if not body.DIGEST.fullmatch(expected_sha256) or body.sha(content) != expected_sha256: + raise Refusal("observation file digest changed") + return body.decoded(content) + + +def main(argv=None): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", required=True, type=Path) + sub = parser.add_subparsers(dest="command", required=True) + init = sub.add_parser("init") + init.add_argument("--diagnostic-enabled", action="store_true") + for name in ("status", "observe"): + sub.add_parser(name) + start = sub.add_parser("start") + start.add_argument("--job-id", required=True) + start.add_argument("--target-zone", required=True, help="JSON object with x_min/x_max/y_min/y_max") + reset = sub.add_parser("begin-reset") + reset.add_argument("--job-id", required=True) + for name in ("move", "measure", "finish-reset"): + command = sub.add_parser(name) + command.add_argument("--operation-id", required=True) + command.add_argument("--observation-file", required=True, type=Path) + command.add_argument("--observation-sha256", required=True) + if name == "move": + command.add_argument("--target-x", required=True, type=float) + command.add_argument("--target-y", required=True, type=float) + disturb = sub.add_parser("disturb") + disturb.add_argument("--operation-id", required=True) + disturb.add_argument("--force-x-n", required=True, type=float) + disturb.add_argument("--steps", required=True, type=int) + args = parser.parse_args(argv) + try: + if args.command == "init": + result = initialize(args.root, args.diagnostic_enabled) + else: + bench = Bench(args.root) + if args.command in {"status", "observe"}: + result = getattr(bench, args.command)() + elif args.command == "start": + result = bench.start_job(args.job_id, body.decoded(args.target_zone.encode())) + elif args.command == "begin-reset": + result = bench.begin_reset(args.job_id) + elif args.command == "disturb": + result = bench.disturb(args.operation_id, args.force_x_n, args.steps) + else: + observation = read_packet(args.observation_file, args.observation_sha256) + method = getattr(bench, args.command.replace("-", "_")) + extra = (args.target_x, args.target_y) if args.command == "move" else () + result = method(args.operation_id, observation, *extra) + print(json.dumps(result, sort_keys=True, allow_nan=False)) + return 0 + except (Refusal, OSError, ValueError, KeyError, TypeError, sqlite3.Error, subprocess.TimeoutExpired) as exc: + print(json.dumps({"state": "refused", "reason": str(exc)})) + return 2 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/physical-workcell/bench_runner.py b/tools/physical-workcell/bench_runner.py new file mode 100644 index 0000000..a06558d --- /dev/null +++ b/tools/physical-workcell/bench_runner.py @@ -0,0 +1,170 @@ +"""Inspectable RGB-only host for successive simulated bench experiments. + +This is a deterministic diagnostic policy, not a language-model robotics trial. +All guidance comes from exact public PNGs; private native state belongs to scoring. +""" + +import argparse +import importlib.util +import math +from pathlib import Path + +BASE = Path(__file__).resolve().parent +SPEC = importlib.util.spec_from_file_location("persistent_bench", BASE / "bench.py") +bench = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(bench) +body, vision = bench.body, bench.vision +ZONE = {"x_min": .035, "x_max": .105, "y_min": -.025, "y_max": .025} +HOME_X = -.12 +MAX_ACTIONS = 64 + + +class RGBHost: + def __init__(self, root, journal): + self.root = body.directory(root) + self.journal = body.directory(journal, create=True) + self.events = [] + self.sequence = 0 + self.job_id = None + + def api(self): + # Each call reloads the same retained body; never initializes an episode. + return bench.Bench(self.root) + + def record(self, kind, **fields): + event = {"index": len(self.events), "kind": kind, **fields} + body.create_file(self.journal / f"event-{len(self.events):04d}.json", body.encoded(event)) + self.events.append(event) + return event + + def observe(self): + packet = self.api().observe() + content = body.read_bytes(Path(packet["image_path"])) + if body.sha(content) != packet["image_sha256"]: + raise body.Refusal("public image bytes changed") + located = vision.locate(vision.decode_png(content)) + block = vision.image_world_center(located["block"]["box"]) + pusher = vision.image_world_center(located["pusher"]["box"]) + self.record("rgb_observation", packet=packet, rgb_block_xy=block, rgb_pusher_xy=pusher) + return packet, block, pusher + + def move(self, packet, pusher, target, purpose): + delta = [target[i] - pusher[i] for i in (0, 1)] + distance = math.hypot(*delta) + if distance > .11: + target = [pusher[i] + delta[i] * .11 / distance for i in (0, 1)] + self.sequence += 1 + if self.sequence > MAX_ACTIONS: + raise body.Refusal("RGB host motion budget exhausted") + operation = f"{self.job_id}-motion-{self.sequence:03d}" + receipt = self.api().move(operation, packet, *target) + self.record("motion", purpose=purpose, target_xy=target, receipt=receipt) + return receipt + + def position(self, center_x, purpose): + for _ in range(MAX_ACTIONS): + packet, block, pusher = self.observe() + if abs(block[1]) > .018: + raise body.Refusal("RGB block is outside the supported axial recovery corridor") + if abs(block[0] - center_x) <= .012: + return packet + direction = 1 if center_x > block[0] else -1 + side = block[0] - direction * .065 + wrong_side = direction * (block[0] - pusher[0]) < .050 + if wrong_side: + target = [pusher[0], .135] if pusher[1] < .125 else [side, .135] + elif abs(pusher[1]) > .006: + # Stay clear of the cube before descending from the bypass lane. + target = [side, pusher[1]] if abs(pusher[0] - side) > .010 else [pusher[0], 0] + else: + gap = max(0, direction * (block[0] - pusher[0]) - .055) + advance = min(.09, abs(center_x - block[0]) + gap) + target = [pusher[0] + direction * advance, 0] + if not -.32 <= target[0] <= .18: + raise body.Refusal("RGB recovery requires a pusher target outside the workspace") + self.move(packet, pusher, target, purpose) + raise body.Refusal("RGB placement did not converge") + + def park(self, purpose): + for _ in range(MAX_ACTIONS): + packet, block, pusher = self.observe() + if abs(pusher[0] + .3) <= .004 and abs(pusher[1]) <= .004: + return packet + if pusher[0] > block[0] - .065 and pusher[1] < .125: + target = [pusher[0], .135] + elif pusher[0] > -.29: + target = [-.3, pusher[1]] + else: + target = [-.3, 0] + self.move(packet, pusher, target, purpose) + raise body.Refusal("RGB pusher parking did not converge") + + def run_job(self, job_id, *, disturbance=False): + self.job_id, self.sequence = job_id, 0 + started = self.api().start_job(job_id, ZONE) + self.record("job_started", status=started) + self.position(.07, "prepare") + packet = self.park("clear_measurement_area") + recovery = None + if disturbance: + changed = self.api().disturb(f"{job_id}-external-force", -1.5, 80) + self.record("diagnostic_external_force", receipt=changed) + refused = [] + for command in ("move", "measure"): + before = self.api().status() + try: + if command == "move": + self.api().move(f"{job_id}-stale-motion", packet, -.28, 0) + else: + self.api().measure(f"{job_id}-stale-measurement", packet) + except body.Refusal as exc: + after = self.api().status() + if before != after: + raise AssertionError("stale refusal changed durable public state") from exc + refused.append(command) + self.record("stale_effect_refused", command=command, reason=str(exc)) + else: + raise AssertionError(f"stale {command} was accepted") + fresh, changed_block, _ = self.observe() + previous = vision.image_world_center(vision.locate(vision.decode_png( + body.read_bytes(Path(packet["image_path"]))))["block"]["box"]) + displacement = abs(changed_block[0] - previous[0]) + if displacement < .02: + raise AssertionError("diagnostic force did not create a meaningful observed displacement") + recovery = {"stale_refused": refused, "rgb_displacement_m": displacement, + "before_generation": packet["generation"], "after_generation": fresh["generation"]} + self.position(.07, "recover_unexpected_displacement") + packet = self.park("clear_recovered_measurement_area") + measurement = self.api().measure(f"{job_id}-measurement", packet) + self.record("computer_measurement", receipt=measurement) + repeat = self.api().measure(f"{job_id}-measurement", packet) + if repeat != measurement: + raise AssertionError("measurement repeat differs from exact historical receipt") + self.record("measurement_reply_reconciled", receipt=repeat) + self.record("reset_started", status=self.api().begin_reset(job_id)) + self.position(HOME_X, "contact_reset") + packet = self.park("return_pusher_home") + finished = self.api().finish_reset(f"{job_id}-reset", packet) + self.record("reset_verified", receipt=finished) + return {"job_id": job_id, "measurement": measurement, "reset": finished, + "recovery": recovery, "motion_count": self.sequence} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--bench-dir", required=True) + parser.add_argument("--journal-dir", required=True) + parser.add_argument("--job-id", required=True) + parser.add_argument("--disturb", action="store_true") + args = parser.parse_args() + host = RGBHost(Path(args.bench_dir), Path(args.journal_dir)) + try: + result = host.run_job(args.job_id, disturbance=args.disturb) + except Exception as exc: + host.record("attempt_failed", error_type=type(exc).__name__, error=str(exc)) + raise + print(body.encoded(result).decode(), end="") + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/measurement.py b/tools/physical-workcell/measurement.py new file mode 100644 index 0000000..2b94f68 --- /dev/null +++ b/tools/physical-workcell/measurement.py @@ -0,0 +1,150 @@ +"""Computer-side optical measurement worker; exact image in, durable SQLite row out.""" +import argparse +import json +import os +import sqlite3 +import stat +import sys +from pathlib import Path + +import image_guided as vision +import order_protocol as protocol +import workcell as body + +SCHEMA = """CREATE TABLE IF NOT EXISTS measurements ( + operation_id TEXT PRIMARY KEY, job_id TEXT UNIQUE NOT NULL, bench_id TEXT NOT NULL, + generation INTEGER NOT NULL, image_sha256 TEXT NOT NULL, state_sha256 TEXT NOT NULL, + receipt_json TEXT NOT NULL)""" + + +def image_and_location(content): + try: + image = vision.decode_png(content) + return image, vision.locate(image) + except vision.Refusal as exc: + raise body.Refusal("RGB evidence is malformed or its required silhouettes are unavailable") from exc + + +def compute(packet, content): + if body.sha(content) != packet["image_sha256"]: + raise body.Refusal("measurement image digest changed") + image, detected = image_and_location(content) + located = detected["block"] + red, green, blue = image.astype(float).transpose(2, 0, 1) + mask = (red >= 80) & (red >= 1.3 * green) & (green >= 1.35 * blue) + yy, xx = mask.nonzero() + if len(xx) == 0: + raise body.Refusal("orange measurement silhouette unavailable") + return {"method": "simulated_orange_RGB_footprint", "orange_pixel_count": len(xx), + "centroid_pixel_xy": [float(xx.mean()), float(yy.mean())], + "block_box": located["box"], "block_center_xy": vision.image_world_center(located["box"]), + "footprint_area_m2": float(len(xx) * packet["calibration"]["meters_per_pixel"] ** 2)} + + +def read_result(root, operation_id): + path = protocol.directory(root) / "measurements.sqlite" + try: + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK) + with os.fdopen(fd, "rb") as source: + info = os.fstat(source.fileno()) + if not stat.S_ISREG(info.st_mode) or info.st_uid != os.getuid() or info.st_mode & 0o077: + raise body.Refusal("measurement database must be an owned private regular file") + except OSError as exc: + raise body.Refusal("measurement database is missing or symlinked") from exc + with sqlite3.connect(path.as_uri() + "?mode=ro", uri=True) as connection: + row = connection.execute("SELECT operation_id,job_id,bench_id,generation,image_sha256,state_sha256,receipt_json FROM measurements WHERE operation_id=?", (operation_id,)).fetchone() + if row is None: + raise body.Refusal("computer measurement has no durable receipt") + result = body.decoded(row[6].encode()) + keys = ("operation_id", "job_id", "bench_id", "generation", "image_sha256", "state_sha256") + if tuple(result.get(k) for k in keys) != row[:6]: + raise body.Refusal("measurement database columns disagree with the durable receipt") + body.fields(result, ("version", "source_kind", "operation_id", "bench_id", "job_id", "generation", + "native_time_s", "image_sha256", "state_sha256", "worker_pid", "measurement"), "measurement receipt") + if (type(result["version"]) is not int or result["version"] != 1 or result["source_kind"] != body.SOURCE_KIND or + type(result["generation"]) is not int or result["generation"] < 0 or + type(result["worker_pid"]) is not int or result["worker_pid"] <= 0): + raise body.Refusal("measurement receipt has invalid types") + for key in ("operation_id", "bench_id", "job_id"): + protocol.identity(result[key]) + for key in ("image_sha256", "state_sha256"): + if not isinstance(result[key], str) or not body.DIGEST.fullmatch(result[key]): + raise body.Refusal("measurement receipt digest is invalid") + body.number(result["native_time_s"]) + measured = result["measurement"] + body.fields(measured, ("method", "orange_pixel_count", "centroid_pixel_xy", "block_box", "block_center_xy", + "footprint_area_m2"), "optical measurement") + if (measured["method"] != "simulated_orange_RGB_footprint" or type(measured["orange_pixel_count"]) is not int or + not 0 < measured["orange_pixel_count"] <= 640 * 360): + raise body.Refusal("optical measurement count or method is invalid") + for key in ("centroid_pixel_xy", "block_center_xy"): + if not isinstance(measured[key], list) or len(measured[key]) != 2: + raise body.Refusal("measurement center schema is invalid") + for value in measured[key]: + body.number(value) + if (not isinstance(measured["block_box"], list) or len(measured["block_box"]) != 4 or + any(type(v) is not int for v in measured["block_box"]) or + body.number(measured["footprint_area_m2"]) <= 0): + raise body.Refusal("measurement footprint schema is invalid") + return result + + +def run(root, operation_id, packet_file, packet_sha256): + root = protocol.directory(root) + protocol.identity(operation_id) + packet_file = Path(packet_file) + if packet_file.parent != root / "requests": + raise body.Refusal("measurement request must be bench-owned") + packet_bytes = body.read_bytes(packet_file) + if body.sha(packet_bytes) != packet_sha256: + raise body.Refusal("measurement packet digest changed") + packet = body.decoded(packet_bytes) + manifest = body.decoded(body.read_bytes(root / "bench.json")) + busy = manifest.get("busy") + if (not isinstance(busy, dict) or busy.get("operation_id") != operation_id or busy.get("kind") != "measure" or + manifest["bench_id"] != packet["bench_id"] or manifest["generation"] != packet["generation"] or + manifest["state_sha256"] != packet["state_sha256"] or manifest["active_job"]["job_id"] != packet["job_id"]): + raise body.Refusal("measurement does not match the retained dispatch intent") + image_path = Path(packet["image_path"]) + if image_path.parent != root / "images": + raise body.Refusal("measurement image must be bench-owned") + result = {"version": 1, "source_kind": body.SOURCE_KIND, "operation_id": operation_id, "bench_id": packet["bench_id"], + "job_id": packet["job_id"], "generation": packet["generation"], + "native_time_s": packet["native_time_s"], "image_sha256": packet["image_sha256"], + "state_sha256": packet["state_sha256"], "worker_pid": os.getpid(), + "measurement": compute(packet, body.read_bytes(image_path))} + path = root / "measurements.sqlite" + if path.is_symlink(): + raise body.Refusal("measurement database cannot be a symlink") + with sqlite3.connect(path) as connection: + connection.execute(SCHEMA) + previous = connection.execute("SELECT receipt_json FROM measurements WHERE operation_id=?", (operation_id,)).fetchone() + if previous: + old = body.decoded(previous[0].encode()) + if any(old[k] != result[k] for k in ("bench_id", "job_id", "generation", "image_sha256", "state_sha256")): + raise body.Refusal("measurement operation identity conflicts") + return old + connection.execute("INSERT INTO measurements VALUES (?,?,?,?,?,?,?)", ( + operation_id, result["job_id"], result["bench_id"], result["generation"], result["image_sha256"], + result["state_sha256"], body.encoded(result).decode())) + path.chmod(0o600) + return result + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", required=True, type=Path) + parser.add_argument("--operation-id", required=True) + parser.add_argument("--packet-file", required=True, type=Path) + parser.add_argument("--packet-sha256", required=True) + args = parser.parse_args() + try: + print(json.dumps(run(args.root, args.operation_id, args.packet_file, args.packet_sha256), sort_keys=True)) + return 0 + except (body.Refusal, OSError, sqlite3.Error, KeyError, ValueError) as exc: + print(json.dumps({"state": "refused", "reason": str(exc)})) + return 2 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/physical-workcell/qualify_bench.py b/tools/physical-workcell/qualify_bench.py new file mode 100644 index 0000000..702d2db --- /dev/null +++ b/tools/physical-workcell/qualify_bench.py @@ -0,0 +1,169 @@ +"""Frozen SIM6 public-interface trial with separate native/SQLite scoring.""" + +import argparse +import hashlib +import json +import os +import sqlite3 +import subprocess +import time +import traceback +from pathlib import Path + +import bench +import workcell as body + +BASE = Path(__file__).resolve().parent +REPO = BASE.parents[1] +SOURCES = [BASE / name for name in ( + "bench.py", "measurement.py", "bench_runner.py", "qualify_bench.py", "workcell.py", + "image_guided.py", "episode_cases.py", "order_protocol.py", "scene.xml")] +SOURCES.append(BASE.parent / "camera-capture-experiment" / "capture.py") + + +def retain(path, value): + body.create_file(path, body.encoded(value)) + + +def source_snapshot(commit): + if subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=REPO, text=True).strip() != commit: + raise AssertionError("qualification must start at the named source commit") + snapshot = {} + for path in SOURCES: + relative = str(path.relative_to(REPO)) + frozen = subprocess.check_output(["git", "show", f"{commit}:{relative}"], cwd=REPO) + current = body.read_bytes(path) + if frozen != current: + raise AssertionError(f"source differs from named freeze: {relative}") + snapshot[relative] = hashlib.sha256(current).hexdigest() + return snapshot + + +def native_score(root, generation, state_sha256, zone): + # Separate scorer only: never imported or invoked by the RGB host. + content = body.read_bytes(body.state_path(root, generation)) + if body.sha(content) != state_sha256: + raise AssertionError("scored state digest differs from receipt") + state = body.decoded(content) + model = body.mujoco.MjModel.from_xml_path(str(root / "model.xml")) + data = body.mujoco.MjData(model) + body.mujoco.mj_setState(model, data, body.np.asarray(state["values"]), body.mujoco.mjtState.mjSTATE_INTEGRATION) + body.mujoco.mj_forward(model, data) + block = data.xpos[model.body("block").id].tolist() + pusher = data.xpos[model.body("pusher").id].tolist() + return {"role": "independent_native_state_scorer", "generation": generation, + "state_sha256": state_sha256, "native_time_s": float(data.time), "block_xyz": block, + "pusher_xyz": pusher, "block_center_in_zone": bool( + zone["x_min"] <= block[0] <= zone["x_max"] and + zone["y_min"] <= block[1] <= zone["y_max"] and .02 <= block[2] <= .08), + "pusher_home": abs(pusher[0] + .3) <= .005 and abs(pusher[1]) <= .005, + "external_force_cleared": bool(not body.np.any(data.xfrc_applied))} + + +def sqlite_score(root): + with sqlite3.connect((root / "measurements.sqlite").as_uri() + "?mode=ro", uri=True) as connection: + connection.row_factory = sqlite3.Row + rows = [dict(row) for row in connection.execute("SELECT * FROM measurements ORDER BY job_id")] + for row in rows: + row["receipt"] = json.loads(row.pop("receipt_json")) + return {"role": "independent_read_only_sqlite_scorer", "count": len(rows), "rows": rows} + + +def score_job(root, journal, result, expected_count, expected_bench_id): + measurement = result["measurement"]["measurement_receipt"] + reset = result["reset"] + stage = native_score(root, measurement["generation"], measurement["state_sha256"], + {"x_min": .035, "x_max": .105, "y_min": -.025, "y_max": .025}) + home = native_score(root, reset["generation"], reset["state_sha256"], bench.HOME_ZONE) + database = sqlite_score(root) + row = next(row for row in database["rows"] if row["job_id"] == result["job_id"]) + assert row["receipt"] == measurement and database["count"] == expected_count + assert stage["block_center_in_zone"] and home["block_center_in_zone"] and home["pusher_home"] + assert stage["external_force_cleared"] and home["external_force_cleared"] + assert measurement["bench_id"] == reset["bench_id"] == expected_bench_id + assert home["native_time_s"] > stage["native_time_s"] + events = [body.decoded(body.read_bytes(path)) for path in sorted(journal.glob("event-*.json"))] + motions = [event for event in events if event["kind"] == "motion"] + contact_reset = [event for event in motions if event["purpose"] == "contact_reset"] + contact_samples = sum(event["receipt"]["pusher_block_contact_samples"] for event in contact_reset) + assert contact_samples > 0 + steps = sum(event["receipt"]["native_steps"] for event in motions) + assert steps > 0 and all(event["receipt"]["max_axis_actuator_force_n"] <= 4.00000001 for event in motions) + assert measurement["worker_pid"] != os.getpid() + if result["recovery"]: + assert result["recovery"]["stale_refused"] == ["move", "measure"] + assert result["recovery"]["rgb_displacement_m"] >= .02 + recovery_moves = [event for event in motions if event["purpose"] == "recover_unexpected_displacement"] + assert recovery_moves and sum(e["receipt"]["pusher_block_contact_samples"] for e in recovery_moves) > 0 + observations = [event["packet"] for event in events if event["kind"] == "rgb_observation"] + private_keys = {"block_xyz", "pusher_xyz", "qpos", "qvel", "native_pose"} + assert all(not private_keys.intersection(packet) for packet in observations) + return {"job_id": result["job_id"], "measurement_state": stage, "reset_state": home, + "sqlite": database, "motion_count": len(motions), "native_motion_steps": steps, + "reset_contact_samples": contact_samples, "recovery": result["recovery"], + "planner_role": "frozen_deterministic_color_RGB_host", "passed": True} + + +def run(root, commit): + source = source_snapshot(commit) + root = body.directory(root, create=True) + retain(root / "source-freeze.json", {"commit": commit, "files": source}) + bench_root = root / "bench" + initialized = bench.initialize(bench_root, diagnostic_enabled=True) + retain(root / "initialized.json", initialized) + scores, attempts = [], [] + try: + for index, name in enumerate(("ordinary", "disturbed"), 1): + journal = root / (name + "-journal") + command = [str(BASE / ".venv/bin/python"), str(BASE / "bench_runner.py"), + "--bench-dir", str(bench_root), "--journal-dir", str(journal), "--job-id", name] + if name == "disturbed": + command.append("--disturb") + before = bench.Bench(bench_root).status() + started = time.monotonic() + process = subprocess.run(command, capture_output=True, timeout=240, check=False) + body.create_file(root / (name + ".stdout.json"), process.stdout) + body.create_file(root / (name + ".stderr.log"), process.stderr) + attempt = {"job_id": name, "attempt": 1, "returncode": process.returncode, + "elapsed_s": time.monotonic() - started, "before": before, + "all_caller_and_worker_processes_synchronous": True} + attempts.append(attempt) + retain(root / (name + "-attempt.json"), attempt) + if process.returncode != 0: + raise AssertionError(f"{name} failed; original stderr/stdout and partial journal retained") + result = body.decoded(process.stdout) + after = bench.Bench(bench_root).status() + assert after["bench_id"] == initialized["bench_id"] and after["active_job"] is None + assert after["generation"] > before["generation"] and after["native_time_s"] > before["native_time_s"] + current_job = after["jobs"][name] + assert current_job["started_generation"] == before["generation"] + assert current_job["started_native_time_s"] == before["native_time_s"] + score = score_job(bench_root, journal, result, index, initialized["bench_id"]) + score["continuity"] = {"before": before, "after": after} + scores.append(score) + retain(root / (name + "-score.json"), score) + unchanged = source_snapshot(commit) == source + assert unchanged + summary = {"version": 1, "source_commit": commit, "source_unchanged": unchanged, + "bench_id": initialized["bench_id"], "successful_cycles": len(scores), "required_cycles": 2, + "attempts": attempts, "scores": scores, "passed": True, + "limits": "deterministic RGB policy; axial force disturbance; simulation; no hardware or model trial"} + except Exception as exc: + summary = {"version": 1, "source_commit": commit, "passed": False, "attempts": attempts, + "scores": scores, "error": str(exc), "traceback": traceback.format_exc()} + retain(root / "qualification.json", summary) + raise + retain(root / "qualification.json", summary) + return {key: summary[key] for key in ("passed", "source_commit", "bench_id", "successful_cycles", "source_unchanged")} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--output", required=True, type=Path) + parser.add_argument("--source-commit", required=True) + args = parser.parse_args() + print(json.dumps(run(args.output, args.source_commit), sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/test_bench.py b/tools/physical-workcell/test_bench.py new file mode 100644 index 0000000..26ac33d --- /dev/null +++ b/tools/physical-workcell/test_bench.py @@ -0,0 +1,290 @@ +"""SIM6 focused development conformance with actual native state and SQLite. + +These gates are separate from the frozen public-interface qualification. Each +test retains its own private inputs and outcome beneath physical-workcell/output. +""" + +import copy +import importlib.util +import json +import os +import sqlite3 +import unittest +import uuid +from pathlib import Path + +BASE = Path(__file__).resolve().parent +ZONE = {"x_min": .04, "x_max": .10, "y_min": -.025, "y_max": .025} + + +def load_backend(): + spec = importlib.util.spec_from_file_location("sim6_conformance_bench", BASE / "bench.py") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +class BenchBehaviorTests(unittest.TestCase): + def setUp(self): + self.backend = load_backend() + self.work = BASE / "output" / ("b6test-" + uuid.uuid4().hex[:10]) + self.work.mkdir(mode=0o700) + self.root = self.work / "bench" + self.events = [] + + def tearDown(self): + result = self._outcome.result + failed = any(test is self for test, _ in (*result.failures, *result.errors)) + content = (json.dumps({"test_id": self.id(), "passed": not failed, + "scenario_kind": "actual_native_sqlite_conformance", + "events": self.events}, sort_keys=True, indent=2) + "\n").encode() + path = self.work / "conformance.json" + with path.open("xb") as handle: + os.chmod(path, 0o600) + handle.write(content) + + def event(self, label, value): + self.events.append({"kind": label, "value": value}) + return value + + def snapshot(self): + """Evidence around refusals; SQLite readback uses its own connection.""" + return {str(path.relative_to(self.root)): path.read_bytes() + for path in self.root.rglob("*") if path.is_file() and path.suffix != ".lock" + and path.parent.name != "images"} + + def sqlite_rows(self, query): + path = self.root / "measurements.sqlite" + with sqlite3.connect("file:" + str(path) + "?mode=ro", uri=True) as database: + database.row_factory = sqlite3.Row + result = [dict(row) for row in database.execute(query)] + return self.event("independent_sqlite_readback", result) + + def initialize(self, *, diagnostic=False): + initial = self.event("initialize", self.backend.initialize(self.root, diagnostic)) + self.bench = self.backend.Bench(self.root) + self.assertEqual(initial["generation"], 0) + self.assertIsNone(initial["active_job"]) + return initial + + def start(self): + self.event("start_job", self.bench.start_job("first-job", dict(ZONE))) + return self.event("observation", self.bench.observe()) + + def refusal_without_effect(self, callback): + before = self.snapshot() + with self.assertRaises((self.backend.Refusal, self.backend.protocol.Refusal)) as error: + callback() + self.event("refusal", str(error.exception)) + self.assertEqual(self.snapshot(), before, "refused request changed retained effects") + + def stage(self): + """Fixed contact trajectory for a declared native development fixture.""" + packet = self.start() + contact_samples = 0 + for index, x in enumerate((-.175, -.07, .015)): + receipt = self.event("stage_move", self.bench.move(f"stage-{index}", packet, x, 0)) + self.assertGreater(receipt["native_steps"], 0) + contact_samples += receipt["pusher_block_contact_samples"] + packet = self.event("observation", self.bench.observe()) + self.assertGreater(contact_samples, 0) + pixels = self.backend.vision.decode_png(Path(packet["image_path"]).read_bytes()) + center = self.backend.vision.image_world_center(self.backend.vision.locate(pixels)["block"]["box"]) + self.assertTrue(ZONE["x_min"] <= center[0] <= ZONE["x_max"], center) + self.assertTrue(ZONE["y_min"] <= center[1] <= ZONE["y_max"], center) + return packet + + def test_successive_job_gate_requires_measurement_and_verified_reset(self): + self.initialize() + packet = self.start() + self.refusal_without_effect(lambda: self.bench.start_job("second-job", ZONE)) + self.refusal_without_effect(lambda: self.bench.begin_reset("first-job")) + self.refusal_without_effect(lambda: self.bench.finish_reset("early-reset", packet)) + self.refusal_without_effect(lambda: self.bench.measure("early-measure", packet)) + self.assertFalse((self.root / "measurements.sqlite").exists()) + + def test_measurement_is_a_separate_process_with_exact_persisted_image_binding(self): + self.initialize() + packet = self.stage() + state_before = {path.name: path.read_bytes() for path in self.root.glob("state-*.json")} + measured = self.event("measure", self.bench.measure("optical-first", packet)) + result = measured["measurement_receipt"] + self.assertNotEqual(result["worker_pid"], os.getpid()) + self.assertIs(type(result["worker_pid"]), int) + self.assertGreater(result["worker_pid"], 0) + for key in ("bench_id", "job_id", "generation", "native_time_s", "image_sha256", "state_sha256"): + self.assertEqual(result[key], packet[key]) + self.assertEqual(result["operation_id"], "optical-first") + metric = result["measurement"] + self.assertEqual(metric["method"], "simulated_orange_RGB_footprint") + self.assertTrue(1600 <= metric["orange_pixel_count"] <= 2100, metric) + self.assertAlmostEqual(metric["footprint_area_m2"], .0049, delta=.0009) + self.assertTrue(.04 <= metric["block_center_xy"][0] <= .10, metric) + self.assertTrue(-.025 <= metric["block_center_xy"][1] <= .025, metric) + box = metric["block_box"] + for center, lower, upper in zip(metric["centroid_pixel_xy"], box[:2], box[2:]): + self.assertTrue(lower <= center < upper) + rows = self.sqlite_rows("SELECT * FROM measurements") + self.assertEqual(len(rows), 1) + row = rows[0] + self.assertEqual(json.loads(row.pop("receipt_json")), result) + self.assertEqual(row, {key: result[key] for key in row}) + worker = json.loads((self.root / "requests" / (self.backend.body.sha(b"optical-first") + ".worker.json")).read_bytes()) + self.assertEqual(worker["returncode"], 0) + self.assertEqual(json.loads(worker["stdout"]), result) + self.assertEqual(state_before, {path.name: path.read_bytes() for path in self.root.glob("state-*.json")}) + self.assertEqual(self.bench.status()["active_job"]["phase"], "measured") + + def test_measurement_replay_is_historical_and_does_not_run_another_worker(self): + self.initialize() + packet = self.stage() + measured = self.event("measure", self.bench.measure("measurement", packet)) + before = self.snapshot() + self.assertEqual(self.bench.measure("measurement", packet), measured) + self.assertEqual(self.snapshot(), before) + fresh = self.event("measured_observation", self.bench.observe()) + self.refusal_without_effect(lambda: self.bench.measure("measurement", fresh)) + self.refusal_without_effect(lambda: self.bench.measure("second-measurement", fresh)) + self.refusal_without_effect(lambda: self.bench.move("forbidden-measured-motion", fresh, -.1, 0)) + self.refusal_without_effect(lambda: self.bench.start_job("second-job", ZONE)) + self.event("begin_reset", self.bench.begin_reset("first-job")) + self.assertEqual(self.bench.measure("measurement", packet), measured) + resetting = self.event("resetting_observation", self.bench.observe()) + self.refusal_without_effect(lambda: self.bench.finish_reset("no-contact-reset", resetting)) + self.assertEqual(self.bench.status()["active_job"]["phase"], "resetting") + self.assertEqual(len(self.sqlite_rows("SELECT * FROM measurements")), 1) + + def test_exact_motion_replay_retains_one_native_effect_and_conflicts_refuse(self): + self.initialize() + packet = self.start() + moved = self.event("move", self.bench.move("one-motion", packet, -.175, 0)) + before = self.snapshot() + self.assertEqual(self.bench.move("one-motion", packet, -.175, 0), moved) + self.assertEqual(self.snapshot(), before) + self.refusal_without_effect(lambda: self.bench.move("one-motion", packet, -.17, 0)) + self.refusal_without_effect(lambda: self.bench.measure("one-motion", packet)) + self.assertEqual(self.bench.status()["generation"], 1) + + def test_external_force_invalidates_stale_motion_and_measurement_before_dispatch(self): + self.initialize(diagnostic=True) + packet = self.stage() + intervention = self.event("diagnostic_force", self.bench.disturb("unexpected-block-motion", 1.5, 80)) + self.assertEqual(intervention["kind"], "diagnostic_external_force") + self.assertGreater(intervention["generation"], packet["generation"]) + self.assertGreater(intervention["native_time_s"], packet["native_time_s"]) + fresh = self.event("fresh_after_intervention", self.bench.observe()) + self.assertNotEqual(packet["image_sha256"], fresh["image_sha256"]) + self.refusal_without_effect(lambda: self.bench.move("stale-motion", packet, .025, 0)) + self.refusal_without_effect(lambda: self.bench.measure("stale-measurement", packet)) + self.assertFalse((self.root / "measurements.sqlite").exists()) + before = self.snapshot() + self.assertEqual(self.bench.disturb("unexpected-block-motion", 1.5, 80), intervention) + self.assertEqual(self.snapshot(), before) + self.refusal_without_effect(lambda: self.bench.disturb("unexpected-block-motion", 1.4, 80)) + + def test_diagnostic_force_needs_explicit_enablement_and_finite_bounds(self): + self.initialize() + self.start() + for force, steps in ((1, 50), (float("nan"), 50), (2.1, 50), (1, True), (1, 151), (0, 50)): + with self.subTest(force=force, steps=steps): + self.refusal_without_effect(lambda force=force, steps=steps: self.bench.disturb("invalid-disturb", force, steps)) + + def test_foreign_or_modified_observation_cannot_authorize_a_motion(self): + self.initialize() + packet = self.start() + changes = (("bench_id", "0" * 32), ("job_id", "different-job"), ("generation", False), + ("state_sha256", "0" * 64), ("native_time_s", packet["native_time_s"] + .002), + ("image_sha256", "0" * 64), ("phase", "resetting"), ("source_kind", "real_camera")) + for key, value in changes: + with self.subTest(field=key): + foreign = copy.deepcopy(packet) + foreign[key] = value + self.refusal_without_effect(lambda foreign=foreign: self.bench.move("foreign-packet", foreign, -.175, 0)) + + def test_corrupted_native_state_never_causes_an_implicit_reset(self): + self.initialize() + self.start() + path = self.root / "state-000000.json" + with path.open("ab") as handle: + handle.write(b" ") + self.event("offline_fault", {"kind": "native_state_bytes_modified", "path": str(path)}) + before = path.read_bytes() + with self.assertRaises(self.backend.Refusal): + self.bench.observe() + with self.assertRaises(self.backend.Refusal): + self.backend.initialize(self.root) + self.assertEqual(path.read_bytes(), before) + self.assertFalse((self.root / "state-000001.json").exists()) + + def test_corrupted_source_binding_refuses_without_a_new_generation(self): + self.initialize() + packet = self.start() + manifest_path = self.root / "bench.json" + manifest = json.loads(manifest_path.read_bytes()) + manifest["source_fingerprints"]["bench_sha256"] = "0" * 64 + manifest_path.write_bytes(self.backend.body.encoded(manifest)) + self.event("offline_fault", {"kind": "retained_source_binding_modified"}) + self.refusal_without_effect(lambda: self.bench.move("changed-source", packet, -.175, 0)) + self.assertFalse((self.root / "state-000001.json").exists()) + + def test_corrupted_retained_model_refuses_without_recreating_the_body(self): + self.initialize() + packet = self.start() + with (self.root / "model.xml").open("ab") as handle: + handle.write(b" ") + self.event("offline_fault", {"kind": "retained_model_bytes_modified"}) + self.refusal_without_effect(lambda: self.bench.move("changed-model", packet, -.175, 0)) + self.assertFalse((self.root / "state-000001.json").exists()) + + def test_corrupted_image_refuses_measurement_and_does_not_create_a_database(self): + self.initialize() + packet = self.stage() + path = Path(packet["image_path"]) + with path.open("ab") as handle: + handle.write(b"changed-image") + self.event("offline_fault", {"kind": "retained_image_bytes_modified", "path": str(path)}) + corrupted = path.read_bytes() + self.refusal_without_effect(lambda: self.bench.measure("corrupted-image-measurement", packet)) + self.assertEqual(path.read_bytes(), corrupted) + self.assertFalse((self.root / "measurements.sqlite").exists()) + + def test_measurement_receipt_corruption_refuses_historical_replay(self): + self.initialize() + packet = self.stage() + self.event("measure", self.bench.measure("measurement", packet)) + with sqlite3.connect(self.root / "measurements.sqlite") as database: + receipt = json.loads(database.execute("SELECT receipt_json FROM measurements").fetchone()[0]) + receipt["measurement"]["orange_pixel_count"] += 1 + database.execute("UPDATE measurements SET receipt_json=?", (json.dumps(receipt),)) + self.event("offline_fault", {"kind": "retained_measurement_receipt_modified"}) + self.refusal_without_effect(lambda: self.bench.measure("measurement", packet)) + + def test_measurement_column_corruption_is_not_hidden_by_an_unchanged_receipt(self): + self.initialize() + packet = self.stage() + self.event("measure", self.bench.measure("measurement", packet)) + with sqlite3.connect(self.root / "measurements.sqlite") as database: + database.execute("UPDATE measurements SET job_id='different-job'") + self.event("offline_fault", {"kind": "retained_measurement_job_column_modified"}) + self.refusal_without_effect(lambda: self.bench.measure("measurement", packet)) + self.assertEqual(self.bench.status()["state"], "unknown") + + def test_retained_interrupted_intent_blocks_all_new_dispatch(self): + self.initialize() + packet = self.start() + path = self.root / "bench.json" + manifest = json.loads(path.read_bytes()) + manifest["busy"] = {"operation_id": "interrupted", "kind": "move", "generation": packet["generation"]} + path.write_bytes(self.backend.body.encoded(manifest)) + self.event("offline_fault", {"kind": "retained_interrupted_dispatch_intent"}) + status = self.event("unknown_status", self.bench.status()) + self.assertEqual(status["state"], "unknown") + self.assertEqual(status["unresolved_effect"]["operation_id"], "interrupted") + self.refusal_without_effect(lambda: self.bench.start_job("next-job", ZONE)) + self.refusal_without_effect(lambda: self.bench.observe()) + self.refusal_without_effect(lambda: self.bench.move("new-move", packet, -.175, 0)) + self.refusal_without_effect(lambda: self.bench.measure("new-measurement", packet)) + + +if __name__ == "__main__": + unittest.main() From 4ca3827902904fc6b60730b3a2aff0f6396464b5 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 14:14:12 -0400 Subject: [PATCH 092/216] Record asset ISO proof and register exact-range image recovery --- .../notebook/2026-10-11-u2-vm-provision.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md index ec872be..5b5df11 100644 --- a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md +++ b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md @@ -26,3 +26,21 @@ Test: stage exactly packetv3, Python3.14.7, uv0.12.5, ChromeDMG and their manife Predicts: ISO creation does not require hostmount or global changes, contains the five declared source files plus checksum/provenance metadata, and Tart's CLI/source passes readOnly=true for the attachment. Against: ISO creation fails like host DMG attach, unexpectedly includes other hostfiles, or the supported attachment cannot be made/readback as read-only inside the guest. Refs: output/u2-vm-provision-20261011/tart-run-help.txt; output/u2-vm-provision-20261011/tart-run-pinned.swift; output/u2-vm-provision-20261011/prerequisite-provenance.json + +## VMU2 · update · 2026-10-11 14:07 +Observed: VM3's test enumerates four assets, while its Predicts line inadvertently says five source files; the intended inventory is the packet, Python installer, uv archive and Chrome DMG plus provenance/checksum metadata. +Next: measure that explicit four-asset inventory; do not add an extra asset to satisfy the mistaken count. +Refs: output/u2-vm-provision-20261011/prerequisite-provenance.json + +## VMU3 · update · 2026-10-11 14:13 +Observed: the Apple byte-range downloader stopped with curl exit18 (partial transfer) at roughly90.7percent aggregate image bytes; completed segments and all partial files remain. The full-image SHA256 has not been checked and no guest exists. ISO creation/inventory verification succeeded without a hostmount; guest readback is pending. +Inferred: a bounded byte-range continuation can retain useful downloaded bytes, but partial transport success cannot certify the image. +Next: commit VM4 before resuming only incomplete ranges, preserving the failed original transfer logs. +Refs: output/u2-vm-provision-20261011/apple-range-00.log; output/u2-vm-provision-20261011/iso-verification.json + +## VM4 · prediction · 2026-10-11 14:13 +Hypothesis: Apple CDN supports precise Range continuation after a partial transfer, so a new downloader can finish only the missing bytes of retained ranges and produce the advertised complete-image SHA256 without downloading successful segments again. +Test: resume incomplete segments with Range beginning at their recorded absolute offset, require HTTP206 with matching Content-Range before appending, bound retries and preserve per-attempt headers/logs, then stream-assemble and compare the final whole-image SHA256 to Apple CDN metadata. +Predicts: retained segments remain unchanged, each range reaches its exact expected length, the complete image matches Apple SHA256885503b7f4b06609e9a512f2befd40f59730640a3f1233e3892d60affdd51c95, and only then the committed Tart provisioning test starts. +Against: the CDN ignores/rejects offsets, repeated partial transport prevents completion, existing bytes are altered, or final image hash differs. +Refs: output/u2-vm-provision-20261011/apple-ipsw-headers.txt; output/u2-vm-provision-20261011/download_apple_ranges.py From a5c1b7df4866c0d1dd49fe6a94742ac259f63e12 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 14:15:02 -0400 Subject: [PATCH 093/216] Record frozen successive bench cycles and disturbance recovery evidence --- .../docs/experiments/SIM6-reusable-bench.md | 4 + .../notebook/2026-10-11-reusable-bench.md | 13 + .../reusable-bench-20261011/cleanup.json | 22 + .../disturbed-score.json | 379 ++++++++ .../reusable-bench-20261011/disturbed.png | Bin 0 -> 109895 bytes .../reusable-bench-20261011/frames.json | 816 ++++++++++++++++++ .../fresh-cli-status.json | 1 + .../reusable-bench-20261011/measurement.png | Bin 0 -> 109695 bytes .../reusable-bench-20261011/observations.gif | Bin 0 -> 232000 bytes .../ordinary-score.json | 207 +++++ .../qualification.json | 727 ++++++++++++++++ .../results/reusable-bench-20261011/report.md | 62 ++ .../results/reusable-bench-20261011/reset.png | Bin 0 -> 110107 bytes .../source-freeze.json | 15 + .../results/reusable-bench-20261011/start.png | Bin 0 -> 109953 bytes 15 files changed, 2246 insertions(+) create mode 100644 jevdual/results/reusable-bench-20261011/cleanup.json create mode 100644 jevdual/results/reusable-bench-20261011/disturbed-score.json create mode 100644 jevdual/results/reusable-bench-20261011/disturbed.png create mode 100644 jevdual/results/reusable-bench-20261011/frames.json create mode 100644 jevdual/results/reusable-bench-20261011/fresh-cli-status.json create mode 100644 jevdual/results/reusable-bench-20261011/measurement.png create mode 100644 jevdual/results/reusable-bench-20261011/observations.gif create mode 100644 jevdual/results/reusable-bench-20261011/ordinary-score.json create mode 100644 jevdual/results/reusable-bench-20261011/qualification.json create mode 100644 jevdual/results/reusable-bench-20261011/report.md create mode 100644 jevdual/results/reusable-bench-20261011/reset.png create mode 100644 jevdual/results/reusable-bench-20261011/source-freeze.json create mode 100644 jevdual/results/reusable-bench-20261011/start.png diff --git a/jevdual/docs/experiments/SIM6-reusable-bench.md b/jevdual/docs/experiments/SIM6-reusable-bench.md index 5ea7bb5..7329d7f 100644 --- a/jevdual/docs/experiments/SIM6-reusable-bench.md +++ b/jevdual/docs/experiments/SIM6-reusable-bench.md @@ -33,3 +33,7 @@ One active job and exclusive bench writer; exact source, bench, job, generation ## Decision rule Adopt only as an isolated experimental tool if the primary metric and guardrails hold. A recovery failure is retained and narrows the supported disturbance envelope. This qualification does not establish model-driven planning, arbitrary manipulation, hardware transfer, power-loss safety or production Footwork capability governance. + +## Result + +Frozen source `0091e5f832a3aef24ef73fdc9f1ee76bd64b7e46` passed 2/2 first-attempt cycles with one persistent bench identity and generations 0 to 29 to 70. A 0.1333 m axial disturbance invalidated the previous image; stale movement and measurement refused before fresh RGB guidance recovered placement. Separate native-state and read-only SQLite scoring verified both measurements and contact resets. Fourteen focused final-source conformance tests passed. See `results/reusable-bench-20261011/report.md` and `qualification.json` for evidence and limitations. Adopt only as the isolated experimental bench. diff --git a/jevdual/docs/notebook/2026-10-11-reusable-bench.md b/jevdual/docs/notebook/2026-10-11-reusable-bench.md index d63fab5..cb315bf 100644 --- a/jevdual/docs/notebook/2026-10-11-reusable-bench.md +++ b/jevdual/docs/notebook/2026-10-11-reusable-bench.md @@ -12,3 +12,16 @@ Observed: the first source-stable development sequence completed two cycles on b Inferred: the axial RGB routing and contact reset mechanism work in this development fixture. This is not the frozen independent qualification and does not yet resolve SIM6-P1. Next: complete retained measurement-integrity and reset evidence guards, run focused conformance, freeze source, then qualify a fresh two-job sequence with separate native/SQLite scoring. Refs: tools/physical-workcell/output/sim6-root-dev1/ordinary-journal/; tools/physical-workcell/output/sim6-root-dev1/disturbed-journal/; tools/physical-workcell/output/sim6-root-dev1/ordinary.stdout.json; tools/physical-workcell/output/sim6-root-dev1/disturbed.stdout.json + +## SIM6-U1 · update · 2026-10-11 14:12 +Resolves: SIM6-P1 = held +Observed: frozen 0091e5f completed both first-attempt jobs on one bench with generations 0 to 29 to 70 and continuous retained native time. A 0.1333 m external-force displacement caused stale movement and measurement to refuse; fresh RGB-guided contact actions recovered preparation. Separate native/SQLite scoring verified historical placement, one measurement per job, both contact resets and final idle state. Fourteen final-source conformance checks passed; source hashes stayed unchanged during qualification. +Inferred: separating body identity from job state supports the requested bounded reusable simulation loop. This does not establish model policy quality or arbitrary/hardware recovery. +Next: retain the result and close this implementation package. Any model policy or instrument adapter is a separate experiment against this interface. +Refs: 0091e5f; results/reusable-bench-20261011/report.md; results/reusable-bench-20261011/qualification.json; results/reusable-bench-20261011/fresh-cli-status.json; results/reusable-bench-20261011/cleanup.json + +## SIM6-S · summary · 2026-10-11 14:12 +Established: persistent bench and job APIs, separate image-measurement worker, bounded RGB host, contact reset, diagnostic native force, focused corruption/replay/phase checks and a frozen two-cycle qualification. All started subprocesses returned and their outcomes and evidence remain retained. Existing episode/controller routes were preserved. +Uncertain: general model-driven manipulation, non-axial disturbances, continuous physical clocks, real cameras/actuators/instruments, power-loss recovery and production capability governance remain unqualified. The first mechanism prediction held on this narrow sequence; no failed physical qualification attempt was hidden or retried. +Decision: keep the reusable bench as an isolated experimental Footwork tool. Next work can expose the same prepare-measure-reset contract to an agent or instrument adapter without changing controller authority. +Refs: docs/experiments/SIM6-reusable-bench.md; tools/physical-workcell/BENCH.md; results/reusable-bench-20261011/ diff --git a/jevdual/results/reusable-bench-20261011/cleanup.json b/jevdual/results/reusable-bench-20261011/cleanup.json new file mode 100644 index 0000000..8c3de30 --- /dev/null +++ b/jevdual/results/reusable-bench-20261011/cleanup.json @@ -0,0 +1,22 @@ +{ + "background_controller_started": false, + "host_process_exit_codes": [ + 0, + 0 + ], + "measurement_workers": [ + { + "job_id": "ordinary", + "worker_pid": 58696, + "exit_code": 0 + }, + { + "job_id": "disturbed", + "worker_pid": 58726, + "exit_code": 0 + } + ], + "all_started_subprocesses_waited": true, + "bench_idle_verified_in_fresh_cli": true, + "evidence_retained": true +} diff --git a/jevdual/results/reusable-bench-20261011/disturbed-score.json b/jevdual/results/reusable-bench-20261011/disturbed-score.json new file mode 100644 index 0000000..bf29597 --- /dev/null +++ b/jevdual/results/reusable-bench-20261011/disturbed-score.json @@ -0,0 +1,379 @@ +{ + "continuity": { + "after": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 70, + "jobs": { + "disturbed": { + "completed_generation": 70, + "completed_native_time_s": 107.93599999992985, + "job_id": "disturbed", + "measurement_operation_id": "disturbed-measurement", + "measurement_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 52, + "image_sha256": "4a3a1f6bed1d0140562fd77a0b71d21f95db426f05fa78b77eb692fda4e44de9", + "job_id": "disturbed", + "measurement": { + "block_box": [ + 340, + 155, + 382, + 197 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.006666666666666666 + ], + "centroid_pixel_xy": [ + 360.0121880441091, + 175.5113174695299 + ], + "footprint_area_m2": 0.004786111111111111, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1723 + }, + "native_time_s": 80.51799999999375, + "operation_id": "disturbed-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c5ba99a999848efcde59f32b74af4fb92060efb468ecbe76c78767bbaadfe99a", + "version": 1, + "worker_pid": 58726 + }, + "moves": 40, + "phase": "completed", + "reset_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "block_home_verified": true, + "generation": 70, + "image_sha256": "502d9069172166fc632ef00f9983fb5c5115b043a0ef20ef7cb667b7ada67b40", + "job_id": "disturbed", + "kind": "finish_reset", + "native_time_s": 107.93599999992985, + "operation_id": "disturbed-reset", + "pusher_home_verified": true, + "reset_contact_samples": 6764, + "reset_native_steps": 13709, + "state_sha256": "0dbadbe16adc1b92eaf1474894ad4ab0548428609d59a3e570da804614ca423d" + }, + "reset_started_generation": 52, + "started_generation": 29, + "started_native_time_s": 45.39800000000952, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "ordinary": { + "completed_generation": 29, + "completed_native_time_s": 45.39800000000952, + "job_id": "ordinary", + "measurement_operation_id": "ordinary-measurement", + "measurement_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "moves": 29, + "phase": "completed", + "reset_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "block_home_verified": true, + "generation": 29, + "image_sha256": "8541989ea39a283f4a94c00dad6404c12083ec3518652a863b0aea9f1fec18b9", + "job_id": "ordinary", + "kind": "finish_reset", + "native_time_s": 45.39800000000952, + "operation_id": "ordinary-reset", + "pusher_home_verified": true, + "reset_contact_samples": 6757, + "reset_native_steps": 13709, + "state_sha256": "716fba0b934c91016341803c109073fafab195b147eb3670fa6cd2ab8f693833" + }, + "reset_started_generation": 11, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 107.93599999992985, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "before": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 29, + "jobs": { + "ordinary": { + "completed_generation": 29, + "completed_native_time_s": 45.39800000000952, + "job_id": "ordinary", + "measurement_operation_id": "ordinary-measurement", + "measurement_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "moves": 29, + "phase": "completed", + "reset_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "block_home_verified": true, + "generation": 29, + "image_sha256": "8541989ea39a283f4a94c00dad6404c12083ec3518652a863b0aea9f1fec18b9", + "job_id": "ordinary", + "kind": "finish_reset", + "native_time_s": 45.39800000000952, + "operation_id": "ordinary-reset", + "pusher_home_verified": true, + "reset_contact_samples": 6757, + "reset_native_steps": 13709, + "state_sha256": "716fba0b934c91016341803c109073fafab195b147eb3670fa6cd2ab8f693833" + }, + "reset_started_generation": 11, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 45.39800000000952, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + } + }, + "job_id": "disturbed", + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06769387394718734, + 0.006864712111564605, + 0.03499573045536974 + ], + "external_force_cleared": true, + "generation": 52, + "native_time_s": 80.51799999999375, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 2.7238600186678546e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "c5ba99a999848efcde59f32b74af4fb92060efb468ecbe76c78767bbaadfe99a" + }, + "motion_count": 40, + "native_motion_steps": 30689, + "passed": true, + "planner_role": "frozen_deterministic_color_RGB_host", + "recovery": { + "after_generation": 41, + "before_generation": 40, + "rgb_displacement_m": 0.13333333333333333, + "stale_refused": [ + "move", + "measure" + ] + }, + "reset_contact_samples": 6663, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11790274447954756, + 0.008162951649690725, + 0.034995730455369745 + ], + "external_force_cleared": true, + "generation": 70, + "native_time_s": 107.93599999992985, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 2.7238600186678546e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "0dbadbe16adc1b92eaf1474894ad4ab0548428609d59a3e570da804614ca423d" + }, + "sqlite": { + "count": 2, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 52, + "image_sha256": "4a3a1f6bed1d0140562fd77a0b71d21f95db426f05fa78b77eb692fda4e44de9", + "job_id": "disturbed", + "operation_id": "disturbed-measurement", + "receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 52, + "image_sha256": "4a3a1f6bed1d0140562fd77a0b71d21f95db426f05fa78b77eb692fda4e44de9", + "job_id": "disturbed", + "measurement": { + "block_box": [ + 340, + 155, + 382, + 197 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.006666666666666666 + ], + "centroid_pixel_xy": [ + 360.0121880441091, + 175.5113174695299 + ], + "footprint_area_m2": 0.004786111111111111, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1723 + }, + "native_time_s": 80.51799999999375, + "operation_id": "disturbed-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c5ba99a999848efcde59f32b74af4fb92060efb468ecbe76c78767bbaadfe99a", + "version": 1, + "worker_pid": 58726 + }, + "state_sha256": "c5ba99a999848efcde59f32b74af4fb92060efb468ecbe76c78767bbaadfe99a" + }, + { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "operation_id": "ordinary-measurement", + "receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef" + } + ] + } +} diff --git a/jevdual/results/reusable-bench-20261011/disturbed.png b/jevdual/results/reusable-bench-20261011/disturbed.png new file mode 100644 index 0000000000000000000000000000000000000000..fb0fc4de5af3bb97b3ca666918dc1233c8f5117d GIT binary patch literal 109895 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 jVtfZc{FETVxTr^eJhT5OT?NlDmz$ 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 z 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д>=>T78g7nJ(ksn^d0)gTVu?}L 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 Ldhn4gA>sc31cjXQ literal 0 HcmV?d00001 diff --git a/jevdual/results/reusable-bench-20261011/observations.gif b/jevdual/results/reusable-bench-20261011/observations.gif new file mode 100644 index 0000000000000000000000000000000000000000..29a0eb00c08e1ab80143d3cd24f4cbef2da6cdbe GIT binary patch literal 232000 zcmV)0K+eBMNk%w1VSoZ?0r&p^93LbdASE6kB_1IrA0j6pBPbyxDIz2)A|)#$CM+W+ zEhHx`Bq%N=C@&@{FD5B4Cn_-~D>5i6Gbt-FDJ(N8Ei)=DH7YJOD=#)IFEuPMH!UzW zEipJQF*hzUIWICeFEctYGdVCbJ25mmF*Q6gH9ImkJu@~uGdDdmH$F5tKs7i$H90{x zIX*TzLN_`JwrM^Mms)4J3mJ}KSn%2Nj*SEJwZx7K}bGA zOFn6vKtoADL`*?MNE2jR7Z5F zNJ~*jOjb!uQ%X)%N={Zvd9O=PSWHh=OnkFVQCdz>S58w~PJz5nQ&~_{T~SqAQC444 zR$Nk6Us7g*Q&wJ6S7B3uw^N40R9IqFSYK6HVpdvWR$F9NTV+^VV^~~fSc0=zU1V8a zXIYHKT3%&ZhrC*dzgu5tTVH8gU}{`oXkB7#USeuqV{Kk!a9(SEUX8?FoqArMdS7E} zUu17zWN=?)ZeL|?UuAG#WpH0*abIV4Uyj6JWo%$&aA0O}U}kb)lg?nGePL#DVTiP0 zqJ3eaeqp75VrFh)XK-R?abjn3VrO$=lF4GBePW`0Vxxa!XK-X{b7X3CWS7%qsDfo_ zab;?CWomY1YjTXq?z-Zgy#!(`s*c zYHxaKaC>TSers=gYjJ&SaCvNTdu?-mZK2+7a(ixbeQtAqZ*zTbb%Aephj4X%aCLxi zc7bqqf^l|%ad&`mcZ6}L<#Ts}b9jPtd4zL&igbB}bb5t!tnPJsgm!y{c6*0*e28~@ zhj)C2cYKIY!HdqgV5%TllJ7{H00000fC6X%00{p80SFvO zupoc{2oow?h;V?zhY%kUm`JfA#R3>JYQ$)uqelY=LWV>@vSi5wC{wCbu%M+&mkeUY zY(SHygPS)YIDh~lg3q5mDF_`(w1Uy2NR3{|z_h8;rW>M4joP8A)v6z|YTX*5tJkh0 z!ipVRqO94oC(^22djf^qwtHYCg-k#MsXwzKY(u^{VNqsGq9NkhJwtqC|np)~OTc&6*8l#(c?p zfdZAlO$sL|GUUgO8T^*ZVagB(r@UYWS&Xni3grW-c`gMblNe5-IZ5XDczJ1MOo349DPLINJ}D+BuWaf zWF(Qey$57ZKJrL`jyTq7BUChQAR~-gxflY0E2fCxi3`qUSzRF}`k`MPCZ^$|kVY!$ zq>UoBXkUqjXjf%(VRoWgg09G-pCRxm!KOQkiEakmjvy*5oF9aLOkqo%rF$)T*oH zc`BbD_z7sBf_~Z-W({Vl=%tkoHtD_i=BsbLgDom=qMXX*sk@KHD$`Yn7ejHIsnnV==OyC7cw=5;BBmFnyC(@;lR@1;pcR#&0!o{*xbqq>-|e+%E4 z!3E($%wwz(OpH^-yWN^=aJ#zf>#rb(d~(SqpB%EvERX-^@~+jYIrB_5ZA%-@JnD=i z*<$;=C(temJ#>mjGx%WD^mZ8a=A3t4Db-a^1{c9w8|>%TV5fQ~*<{!0TEsr8eOpaL zURWbR#r*4h7 z0_KZq-Z`W-lyCm|=%=rK4dX-F;nGQapV_AcuXylRsGp{~YUEC@Bkb~#-Rx@Tw%f%` zZXWBM-9{EX?2JqRzAN67j)%PD#cX-(X&$$_B^x=-$u-kk74`7MpHp>!Pm$x=_B2Bm z?}2YZ78>9BW=O*t+K_#os}Shq<-M!X??7A|!Rh~Cq_F)xrGNf=-Pt4tpXTMpRt3yh znJAdRVEIk}3~XSslqCQN5-(W4qM*ic8tRZR)utCkqMCN__NMtU3EmPAF~ z)s0zLRF)PE!bLBBF-l<+Bg`&{Ei;~xHXQ6=;#$MT>AA6l*CUOeR7g3sz{QYx{7{89 z2gqU?^N*X;;e_JX!-1tmkp;TniyG-j{y=hENo)-OW#c>zLNSw4oMI=zqd-uGQcI)E zj+VM;N-jxIITWm*dCnv_^~mImXoOyUXxab9J6X>^aTLuQ#nQ_{0aISWWDL}fS;HGR z^q~-q=tCJgL#QcJLd=xk!0K0^Ap)p~*5qF#vze4_0>zSNv{)3;bHL-#?UP($XR*>L zkYcejf?xzwJOM|~R^l@!JBj6d>hr-h_R~iHG)+LiGSCqSs!%N)(Z5&#Lxt*#p%Tri zR=3Jki89n_7j+B^3fas;ada%w>`MNu^2pVZ6e%W^6-rZDByfh)Jn?*~m#)~wnT~Ru z>}=NXKy7#^C zE#_(yGa=Vzs;nkLk&2?p$d6VNx2j^D1(e9!*i`bjKMihghN~oTy7ahF;;V9}qebmF z_qou`=>%0tUEm}ZCW~b(EYmm?-nyoith*&@ex^$~YA-?O9gzy;1=`2#k-dI|?`d0B7Y-Eo#qIXutmuE+nCKOOO7g>vG_R&T|Y?URcOR5UvpRI2F>t)p;k!yr5K z$B0g}q8E*5L*Jl}^F54_Glk?N$5u169gTle2jEDKbjnJkk8iJgleY1O!43BEgUN~9 z!A8*0>6$PKfOCbrhr$e;yt!g(E{V6$(Y81M$Bjn{oZSP z{No_cfsVC}FZy;nQI-FejFJ<%-w~v>RGYr-xt$`y>8%^C?SA)lF^RFe4kxenZuPM8 zEgihcy5FZnrL6;g*z~l7NFk21!GVHsgsbr=C}!N)hTWe$r%ON+*KEZx187Y_f>SuJ#YUs&G`JbGY#HvkQThs|w9Pv}Ko@K|ae^%YS4xL8k>VjCMQ zu}5*U=N4sm7tCgR&!%yc!f{>IcEb075Ey|F*mk95cgSaQVzqqC=X{_7L_(x#XlKTxEgogMoixUwXHJ z3t|E+H(O&dO(8gVM#MiQSY?Tag4~B-_{4%O*kwQWWyx`G+(C3!l79S#gE{yeg~fwC z*kLLGgarRrf2L=3_?LD2mxQh7e_X+5b)*?kxFAxv0tW~o&h{4ysCG0|S|8_yUf2Vy z*aND#g&7a~hue3D@Wz4*5PnSJ zhZ_M?<~L?FcpW#mew*hV@T3uo$cPC5VnGOrKS6{=n0gGye|mz6SrG#4B70A$YzCMq zw?`Pcw?3$NZLjEit+^k|Cq$W{2bivPHjOxcu9sfu*hRkL`3lI9o*sgQ3G zZk^F&qybVRSa>0HbBJe=RhNP)_#S%r5-g=^^%jHP5i){!d0S+XU4)Vrv5go3f5P#D zZw8YwIg<%jlZ&HuNJVT{p=UhVlV(8zoEU}6CXZ-m7z;QCC ztqGQgw_WXKhq5A*z{QNbL0oJJgKpUza5<7Bc@V-`m&BQpJGhd6vr4_8hf*h#fQf%L zd4vs@R9FFa*jW~g$reEQ7M}=;^HPPS_$cBzo{UzWOG%&S37_o=q(r)&LRzFu$%UR7 zhU&AQ{0SNUNf`jj76OWzpD`K+8Wq*|nqpaC$Vi)KS!xg(p^z7OyUClBH*~)VoHezf zXciH*W}JD6oXJ^6yY@;OiS76>zaT1tWxd5mPqpeCA;IFXjU zk!pRoYGBrzzG-=KsiAcFrf|x6a#{e>H5}h)r*|48Z(^d6xTnH4o#|MefvT7=s-3jQ zosfy6;7LB}Q<;mVkDD2(l^U+%N~A-2shc@`jJB!z*{S`~pD5P?Du)@pc$y8Fn)vep zteL6-wyHRHg2~vR4qBVGF{ZO>reiXB7CM7u#;b*hjl&YBJP4xFvMU(mmo}59jx~-n z37tqmi4y4)4~LjvA*h2ofOllALz#fts-s7lRn)cvo7sxsI<7QZv-JO2uIL%FthfW3 znpG9Wu7WX|pbD@5=}c=;rS*EHAc(KSICFByuVX2j44O8tDzIX@kw&7M2V0>DtER6; zVHReH59@w;DX|kfPZi6Y$Qo42s<9heVhg8rD~e11cb!d`o#wTjNRzVIT9o0LK0JzO zZ>O_8Ftav$oZm1Qg z;dOAcbn=_rnTCZwbTzfz2N^FzCtjrl6#)#imt_X zxtuzNqUo*>G8vpQs-Vk;N_($e8Iee+TdXRzt~$ItVVm(*upVive~7EkfuScOwqvV< zayqQ%0lfFrJpL<_%PN@7>ZkkxIim5RB|xaY^h=#(qthE0)tezLi@iAzd@&oj<0`%` z{K7E&xZx_flnZ?y7>{KtUo!s3dv=WD|_jJc0;kbeI`X`OpDKa2uFoEAe|7EQLa zq}u^VTys$CrK-ES4yuu^JF8N>F;omJ1{@Js3|Ly6VZa)(!U})NDaKLfCQe+z9E)`~ zxyH|`!FGGM9Xx=CBE1o!vVLp5Cwv1vw#R%Nq}?0H&iu^bTd9Ox$mknUIn2IK`WNr2 za*v!KlPqpU9E|1ml{9C4>Xy3v>&c%SBm^tUQe4U(bIK2q%D6k6y4%WSJEtsZCb2xC z^w&HOP|I#Ri5I-ahsnHd92TA7!EwwWpV*yyLCp4|t$>Tn*{jT$*~gO#%^cm)(LAZ; zO3mmCWDa%B8d8-!jEjxD0`Z%bq)NZxY+DD~FxUTw&O$Mp06V-70LnZ^rn&iyvRlCN z>=5+at4UX!uKdc2D1Wj%%Qz9xW$d*Xh*4fK%T(Z#HJr6y?OjE)$0Jx5d z(dMbqMC#ElTm)?0)^5$#YAwE!I?b3FeE7M(C%wbkJhVP+w2~aUVF3cQ)s=AQniJWj z3hJ*-Ji$B7&RA}tR*1xyR<*S}?t+;R9+rItVz`fgwORnZx*EXDJ5EV$+oXwcR z*Sh$~i1gA)D;9!n$xLe+TZ+2-o6bMN*scE?z___d@C=9teA#r_p&lBn@l-9XWU)^@ z+7V#9w``6ox*w^%!OmM=T^$#n2-aa;%qA>RwynKq&CF@d(ZHSH3clb8-qFN8xleiA z$er9cl*oGB+??CjqeHKhTp-nLzn82(2nw6qO#v6#-TvFywDQ7ZN??7=p(Fo@i$Mk7!MwFzn^7-quJE>#`o}um0sQ9OlJspLX47sa4@K zfYOWX+?&$PZvN(BAs}*2*btejnr!Dw+{rm@qAE@?i`CP99vpxUl0!WJGEU?7eCS<_ zl&ij; z;#=zqKI;gd@Cv{1NMP^^{?Rv^>;JgxW!~$7q{w`+&1~+{&o|wsYTc-s#LoWgH;v~` ztU%u)!^5?$(yTIB#AcNv}K^BKMl59`z-O!T zJ8$lVV;etDyz5?*9t-b9fApl0^j^W~t34>6&foej>ey<`rjEi>PxS?!+lULkVDI&? zAN#Qn_TW4A5l-eLZOwSyuECz+8$UlCPsDTo70E7)n0#&tDkmmC!6@(dfZvRQf2M?= zriM?03*qfGzxbTp_>TY2)QnCu?&0(BO^!l;6wO-nC$#wj;`yI{?+xwMqaV>#$g)w7 z`n?zMXU+ORfb|A1`v8GN;6Q=|mmEA;P~k#`1dBX`7*XOxAr&oN1d>tXMjsk`d;}Tt z;|`J~N#;PA^2SP*H)_0uS!2e`nK5F#z?rkfPM#`StN;o$#R?QfQJg@Uw8T=TBb+`R z0V2fIsUALDy~?4(R<0Yoe%+8k>;P(boz$^us{P3 zTtYwr|6>p${`Sj{qm1ekNxqWc%b~rM)_W;En#{wAyq$as4?ORcc+Gt)pLt+Xixh?27> zGjk2L*d9}|HY5`;k}%yE;7v#efctT{2#PcAxa2BWt~uvul#v4%KX7p>7F8?(MWnm~ zuS5~gvkCt_4>_zsLk#1ykiw86jPOB=8vIWoBNAi?!2^{56;uR6Rl?H)88TuaO#QR8 zB1-d<6eJ6GcvM41W%AG_^F(Zc#PGf|N>D&cU~z;#_tZ*88tu%0tU1-%5l$a}4AM8= z&Mb4VF%Jt|oD6Lnu~7K~Es`J44CCDN&m|oQXpXZ+LXpSYOSr)&5qEsGw9iRcKUFO-0${ zP(4LeRgfR@nBxg!9mzrrFJ_eDM0FC;*PwtcN?1Ty6v0KSU?f&Ls) zyf*)^Y!{F>fo>oBcCvLXOPAa!&%H9;uUl*P%LCwzS6+H`v-e)9hue3@;O8{R z6GjjE6yZ;WQEa%x6?m0+Vu~$x6uwz^pit(HEoE>BBqS1<$GEIdoj1mtT%4G@D+~kxA?sqZ-8m!J32k5``g99u>(}l!b==) zrxy}ebkX%L#*oJ7qq>c>>OYpl96>g<5Yd?mbPt4J1SR;u2C{4+sZvNphVY-%5s?2v zHiHk&V3#Y|&5k^^yIrtyH#F=Vt9MBY9>AKWqi7v3E>eR)wf0gq!8q@E(DTx_&Q`s# zVJ}N(YZ7eM*1fE~EimF6-`w<79Q2)~Y3gH^zzAkA`3X)t_A^SM!ZV(n@Q-3MU|dTw z7O4Re5C{hJ4+29bkdY0jf(Myk9`(4#J>JoD1JNJ{E#=15)dz&{5#f4bw=L)=- zVbE5nonpCgIt1&$(wIiW8ctwZ!O`Ik`+_YWj;VW&k>2#yMMTqFZ%WzI9%a0=M7Dho zd{6X?@}x){D%uS#S6mIebY^-O)i}q=r#^&y&^6BqF%Zp z8k(?CRF(xWfJMV(OC!N8mulMOn|djyUy78ZUok0H-bbC38uOTh3*-M#g3k#I0`gsZXf*_A37biwtK-)=qx%pvp~X51YHK?llIw zU5hJ3BU;y3%F+PZ-R`!Wh^D^^35QcWA7KlN#XFUBi^O!1V;}#U6z@2UJoH7BeKE_P z{MOW_ovkK+0GvS4RuI7xG;o;3JZ3T*_{$RXBSRRhW!HuTwkSztRB1a;dh*0}L{TAk zwE7gTzUYNt6|RWqRAPhLC6swtZYfRq+#3rq#!;H9b+?qn8{@c^I?m{Bdc2qLLSVdY znbSz^gkB>bdA(CA-K%H26nK4jo=C{ zIH~J=u$v<+;g*cB!X>OTPwu%}4)fVXd%`4*hPz3p@#wf`J+ZY?%-j_(n$a%?*DB>| z#3OfgS9#L~7pVkh;_-MKXJpjLiS<H$}(FI75|BVoSHUi;g!?``qriq1Z+cP|4HLH|t;kA(lXn@*i z#Krx#)DDg4Q7RNS&V?Sl;ri&*u)Ezg&Tggks-$_-Thrf_TfTS+QhkfM-+MDPR{At> z_=-nFP%fjCW4-WMH@wzZ#*fGgc&P>nxYwlBc--ZF@zQo&%?)yJe$qa(3Y9!VCs*X0 zr)r+to-nsAPZ4ip-p`r;F3?Q7IVW?TTyghY#S3NeDdCN7RjOOYr}NZ%Y9? z=CQqfyvu#*ySxDN_g659QdD!D$qoa`*I%9RDZl?jvnbgwNIJ6j{4}`jZvWg+=T2rR zG~fBphraWdKW5U}{dBCdNDxAvk>NM>LQidW;8U)0!i(rv_;~ zV!VPP_eW{9{N)RyfVOsP^yv)rF(IY(sG(FVYw7qaZxmL^ zImO#5nY*O-dpw&PE2l9l973r4BRAaOKXVJZ|LeQ}6hJKb!s`;lF(kt=IlWASqTj%` zwQ#)~k-)2SL+J>(+LOaCVi-EaAKi;G-WxmLW4M$Ez8(O?H-aMu;k6e0ri@#}aU{n? zY{Uffoa>{AR@plrutZt`!c2@O!J{fq+zG=`p*>qaQp5^Vthuqc5&1J76RQjSv%)fo zMOjpm1K35$kS<88E=gmJUA(aa^q&7R%(T=~p70tD0p7hC|+{qclIHF3&)cQDNn?!f?!Ap#- z@SDeHtF0pJl@dvT6VXRw;l~fiwo?R1W7IdcAjqjfv4ccNESyC#e8{4UNCMPFifl1? z`Nh7{Cjw1R9!QZkZ+OcMXiYe+7XlC?a#NlQ8d%rPX1%iO59jck*UN{i*l%aDYQ zk@QP}Yeu9nfhK#HJ6uVYgeHvXL;jk{Komr8Bt*%~BPS3xa@5TDl+XE;&v6tsCpfK? zQAdf8M7=8{St&W$lB&V$MDqhh?=XQAfVmFKO085Du56aP#F5<8O`U5+=Fz|XGs`fc zNazYc0+6e)Q4Q9Zj1INPw(-Rs3&u5(8uCI5>a5NQ1dG`tNx?~q?(~j2G`N=v&)#d4 zmjphCqr}O15Stu`l+mLwb5CG{Px^GyCw)@;1hyqTusqUFqr^U>M8W^;fj0xZr%X)( z4H3h$rzXp)-I>jPe9-@Yj8J179uhkaaI=dG^-WmZ(1oN(huo6tp|RDVj1GOv6wSyp ztV`jL&R>#H>!eXQWD$ac#_&+dh=H}1Oic1z%o6+vj(N<9TTcXeASS3%&{0w*9Y-j2 z(knn!Q*}})Ei)>OASR$7Q`t}c)Y2hUwjXTD)0{1+q_YAgQ%FM4GgU%Aqs`z7vD>_n zH=Vy7vCy%^&{x#ZJ7o-p%+p%T3_g`evYH4s?+)KDGOUt2^~#Y|K+*n>sbguMcSy-Zde zHVE=p&|v}#!omMYtksz$Iry-FFGbBTT{-f=$6!qgG+n}Coe@n!#bl+>wy;0mth{Hv z8sJQf7Nb@%+(IY;Q4wWJ%V-i4UCzX4PUn0&T`He(y-P%mQ9I$wt*}5X@JH;0~!RiovYfuoF8<#oCpy*Uh3P zwc|#w`>T$U<7YT(HU9)WD2y>0HmXjiBu=jUrl4 z>&T-$-9(j9kp#G9L>TRWT2^bRWr|nYrAEZ80UBtD+=UcBY$M*S$$cdV(m@Ei1y}>4 z(lI;UCuQCfM&Y%E(&r^JSC!rf3SP~D#4H`nEtM2_G&z=_U@!&TUR_NC1=hkv3KF0s z_H)15WYacn+<}TygEGiEo!sDzU!ijn%+1;Q)e@e?UyAJ3&jnqL1TXP&lS3U~Hayo1 zSla)l)xZ;g-AC;}p1{L-rC>FR$TDU)__uCWrda|o)-4a zP{UA2Jhj~U#bVFU;-1al(qqo6SwO&YlhQp@7(K=UzRm+aHIr1}*A>j~+zGJTpW3zE z_Q*!_%-162;6CoA;RR&(EY(vz7-j@4h?jT~AOVbY{MGQ+8bSjT%;l)+nCYDW>8orr%i}(arr+F8*1>;9viz z17qI+;9e$UU>=LqCFXUFLt|cw1-?C$bYSq5RA*j~IVR6Ko)k*)T`ofcYbFpshFCy` zf+n5MZ*E&H;OU;$X%!AF0@oQ}_*HrSrF?90aN%cg8_j!$x= zzC0@G(s77&RBBsg>KsmKUiD#Kk?QabW%X-6COp}!W?W@09A7WG-d|mwON+kfF&1DL)oNiL7}Yf&TRH}Z}qlpZ=O%jCbO|^0zM|Eij4?KUgy(RiPY}iU8(1( zHr&`WmLr~R+Q#cP5?Z|E4-|TJQj%B!FXoq%<;_k)c{#Lro?d1+&P)i>PJYzIY z*N(mpzzh^*Ch0dmI0$CR?Pd@CV$2LC(md{|a^e(Eq3N<^zVn{!LYD9LHu54z@}7oo zBsb*xblB)M=SMcG(Jq43^6#Zy%BSMtO%`0-5()!Pyaja%5RmOmO5*>noKPla*$98x z-5!jwuH1%9CDp*y~fTESn<9NY50m=W#&-` zh5^h{%pkpSd_~XfOP~dc=}{@~ARlDSG~~-(@+2qqQaAGW_US_IY`7&e2@35gKPT0) z-qOZc07vZ!rbhzrAcaspWJU3r}vDO-d*1|bg>r~=! zG0Ei*x9C5o>x|aR6X#36OmwGp-M@bE71+`2R*!4EU`)mFOAi8F3oRZO2$?1jFe70h zFW3|obyMf}ez$B?*MbyYbygp02-0uShQ!q>f{5EbcE;5lb_xF)NRLPlT$T&sJR4#J z$I7e5YJV0hV^3vdcauMF^9jd1$}Ma8g)yCF7vhF!J@;^6ggTNJW9GK&Zs%xaw2tX! zbT>Bl*&XaiPj?`VX8X|K|MEsnr}xRc_fN-6DnQ|V_xJVAf~vRrsekYJMqw(@%qI_3 zGz(i;=P89>_!=HLTZi}?@DPgk;Vy6Odw%UCgbJzfv+@lKrrGNBU5g0M?J8t;XHR*R zAG$uZ^OuMD#NhMPW55vK_U6{hfByErRP-g|PVWqC?9K@nfHivML&VCULyPdFUn>7YTQeUUUZb`Ey@M#8h{d&QwYPh#*0P5G-QQ;1DDRkuYSqP3G(1#sfr6E^9T=-RmJ4~2Egf~1`gIoV_#kF992kuqi3In2G0)Qv@hZuh&=of+q zAKX{pWbWKNrIaQosR7wN z`dg#9DO#I&DeABI?jLrj*aWD_VFDFsMG7B$j~KkYbUjXA2juDa*?b482`8zh$XN=Vr3A!$oTM(Zj6kRfe221lhMK1u zdV{XoDtxidhvx>6*?Q}oyS~|`fPkUNSFtW6xL^!zCHrNU&Q@6Pz*$Kd#J?gUv2VWK z8cA=sL!rwfOYGWxH;(Yaq_;{#i5rr*M&iruzW$~i@RV9rS@6LVCj6z>W6q`E3wS+T zAPQ;z#pYlXSIpnVj@6lQ2Tbe9Cugm$nkodV3EhBrD5o6i&Iq^+^UXC&SM$x+xg6Zi zJ^!p|&_Wklw9)Ie`f7X}cDhwyo5+EVf84jPLq{H~#J#Rsih$u6Cgs z9`RyhJoB_JRY&_%()Oe$JaK@7P}7gp{L`ir0PAWkV8QmfSC_7RPhsLS3;8Z&J`Ewx zL+f)A+qk6^C&aH_ASns`PC_@A=&y}#T-O@oC6tlO4}eH<0*VMnK*JrdLuIoPv>4dH zv?%L)aM>DNSkQvY@g;K>1d!(p6Q|HMW^_;UpsYCavG$CRgst150}?eV74C+GEi6v% zV3?`i4d-{jW0~+|r^EjpmQZ9r{0#FrW*J%;QF@M{9)G3=peCXTicn0DTnrh$2#IYh zT9nowtM$bZh0#P~EaTrul17unQ44Qm*B8Pm&M$luj&bxGQNm@%qu@~~dSnv&K7_a+ zP-!cHtdQd#_aH;Y#aPCqpyp7pL=47hPL{M42TE6&4{9cLB3uvaJ_*W`p{!@Mb0sQM zsY>d^td*{O<)>mfs#yxHggx}3@_@)0rOC%WPUE028`kyNzQr40X2Tk(vNz{+O63ki}-4ul*8T3N6aAk4{RXs+3`;KB}GIH42B|0i{V#nx0#_Cy26|Ok|44!CcMsKf}b{ z3RIxeopP3U(D z)Qzrm$C}kGSk-RIH3|LDnpSq^v90igO4^DL*MZFyEOpfR#1&~tk58m%emi5EXCx)7*}4Y`ldgQLO@8Y6_Pr#5Jx*kXyfQ+Ks!~ z?E-egN!{uu*{e%#vU87ox2XnY7(}dQ9hKelhCaYNpM|h(*tFVQ+bHf~Jc*CceK!*c` zG!QrMG9xCjtyp{F!(5L*ES@bgk>%61FiW>LCMpm*l-}Svh09HFwM2e=6d?~ejyBl> zj+!f0uwEC+zIO6-qbpWi=h`OU6^i^oLSA=nSzlg$5?qDw$M#|gpZO#tUL(ga`m(^j zvi<)noa4M-(Dj#tm*$vaIT@%4crvt)Rq&z$EojZkP{I^Ov<)#F9+H;l0ewbZ1Rx#h zl;RS^L)5^CRcou5hM={sO>qiV%;F~+3&zTvv4m>u%o}G&N(DJ8j~~K>CAb>a5`o{W ziy|)`rRyfd-ieWSEzV&7y5=^gxsu0f zws@!N^P>gs;arAzR!tjmFQ@1561+Czv7I>gEI#UG0afF>{mK?o?Qt)D2&qaCIm!Pe zV)AZb1Su{05zFzW>#<7L=B7WrbFC|78}-~KeCwP4jB=FnGG*jOe~Od9tn@7^u<2vL z!L^~j&ooDnF5Xswu>2Bk!Mq7hgTAr_(|5h(VO|fU3JJEXEh4@wO?!a8{U6>`)oBKH$8$#NuunHVf8lK$WeFWYwZ5pQmh#szhnNq+yz%lXc`+HRMfzBQ zW~yXET+3&A9D8+z!RVr0t))!*qM8-qf!HK5x~80sfD_K9*Wn2U;Mp^J#;WLMX;7p0 zh2!k3j8cBo+sV*Veq*B`Cj;!za+;J?I_Gni7X3-5{n7tnbvA|wz+(wyXLkA@P7%vp znB|M1<(JTaAm%_8y(P7rCsm}UdWxKqSj4x0OG4HUytLe{=|qzuW(o3VfRbPtkU^cM zK^oL)ozCfE3g|_qUUd0o2QDZp%H9mNQw3_~LrCbCu_QtKkq?rES?uEt*nkamC~E#< z9gg=Wl)?j)tMlpr2+Hr>OX7qY3Gd zx?yN65B>R_OW~gp*&$dS29)~Wuyp5H+7>=Co<2GrhLp`Ag4~$4XPKsmQ|YDL^oUEa zsf{pMbiwJIhN7O50iLF-x~?mpo@=>!B1SG|k|Fjto6tt_cbUFVY~>j^j!vtFsQ zrezIiDUG$|m3XP-#iaou!~+VX5^UK)dS04J)tcI8PGA>fzUwFIDZ7p>*_N%lf~}tx zsIaXI-{7mEI;crf#G*24z^a#p*3(Oprd{!3e0gZ`ZE9Xz&8M0`s3N1eMPYqx?0|Lb zi%Mh2me9zy2JA?s$=ax_x{_tF?5(=2sKEcMRLZQ-(5z^+VUd=Wd>|=h@N5Tk<(xEW zFp&VoBr6KwR8Ezpcg7g_By2ub>i9s5d8Q9~PVFpOZRZ(D&`lytNM=oFqC}$Yot7>1 zMz8dqZMj+`cD2jB`c1yVZQOR*+f9WXvrWaZCEbKrmXqtXv<#M%X+R<0_hr-qpzYPbj}Crq88v4t99}R z>=p);!WMV-;q4ld?k24uCSX50?b!$fh)h$qL_|TxC)OTsx4H|scCFVo@4J?P^xiNI zPcPb9@AcLzPUwx>qLsd~)si>`z(W7qR0zb~E*-S!ZCYsQTA=StmWkzD&E|kA{K9UW zOf2+qo%E^bd@!yRf-L`*$K=vzZLHAc{*Fdz?nkMgZN%)%RwV;_Sf%aK9Hv%b8S4mK zuwi5;V9;)C*=`4W%?Cp(?+&8x=9pCog!+VOwnX5fT43=;V$f|9^MsY-_Z-fybzFK-&p8FOLfieCUPC8coV81AS6?^`&6uAzu7z+EN5;p`np z@Xjjf)3mMy`|*M)4!RBo*Lvei3^ALV0 zFa~b>60>1kFbVJn7bCM5(|i#(mRn2ql)j|HXrvJ}gJ z3@of_vTq{|2;su?F*pAPPug_ieh{j<=os&&$U?LKf=7d`vCE{=7$S!@KT7AuF>>x| z&DJqinpXYganG)nW4NwjTyTK6^RnWFmEL1L=N4Iyux}|bTKn^eM4%WkRSN@7Trbys zVj`e+m0g#s4d=CY>oqEKB1c}LUv|Mtgk+)0&mG0Gi7aZ9Ae{k$v?Jr~JxS^l^WyhR zwx%jl6}R-}xQQ`qT^B!1PcHKm=5KB~?!Ubo<)U^{-Y6SK*iqL|@Ql>wGBtBLHG9BE zIZr3C@^){pb4@Xka2rU`9!rBX$oGUb0{ZU2fb>$zq+dbK^m+9k|#Nmr-6|ZdAo);DLy87@5Fh_5lRRNMt86G;$FYl zGK|kRW51-Na*0X*vfoM&OZSDEbWTjm^nfGO7n>?hr;bi%@!zi7N};(6M(@;GW^c zH-~^ZE;jajr>`;(ZtLvdwIc{XiYGud9YwMByI6bcXoS9`^;d{O(#!GkFUkGwNN>Od8xFJJp zrkBsAUxl?Yd_`2UsDA{hzeIv2sE=p2IITKGLa&h@e#y_e$S*$Qi+tkGddD-lDf6|; zXClknh|81z#P$X|Q?>We^|QbtJ2chzvhS^#XR1mA?joUy^8I(5Svv?YhS4jtod0B= zjdqMSegEb;)T?%OP`#hOF>GVKY%leozq>dW9EU@&huizpbjBU$_OQOxqVGpybPrly z5tkC;!55W|p>X@KwU52xbVJn@P=OYt#JliZ;EU_vXFLi@@8L7~<12aN-#`8{e*GhP z$Im}Nq!Bofpg=MQ5r$Ey@JmC7U%WK*(q&>7ix#(Bw3tOpM~_;rgrpL3$`mS7q@+}t z(g_roP@FW8Ide%(n@f=7EV7el5FtW>1OYM>hz}nn6QNk z6c8hxusA~F2oNAghTwp5Wy%aNXU4pMb7#&85+D#g8o>e6r%@j$u$pyi*RE5iCM_B? zXwRNCXKrA*@&n0{9WS1cxI*y?gpmgZ?ANbey?5_kIIcV}^S;hIK>rYedx*E+w}!u3 zqsCOJP;)e8sx+xlqCkB948pTWPWv}&GMTymCCrs8O)6=MkO=(9qbxM)A|s6^nnR*=<+FbX$C}+=9xWa7Kn|jOfOSa=ZxJ13RkriU5WGWU0TH zoJA79C7X=zrznr2Qaz`xoQk}waP_jQ7gz{0EHcYV;Y<_KJb}%&-ULB}IGv-@FFTbh zRXXDoW6Uu?10B?XLJhrifl3#Z^fX9`EWrFWjgr3X$8LGS_8G!_Qr3& zP)J6E$enkfbKzaX-Nzwsw{aIWRD7T^5}L6_h$O;Mqir|h5v0BaESN|mn_%{)WScZr zD59hc*2;=4zIaQnHtx#f7Rog9%#u%TQ-rxxX4yGZ?<`f%Jt^q3F`Nbe9hB$XeEzw% z*^XAN=tqwpt`h}6fajqfuI^4J{SGf%}&T)}5 z;R#7JIeA$Qb05T)L-f_H&+SNbqyy4_A_x<_A*pT+WLWE-6s0LiY<5vG&)IGlgD!3C zD;?uqna+fQlC6nN-yvT7@PZxWB@a2v+mrL22PmCss%Jj?9%-_-J?;sOHs7<&rNlQr zotaNEPz#m%WL7on$Vqlk}CPjBkd=L00PoTI(bVi1dc%zama*XNruGDi*c%C zC5hq?Q<={6r6zJ^h7{MrSkh=;pbQ<4Dmbl`=p6sCl{MCAt(l(+P3vToo0!Ha(Nlf-SZCVbs!eop7eDb?s|ii^7|}5=J^LB~LpyLyd@Tbk#bEE>*%ynfOv+ z4E!N|j0L-*3^6Gaiz-#7s+A>nrHLI=!FA1|)wOWdkn!tdSp72A!bmMKX9ZL`Ei=C9 zF@UXYeJfm7)4jPWpn7p6UvKi7n0^{3kAJ;RUN{i{Sov)S1cWv0*A%)?L!L}6yMpLb za3E0wO34S5jpRiam|2acj-%09$!|*n(rS6~S{WqV7w(l()LuxnD?$-$VH{%_&se4? zn(e%7>q5gph@=-W5VmqzlK&iRhetK8eJ%?`rczWX6N4&Ll)0;`XvLYjvo3b2c@}G` z1)FU$WL*df-oJ?V0^~dlVs3`Bw5pZ8?L8wr;d->WCV;+mwX3G)s89Xww*r0jt8xSx z;12Y$I|VlAf&ZIeyNGSUY-%vtrh=ZeO>`(0zHrzdW$g|XIaY|Ms%)OGu2bTT;Uwg zdCoU{cgAx*J+)```I#{Oy$%NiEx-L4IFN@8+rY`j;72<)!oZ5`WG$S)%Vsz~4&-p& zS|Y7ri`Yk?9j!@gl;YDW&P6U#7p!NUa+Skaav&;sPIbKy2*prG8WCy01P1CL;jl*1PB&Vm$L2O8 z>fQ8otEAv-v_`ejjdixOdUb{~2<(~v&wU1HK$!#ZfHV3nUCV$#5v$;aI(jWqN%{@Y z({RWlMY5JI!VoZxgp6`}CK8kus5?38kAyaqAU}2C3^#HXm)ztcdfduqOb0rkUdHZn z`O9;iQkmz=bGzMqZ+*1!oez7s#xAZBmXze3K;F_!Zt_#33cx8-Rf$)P=5?=|gC{7h2la&i3!Q9Z~kpbH4R0wf+J+?|RRR*bF@a zM5k(yi$-|D+oEJ_;P7lf(j=^+C~H2NWa2WdhbWJ;H14A^4{$zba6S*EV#z|#p!7V% zgjnyjR4)WYFa$rawN5BrD2HDEWN*i4k6(VuK>8-wgl*V*Zn$jX$bzn6h7NX)51F7M z=>`zGmX7Ig#mcY^`cfbXxh+k)%*(*7J3Iiu^ltmit&6;_ywoi0*v#GLicuN`zS2+q zDuw-S!~O8Bj=m3%?#^ra!u|#g|Gs1Y;3u&LF96d71r9IqBx<=JPCkMnfiSCqnk8>M z&7(MJ#5B(%KxYd!2tq`zlr+%ABBuo7U<57k5=D>_P3ZM3B*$cglz6RkT(Apni6eqa zKu)4yq@X{V<@bOO$(V#bf?@}WqPdF5hz3ykFs2BvN(G=U1y(=_frsjB#p=4loAizY zs8F2nl^&)3QI&lSODHLmohI$0pK&@bMXg`1n=wfmBiohR}OSx?E z*(zoLX&}0Y5O=H$`mihsyY1V)Lu|4p`;?J6xQ-mjioEDf-5>+KDr0=wZ5qw)ovcyb zCM6rSvHkAp-gv`&{3IO3vEK~q90Bew;4lu^k^dBJJN|F6>~Jm6q8<&<;T}mofZ`7q z5VLB+Ss<{pC`i=*Is%j!(LrhiA`yoS3L--$vR!0N4j5AoF!C`WQv@4R4q|O1Lj>0Z zq6|E7*IE#i5;4er%XElsCK^a3g|8=OF+Lv2=qTnXfG`(ppeC0uV{+#Rqc0eF@|uXz zR)Eqjl5qoErfa&7W|C4VnUYY(?^4R|jL;}GuJJUIhMwvxEANXkfTJtp&!51u9IHbE z#4@q+PyhUF4#{#Y70xYDfGilv;d+1%hhi4%@*g8l!!D`vUcw+FFd;>a^FRkjJ`dGG zuP{+-ghB*zVvR8)Q}ym(K^e3`9rO+olnyAfG9PC}R!B2%iv?+^_C(9aaF0M_aQ9T= zBxxcgkL&UOS`t2kLWp9rHF41fYLW(Ia~GR#V|)<_aWe%@V9R`R1dNe8?qUjolP~6wQdInkI|0Kx&k;I2pe)ys{@O9{ z{0|<#BY5U9Jy&2omEw_HvMwb~Zt}9j3h~npu|WP3lthVxO3Q;Pr=lNy`TG@=w~ zrj(xl$PhQOGS7}R4drh;sRK;uL_5ZGEzc4y-BIw?^gK@hEzIOi2gs3##U=d_5OdJv{bk1s>4<36cFHApZWG4#a1FjK2g3sf;>Dp6fa1S2(J??4Y2mSGh(VKcI|3^t}* z?=msdLdf7>#bt9sk|9a)BXX}Kg@nkQ1(=lNR8ciGRrNjC)|@?!zW7jt~p-AcL(yO3_dM z9nv8pvRnxCrMcs8}mn&G1E(ZoMW@A%Ets+)w)7r#D+j3MbOh9LM^Cx>2IyzuTz4K0lcD#so z&#d-nopP<3lsSXOS+_?@p*CuzwchM4?yPo8jiaw#1!lk$z}}HN!c#o)Zfw!CY#FLt z+fpsgqIVYW;oK%w<#Q*DAW1gLKI_#GJ^Tnbck|>(k@Q$6LkpFa?3guq)d*UlcFv}i zGwiE6A!B;6Hfy~U1F%;E^nwGnHw3zOJo`_46^l*L(@o1FeHpJ^Q}v?W7nmq-CORqt z{c`hktMekl3nBsx0(4LT*ihXd#x8P!7dC+b8ITvafnlrGCO7sn=L^7qb2=7ueob>{ zaF_10$Zo<2LYIA6v}Ik^JW!YhT2}^OfEQg@OmY-gbG0pMxERGoI|OY`GypKDn2XG; zXw6HAhuAZg6KI;ZG>&+el^A;A&N7}DiuG&Xw3Ujn*Ez5lJPnD9(^4J(*|L1mRgCkI zN+io|ed1jMQdx{_jqTPyG)^HG(ogBQgYMXr@_1lP1jhPUVe#Od138}M`JM4VVF~%Q z3>ktkwIDJSBIvkdZ4RhFH5G*I9|w#NXFI9l6oI<2%a>WG;4ic7%~ znUlGTzjl1zf&`qIY`wS+OJ?PDx^`x^qPGGDV8E(&XG}CYXFZw(K$=!q89QD%1CY6}fH!#4Ev17PIg|D_a#@$5 zwrL;50A$*ipBI?5@*A%;ir2?fF2GJo+KPc1nn!@B#a3L=RBWE$x2piSpP&keySRcFK`8`A!(2Tejc=&l!&whxA>=0$ncKHDR3;`?II8i!Fe*?6c^ms`-Xi)n#PMmp@c(vaS&+-a8VLUlpg^JH~nai`#3<<~o&fpTO z$ANsfgS@zhT)CNBeb-k$lH36=X{t2|A+P$4vs%jk=~ge9T!NtBATf{GI|8=8+!Fsd z&By%Az5UzyfZG$dK`)Y0-8!GwpybeipEZ>XKvK%L1+Q}s&!xbii|pt6T-p3FlL^~J zg|I3N9MKcpE5L%3v+B`H0Ky|Z+$elbUgpw=HN!RihdI5|k@nM-wyjE=#7mqtP8`Kk z9M!9o8#P7lbQ&>?x!+#>uw;G5LqG&-eYbVoi-mjFd!4w4oXCT{JsR)Qh7T_{Y!KU6 z3Y0z6@OAU(ybGS4AUSK=sl6`|(Lh`)+ZnY%#a(g1J?pdn>Km4UFVWl`cwJnM-Q}G2 z=sY9pJA+X%NJzBz`Wgop+7J1iuq#H&J~^@fVc;uV;43mZtGKPB6F$NvyjLsxcpe_p zH=B7jJxM$K!?|#2MSau@;NwC5)N7ix>F7FNe5b27IbfaT#gtZ5Cg#7Fx3^aWYM$3` z9@ur>$lE49>a+nX4uYKC$?tVPM=cAoAnCWD3GTG=qJ7$HA3%tHPwkgSTFWsXmD{zx z`JLa)uRgscl;y;J>@UX?XOB~5Xv*!JBz=07U7(8gOfkFlh87z1R5u$C}FasiQvIf3LBO(C9&cwj2mCkq9u#uE?c&AxxA%G;K72Sc>WAUO6bFe z6)$$o7_w^BapKTD1F$w_b*f_U&Q1llcNZ{1-2jF>jF!Ig1w5jZG&$?AZxt!GM?e<*OIT-Mez(0`cJk zTLSJt;0`$CfM5ZP<;Ry2egW156P=Al+7win#@-d`sb`sGmv!NVee*Q|+GnDXh8SX$ zvbS2QudRBVY{cOvT&%LrD(kDZwJO`H$+gB@9MMHb9d&A`aa|eNX(xtu-Gw3Ec;j)p zsb!L>2U(@2O-h;*P<#sin4*d1x1U{d1>v7t0+o86x@u^DIEhB_*#rk?6ps;aVztF5-t+S?#<&rNsT zb`JtKZ*J>>D{{Kh(d)0k2D=8a*IBn+;$eIjo)^!O7i|~Qs#ocxiD65seDpOM^?gc! zdskh9mJ7tW=oYyDZoBTjJ43t@!eAkW8QSY1i29D$ufHg!=;pv4s3{}DR$;I(!wvKJ zWyD)jTyc>ZkIXSf9)D~=$V!e}vXLiexh0ofvV4=vFUv{e1~d!BftonGsWVh3^z3uZ zTD2(j(0ulJG+F}ww{#GNhWj+AF$z?ovYLCS;25o`$7@~tTG$2?D$kVdFjF{NVk)J! zwc!d6d&^DU?gqjT(k*X%*c%@D_P1U6N^s91+^`OJ9Wo>X=DkA-t?Sgy^=^NdnsuM${f(W?}1NzW0KRH&V-fp z8Rceea#M;*;4k>mX()E0pPue#7PI6J3ue&4T9h^}|1~Xui`oom%qA(c@z4sYVW8K@ z^FUA$P*jkLlzUK>!PUU#I2?4_2So_XV8YFWxJsc4S133a8V-htOI)(P00w7~2XdIn zA$qjd!}ho*h@KfteLM%c{rGQb=6Yg*qKKd=RSuZZKpmrbH7Yh7^&oQoO zDP}YZ8fiq89I^2x4};i`miNboROulaLy{fuD3Uzt5lMVh2?PEJ$Sn!-OJXAAji@5C zNuqE6ksnxJ`$_=G_f3UHKPyVm>SsTrX)=FY*g>FxFfKxgvMzTac;xdBX)9UDb_IfkeeBo%1r;}>x1rD^_KVt@Wqx&fstbqrc3>#i8PEow*w^t2~F{Z#_q zkr4#_{D8rRQa(8uZ=eP3Qui>*kcBRwp(c6g9S?xo=pg`mqP^%JU!t-fO@L*DbeSPT zdX+>T;vNTza(7L#_SrJ$C(!=Dvxay@sv`eI?Xi%XvD~CCCOh;PC3G2q6hs$U^d*Cu2SI z#d|)M1SoY1`*5}VWPT-(h!l(l<_PmWfG$g1^ZS+{XP#?nWV;>_T0f~00ONDjnpK}d%!yUGP4b};v2aTA-Ts$#j zQyj*B0oTR7-K}M1RAWO%S;spjNcWicN70hjBC0KNM2oCiBpV4!7+o?#2;$@?f2p<~ zoidHiM-&fS*`!+DvLvf4KQJG6%*rkECew_Cn^w55qlB}Z9R)$5Qt-|MPfe=Ao7Bp9 z8qnt*bW~Mo@IynUgK%rK#kWc;Nc&A!a+tJo23NRCs{sv%)3madC1CP)t%0kd9AgNc zO0(V7o89`HgvIICzBW;?1VSgfY>n$&$6(hlkf*PKy<#n^2+O;jaR-F|2NWCMxV8@q zw@eTU+J#O#Nv7pUk&Vo;kuB7<-PY(p!adt@i;pLUEFZc%pzd|IX$0-Y=Ws>ZflAIh zx%H+gzJ>7Iaq@e*c!BfOuzN~U5xl4o2XDd^-d2VS+H4k_0tO{MaYfIHtBvTq=RXhn z(0_iu8HY4}J^m|Ui5!MBJUO#GT^aG}Sv8|xd|gR1^UX0K!g=AV;Qi;Hw`ABrgtavd zYH)nkJxIi{EBa!Oe!F0oNXwHI!BN!x&!`)6VT7!@)dzxgjA|WvUH>}RueV2&al7oX z6-c-Xx^}jc@7#%udr{W+TP@qY%kZWo(2gr+m}GDFhGtyAX1^!@U7=H51H>8GwOynE zbEt7ttrRVlu?6H69&<)E4p(_og?Yq5LVO@XqDO)yXo8(5LL{^|8%GBnmtTRiU#d4O zBv&l0M+V&i9)5O#l)-Y~wI1!Uc-*92+~OBEr$h)Ce1VlNJ5YQ!aC|gyd_u>3S=4LL zcRPX zc4V@BoXL)Hed*)$* z7bqSYNK2GgXpQ%QwGo0M2tp^=d4_-qsK|;a2tuV;9JBHN8ZL->AU7Q^RC29{a^bOq z78q&=h8mZ1XQuWUL|BBYmPD@BX5`XDPSgXlh9DefYqy4c4kCqE#B08$0x7_a`htb+ z_7pJIg4Srff*QZ zlgC}BVQ84A1#h!?BWQw#(0Qxaik}CQsF;GKha0UjX)u_2!9s)BVRAQ!gN<`Tn`mIE z5{#2VaPU!#-o!cHVgyNqbB@@IJcmxw2z1pb1J}s^d{y{s-IxMc$YR45jv#P-*mqf( zWk~%Ii;4mWB!y z5nFc=@rajjNKqEmmvji25%7Ne*pIixha7w zt$35a@hbOqdS(?Y!l{b@)-1<~9!I5|3|1JRp*ce&HQ+>e8p@2+X*xY{oePqc+BpL< zz@_apbj~+VEfAjEIG(vvo-M{Z>4`oul5Fm|MsB%|aXFv#$xv*lBzSp#6Lk_0aWQ_$ zJ!Th}62MV}S(vz`0S0=Y>ZTL{({6(}o(|f75W0|fGNEKKfRuTm1!#a7ih!*KXZGQt zo*5qx$eI#3IazR`&eAMmkeZ)(l9$;3nlTESGa5pzNSiT<3Aw7PyUMG)N|Uy^qrTCj zKB_Ap2c)-{RyLTTH^hVIF*!dNjEZp>P7qX0IyIehA9-N}cOj*uW1Uh|Yfnf6+{vXd z;GH8Drem4{W!f)i8d)h~mWjEh9MGl##g;kNBj0z1a@vj;QFF|fJC3#IT;C5 z)Jm#X!ya36DdvG0stO)6l$!Q{v-WTgI;*ogdk;Sgv_Xpx_b{~hV6;bzv`3o{OPdd~ z${WCBo4qQvQ%kkL8mzrR9QKv}E0R`LwpcjK)J)s)Og2Pdm2s+Bkfch=vO~xjPnxZI zp^QtUb4?UjJeN-4T8-9NuID;pDj=p~%C08ht^rdPR6hlkQ0OnvF0PO6DyEgaj^x7Qc2D@Q~h?!KOX+gVacDuHlyZ$p>yvv!LGauU(yofQpje$+n5?&4DXUV&~EXuRa z8@P!kiNT0^!!@#& zi;FxV47msaZ74JUm;P$P)h3VGCM5-{xqkY>1`)$D944Ympc)`NIottv!ov!BB0%iA zLL9qdVQ-jv7MjXQT(GG?z;F8j#l9Oh)H-NZtQdHfO$r1VnzC}9<~U&B9n9;qV+_4z zY{p89z1pk2+#5G`^Q)f+$M=lSy$X6cYB%&1i>KEdwkUEVS8|J!IBex-31>}_fxp^x zIfN_)+tmc}@nHX}YOF>V(dDg>e7BRVz?D296p}>_tjQ_B$(>xDgxeyboWVaKJRD4@ z4x`HP$&Rkf!m*6Pd8(%s!IuV$%Ydq|3mYa5Tf*L>}(`|Nq?i?un)g0vV1%+Zqr-Cv6H9i8TBd^UmKYz1^B za}({P7R`GYZ5MM(opsA|Oqfm{y`>->(j%S89KssJT!p}B$6Y!EMFWdVyw>6OSE#`&UFpXr$~aT2zun3 z2>~wu-~*lspW5zLMLQl?EU+viE!mPN{>s{tI`!8$S2 z6ritg`P==fxermf!~KQ>n*jXTr^%hL;>O%X-4o9Z-5Vg?(+wxpU8e7Y-BC@%0jP+X ziq&b(shVjQJ~iUAw9V>`K%=%A6)2M85#QRuqD}DD&r8PmZN}NF-`aaOFS&~1OW=tv z;0Vs>2d?Oko(Yy9>7Vckm0;>VZJ&rEcn{UK>98n=vT= zgF?D#-J#(;=rya6V3*yIn1g%W)F>kEExc#qCqAXs3CTXUI+QE}uLA>Fgds1$+8pvB z-H7AkS=}n#A~JT{KrZCF%_B!1em1@2OkP?!Em0a_+){oeRBngv*RVU%+%|U9NFA9H zx-(!to?;HwdbizXe#H1@nc$t~nMvMzktja}qF`MZa^BEntp&~c-gxdE$->s@T;G6R zy@EdI`JfLNpAUszf&kv=9}n^&AMyeY3X(qQm44}#uIZf4>7MTLqAm!hF7u>b8|+)G z#>(nJnv04vlsXuaIV5U4q}~v{q)o}|dewX3B6!s4jH6BLtMk#vp4wWpAvOO0>|x2E z(mw68UG3J6+rX^b9_%niF2XgPC9mwS;7)DgUfkM)+z9(^1JNU4@-ljuVAQJ6@yY)QY^)mML8qgDN zx)ViC6J-w*t$g+@91-D;pHGgtZf~%3n9JT10UXsbqKg6hkM~;+5F9@L3>+B3purId z6Ov%au!ISSCo*iHNU_7kiv&L$M5qu;6)Yb^V&O8f{+z<@~vgtHlMz?aR<$%+sN)+yqNUv<%=oQU%-I{hcZ>z@ZrOQ75@d**s&$ZkSkU4 zRN1m8Ntite;@r7&Akd*h>(PVf&S}(i=*UqWCypD~v0<;FOgRInlxp~d>O=L5Fb8zj3?j!W5@X&IC8Adal`$M z8Z%_fj}Zd~3>Pn6xNyP3e~T7Y5KurAPJqaSh8j|61Q0k1L8A{iphyD>HOL?X3@*&z z0uDR0paKvukyn2|kPH z?z

D33h!(qpf^8*G3tKKbgq4+j1C^Y6a_2}I$*5=uz0Oa~$4po0y%yfDiPujKGU zDl3rk#3xg1k;xd9tP#ltbS&~mA%h&b#{@vO(PJ4K;Mf5tGmb#YDJ!;8Vl6eS5F-dZ z7_-bX(^QkqHhCtww9DQnwYl8!W zQcJPIEmN*K1*BbzJXgdU+m*7*e%%b% z&p;CdG-8W2_6}r|RhC(2pH&0e+%B~=IO3qXR_x@s?bf*{z~xHZ>Xx`pJ3iO#4hSH` zD=%L4*mKVY8)^`Kh8gs|uiyUuWkH32QE;B%gBMH~!iyZn5MqfhpqNUUP0X0Zmm6SN z<&bwg8G({bKA-#rSZ2Uwj$?k3=9;Oz`O2Ixq|nWt4+4SA1vR8#CUBnf)>IKUz3FIi z@`%!w77~6gwU`V+307mm60p_;O&LlGQRo^K7G;I7ISNu!>B1MNa<)ok zWo;nTl-tS@sy3yp9pjC6lSy?j^X( z-R|Nwuix2#2EvPv@%Xi$&(;`A(L;A+3*m?t>qbx`BEq4RkU3UBp;I1Zx-GbHIA4Ha+O9G~O>Igno{C!z z>9)fjn(Bu^6e1>A#TO&yGZTVYVn6-=sl-b-5pj{RL=+iE#VP`e4_T~S=IG$XFUF>G zpQC8B%t)=XQKfXJ6Pp&SuqY}R1&-h%)CW6gld28jj(L0uyZGoXc>U3L^%7(a23Z3` zB2RhCTVx}j2T6vM>3@{8N? z6qjHvYXyocC`Qp&kE`Mp1;GdZ+%nX1$bx7@n`Ik{g075M8C^!LrAE_rl$*>sY`3CQ z*q)dauqZVGG}YD8+woC6JTQ+;*AvJ=(qNFpv(F*@rMyMBG;0ww{gf8z%O-7{d`pwNw5}VOo1-*S>;=4=ikEoB zGw*r*lio$9K$s>t0Z@esU-=TmtVczvhw|&m{c0?H?qi<<&R5j}v#)&!-s*}N{8gJh z_?G&cutq#kVW5#9!x~0G3OHQMxppMPB0kBTN}Liuzof6x^pj0i>_I_^3%VkVakrMM zSmk6P$B%`q3(48ztNb_(G^`<6+NoI`9y!TB+{fOU9Jp9bnO33@g}hgbWqfP7pi<1t zuOJ5+Fo#)-V^-E1BFY9cpShyB*-aR(;_x-IdD~s^=8S3FoESfM+E_cO?DV|sKD$)A zy3>Job8u+j2~WKLGFWsBke5iFrZ)wWeqM&%n~(};dLU-4?=3H|p^1IEd)`w~e_ixn z8kKsgBun4Oj&xupH6Xz*dVu^+G&5M+Pu4kWSgi-*fm`=d1VG!hhG+h3xqg_g!%k+g zkFAn3L~YqstBJD%1#O;4yRbs3HWd_W@kTABIFZ`13x5M{GEf%C<<2Y)IosK|tQ&9b zu4j`6R~RYV+c2x({3_&)Z_o#{F|CE|zPT(2+IlA73^fgESo6?07@S#bV1u*9$Z*~~ z{5Rr+EDHw@=f5kq+8Qrxb;u<YQw@VFGurDMG>Dem^NqvfJuhG()1kQJxHfKTE~6m6 ztjURvy9qy8KIV&>=hGeXC^2o9)91{47YESOo`wOX{rt<1%Z0I>_StCa9X z3gSSrG|N884iyWOwd9FHIl-aumXA^jZGlFpm=sDe$i$n$#j`=j3(UxqJi|0hAat^P zf-=IPHyEY2$c)U#WXBn0OnNH?9j#2u6g|gaLe1pN&g9I{%ttZXB4qi;)08NMV>l4K zifWA=6r!bM9Gv~$x4&X z5#Udlbj5|iPNGpio3sE<^3L!4zfcm-q*FSP>5-w-k)qtc_i0Z+eE|6XjL-U^B|eok z`$Rzf6uYtW&;K+Kh!9X*OuGVIy8~q!w-d{;bO{V90<^r2Ero)-i;gQbA?9e5Z*svF zqKX(=&2z$yJ5a6BWcn^O_YyCKYQOwoPV3w=5wz(|a9G=&(A)*D^S8imYh?K~LW zQElx}%)ByC2vQ*p*UuaT(VRlkz?{s1D9%wh(8)b>f>Mo=(k;lAHfoM5mB_BxQb6fV zz5>(W%$?zkJ{&Mp>qAo+SWY$74@DA0?>i8d^v^k^PW`-7jL1&yT)&CoQ|`&h0BqEw z>&Zd=NklcJ`y1J(^F;nb%0?YUQfx{|ozw!X&!}X@{H#h$)ztt0JdglAJE9>_r11!_ z#H$S)OD<5C?O4^DFvhIm3RtyGuSp7Ts@15FM#*~DXrU-yg@SDiR#NdHVl`G|Elhk$ z%oml>YrRodNZYiv*0VK2ZGBrEg~uiI*2WN5ait4#mBK7CjU@G=Hvl8s3$D<)sECu- zj;dFCeU9kh3Z7WYef81|^4E>z$ao=GKAew(Ew4X(wC8MChmBMJq|@rGN{X$XJjGb; z;nVH$)A#dOL7fp*E6+k5u%i0mAaK>S*CP?Z#mp z%wr8(eppc$ zPFeI%642RBmB5|_)t?=<417DHWl$mD6P1!CoER5PY1$a0O>P3;Z)&V)e4+AHo7_NO zHON}I2~2rnxA%o#e%K35xIFq*qE+BuL}tgeP2?K?{a;7!QP+|LP$1xXG+@0&V1irV zgA+*L`kXG*jp5Q&^6fo2o>$aS9Sqjst{_1`!44!)sqK(lfE`obIk}W8SQJ)ah3(v# z)8a?cRGe!-8KzhoX2gieSk+ysp$ovG15_Vo097Mm+ASF(E@DLmMI~P1SECsxwh|2y z-kz1>DNe*gTo5eIVl8f71oC17Ri^2s-Z3s?s;L@Q6)d(fEN!B(H%=ipn`0h}!NiLe zJl11T;o7$F#!~@XWaWo_U}$~_WO$oj#1I8)Wn}$b+q8WJSI}sUzUW29Uq=RDNRDJm zw&Y7b*JEjo*xTeS46aX>7K4m9Qa+AT&d|R9!_tzf4nVOZSO($S36Fpsk6J#tL=#EO zRpI<#VO#WN5&-6476AoZKyfx*Ho+xiPG%hrHD?A{*rmT9Ca`KYVkAN02FT{6>|Jhl z;%^3LHWBA>malSFi1uoTbmn5`^{_9#z%V{G4jg0ag{D72V;0+r7vsAULc_(<0`V<8 zFF?F-Q@k`lgWB*_z%*#c+re=BV;^+rhYn;yo@i-JM~n7o(k^Yab21VLx!wd-|GyS#R1Q#}I&KZCuR8o%10>%bZp+dJ+RDQ2{| zZW6p}c|kD9OCN*mG??sk0!;SpV{jx)KD|DJFzoHAD8p8B z-040ZKm?FTTWXy>la_ohsJ2tLCK_Y@=599c^L~J5Ce$FFW}*yYu^#K(E$i=r&sehW zwT3GS(QhiYu>S_|E#}#~?n*iTA=P(YiM~$ozn;5#Zn3G^8`)%T41>zN%S1K5ITJ4_K2sG)2qh^2!fDWC1X5;RE^a zGM`TG{%*G}W?YIGCwBAmj&qTfX4Ox!4!LAV4wXi7x|C7>oKn{m%f9S<;K5=o z@f3AvR&Vuw2%I4#93!mJT6YCm|DbuBuX&umd7Gc{Tfg;OFW_CLi#-6dEJD(LR97Y? zNZcs$tk`gbgvM-}F*i<>I-53U*9j??LzV(g;pDF9lfLypIT{$rF6VYf1CSJ00nZKh z{}!rp*KZ1`>b1UV3t)Hta(D8qX8W@$c^_GNUztU{_dTcYv8sg<9Bs-tT?i-+3ADd0hYbdc2FEKWQrDBEJP(cGZnyCj+PVHs8h; z<&d-5bPn8fb~l9fXu|yK{}Q>};V!Sgc0I(tvPUGC3lK49`{+@K_*y_P5$6i2h(G5} zKDGN50mc84bCWexfIuJ+L4tw?4JufmaN$A*4IV;t0AV7IPT-TaU!h=4?Oh10}nf(h++;a=3v7OHo!=O z3^U3QLkuv$;KBR3<`VGUVk$4mj|@mKJ5H(Ul&7B$AXQrPL=&F2$r2k|P*- z6OkwQ^ixnn|7}o|OGqUpXiZU3N>x=@U6s`tTXAK?S7D7+mZ)k$!B&F`#zof^R@`M* zfPD4k#bAROW*B1kIVN9ZP*`S}KKW?2S!bJtCYrIPoyJc;%BJR;Yob64n{2DpR;_NX z@Rppm$_*!rx8HtCoO0U+C!M+HmU5lC*h$hzBi@1c-FW1gr^g-lrq|wk@y#cnefJ%v z->hW(6>Ar-4rt)238G3xgKR;FR#{|?71mc8Zs;M0A%@sPi9G0#;tnk4aKno*)*$1I zHsYuwk1qV^qY6O|No1iU460NJFg3|ipF-`Kfk+p8bmvBOMldG?55VbWm~1LUrkVwz zIndMv|0M*qn+?Djr_x9pO+lV|N{Kt1{?E5)+=SdlCBwN z#1@NeY0LJ*Iwq#H_FA;iPRq)*x8J55xVw9M+;O~rt8Fdl5+B{V>$cm7A?}7Z?|A0n zdoO$Xy4SB8Y^-q~eut&8->d}#7+|Yf9LR9P4o2*R;uS0LRfZaN_#wwYcx+~A)HScosZJ9JTLni_5)7E_Y)%5y+S*pAx1r!C2CN%V9F@1dP0DY9o61!% zg{iD;r3gkioQ0I2I3_?rEe~s$9f8PzRIS;}f%>t5$9Q_QY*w85QjUhxXxh0Aw>EDj*SHN4^>ayrMej=LHOo<2B_ zUiOOKdgNfq>h;TW*;5Sn%8)sN`KK@9Yn7_506B-b|f_2JZ*WA>>1xRgb{~=7% z)JP~MFP#vDTguV|R(Pkek&PrUl%SK2;sKq3z=lTJ2?|h9Ou8|uQ9guJ4M)(oN)0hn zN7PghilD@=ATDuCh!AAj@)iY6VG0YgBIPW1IWK~dR%2XD89#T%G_El-ZTyTr`0+;3 zAd7W$T zaDx!(U^dmX%@KAmBH@%%3Nup9J5>OkA$cJTV~COsummaZlnDspi6pm~pq?qXCrKD} zw;uv=1ON>vRtB1tAs7^)2@T6a8QQoh#wDUtKoEiwCRV+0@v9ltoESOBQN~#B4QRYf zNJT2Fksb@Bq*3Wg=_u6MR4b;sk;U)mdsE}wf~WTt7fpx5$N2tqT0&I~QHzSyq$<@B zj*OSQ_8`ggNN;-7yJ}XmhlVj`?yFqf3t0^`mn%dRRcM8b#LCjdSHcpmLzpEkMO0T3 z=|BfKzyXW&X9F7SRb_sC0bm7t&w3&gu{BYwl8zF=v%yeGldV8y|1Z0x%xbm)oc-Wu zujb7*aV?zUtcYpLDS?huAhj)2XKP(6l$AhgwzaiwO$t?l+@hc-yyf9<`3b}jNCj|# z6R4&%h1?<_^u$g)3tAfIP$@(=qI03{fV5!I|MUk8WY~`}o;T3uFv5z%+ z26ZGgDXC4<-cz>}z5vDza(+`^`|dZt`Q2}~`YW#BxWZZhUd4ciN>l_RczMcO9)kzr z;0Nmg4|t#|_2AR5`fQb}lLjSNM|qcpfjGo*8SyG7#MZVVRK+ZAFKar=DS zYN54|8oFS@!{bo5@b8wM~)n$lv#Rb#FvA5F)B)1@o#c}0y<_0DmQr*`ja zrbVszUMpMSGUT`PE9k_xw$TTf=6)O8NDw!RYiUb!_h1JzPWQTdDWiA) zPu>KSS-pD#J=gAdaeIDr9)#%|s>G9R+(TK~e9x>h1_tjI%8OflOT)){K?x6(r2@Sz* z97jmN?`a8UDc?g(+0|?lHCFJ@)yT^P7V8z$_ubnGz}}J6gb3te?Oh?jK^FD#UYKpf7b093KAG}$Nf~O> z@ugw%DIfE3ne$;B1<2tX(&5KJ2?V8?{|DsZ9-iDyz>PeDUorWJ-Had11=ny{3gIkb z5nzZCI3jaFB3h`$gG^Bl!bSb9N+xPz(e*{7@!w&5Vq!4H=ZGTV8Krxy$9t^DQZ8j9 ztcO#&3mt^uRGLB~xT0*>1|Qj)1lnRRc;#32f-TM(F7`$&(#8hTowESrQ3ac@5u?07 zRe40u9ZU}<$;S%*OJXG6Ga_9yTALP7*TO`X4nmCl5gLUwQ6v7DL3N%u4k75J$c*jJ zjj1C$+DH>RVLZws+)Uv;=40M)02cP+$NeKf3Z!KbWJN%k@FC>GDda(@;Q}~>K{_Nw zbQ#7?Bt?pZMW#fPWaLI}9|;^2|47!`kMz)^6e8Qu#LNj!&8cKoypQ|6q!Y!YDox_4 zC|QB_$e(Q;vI%F4n_Y zXH-I^dxl_Dx`tJnLaqUr?aUXphzovoWq(@geu|}Wz*@Eps0Q9qYY>%D<=s*(sNeCy zu|<`#MVKYYfu`N%^>_|5UTF7x&xRq)fRxYq>|ltd1!9IpiE_n>24RXqCX4D-WyUBl z&1mb{=#8EL&gf`9_NbA$M4xzEYYl0^O(X??;Y9@B!YL_36d%2xm6O!^$ETwVl zG(lp*2Og;%30zyhP*H>zdVs z6!vfB1|pB}7><`o89 z=m8z@0ioV*$2QgO3e{@-R4lr}A8qAMsa^4cr7vjl7HcsUd*v+>(zoa$?(m{7;%ulQ zm?JDz|09iHgU(AHnBcvzD&bKWv?X2|%nBH3m<$RC_S7$sg^ZB1B(fjm8+U4zywop zx^~UrVg#5~=>`j&J{84EfN&ntgcOoM3G3?#U#?#vr%6hR3#(sN%t5E*oI))QWIzm} zp~`eI8WvqwUSwA%(n=WwWqq_kQI@A1%%ypZN1^7f?)Gl)uEy6vD)7?cEqHOucJVv+ z=UDpAa@@}H2GuWWLZ}**BPf-yHNqqPT^!4Cvte(2Y|@35LDG_ehVpUKMqd4$RVp=( z|A-FquOb1)WQ_cXNd16}$gqebC!xC~>y8ajW}a0%JRNV|Vdm%kvk@+V2pO^8OSDekwnUs)D{H zBn`A44|N-OgI98|NDM4 zBd^H(D&fjV@=5P6|1MBVODnyu#NA9#nayOPDc$-dsZqV#40C5Pz!Y% zj+4>6Yf^jMP%Lg^H8s83YdspuRGY90@GAc+H`;h2!(VLoVLp0|CK0kK_;no zV-t6~W(30~c#HRVtEa1Hn)u}$1stO*f@_3JHm4!+hG|C{; zM)X8cflXecl3%pNED=jOIY)Q&$4I%1<<*T@d5tJ*kFnmCFHo0{z?X-4+K_pf&+X7u z$+oKb0_$y1zd4*6#2JdvcdxQ+inl8-AD){xQma;a`#F2J_mVs=|DhDRe6w84Bs%6U zx(pQJeqTzYYf4xrb0g|pBwpuR*rX+Xm=1UPH7A|sL@Zr9hDTYIrd{kE?6rC1frIh^ z6Dz76#X7a{(H{xY*p*e+Q)0QnUYE~~o- znLV=Yyg&DtGm4OIVMyeA7v4$Ij54^2H+Ta)2nqb07kr%~`~$4(MJ#-n?fK9+Jfi@5 zpbI)5&XdLW#4u&NU*X7%a5dXJI^n2kSf4>M|F@e$;zD6#|H8@zoieOjduK+~N*eed z?9%*uu&RWY2OR4G&-Z+LGL(5pkYJS4Hz(7$Z!Gd1q)*>iROwNpL{q2;8q_CG7dmy)r19ZH2;I6zaPj?{%bDQ9&lERqe9oCU z9W!23!ej{(CQTwnbhuDq!GZ$?Zt=dwOL*~L#FQs%y*G!PR^8Zjk7QyhHoK~^M`(3J{Zk)@VeWZ5voT5kCeL|l3q zkwjm5@dd>cQw)a17F~Q1#u!yp@kA1B#0A6-b;K}3SuAvA!c{~W^1)Dy)Wpb4l*}YS zLkwxekU<9NqmMxZ-q)dBiw5dYl z04vYB`UsfUd_Nb8E5)Ql;QB zQ#Z>X1J5*g_EQc<6T!68GQE^26|{Ygh1hzc%_f>^$ZfX}dIK)FbdOtCxptWtqB-ZJ zqYfe{tdjz}?6iyX%{IOG0u1xiECY@8+Iz1JHo|nnJ}&jU1CJ~L++z;_rIhkO1QTqK zK?ogOWx@$Hyl_JfJp>WuTSOdj#+GM{|52EjWsZ?WmuPl=j<&bdB^ z_%qOtfbd~%AWZ5(r9^RniP0KtlL695dvbwWZ7o$TQxd8LL4?tw1=X{yyb8-yR8yUd z)yH17%h$wc^$SI!y{t|qBMlAEM?ebMDuxyc2Zh3DM_?l7PWonR8MD_;5PSE*ASTZ%=Q)|usXU}0A5 zW(Td>K?OJF%H6dt)w^x|4tTR6Uh%|5gL0h(L{wei$o2!9O*mQL~?jCn86He<2M_W>o>$v7rT(tu1NTxPZtT|bR>d3 zhzQh_r`%T-w2%ex|Aj9+t#qXr%2$Ro#Iil|VFNws$t8J0EPnh6(3Gk)B?B445gR*F zIUO{LWKM{g7kVZ%RVGcADKMKcB1SNX(OJ)acC(pXpk+s7!O4#7M?mu*GKp4Ba^}ww z1wz_7Ddx_1s!$H{oag%R$sRPA?>uysYd^gcr|$JopaaDdbqvZUghsC;MPR5B9s1B6 zM06#Lk_io@=%`0Ul5muA{QbSN0r7m?fyz3pez)QTTR<#B)*-a+5%GKgLuQ>0D z7bvTDJ?y1b|6gnE&MLzLuvVVOeCaV5d#)xXzTSsRa@eJR@*to+Q0ab9a?-{!;aZQ0 z0%QPeW{;kkvXxzyn${EsXsKLfD~oo52gK27FIbDz0u7m>7^iEQgb70^2ug*OlGCyj zHL2y6OMDfRn8*}M^XYTA;sM_dQ5jI}nN@907^`!ktI&nYjc(LkVh^s1UG2_fiZ%Ie zBsFR{j&5;r=!HtOikg){lIo;o@u`5>0^s^~u5`50uT5`yIsgY)z&3XiKeaA9b*l4AQ~vfBr>}m%(+8{;ppNC!%)&r|Z=Gvhb5VD!X{u9!B5a-5gy*)Q!J~bn z)#Z7(IL=m%Co4i?>DcRDC`M%}RmpAfwX!_mR?oP}tuS-v7-IZ++Wh!XSSO9}%O8AcQ*CcY|+gs_@N#RaNex&JcP&@LZlI* zK!g<##oPR5{8a4?3L8@_&jj-Fh#U-h-gCAGA5gSGfw_aeNJ3+N=pfMi<`Lb&qq%Dv zp4)`dKkpq;gg*2xI>qSfMS9pXP`RdG?&(o~XPpAIUQIH%?vG5xz&?#D z$SyQGzyli0DHsRsGKDpU0@xr4T;Pt9Y=cp7pzb~p@7g8r&fu%wCECQQdIC?NutPf# zVr=@Q+scEk$N)_W1`X1u#u%or@^o^Rybuwqi2O>(ltB@8UVlw@ab9y0S_z#xMJ)W zkOMm4iy-jq9xN#;P{JMwHgqB=>R|LlJvi_30- zv=FG8sPNxj4r>6Y%jLhsb}P|+z(Cofvj6V)0m%g%)iw!Hh~5KOh1lZ~{{U z7%wm=Xd?zF@1`;I)aG)9EQU|DO8hxNHr}14n!UR!}<*Kb4z0n1~$M9M#U}g}; z3Wo9ALmh1?w{q!y+_9H_sSijf^AyX-OaUK5uR^-4$tvrBPH*1^|FX)g(Dg)}E0HO}(kVRP1A-D%hLR{t%8bYY zDM?K!;esls&J>|CDi?z)tMW10g6kx}rvmA~Z1EOtjVf@%1IW|Ccr7)2tpd%mThLN1 zCrR#-aV6doCFF80l_(nTavBwih)&QVri0qZY>-RkR!$}RgeAQX ziAF*?W3tgA>Md7-Ev1Th(vmhRtx_tmyikLS5Y#+BpenjjK-sfBM~&;+VkujZKJQBb z?9(anlPax}KLyM`v(mtpML-vjKn?Uj$#X18;3yi@EN6olBb0b1)Gc%1LgO+T6|F<< z60D#NUa~O-?dw(B7scr^{{%g$H!tLU*7gmeCO>iBP*!CxH%8 z6ID|dhddkgQPp!jO=>KBN&+gi)PyBJ7b7ZXMZfCkW~VYg_b60jjZ`;-GftHORdrP( zaM!FwHDJ||+Rp6=b&@El16v{o4h1DLHYVrh`+QXz4J{+0t?$Ol#LlW%uWdV!)n8r= z#>}Th$<4;->D=%m-E4GXfDBtTuSfd_^eBW0O{VlrFA8BKW~dBZkpUT4j~NnIaar$h z(G|321~s#cg5Y(4z;IqWsA$Se9wUxvCa(Ab|2E^2kIvShICN=g@s5ZMAC2DaZCoXDICh>5Dj*FTiETaN9sDfo}v5d?JW|MNI9wR?r z>Si~Urs@bWIu$RXcRwS;0JBnPFW^*BwU9W#XpgoRd2M%ot!ZOJR=G23=Z;Zu*J^jb z<}g-?wpJQ{l{vmv+O)Acw5M!YP{mekFkNhI!>w7bX0KWZ@*?JGY_w@C&k#na9*fXO zJP*l|a0#1`^hgV{1eXfW)o=}0aT9lh&y@-n$RMQ&AvXjJ!%(&8)gg-pA}^1GriAhy zIBG7AYBEmw*Z{A%=3qrm`bM&0SC=88{~!vKQ~M^iVyA0~Wb#m0f+iV7(zdgAefKAT zm;Dfji!QNvjn`3=*A~Cm0w@(epZ5Wxm;aoyFXqTF?(;69S3g;$Kab^m!6JM+t$fW_ z0?{{p)mK}9hbPc-*lgm_I(8*e;<_G+=6vA$x(^%SB}B#6FIUiP&vx4iSgr~)+{Eo* z6!`Jn$6tT2wgyBVEA!oA6Pc7r37KiK_z?;N*F{1&U0ZL28~2t4(%)btHMMNAA}fZ8 zgq$`ZNzh3m-*FB76(f%i4i&gyoA3FcuZS78&mQ)NB9=LwSaxS_(XK0RsQA%#H;X03 z1;8_Sk)m3_I08olH#Pw2PBo7&|KM0+)_K*Kj!RJ$YekN3C62L|j$3h9xcBKswKC>; zk7s8CG_g|As9M?x6|CjNAhQ=(8x;*lXa2x87oE7^bP#UZpufCm@` z53exML_N;YJrYJ?bTC>UbMkI;X@-y<6XY@->#<&WNIPT}jIPZbnL5xHZF2NQOjcViUHobt1(yg>Y-0G*V31;GRfVhFp4@Z^%vGR3P@S zP5>BfSgwhkvzw79(O?p9!kHzYNG8acHq05FyBH}>mUzP$jAZ9o!grqQS!UO0jq{lS zqLQCyN_76YQvaZElM7hHtiOk{~5`2Io81uVf2bamF)c z9j61}d3G4vj6qQ?>^Y5BO0%2NjsL>33xmb4*C{o7vpE|Ud&=uDBacUWb~=Ee8#*jS z0LT|KqSg1QD%_$c|5Ur2h|xUywm}*s_IIR7dRWg&@CxDz#%7a;lN`?jF%xs9V-(IF zh7BRuS_c91vb6{`!DEsz^hU2pKa-YS%@a__dVt8_xFI4bHkFZ7?_kT)@ZXnv*!23(DnS?l}YHC9A6> z5JhiZ0*d|ya439mA`!z0Tf?b^oy)URa`7q_Tf~L-R8qyn<%?Bhe0o{@vN2l~HG81# zxS%bgEJAxTbX)^?oGLoSkAob-URCYbj*#28Hmd5;^kxSbjed7kiRvb|q5PA0n+dj& zY*RY8S8O=P|7T#%2Yp@?TB9{TP^iZuxJqm|^E5$Qk12yehM73{WZ?XR8OX{C*KqmV z&lQ)?mjSAow914bf)3L5Zci3oc!S1poR&lrXmhr#wP{Luhi}PD&lI23RG-R2BnSM6 z`H%|c6o~5jPQ5RQ6b+&zsuBODie6p3GF-z+0LVMsad2JN<$1(O94#I@b2NL{iQUCn zTxVmPjvXM`30hQ{y(|!#Xr+C@PW#7u4coIN*q{nrj0b)@a3#W>ewm!QfFN$V4+-{U ztk^w!+#MV@IayzfuI{XDuci&)Hg5L=YW{;F0VI`G8Q|}+l{M291V~4oa71#!s9y%D zt8hv0|JYsU!Kz)Rv}t<8=Kf7xbKPay3}J*+_5Wn`$p~p2cvTGJB8k4lcMMm zJH2>3>B~5ePv!n7!0Fcr>Q|iVr=IFz{JsJ@b!hzQCSX)A1INGjR5Kvj4@oM193V!J z7)a2B!GkFhrclA6p+grCA;Op_Lk5kDHE7t_xDf}A9XoXJ;L)RpkCP{Zs8l(mrOP2k zj3}9@go({2PIBgyA|*-`DnNl+8EPeqQKMUuZt=pDDHt$h$ds9yCXJe_Yu2#Y%H~a+ z|2T5OhP{I)k6Au^_NW~+sE?tyjSOL$iz$@dyQW0x9mT3ID_5^%36@oB)~&;bbLH~I zxN)$@!Xis1cC51H%g2~$-ppC^vd^HGL4y{0S?AN5F=HmiTC(KEuo>s-g?Lu2+k#!` z*3D|wD!qD5-L*@1E}^$?2ccEFhmRh!dGOp3D<{sI>ulVx$$IrFnyFKxK5fcW>6W8L ziCPH?Gzw3hI&IpdsU+shmMc{PL3y$yNsv2u#1TgsT_nRq6G8L>L=HKmkU|F;L=ZtD zfMB789%QH?2OM(HK?fROAmWG@lxSj!6{J`J1uRMs!HY0P0Ktqj()fS_4dkd}{{sv3 z=%bGcBp~FF2_QfukqZ2%Ky;N$}}))-?16HFih1uCj&!HFi0h(QJ$XwYGY8kTvX z2m(z=LWBk>q{5pGvJjC(FjQpGMHdZd!$%+OFcL{TpaevILEHyZO!U>n1Wxcd;S+m8 zsfV6<cOJuCEh8b$il=fL?&oEQ%wbpJXt!dDvhRkKIMV4%A zz7&f~u(ka93U7V^hpTXQX%b3taUs{oAj~z#2XxX=_thJ1aK%Pq?1n`O=FBzP5^WT z7HrwGmtcx{GY2($aN!7Ps>x}OEG2XQ<-jBMyH>GD(ZFD$w9{*pyPqZb9tb}M<1vUf?TYcWa4@#n!KAU zue~wJKpLOJVC-iAJ=6Fr5u;HCr3oVCJ%g#7$*$ zs#8T~a3?$sh)*9A2}ydugZ%_fa4sPnedM#KM)gDri<8vjlv1fnRc?Qn1C>_Xz&TT$ z3RTc4-RV&GmgB?<6RyjIyh1TPQ}|{Tec26Q2y?r`Xs=j~|3MbBf~T6|Awyf!LLO&E z!%0nc1~i(n%6YYueaC!Ohpg>$3Y zN*lPNhEAbjfBn1E7yievqdaVJJ!uq94mcCSVeBOfM2Q1E1~LhX3~zRW0m?F{!4$Zx zgCqE0+Rmnd4U|wsLJV69hek9Qwa|q+jG+u^SVO7Za7jAS;SP`1LlyxsY+~aQ5jDWj zvw_e;Y-?LV*c3Op&5cfWq9WcjvXLC*AV68{n-9F`140c>CWa%U6A*XCpRh-bN1+sX zC?|%f7!xa58C4zaIF>u;;iqTO7p(eNoYvLKF1ZrL{~;CmtHKz@k-b<9xxxj!;i)Dw zpFAEXx60M7c9JuoM9o!6S<1(dYc{<&*X`29N_HJGIPfy6CTxiuLbN59?la3zK{p*b z$N`x4lcO;^6_sRKikV6Y;4_1AMrl?If!B12#sJqJE^_l@IPfS(HflE+jFX&iN(cwl z6j61S>4@#zfC*2C!Yp+yM)!On44Edwe)jX902Sy!qckNJ{V+ucP3Vb4R78fFZA@va zP(&p<(Kc1oq78`%MeMfGj(8NLAnBV)Qex7V6mBMDMBGkzqPR#ArD1GT7^Z3}mCJbw zr`l=5b-qF!IgswBX%Xt`ttsUS9_x1W{Co?wWro(>!cm+)3!F0;Q|_<+ucejM!p3aLWPKd;u`meHAB;KVYa3= zIkBQ~qSJKkv{8?E6bCwhpcc0~QbHBVyM-fT8O`V(moo0W4a-7O6y^n})D%4L#freZ z!qc&&>Zkd7)#~VSRJ@oXz@h+O_i&dx|42qMSyiPZ@j`=|Yc22C$G$K$kbUgtW$QGc ze6WW%q-N!uJ8e8e4&u#EQ_<>J~W3p&LLeM>RU%Q?ASZs@p1pi13<+R z87M84!o)PaWF|}2$$#V6pFk4n%u;zHR<@ux8KmXsnlnP^WE%*;Trd}~lG1#xU)GVXDaYo_Hc(QPJp&~sIWphe%!iXI7i zq(e&SN`vvF;0QdE1iQh+vn01PsqDIA|2V^%6s2WIc|Ei0?!f6<<@b0czIVxTkS_M4A?}r5 zeenwq{^DGAKt(X{lp!i)07H-yYwvqgp|ShscYPxJ@BE;oW0KZE&^^N0&Ymn~4X>zZ z4-#>Shj~mgA9Fl4zHyGjcFlFxk;q4mBsrg4w<*^ej9C6#uI{hLR))6pUfjP0S9&VJAC{Fx1-E)O08Zg_GN4sX5BD;)mrfvXTI^(8x|eYC#Ne8DGY z{6u_0QgS|We8{JA%-4Lu1$`JGbANU-)K`5rM`+o%WpmSg-v@qIG=2~iD1u^i>E~Vb zky7%pbUqP(Pq#*q;{}tmUQ~fOnS+CL#5s2afO@nCG4^7!LM#78ND1g03%E#(^i+p| z3sQ9~RAp7t<{4q785_7&(O?a@2o2Fti(eIC+%i_p0%EbD7-@AFs$^n)@m7UoKCYt) z>0>XrU zLx&CJP!}?BdFVFTr+o|&T`tglJ|_cuvU-pfXBdV-~wVJC>z;!3$tJwD7YJ^fMR=b7tM%1FLqZlMq_%#SHA>ITro`f zb4>i>Kjp!B|Mmtk;|L$3H+mTZa16vTJ+O`>DKecU1Kvl44zXp~hlLYjbN09)`Dk2U z!jA}bX3X~@Ed+8{!y~m-kj2+D41ka*$Bremi^Vf{njw`IhL!eti`HEU@n;S)<& znDud(|0|K0+SCI>*O&w1dN2?JuQ!>pSD9Ien<2EBoS6Zh*;*;`hN8J* zkP1+8tI3)IwUDm4H4X`f&nJ;1Vw-1!o4J{h1HqeavU5=soQ%d%dNY2OWt^6VX^C<; zjnZi_`J6HtiKRB3QgKt(nV~u<7OC<+=;n#DHY<;CRO9(B;sZYC$!oVzEVHqck|aEs zaY>%BNwtWTxLB!{ii^9*i_id8%%FG2z<1Y!R)E(%gVz`0Q%K_0IuD8oif0J=!W=+l z7VHL0aAC*~FqgutiT8GBFB|7sMcxiKAXtTDWO( z|8)2zK58PL37Vlfnnl_GN7^(=iiS(7nyZC&la&~wujeq|bTF8U`Mlct!4Qth{#@b{+Z6`f3xDN#{%sdk-Pk*9KiM?u9LvIcg6 z+Kjh?E2m03i_}O^r5MNJb`=PBmf?%0VRuxiiTs25nK83m_IM%GDsv)2LOzqNLF$l3^KlEQTi&{w|KJ*~ zaJHnl)uc{}HRl?oD+inFI-6edt~94M7dfvJ5+Qr|ToLgC3!<+-N2VPSbUW~`BoVMj z7e?QuD4V7e$5tuqOo>ys)tmRAL~?zA+oL* zF0fb`D7zWYP zZ6Sk?XQ7gpgF0ADmgk|HC!&k>6QGA=2Gq3)^tCIoF@Hi5Wb2M*dm#F{AQADb8zdnF z;kH`3qaE_DBSNu8Z5Q|L%&V9CC*j zd40|0r5x#zmok}TCy&IzaVr(Qp%Dc}*i*r=2Lx2I?k zV?JpJq3B=##R&q2NDNqDXSs^RGP26z8YX)TPdRtUW{diHmCu{Tn0m%p$w|oOm0vkM z;WD7HF)X#QZ9m&qYxx_xG79FSsA>H;&IwpKWMv^NmT)xh}3ArKtFK5DlW9GZD+Bj=jIgsUVSEHzPs zBp>V}gj=`{Fv7f*xNjJn7J$MjOowE`!b&7FUHUea+mUh-rUI07@X=B()i|Nnx^r4Nm8gG+oShR(7ChM;pJ)h#;0Q%K7n3j?xHbw32)^B;p1#(0 zBTXOkeE=$O%XIf8`a5KwleeBGNWaErhLk&tjeq$ zG(tM0upG;!xywNE!B2w#w>%^td_%kJq$BK_c&50(6+}Bz%yo!F86vMTBLXiB!`t`F z(iNQ5bwwbhMO##e-9@?tt7%No&Eypn;GD2>I?hO(29~Hf|Ja$Qpz}Uv@v1}h&iy5* z99yV-(RbOtl*eOf00!I$WIz~%op;jWc)vMOm@SPTrU%oOKBgwM-;TZIDmhBT+5Y zQ@u4+9n3B_L|N^)X@i^AZQWs=bG>;{(7d^MGazZL!)%?++ibdv$Z117e?{CBlb9(s zi3V~6wdfocua*aW3M+mz7lAr<99wpN!GP$As8O}3{}aey7Kju)6-4e`HkJ{^wVBax7rHcL_O6>qrtO0Lr;Aq z>5a>|+}^Ay=P6e-CJbC%Qr{H$P?4M8`@NA+6sBW}Hv^IbL-#QvRp32*DDBshZ5n@{ zM#M7N6qkZ2b-LF%C0`ON2Nxb|ZJ~IWkg&vBj&{iYE@nsuGHwA=Tr04OUma6>E|<2G*_ayvUvenU7Ipz=x3telgrG9mS`vgevaNzB`Ikm zfs$?Q)|VdFF8Pu}44w7&=}2s+d|m3Ch`Xtd9J?z>2Uv=ykj1~Eio;^-OaNv;nZGG) zaz`z^-s>*@>%czaG_Lgdxu18ZVbTMF$S#7g!M)vkmfoYsDAwBk<${8ISKY}k7J8xX ztAkUUd7qA0S36`wA(&cwqUAWO#;qS4licg51OJ-U+ygA{(Cr}hJ|StYqiMtM`{*-o z&T>T~-cvpBQLXSxdhk&L`ANd?4dCYwP&5$`@$wy!6>rR3Z6?)+=o?SDa06Yx2@xRg z=z=(igeWN4?89TEQY)|Nn{L-pXMadsbp*42eQmp3rxxw}&hQ+RwPwY-GGO@p^ZINo z?Fkve=3tO2pDjMnna%Xrzu5(S(7hNfojUc_8;sT_st1aoDagm8zzM>k^K<10unoo1 zSjbM>?e{}4@pgHBX|=xHt8dR901-uC6ek4>GC_z?$wDJWhCGBAM506>J}g?~!9&Lm z9UXDt$YDby4U!~foIL451DP7xq{g76SjCUi|z!M=yjo<4mH86rgJ5hhHUGKC7YX_F~aqeiiU&+3&d`nBxe!rv=bu3o-;1q((P zVTd7+z+(Ppz!U`vh20{p#S&%^l zS1gbiVE_b>zh3a8u@?Gnd?h|sMiFI{P&h#^lS#;X#1Kcm>#n=)u*(AvC#jQ8j_2B7 zj=AKJD~>oZzyJd{FM8umx7=={jkbYab0Q%oR#T!O)E+V|h>AwbXa|lw^2`R#OwtU7 z%PM;brkNnC$uSamS}d`liYjcdqyoDDDyjOiN-wPN`YNos###Wbv({=W0Z+|Zpwvwn zs0-7sAg~lGz9^*tFi0NH?LrEaigcK%&2~ZYPf+1PWWZ2UN&prZe z2OdWAp`y|zdb1%T*lZ0=C;y~~VzzK+yA3xnd-L))GK4D*jpLMCgGx4_doId5@W|u3 zJoeCzyYIp?5|c;HOK-jQ-iyx_SLU;CmRaz_Wk3HW7Er(f4@Bm`6dPpb8IK=~CS(am zB)LKjw?R4Ols7E7Wotw>@tFowOa?(@GA^*up94$0F zpWSm=8T@3aGGYfM)KEl!QZ%T;8g+D5s9>ewDoeRiwXRbc=yX(2+Zt7YQstVfu2eB) zwbfTCowcc2jlwloUH^UJb%bAoCAL^VF-tbHWlIw2SsXyih}t>h%ywID5pwM{aKWvu z+_HDuB3&-oHO^gl*NB(i=%U0o-|P70caS~+Hqwzy#%G#6_e5C*K80VIPZozE#s!y& z{R8lqiVegV83j3R@MDlecG-wLqzwY1jDXm{28RMTBA7wLV;-B?f-;667gg*<^V<(D zXyh>auuoy}anC5&qlry~A`_1o&yfi6H16?Bdriukl(xnk>LtfrU@L=gx-_;hiRo2v;}{91baoQ{1E|)vB$i z>H(75)aEjmfd96zWmKEv99=vIItYYLFQco9tY&q()TvG}KN*4RUI&?B#cp=BQzVc*(Y3Mm0`c|>N_R;5Oxafs`{_`IISqy(SL&nVbXCjcf>_g9lrUC=VOla`0 zLCBn7iv$Ft`NdCzw{RGah*q>ytfEIE+yv9c_lP550z8KBUJG5>q$pXh4Q)WB8cdl( z9qte~J@nz(#&x_Q7SV`ti->8er9_Q@=7~_`6G{;20zkzMCc*kuAba8yE~f5_gDKqw z80R>>)c+B3c=22sOO?4cy3tc`?40N9f)|sL5sy>(OX>L7$HFZpkiP}?PK>p#6UvHt;p%IN0t1xGeIAMyVt<$alie-2BB{e4D!K~Ip zCG|{+hJO0jr&^jhIL1+?bNq@)?Rdw&L`9E~a+G0ss;G^EAdrG|j8KPa z$jZ>psG31)BR|8`rds5wl+>2+sEVe6jEf4&+bUPR3I^ibFgfvRPFbZ>o$TddYHS71 zcphOMO%%+02!l^A??a>gyi*#b`nSt1kJLkqO5iBPnlnym;K z+I-Q@f;l4^;X-IQ0wIrl1SF_Rq6`Y-~R$tSTiXku`FZY+9@)@3f>)4dq5f=OcEjy zo~oL>HIOo8HN(CE&M33=F63~{dLzD9iD$dkcfNIC=TXm#b;OE=?X?!~i=U0>7YzH| zZ$&)LY{&cujUYRdL)a)FWWVu^A|o(?APS(!LiRw+GWi&rtzg9_R^y)m4M#--A<|5t z9wB*IVDB_UlBQPX7;0@wH1ryB*34$F{ap)m9Vg1Q(?5-rfgtpo|j0Or7~P;Ic#vwDy8Ej zJ#25<-T|NZ$VbA1*)?H#b>GAK3QTbaw%ix{_stlzOvIK);HPi&4H5hMuW6;rG|9leokqye40~4hl{4+(q2;~ zUFl43x}{zP^{7kTR#eATPyKuK*J+)o$6AT6W0tTJyWM%DjOc+~v;PRQGmYR$yM&-H zVrx6C(haTx4(REy4+Ak(su%33ntkD(*jl0RS+QIC5gyScZeyQbD!5?Eg`I(s9J85Z zGAwEevI~){BGbXg>O2c+pcBC?%__YE$(hgE8PJL!{0JxdSizz}E!ayZ6G9;s8o@s3 z7Zzc0#8{dMvEdaUU6S?9$h?0YwKp63KAZb5 zj#899B8rcC6vY8QNRzazkgqz*6!Q}c_N$z;(6miE3q_O*rTd&htfNt*fT;M3`rD(V zC=5Qdx~s#wpz=S9x(sANq&=a51cR0XEiAs0`|Fz5NIc6k?6 z%DWDOn5Eu2s10RJy)`= zEqnuc!6zHSA%60$FCiN^8!qBA!!s-*ZF!S8ajqqDL+FA-=!>Z7qavBpx|%~Y?c2le z^23lSHSmkH@gu)8Qo2NBzw}c-Qh`KCOchG3DfzoZOiW2rGoAbE#QpLBMdLq1iHuPs zmQtj(%xD&|0}WPeFjx$NHyHxe2sYxOFyyf?W7{fS-2X*W@ zF;h4N_lS>P+AA89m>aVo1IZX{?6C*h#*rbJ46!#I)V#nHOu^hid&7p7(YF$Tpe0)d zY-}=|3AohjnGL!!Cd@KX_z_dErKah}?ue(^s;!EXp((+q8rmn}5F0lOK8GxmaS;e_ zIX;T4NIjz)A4tGHb106K!>=nvki5g}ySgnh9FzPgluXH}s1%k2I-7*am^6z58Va=(uT%jpqLRo#!QCIItB~+1q|8`$~-uu5ut)v$E#VR#8pAlF4Iwf6FCkw9ZzUfSu&Y?hK6Y1W%q?jQ#5sqbyJJlpUp1&-Gj+ zMl!&T;E3L#mb0r$;hDutLX%C}O8m@E{oJq)lOC}$$N-HtCgC1F=nj805)|6Z^#~zR zU{DpzD~EZQ_z|YS3XorbJY-5Y#0r_k`v1mfB1dkp)o{R7aIjTd)xi;crgQ{7Amkrp z;w%9{y(2`z4VncTX~Ot`Jra_=BB?^z3dkq9t>@@b)4ZV^YBP@;QZfve;#wQFF({Lp zO^RSX+{{fzLdCtAs6VN`Lc6{y&50}RE*M9x9P3hS&Rn`{6wtsLmwG=g0K zNpt`;#Yr}GQ~LAC3y{+}#g#f`42=pfLPE+}^E%r(iKbMrXpxpZGgPU%%BnIRw!1J# zWgZPvwha6*D!C`UL#w{aR9J#Ix7y4WQ$`*^ty6G?R&Yke!w(sO!D_^x1W6HC9T95S z5NxPbZun3SU@6h0!2jd67X?=((+m5K>aPD&G4f_+XiMOcMp*oM`LHhoy`^hr*XQ#!3vUfGF^ z)!1Pvq}eG&kM+|FGA+QY1n#C#CZW3na-Td_St z7oH0#noH|2SXmm5EW5r0#?xDHx$K2$h06A^%)JCg?faKQ2mij*vtY}q1ckA+PYil zke3JUy(|e*;Cr(lqW^*l6WlaOu7f()<=ZphjjqO}F39bhn0sRFQeiEs(=PI;iPhJ@ z=*jJz6d5K&fUV&%CEXns6@pbdAYNF2)eFDa&YnCq*p1!85DJUs314YqCmt#&j$)OV zV)k?--oawxMLR^DurBuEm8HOzUEZ$RMM)Ja>H$zoMJwzm&`ou#v}BrWbB|F~pZ57S z2%Sq}A~$22L2H85kr`wTC9+-RhW1V5j|OQ)?gm~ZG6FKkbiAz5`&tTOQDi0CTv)vr z?PT{@I8fe9OaL<+)ect@O?tVf8q&Cg)FB?CU|5djh(yCQOg_YAsHc3QyjhkK_M2eF zqC**+dp+jw{QpB`_FOS?=6?-SY*sqbRRA{9G_|N^YyM$u7UCh!3T}SW?j(#P7U!T? zVkQnMLeW!W>DYEoMO<6O_bgO-p66|$DlV4g3Cw2;Elsc4RxJTi)qG_#EW_87 zNVkcw!%aDr3*qOBqCWBEDmvj{snT+`*eu;#t={TL=~6GHijoRzApW$3CDXDt>y|?6 z9`@k|!2jljZR?zj07~iRBmT*`{?57{XGJS#+s#w1D=<^!-H-iKz-C4GjL%<_s(LmE zVzV%OUTpnj-mmnq$mT#+y41>srOP%1Pwlcz2q9(!TA}SFqWvrIB_@i#Ms#Bk|4B>{ znUM4?vZ0+ZUUad@JJE_ZW3!f zWtr91HR~-Q9Yf+fYVW4y*pyA>3j&7H$cKU`mrHLGUhk?d=bb3#EJfy}aEfK#&c1l& z{MK)oLRkO)?@)OQ0cXGWD)4MxQ>;+%1+PC;3uiwXN(sm7yw=$Byzm3tjK5B*1!JmL zH2>5?eL#dbURz|@edg!qiJo5Ez+beNfkt5NsNT2Q%=A#k9ziYch0D;E#%aW{0nxEz zAm0o97=07uYtZOIHe^H&>1}^sLrxiOxHkrZnZ;Z($NaaP*(U#RL7xGqD_g--K&@p= zCjthuF#C1s&OI&!>TLzmR`%AvwZ({>^W>^?J73Z_)N?4}bG}h;L6Hezw(6_iK0?n| zL#OYq_PMQK^hWm_vPNqFN9(lq;Y)`#Ru^pN zDp{)(@e$X`FLpaI`I2PwDqf6PyhG!?!xw#F8W%F&R768f!dXu>T-o zu$dm~9}_Y1bKHy4nOor)p7pIwa zj~`hY&ZI(Wb)nnSLZ41$z2!K6XUJ~_*R+}CfiK*GUqjkdIp|7w8(8>cp}v@#jE9H# zi0`k7ABu?uFOWiX`&M*~r{Nkd@Q%k}MTGRraf^_r^!8e7wk~;5V;oKgjMIr-F4~pa z#ZyB1zse9m1grVLZuJEmUcx@qL{-$a>fMXI0 zg*n!dyn5&=yZZV8a>={Ui(ahOz6J!^XxJwEvJVHeNBgti|3n4|a00<~>;J~>Ah&G_ z7jDCL?cp_Q)}m2_X3^p^W*V0v>v-%KF=4`f{R$S$7fN5baNTM-YnCiouU@gLIcn4? zQ=v9#%A`pXCPzXI^(oqC57InJ^Wc%=^bJ&~ZP>6`qvoobGFriK{%*msYH10R!yV7%o_-ZJ`2g+!S{6rVs%F@ZiE9 zJaAy#c!T5(7BFw_TtR~9(GgIWE?t2F=h~GYH%^?m@bJCI=f-XOg8%H;u3K|RjkvXX7-*Pbf(7QoUqSH2ml1bKSXUEq!R1yIQLKg5 zS!IzW))ruW)st{~ z$nsK4xZsjYE-CpE%r7Gm^U+7kSZU=m7ePZ&G}cUGjWyI0|^w4IBmKq zj+z9aiDsD#VdIcQUvjA>G|yaVB{Cl&Lrjz=IjIs$x4iUHk*)}N%1x$d!qZQWJYt9= zL>Yw?A2BxNVpMFb*oIYDl~_hsB7(SuhgooF#abC=XrU7o(*Gr)5_vtiSA#w*C>Vk~ z7>L+n1KJSafBi}3f_^OEhgp4|%}2s$@PXjoX{)XGT6(kDR$c|;^%mZ6#C3;Ua@suy zoplLR*KPvYsoPv~=YID9xxqys?rz|o*DY-8anK&Nq`^1B2qH{NLbUfitAb@NNUSUj zkOgS04FwL1;9$NA=GU%!MTn~sbkXXBtQo4sVXLc#2o_gjl!yk+SEMthF@YYF4A)j_#7vf4QUoU1W12bV znQDf!Hrs8xttQ%ZGK3A;V2WK)MjI`|buv_9Ez(IS<^R&lN>IZT(@d?@1Sya`_GIZJ zj@$^e&r9KPhl_HAx?+l0(OhDxV6ED!t7x&sR)$iXTo=iD?b_h4gatcnVi+SES$`7i z_pl0^)weJS2^$Q82-vE&Ew|~>RvWnd?v^ib_nxcVyv(uNE&}jICvWu)*n2O&B)rD3m)6mK~A zEM_t*1Icm-iAgC5hDf9| zCBAu0BhSc^MaBjuYKZ9}+Rz3=(xf)GvF%MnWd9r7=ClxPKqMk{s|ZH&#tbWQts__q z$w&e>H72>_a58yCD^jtFq>X}7ny^%+ZbXQpaBvSyxm@NfII2>8PAg&%gI7d1IuDr+ zbt$72>u{A9*Y(9O{{z-x_-DKPJ%(ZuV^(DzCckJcOautCR`IYku=N0JHp^=szkZW1 z@J(+y)my;ztdl+MVds?fIu7{47oPD+pnSQh&H2!iKGqCuee65f2!LlF`8n)aEO?~- z`jfx>?T>#tD9j-l)F1&4@Gf;R8C(vCzyw;MWnvLgSMDeVG(hk~YM`K~awdnJ@oa-_ z^dP1jv7?`4ViTd@1dwXdw3r}?g)V$yl>ee6jAI0G{})%6PpKI3pcyDz?U@;40kN2In^+g z6B{+J%!$VzsOZ3K>^QXb!pbr5=*0P6vrw zHwJ=Hx4lVDXp3l>?gSA%LGdDa1C-W~Arg`pN^phiBI0OblbhT#6hAqmP!M6GH6EpM zO35Ioq%xJNwBafdEW;f`r$<)tF)gt=U|g;#$fy?bFVQTFGi%qF$kHIIkK8JL7VFjd zAS|r$G2UQX)5*WyMy<}1KwHZtz3!NDUa6#OySS&WyTUS-vINffB2Y_PTHvqfOW$C9 z>7Mol6L^bdEPjsZ*#6)zvIL^6fuae(0E%q0CF?8`;_}%Ip@np$9TAC4gq3rSsr)T&kNjnwyPn7LROp2a zx*>D}6L&}I-9K@}Z-ok6N|e+^M#a=7kkSdICZVJFQZ6Z$!>{J_OO;Zo;lHR7@K>@x z;IeQCv`l>qTsjNYK|Tnx4|XQ821H>CON@6%<_z#I2_NIBrmUI+(``tS;(j{Y?0x2WcoSQein0b#uQUo%N}x? z587;muxue&*_sM0TVPng*%dI9$iFFCQ3aurIXSdbDKs*Q8X;G-O^~rBtw3Q+VgWU& z*%^jcBQ7#%h)^8&r3^;Q-xqOg#z)}Z}ku63QO%}O;0QuaZF6~h<`H*zxd z#;|6NoLFTO55z%!_E~)_?GxwN+ShhKwzth~7-L7q%?Y=-$1O{9pWAuq_Ay{(!|rw) z?_h}?=3^+ z^_qiGRoc}Kh0#FUEsJBpUGE%O3d|iQ*Kw8QuaQ z-d!mkxiKDJ@yp|>TYB&kZyf>yoxt{nHPi^YT3+cnVD;~(>v*&P`pI{6fP5Y-iXIVq3}$7PX5mT!sov^EffJSm1A&=o z#hwIF5Np*Q#ogXJ1q~w57A8ExB)nHB?3O+SpKtlop`f8Ks3D~(lyZ>`HN;_~Z3EiG z2{>4vn`BfHp$(%c#GQoHGzg;jU5O!zmoN;2a4F(>ElPR`36SiB8AXmz$X^@X*H5Jy zRR7=~9n}$l9TifIBCTc2#Vk`mY|G1V{)h@MHWP?NSoJnTH zpCp4J4#W8!N}?#rOBIPsLdrc+3K}^AB23ODO5Gd%lm!V@f3;d21=vyTQBn30g8x~_ zTqq@j@rtjtVj{uf+A)$3T4gOt;O|U}Xz1d#phhohOWr{qSn>ly)P&tj+s9>f#Ra}~39FDZvdx<7aD9y+1lgPCM$)SWmC7<%89P{;A za#196P2WO1S8ifo_F*Y+whhh|L`QuT4}BlrjNjf=(Vz_7FSw+pIcL%-4l6KD8Sz9x z+GIeMns&aCCceRbsfZ^Q6&?u~d76cJo~KjY3RH!Ruf@*nz-N3iAUV>fv;Sb_eSVcC zSxaj4C*H-zT+&8ZvY=ZYD1tTzgDxn89-f1?rQ$_sT=E8mTH`eajBE7bX;=&KjD`*J zWnY40h&~dN{YQxwCOW3$l(8d(FlJ-QC}et5jdF#FoQOHio;s~ljKr1)5rW2vP|~ad zDio>HAV~`qpUI_RLG2krIUo2j)I;0}L_Js9)S(^TAs)I(5^Z00HBp#K+NAv)atfXK zjhEmMPNH~`OnhAX4e3qPq)pOS)ZHm}R^3#vnyc|2SjgI}73J3vsuMgFULY#$xaVOo zYJ8HT18UXo*e4~0hOJs^v$dOu$;MnVkAOz#r-CXnT8~=7%PM(WssEnfsiLZlN#itD z<9S#p25d`zdH}83>aFr+=Ivl$@`r!;AjSycVfGubR+)=l**hZZjJC|OGAjhN8ks?y z6>262Rck!i*2dw}O@N^orqD|$$v;(1Fes-;gqLw06mo3|MSMw^n2kbQWJbnG+w3Mr zX(UL7WJ7=yHI!s`VZ=d!m!KeGn!4mlz+`$sqWhH*{8@?`DXe`lh5hlQo3Cbwq&X&0jLI!$AEgO z;wi^7CTIy_4+%1;ys)KmG{Cq4ZP50HZMf=>Ax|$RtMsb(Uii9P262hd|-NF14y| zsZZ)3C<-M}mZz<0Q`l+jQnDxQc1*B5C9xFCgo&)%LDKGE#_vw5(i#>BV5(WY?6)Xy zgpOq_T`vlXD)maQ&QdSWhTHY}Ecj?I<5438v}%O{Bl2WpFU_i0J@H;LtqwY^WuWi9 zO|3JvFX^$U=^>%~W)s0})4|cBWZI+t-Y6BO6Fs7hIB{iDI&_Z4t z&mbm^FZtr2G3f`?-cLFHsto{}unvYFYnGJ>-25`3!4>lTl2-nnO3kRq&FJU_T_J2; z96%1uZM|6~E6oWRDb##xCy&H0C?9NYL>op!DgQUoL&>2;P1J7cW(H?zIA|0{breLD zGNefwAx;tBAmohzwvv-v0lz`ebg~v)(;-z+hjqslua~64^SWv-0Ed?>lyMPhtmT^ z5SihhNRKp+QmY3IjoJz+kZdc+@l%}@pD&O^8WvYtSPw)C}b{Ph)gU>3(S3M#gA z*mJz#GjkvwVUzKVJ$4J0NB2S=tQxIl!*P7r>a@@?{qW#`Q`mq&S(IHCX%7LwX)TNj za>~pjYbP9-iIXCa?QCOEN&D!J5>04kYZ&%++`=^7lEg|r@G>aFaf9CuscSY^u*_lb zMLqW&exwow=b&K&2s8MnNSR2)N zmbF=*#Zfj@q3X9PHdqk<53osCqyHkyfRii)Ld#tvxM-+swlMe<>s|Mn7+@2lgnvhe zKciwphdpPHVsE$@cR2Qb$6igN1o+Eje{W^eV2X=|Fl{zx?;tW!%mO~y`fd!3zc1Fl zXpSSRMpG>Q#!Rz{ZAjCe&X_GE_!8DO7Bq)yHs;aWuJg9Nh(ywYq z=GH|a*p>l!3i*)t@@*yzx>pRz(k)S7g; zE5p6bwQ{--H8}X;Hne+0yt`5pVwobR6*aJ$^71Uef-keeO!9;<=hWxM@OIAd9R1{2 zt1j!3;(>u(e(&1sVzcb;K|}=rHd6Wwz11*;K=Jn$*0(-!#sj2 zHp{m>Jv+x;!91(W{29}H&A;G<8g1ppal+hst|A$J)SJ-5_&JK6(bss^YArmbwrYzO z!YN$TrLEaY69}$bL2lf(CCs)B+ck&Rs7;F&4O&HL&z3D?#%x)#WXM1g`}IqhFkZfV zQ$>$tXQEMHEPo)O`0Y>dgKTZB0_!o>`|&TPaZr^<;Zz6^-UW# zZQ86+vlUI5GGM@h^)lAWmMvM(rnR!x3Kh3hqQs5sgf3ksca`MLYh*~@zCi#7_A!_+ z55qbT<4~;F1`WrLX~>WPgE9;kmoc+Yv6*uU&nZlVCNY{c2@xYihybw~ga_BJJ#f%4 zoAzuBw=rDMegDBiZwnQG2d5xGLImT-AtYCx{6X^u&!ICh%V^NcgjFe|V!$z*`cvBefc z%rL_U^8pAS0t?J9zx2}UE+*=7Law;pqJpip(n4zsvc?Jv46n*S1C6cJz^VDv7$jyP^3`b6J=&aMuJH?SR95@GZvmiCuY{*QB#tai9FG1pR zn3Arna{o$}UTU%?n~of%QlEeliYP>SOp2+daI}#s8P{k-4HvueN<|dSDlv-@+j{H6 zC_3CQ!@Ms1tHK~AjPOAo5@Qet1tXKJvH~$1u(Qwp>uL{*Ja zOT~&R8=umVN2CbJIY^;?;$)|vPf3zVSz>w;mnf<9<)mPKSyanoxI`wSWt0KaqA{bf z#{U{Kt-*#(Kfx{t96j+Y`%XOx3foUWvDum$t+6&#nW+;!W*Db`2}Ws@ro`n*qGwVv zl}dl+k9c+zH;4luwH$@IM~G+gDm37 zEJK!IWfKO?S<_A%AzFYv@K*zVb%XCW_q;6*TzZ*{H@b7%RR96y*Iho{ci}buIpUME z*IRsp)0f}dtmS|MfCU~nwb@CCU0H@5et31rY-nHDi!qLHFbi`v!hQ`y7I{{<+&Vce zvrd#E6^X$sE{oAsWHz%K>1anv>5<}g_7hF?q)0}>Nh*f+Bq-ei7rUquN=A~UE&qYU zBgx1JGoFz`tYytiXTrt{wUH2RgiRoGGFzU)aYGymL~RMt#tQ|-wH2oD863&TM-qjM zMU4a{CrL?5{5A`~$>JugARJFHr3p-uQ-F*CS4Ps0V=uNUs6V zYghBw^__Q7a$b>CPXw;VtqQa!mW&*C6=) zN`4dyLdWFzF(u?rWFC@B8%4wxS7iZ!WEmgXRD-@rK!KXhS@CV;~6G z=RRNPkQTy?A{R;FM&RjAk(9)VN@Gb&Uh=nb;-pfX2t`jMI21>4(NlY1ARew6MyqJ$ zRFxBh7%o?qR%MPY$ox>};J6q2g|3diGF=|^=$Kl{z+ticqY7dtJ7*E{c88QreM;%O zMtUm(!V4GmC|SvOT@sVq(IoVw*GcLbhd9^6-g|sgN>k1Tm8rasz*1wdgSk>bDd3Dz z8)l$dJ_eT*Qw(Bu387vBrhdWv7%@BaA^!RAe<^cjSXw5{7|BS1QUAeFQ(`HaW z;kF?UiHJmGJ2j4Yq_rZs(n)yHHP%5gaAkb9OtQ;6% zDwZ_PR4uRqkz8t((_nTCFulCv>2T23$JDZqnTh4H5+=x{uF|Q9tW8uIIaT&l6*-Zd zr1UK5o#l1adDwwob&Tf#2Z)t;3^pqT^3|JtZLcSP+;)xO=2mUph*J*BwkJ6C5Vv*ShC(9}H;WvK8SaFd z62JUhzDen5w}?sL1ZTxd5lK@;$rrZ z53(_1Xe?Ad`tiR=4Wxkk6Ia&YuB`_y77lj2G|XXo zJ@UgKMyrS~pjNh;7+|Z3tBObSAG+Grt}ljhWoQ{O8qnB%Hr^$U39IA#AvUo<9?>$1 zEI=c-=ta{^vI0?BGt5GHvr>Kpm3v~O&?;$YvCtsWsQ;BYp<-NP?laL9^sqyE?$48St#BWnx<^a$CB-9)o*L zy$5L6c)?Z|^C)cWW0z~g=85FJKAb&hkC&VC}fhRoel&>x&--?)8nE#uhVo z#?YPa3&|0Gck!_?L1Z#zx{AmwYgxUsLRo8C*2z!SEY1i~2*eSof>ve)1_5WzTkIm? zASB7%8eYN^&J$}bbRiJ25knasIz);CHZVlIRt=Xzd0(_0^fbGJDjo2zI*uaB4lFjX?2kzod zU*w~dObnIoBgOX4KeTPz76z{ZPw)`rmI}|@E{4=9M8`5@Lmm&v`sdwHMrACoD=;s~ zs%gpe&GSG{XLx3UdctQc<$`De7M$csI0$K+h!<9i7>a>}O2~*H&dhAjwyr_<4r-s= zOdz~r4FAba$dI7ALAbuqhq%!8tYIQVZvXir3K^;}gnl6kpJ=-NCKjrTqke{h4o4^o z;n8mHyPQJ2c206krHp<~{l;R`IBi5^1-_2XR&+|#bfy06&js_ZSP%rPSB`QPzBkiul~x$5Kn$M2AF1$2HP$2ZgBEUB;E#y-lA!;lx)ec zDVsElvw-9gjL@61FPu(qoMgfYxh&y$A<&4So!qGyUTbP(>&&=t&FbuHfGZ*Sq#F#< z&hE^%@~ojOLb*z)xt!|`rH{~BLjQwcVVtgOCp-$Iv-Z6kWjo{tq-tFxF79HC{s*4N#F>u{XK}7Q>Es zesSy^pj>uQJ8)6$D6kiO5d+1gs$h{liqROOt?rU>6<;G-q~+R3umlw*8f6I-!);=6 z=^7m*8wq1qeyM)C(Hnp4n8MKtD6g4TCM;gc9HWVvXoO~hFtav`5Q<`FFl7^vP_(Rz z;F<(V5H4waA<(iU%(_Gw=BCVMi%eQb%?|P)+l1rfgyR@8HSG){1|{U6Va!@fQI?1# zoTzU$^3W#5x^e;}vrD^xg#Wt;A+sFkamJ7QdajJlDCpYH{U&iHk>C6pv zg32f5(lSI5sa&lTP4U_U1~!zD16omAoH8tt{j>%b28So@7e)#uu38^+40%W-sC|{u@AxMEpHj}SVCX(cq!Q`F~T;4 zPJCJ)yY!waEJo%2rl;!VcNyZ+u zVk{!Qc*#%b;r? zN1`9A(6u}Qwn(!~?uiTWDYw>8A;Dn{6(SqN*0@>-4&(4p=CBH#%OtMW7j^-P)Rl^` zk8l7Hafsskzz@7ql2pozC4ue{)hIgKqF?!db*Ni&%=7cQgq8wWiu5mqvb$biN!$me9}k8 zY>9m;CjYPmD?)U3XLpR<>SBL76yAn5L@)0}Ohqv_ugTc)fpo^Rj4)WUuO64M37_y$ zq!4Ra>mLEqgak57&g@LY7B&ykPZqKu+&8z@HXzsBctd^Vxc3i zPtk-^B)#wZPI6vV%KTdDUZGQQi;hhj*Ky~Ij&jnDm`(>OrgDu1+@$Vx7`7-mw{xTA zb3r#ZP?mHXY&jyeITCeI6(9jr7XcE0bwhS!Beh=CLm0g!K4{l=SC-mZwo}`Zu3~mG zemC4!kgrU&LGB1IbF8o!PkH|`@`838Yjxg?cABVn^Ez+el)?|TDM&yn;81}cFSE3W zCjWf9OtnVhZg!MvNKSnv&h}aeh~{@l<#&FM6pzhhg~DWNl;Jj&h+LO7BQ-LkW}>>T zODE3wCxB$62+>PXaybdt{0!G65qFu?)YGaHFXk_F>24O`ohir?Dj0fut9e)rA8&jJgvqc|aIIZk5vn(^A z#6}e^j_;#d<>2?sP?p2 zFBkmRf58m)TI*S9??(YyY>y9Z9b2D*v<>kXT;aC)wnUDhZ?OADgQiv%l%y5XIOeb@ zQ--1_jG_?1OZ>)D5*M|B%pPKBDnue8nsqs@hp4#oAnyljPJ!n^V?C!0id3U#sni+JK zhKlg4(eUn4it}=rtTtJt za9QcF3gKzYNRzfsb8W{qHTg-nV6(U=TuG;48Vu!7I-(*Qyj%x6S?_iu1vn;b!hm6v z`~3E_QQM;jS4J$YE6S9U6L(*wQzjqJO_gAjaXYsq7gzv`J9~1d`pdua6aY;zr^5#+ zT_d@bn|2fM!=4+upSqW?GMK5G*tq;-LH5GL!>OP8n4{W<(JF|+8~+4REO$`@+p_JI zVClRKgo#&>+}L}YVeoi&wl5uTdBxej)1oZQxoB@SM(%B9@{NI*HuUoP2u;trzPD-- zE?EPue9aeqGs2F?1dq9};{3Re{aC}MgSa-s`OgJb~~Iubau?|`+- z`?}~;zVt?DggFZr{n86xb3C?VWld?)Ixms_NUdOlCI67Ts6-gRZhDZ863V08z;uVo zf5*zVJM6N1lBi?Lxm*IjoT({r%)cE1x?QThg&3DPK*2j1RVjCk*gslq&gnb__ln$X zzy)7$uv8U!XRv1h-Q8wYi_Q5fx){+l4~&=gX0}NY2AqPvssDS|ct#EGXeu3!^?9Gg zjA}OBN24L3f%N#^*G*FM_>`37Po0kW`H&$xkylRR1-Ox~Z*RBHqd4K#DH(7V_@h;d zj99WIBRD$Olsen=Uv&yjGuWqg(%Jba$%C@hhEh+d-MEkY+MgvwPjyT`U3gQk%KNs*T>a+EWpxtMQ%ARj`Ti+y&j+mjWI`<@?V` zCJM&cRlFbzbkN9(7FDMAi-C~Q-5E09@r)_+NGub}i1i-tc}kpUSwGX`yX4`rkWj#u zrIdgTF`P#UTkQmCOp;-N2nN-xT9n&h*A6aVIRKD$PeB)hbu#Sf%2&tB6{ z0Bk^$zt|zM(-=3W^ul8Tmel;6-(}izLzwDct;uNz>#Z&8;(fWvl99MQ?7#gv${qq| zc-$$h+_mytrUN>%Tiw@P7~TEd=`P;E$L_I>cL5@WKota87(B?rg+dq%8OnG_BO(nO z6m8(Zp(CS49zHsH^bsUv$RQ+28ab&Xr4lAATRM3eC8kU&R%+JFf-~n9FFU<>0Rt3F znW1Qks%e8X>6@i;n&QEeCu*KORQL2DLka*->FNP3r1MD^@~P_ejn2w5gn> zZ<4lI)268OGD3s;^tmN_PMkJtQjsb1rIVH|Ri->ya)?NgA3gHWs1ZlSiV+{$ZwN!7 z3xo#=3jCjf2?CNpAb}zrcpwN0ir_(m4tl_W1`9)2i61R{<| z;sYk0h~fhctjGWZ3%m&9iwexBKms<}h(L}y=6IuxG%65dj0~)}Vv0sWKw^>-NbsSD z6>w-lh8S8%C504n@Zf_YEQsKN1(G13fB+Jt0)PJpxqzQT_DM9~MHs=y14r$FBvN`N zp_CGNOo#^)crb4(M>)rwa!)}ORdIb>r4?6RX~KzEWSw#fE2*SH zTU)Z>g3B&-oyvhDxGA6o$9eSXPofq;O2Z1*(XDq`I%`DnE-}q!k1kls9=^3MrfskRAL|{ zhEP_}Bn3+*Ng@PBrbuK1E(R$hjXfr?0|{@awz4- z7-TFV2UuFXB?uFL2`0qV7>a13iz3C`8&1gq=~PusN~xuffTihJoO+tdE3k2Zk8$Vz-67^s;SlOni<<-g*4`3vhd2zn4+h^lAOj)%%(0 z@P80TEOD0$S_~n^85=F-$3lZRa?k%eo1C+hsf=X{pxMh}#-kq5tY$*G8If}KfdBO@ z0zdnZ(1u2|DH#oEN~50#Cg!Cty>B2XpqkaLCIhWS#3EgL)A;1no{^-7UntR+p0+m= zw$%$z+ksn8f+B{wNyjMa${XMKCKX9d3M+*O9^t~miL!L+Q?IDv;u=RP$hjt3s)=1P zl%b4eG(&To1C6at*BD-@kyph+BkIbyI%PFu8DLyS>{PRwywt@PwX@b+WKqT4rD9vU z;Y6mwvWegoVmN@S3i6tgx8@*a4eWxR^nfy`omkH%G-2Dl@YOvdD1nA{3W?Z!FuwA& z&;}}`LBg)aFseNaVo;ly(>(vEG^81gV;bVn1^E{u|LqKd0&Ee>7I?sz&1``|av;u5 z_CF*kse(Zh8k97+ODid@gIa132%+{q6O^!oCPc_WuGUH#wD2Ndd!g7!Lbf~65N$W? zQ%ta@L$?WvCq3~=P=rDh={%tLk}!fZ};w{jyjuCc~7w$Y8LQ{AkZ@r*FSDjBH3V;-fYQ9i(=)U>A+D4gPaE7b~ergP#ag{@>^*V;KgvBh(S^UN0xbJ(_< z^st})EL1=hwJxPJN;$_-;zAwa2%;7)qMx!&Pa6lhJ@SH!dpS*C027#y7KT=4JflfZ zO04Tr<5n((DPh7Wn3}3)cCM-2A1x{i+k8qlV-YTJfy>BpnG0R%nq+jIcc`KKGm}`| zPIvGb9#EFYd*~^p*j^Z?b>bkMYQ+y*5hBaC2IzfIBY`a~R#&@ffU>;Q-~RaeGm=F! zu*D400&8U093B4v0VuxFi5b|U#WEH}(c~G4s7ZkfN)}2SK3dW;j9D&qX|tRq=V#5S zpEPAnYg{`mf??S|6|PL;p}XM} zDvZmPQN?9i%jKeTq5DN<$x3t7J=W(ulU>mHIgXkm3`m{Ds%S}TT5{RNwb+v0wB)8+ zi2RN4go73NGBtTlWgb$(+^*_a6+2##*H*cjy(nxCtOV|tfyIa5vzjlh4Q7abApF@9 zau$9Dk{<{#Tvsb`_ySO}fQ~^XvJn4u#72_wU|VLu6eD28El$9TVeHIj(zwRbq#%xS ze8FO0pvV6{&M-F}l-VH@S!zZ;azgZjrqM2WYo=uQDu?Nb=HetEEnC6j*-vQRb6%eEa;Y+ zoY0z^jet$H z`Y!(ozgI#}mi!yw^m-e?uVdTWih0a>TX^4;*oR654~kJVT*aw)MJzr}F1kP!NBI)- zV#rjCB!|WrSME9MdgfTjH-7P(;qqk!zb`k%3#xR{$JpFFcY;jC&V3h_p9j5>$1^&8 zJ)M+9g?f5EdHN=6a%Jtkr0U*d!Vp{yPqM-qY^p3+*AI3d4MBMgBYEyaVP@xRXm>H@ zc2|_uc6#-8a2I!Thaxh@B6jy;c&B#?bZrX|V-`4LfoEeO7BV}QL5D|KYIkl;BV-7& zZekL7lBWWccTSc^TJym|1G9NCv>vNvHs;}P_H<9B7bvARD77UNhaw%grCSR3C=LHd z6@Wtsg&;UY6-7H|ae)+P7?n|5q!)N}XCFmJ&u4tdS5hgba^3ZOGW9xsfk)9|7a9dQ zHRngOpgUD$aXWWNh!i|Pw@Bn?9Gj**^_6~7#dJ*vFQsN`r)CB5CmvO&FDr3%{}Mj# z!GG~_5e8Eq2qS<4D1#C{W6Mx#L( z&^JcSU~YDXoHeg|ef0U?ymPkIBh=ZHRiTOc;EFgokG$5l$F^so>YDaE)r9UCV zigFitCjx>j0&OQYi+Pto)`p7Lx5K zF)fPr3w!Z#f}sq9!H=U+e2C#^+r@mvCmNAS7+>Tn3b_|>h$?e%GXs4BI*Gs+>G8Eu#Bh!l}5|t|BBDi=XDprfO=#(7@mD{N^y$AvQ69LtEl^H@= z6H<)F*n$TN6adDAczLyu2^A{p2hRkxJ&c|mc+BwcQaxG_k{#c@=p$xDC zJE?I~G}mZ#c%!jkn%>ttJ!g?Y2c(+znw?gp>jIKf#dJs5U;f2OyD5LYIbZ@RrR#BE zRw|7$`E_GSfbC;|y!NGBsUXGJfE&{>#a5kYx+Hc=rz-#BrZ@tpJL0A=LZ^0mry^3F z9&&;mvqA8wc;3X7Uip>cWS^jgWbtOGmxp<70w?&EZ>!~bG-L$%vL`SBmys%$Z_{Pf zahC|!gpR_O5o#5EPzaye6^K-OQZ%Z?r8uTKj~zOPt^uN}(NTZ#Dj)?$U<7@#imS($ zEGRmwxjM9U)GWa_UcpK`b6BId!+jQqtUPx}!4q_dFfOfm9OvRx>LRU6$9_BkbxrD3 z9xI?xT3{@xbuXz(F-fjqcWYwjA2>;$&-rVn_^wnEuVy;0^lGnkT0m~PBjKqda$25I zIhE)cOan^+1-qvildvDet}aNQFi1jVVkSu@ZxsJaZ>N+EM{E&DSgVIb#kGj=hZ*UbV%urzLYw+kt=CbK*CTb@nlGaCtu5)2 za_fKpCzES+w|EPRT}q!8wv#+rKN&_LyVNm2DYMN%>+36f=AmB#!&IR4K5M zD~tz>O_mE}=(ez$8>nMKP7L#I3Nvpjv`(dKx^v<$_xFRV8-GzigmdXnKjCH6s(uYx zy9afiTCSu zwYI-_J5G8lR|&$EJsE5T46g^=Aqh-D>4~1&8I@3ZxYq{35lo)`dX&5fxj=)#8tk5x z#lhPYWGyHH4ePMX2(kQeHCU5QDg0y^+o*UFdZH(UGvT@j3XV6dghhdHddU>#c#bW5 z6@RG+fhm|}feM7Fp>ZY~sOq6~#!;37a#;LDO)D6fbE4Y}eVF5z*o?)#Dx6Ayn-JzN(2-fXK$s+C1u46iEL%J=e;lHW9l$(n3|oZO2PB)J~~%I=9YiN`di z972x=mSI^ngo;kD+(Ih6!vCqUF3fK%QOl#3L%IBPv3tXJiI+;T!z(+?RxzRP^3OVrbpt&<3dTyU)XF4mll|+zUwVvL zvP~&H(V$$?9`eW-&A=9DVh{hU03E%!FUB&PEYjSDrkNcjC+%Y#bZ#DujDX5+?H1GK zghHiNZ}#R+JSb&4t-7`RvA3LM^FqT4x}XAO)S8M=EQ@9l7qgi%vv5tS&a8XToD01t zIbXP#)Eqmkvejcfv|!x~%lnwGv(??rDn2WDiyXKq5ZkIdWnI z)VO~Kc!4(}OCq_}#M-TmG#<1iGLFg)>sjSw5b&mC^OmTJidwu4pg))=1S;IaO|nA$ zWha}dWG2k8_p*o(#D~NQI(im1yEwqBpWfjq^Wh*)Go)VXrk+@+e&Q(ZSgro*PZH}c zt^rKrO}6gR@8eeYS*R0xc{pfqaDqx75uCH^mgE7cM4n|@WopW9mrIT}&c3p+$3*Lh zNRWU??s)A|J=LLdJJv1D%%vK^H||(m?$%t^VsBH5R?g;pqqLFEpR&%>&WC8M#%pYT z=hr;`E|P(6go8fth5l6skLY3*oclL01(S(?tX2cazn;~lUV8DDZZR@{A)u^^lB=Gs zh%zc8@(uq$K%*YoCy(+!g6gS0W2@fsH#V^02FiTOK`{P76MpNsE`z)NjL>+fXPK5g z?&CS_+rS;%tShoJtjoJht%mYEtNUC{}bq}_8A4$$(H}&k_M>xm&+=y!n5KIIP zG@?X_5rhbbEDX}Hp$~`=eelpx(IO5UHZa=YNP~t9kRV~ea8c5v3l=O?tYoPog$ffX zOw61~!X^n3Id$gr(9>s64jP0G9g4x|1*A!lTBy*J!c(YEB}AY~6~a}l543L8+JHd= zunqqfj3rA}!CABj)UIXQmMz+|W#uji3zq9$tXHd6l@Jwb(+Umc)?0NQV-_xg$A3}s2jeqoL5~od@ zIE`XI>eMMzsZzCyRX^4&{P=O<+O;d!e_ePHP{3ab9Ol4b3j75bWQuX{!D1Mc5JCtg zWROA!8BEZ?0~H)lKwbXJrN901!_U50T9FTx_fBaKJ@qCjZ#+lBBgDHtxZ5K;>+t`e z?#JiaU~Wj|$}p}tFOu8>IN*HCLO0!_u)?<4W_xX*gA8I#wINV5Eh5q`(kLU)KJrY4 zkv1zyCCpYz!7|EBkPI@N81pG8#ELqKu%!U=ORBxB$_s+Kw(=@0y5<@SE(H*1)GbKg zLQB!I>T00Stp*L0s=oXJOfWtTJ1kGd7Go?Y5a^UF&Y0e8lO;7vIy0ouL<`d*9=?QV z2p_myh&6;5X^965ao;4;B?y zeD7RN(37#ea1pVw+imm6Rt`CSoGwT;q%HC|B%AeONoAjel1kfRW5S6mnaFZWUmwzy zqFXT{v&>m#h}DHx-IPft%I2h#C&o(6Qv*>k;8QR^{hDgiK{4&>&_pR+0Io>8mQ(?) z$*Rk0t+3jZ(?2O_O0dC{Y8nGlOFdNt5K@I~RmxxrT7{Hig`sB}Y8^979tzjB*VKFk z)}WY)Ww|zFQ)V{FBa4GpT57GO&N?}+%T7l>z^ho1@+L{IT=w2ecfMC%frVWY_k&kN z0qG?$V1WVFH$#6jgi!Z;@lCK`gGH1b7ZYQ7z4eAuVbR4=B8G9|M=Jj&#E%@g+m>^V zJ*IXIX_GUua+A0CO<80gpABZ1U(*sHCKRgq@WOGvXro%q^o%4mQ+oByH^s?lkg;3R zl$NKa5r%C}`P0+_l^3!-04!e#+oI0mH4Hi`E)@(*1Rr3wvq_*+eqkG^3e&W>$?Yd} zv)kQnlDEsaDl?i0rbORE%PEtb1K7WFd=o$?jkuB9MaIC_I2Yh+n+}Uhv*X zFg6}ccC)C@8I=c%*2%|Vr-+z(P6vtdC?Z@~%-)W8#J!GDCv*QHBa(7RRx*>N%!rR8 zR?K8}5F^A-eq5qo{Yay;o$+jc{M(HGFay8&nHaughBQ3MNd6WQ zkKhnAsKk{Hc=)A;{E#&V5s0t^LM&t5#)!#6;*v~uq#`Y6TF#-?<~SxrDq3+n-U(fJ z3NbE7r00w4LB;A?anXyK(LVX{PrTSzuRFT2jw8igNImpXUc_q_yU0%;Q-smxRg^tn zJl(ho5gtZr?~xnx(Z?n!vhk73WG8EqZ<3WhD&g}=uF?OJC`ZYVQrb@ks1%$H^oOQ2 zwbGR>fu&4jNz0?v4FtGU3<7t#lwLN_fe$2<2Z>q1tsyg+%7m-fJXkhpig1Ka2}}vA zY0YbDAe$=e2{*eb0$R>QZ>?%mO8Qn#bD}eyffEfo-O0mTnZ_ZCONh)o`x<<*j0(7k zoRgBIM1U4)NNsQqK{bc1Z1w1K+`-Ye3gHMvL^M6RH5ZH01ylNLGjXJ*u5MXo z*z9uG2jn%HQR%B+0XwR}DrSXZt(!OT29s93M4T((FF9RcP8&`Zhf~$zXfT`E(`*)q z@MEeyUlv;1jFz;zG3~ONm0HzeuAo1f;F;SEyw0(zwKX)=9NTCdC6 z8%kisSH2RV?`YU*)iUW1#wTgqW=@gx+$CKzf`)9YHR;^1L|t*#QD za9dOj*Je6X!yA6eG}-pyYkJyLhAnYqz6t*m0J?-FEq*MFBP-*;+1JrGh9_#c#F|g~ z7@zqRa%qb^R3-*g$xvjnY`OL1Z(UEyTs)6N&jp_`&S%TR^|D9JoLrK=(aZ;X?wZ+L zpXNF5c@Rqv_2`UaP+QhN)NA1#3hdCgv8h47iTmNr%Gc~Qg*WW zowU^ZOY#6_TGK0MxvoL|;S0pP0#F(H*-&jYoUfYIJ6B5rdakGr0zK#v7&?bz{#U>X zR@a4Hxv#$&&S1a9_AH=!XJoui%T`3|IQ9W*;yDC`1ksZ}u2PW6PGn_GZi&x|*0x_; z9dDa0?g$+}7@hLqE$IoPyb~mKX$99|7c{z$Sx}?D13bbLvkMfE3OqbM(kR8tw>N_x z>6xBHs+iDeBuCmF%k!Q-LpcBP^1Sov4bfAtLVKB|f}bscuhi(3_M0zLs;`ZUG>1IHXhSqlBBFePoU*&Ne{z=NXd)-d zoNjBfZyP{{DuhDdB1qsZb3?augDD7X7yN*(3Y3=&%)m}85tiye`(T)hVnD`=9-7*% z5-fzA(kbldk*0b6((##mwUoc3qJo_8$RNrIks}ED-4?pVm`On!b$PDFT@m0;gm6iiYRoOGt|Dp zQo~;JKAWJ4p@F5Akh+qP!#Sj^jG(dC!0pJw^IhKmyQS)cX^Mo>yU)rhAa{1U0!xQ#$I8UQ(z zkh+mWLTI#!0VA-M8?4{EM&X-6Dm=BT7$!s!3vk>*acm1Ne7;IK$3hvDFr>b9thMVi zLli>85L3gWIWhm5I6@hUI>&-68=6D(d%e*RNL|@Md4jgD13QIWNc`)KB>E@INwP#_ ztsr4C*z%l4tS#Fbx81U`yu&h(6v=gamo96`mW&r&m`yN4DcYRPc!AB6+@pKLH<+p@ z)tsq`$}UGhgqzyQ6r7@2+_Qs2d`;NwL?jgv z-GnY8g~>K!zz|fxIE#@vqcca)Nj%#Q733Zk3`(I)I7}icK^r|^{6!l)y$>>fB+#v#E20k5|TK<@Pr8z5FxIZII)Gr7A#!2c=4~J z$B!UGhI~OXhRGN+Ql_lIvc`>k5W{M(J4t6VB`KPdD7~PmMpW% zq?w~@&aZMk4m5}`s9Bxwh@UKv?hQU3O^E zh)9DAPwmu&)#D$NFaKvAGxKKX(IrnOdziG*i7J!|cMSQ3UGN?&kI&m&^Ud2p1lZYb zp^cVUQt@H5oodQmh2KB=!G_gr=KTj?fIu`67=dINXjFU&&c|Sbch&IVYZ6Xao^xL1 zgrR^Nf@YX?AA%^~b{nC1m5Jc#SR#KEI(J(SF9ryOTpTJyBMK>`0AdTly)c}3`|-${ zj4iz1XhSvGq>WHYIi-(y z(O|=IRiy}|R(zf3BArN5*PaP_o_XVlZsKLbpjVQZWt?5jNoSo=iCG;{dLG3macY)G z151};Dp{o}uK&2@ke>n}M3@CSWWouhO4QcbgB|}QX65H)o_!$3XJJ@g6#pO)MK4?#mX&{Nl_sLq)>V zIIC+Wd`n$h5)3B&JVVef-&FLPS}IyA)8_8<^u`_UYFbiN69)s6 zwM0lQ^{ZQj#}GHze8~wIR7Pug2IQ1SKF1lEU%ol#nMX2*6{H`mAy^_O%ZzYjT-Zc94VlSr2peyB{EY=ezxZZz0zS-2W7$ zk*1^$2Cyk0i*SR$Hyv#&Hj&@ubZ0;A{*McbfT>&x2S~-Bt9`I+(dnU*?IQ zNqa6MCg5r&MQAPmO{k{PB2lOiHczPJ?=Hzw_MJW=EV>3GKo3R9IZ zR3$M#V$4^1k3(p;Vt~$`(s8TFz(26rCbb z=OWn&Qd7n=ns2KwBGF!v ztg9mAQ{#MnW?YuG&YbuaZ*!d++6A6>x9SbBJV{YtGEQx07zyNpwPrHeJXpD4wd;P% z+uu`~mbwHUFo%EJ5ndUOgH0K+ap830XU>+kLEz}b)*0ROYM8)CCIufC(-`3dGIb0t z84ru<KGkgGP=B(|It1o5qmETNIIm-#8r9EwRW6WVCZ$Zr2;dAl^*b>D;Hoq8pGn~^I zHae>pz`czzqyO<}k?0wyY3y?h0>#-+>P^#yc3g`S?PW$cdJADT^%>Fl#24gnkp8sv z2zkKV0Kq!TK{Bsj&br<&JDU`x)-^Jn9LPc;mL=n?Wv6(M;ujq|&Me+RZhHXgW+%DP zjfP4-d9B8&sDx|TeyI+u>}^6LdqvQ-4R1GmZgeZTBVhOf89uV^GB?F4Tq7#8x}E7w zb2{1LW-3kq3*%>_`yXNULKr|&@Kon0C0do2!aMupdW$vOe*ZCTsQvA4T4W*2U8=dkG?5Bbzj9+Rj;pX&i{uh`cW$eOl# zNU(0+&@aB|kJr8Fvk-a7cO;)~6aL|#jsrEL_^3WezW?$mZ2Oxu8~VDB{`A4%g)&(G zA65+@>(9J>meQd6-mh}E!=LJr+RTfi&CIqy% zeEb!3HZghvD1E#K23uf&d)H(NNPn7DEH8B%#CB9~_AH+Fc|g}+qX&JvM}X89c4bfo z19yE*_Cz|SS!riTCP;XiCV?whd;ixdD+hz>M}SGd1YqEP2j~$X<8j0#f?E@Bki`Ss z#sffrd_f?DCzot-Cvm-ne$mH!yB7sCSc4zI7zQ_m%R@57(u2;S16b%HTquO&_YqjP zWn4#wNl1Xz_k>W$XYz$UakDBT*A;XaGeP)fL;v7^oN`|L=7(QLfCbouAi--oXo%W^ zbL6BMInb%dK7>YYrY;C7$ zs90!-CyD)rgq0|R28ae9QHxLZHgHIMpQr=UxC7iqilyj?sTgM!D0BjrfdgoXrk4ax zK!eKY5zL4~H}_9~R!%q|jXh9}z9@ddsERB`jIL;g;7AHqkc`X7Zq1mE!iEFwI3%5y zeA%dt`?0{n&=SR)3qdjsl4T?1X7m2aGFLgyxrf>Bo>tIF3zNj^@~g zE--u!185gHbsEWk1}PWJXA`+qjCOa7mj9@a)h7}LcRnNrTMu)Qq9}VX35-SXh4|)z zAo+FpNPrIMfhOq@Wrj6BS&^D&PA*w;Mfqk$aFjDuk3vU@P1%qS8FNwj5ott)$EA*~ zvIBxgkl-hNUFnr^QC?wqfs`ncPFa@!aF%Gv0t?766?rLD^p-ysm&rGmfdO}&l9zgE zdcYu#5XloeD3~i*e2M~rC@7cnC>M@Xljw(&dWnW$fCld;5}Y`K4G4SrhhHZcQ{u;! zo#~l)(-ox0lzIsav;Yi|XPSK(6|Gk?@zQ_-$t+n2fxjq(s5qOnxfji66J#iw4Y`|J zFa{6F25O)N!0C4sNu2n%ZSZ)9r~kN|2ics{#7H?1ow>Q2)Onp?fSq9RhE=$l__rl= zSdClQa1uzK;2}pJm7Xy8n2-q!PYDKX@SfTk7g6?%t#V?aNR9Z(h1j^9{kc>CdXwv^ zo4YBQY!Gt?n4rM5AX(&i(kGxw zN}vyUpf@TR4MS7{Nu}@DW&yI5kph{Khq;BZNuEZa1X{XFIDl@rDUx6M zrPaps3}GjxYJi<=03NLZdqQcc zDF%K&s-i<6tDTyt-^h?k+Nipk1ZW7UrW&lrF{}dVnwp8J21%Ynz^M=N4}I~eM|Z1E zIjXuDrZsA#57H`|mlNEknOh02sVJ`aaRq8thIA^ey4tJn`48HOt-?x}ZfP6gxtSA6 zp&g+F_zE8T8mgk2tGY^{clw?P+7Sec9|w!DRwkkL`VT{Z1P(i{9l?9I8m$Ccrvy5q zrYd@ABNfHaK{;I3a(1E^cvL10SU4ezid8OcL1cu79 ztU*apU4z1zC^;U7G|(umxf(nE-35${4d8OS5&Th5vA~kBEv+ zJGW5V8Iv`KBdn zvUh6*nClUK>$jx#57qa%1}di48V5$}5j)Vh_}LM$DY8Q_xei;mlCeLT+Yz9X1)Iyc z9axrzi@5H(xJFxz9g(c|MwhQ^w0HXtR#3a7cDn!vx@Q}6!RouEONy#1k0DXH52Ce{ zbhj47yt!Md7{lAH8e6(h5go8*cuotu_>sK(W4nd>XpaWEO&YKQ`wyu~zB}=__U3bs zsJ`Qx1pw^69GJV!i?QJgsqTuu#}SO2YN!efz#Z|vdiS{pdcXslxC-1E{OP~h3&CDH zz_jJrnRN^G){XMjzpo!RNbOFYGL;d^2S25C@(dn(0L+{LUhi%<~|001HR z1O*fT{{Sqd0CE720DJ%d2>$?k2o&f8h{1zFgeWY+kRg(X50^-s_^+bHix@LvECO)} zl8GQEHW^70N)sq3QEFVtvZYIx0|^#Hs8C3dh8!V&49VoB&wo01h7?J%WXhvIlPYZ) zbLK%HHErSy3X;i^o=aEi^f**vQKLsuO36w#YtyGd64so$Rf&=%O0147i?O57kY7id z3=2gH6uN+4o_)F&XU>Oi-(I~sH!#qMUA=zY8`kew$Cxn=M4NV@;loH0!8WzvLq6UUIds^%-UuawKM9n&@#RfypsIz`7_@)dYw z$weurY<*lxnBHJ<e#hfffoUUu6bv zC`B4%beI)$&E51IdT&h!mT`coI9Y)%9ydiAGR|0=LO~??8IHPTw_SHB;`JkoK}s`KMj)MZ0P47Hw^l&U(YQfEr4=9;Stdd0QG9y+H(-Abh6SGI;b1r_5awX1gL z;wo;s>$0m+v9b0i?`Y66J1rFflbbNFlcJmM6jwAX@I~$(+m>#Ov6rT=6kGh$!zZQL zSGfPKTCvC%|8wYVqAgY{eYmQ-GPxL{^am}ZkYbC^w%9_8&_okW%h5%>gz*uLE(H3~O zw6o7Zlm9X_*?`kxwlP+Sti|DoC!Tm0j5qH1<6V3qc}vdGi5|z_wnwv-_^OPxPg{7= zMN3@=4Rqjvn+?npT4<#B>smlAd*hN%&XT9NK}a%%HK%*^%`bf+dP}vzZSVs$R3H_K97tM`I zf1SJ66Dy{LEJ)EM!aHIPM~J>GBG4FiQ=Atg2SyxT1X*<=QIpIF1*!omgHUAS;d~Ou z0ERGmb=0C3QJBKR?Xizxd||Rk6efkC(P~skuVno zF_}pTUXPQ@lHtOrz{{(>E(^g61Asa2p9pjY9PIXw6?XIs`P4`w8e+d(*2|jw!)s2l}4eU?KYSyHljHxbtXUnn3}v98Upe&2zQe6U2jx&5zz2keLfN9}FYOfV=# zSx*Nu?!C>8(R1sATKiU4zc_|1K0X}c?T%Q$``8CO2w`HkeM?l$x@IDyNJ_`$t+{28 zuV4BS-KSDl!#U=!ZUg+|-R?slUk>w^;gN|VkA?}nsb+Vs$;*{RQU8|ieX@khAme|W ztH$DFEspoR-{6 zjA~q$C4ly_pa~u1LYFxsxpRx6FSzD~rnkjyjI^xpNoNXcsJ@xTGN)gw4?l-m%wQIC zsZFhs#3Xvvg)C_rQOe#d$XcWDEkl$mQXJ!88m5iaHIA#nYhMF;*g+09xP^Rbj2OF& z$fjBpO!`$t2G-elbMHT@DB(0%tI`I-b#*hm>&AMz*P!<9pvO({VZ*}|<+g~iXU1wN ztUIWWes{d{=FyDU``+A<0;Zw5>0NWX8vpjTsD)kdVe?}jC;#V%p^J^sG^v}0pABnZ zBkf+%RU9K1H*9^XfZrQ)n%kZ3G;Fu45$=}!=qX3}$}{qo;jU)0K(!jy8Z7aN3(qI^ zR)fy_GKGz67|TEpyQlv_^o$t&=mbwWKh_S9P-uj_+2L%|PpV$fwz0i&UT)}qlJ%|k zh3EU;Gth(H>5mWH!$tQp+D(q~wL6~eZqLXP6)ktKspjo*;0gcn!jHWri!XK3Xa9J%bK>nf@{JQhRr!=HxbF4D`-?qaMev25C8e*( zl#K)Uj&IxFLH{_&-?0zaFMjqY&wlOK9*@XlBzwHsEdTF2OGD(U_i$l_Fy4p{z|mhM z4QSB1>F103P3t=Bg?Bymt&euvZ@>24hkGa{e#J#Y3x;{Y*Eq69e4ux8q^AbLqI@mV ze0(-|tp{?_w|^{gegD^i+_w@4gJ$FRCkA+c+QeRY7iq*NIh18_5IBFw!F9%vZQBM6 z7npw-IDOT(f#ZgK9@r230E9xw5AgtkyCH%IW?pEdWZBeWDX4-Tgj4@OX*l>EgQiG`fu<3%*La9HhKjg|jmUIyp?hbtuC{GNPT$VU->-Rli@CBQAhZzx!FxVZV z2z}9afu;y@DUh~!HhxZiU&!C z{?HHpkdPO#kiGXWzn6LSq<7i4i(X)ng#WdV6_Js`cxm{@g&1gz7?_R(xf1_(lCPMO zN_mE_pb_*^NRk*&EB26fCt7(&k)hX%IXP_^!IR<0ksT?NA4v`&Ig+)9l+C!5D=7<3 z=}zOk;Y?%>m$yvR} zW-P{Da~L{NsFgX{5)p`Re&Gb87>Iufn1RU-{g8bbL70Sjl4_}vh?$s+i4hXAdyct; zaoL1nHJPCkN0#Y}_x2L=<&$0bnShy&{;-3kDTGLwno7Bvhba$DnGw3jdrCNoak(;8 zSC>@8jd;16E>U5eS&m|9isTTOf&cjqBB>F^S(wSGoXRN=uAmWX$a{T3HI4Q=$u)D< z>3Mh=Bih*#y~&s5_?h7;o@DtB{?HPIshaAUpz^R1?@1wK;wba!X7zZ9H5q#OSqApD zoijFHRUm!9iH;yDoEK4&7SWC=sgfv~pbE;MXcmbIMTr|^jrKW__{fc%SXLRzpBp-i z9}1e``J)6%kR)27&WM~Us-6q#o@Vr-)L3_+m5U3wg86u(7`mVGMQz-H1>bp&KPsT) zzz+UUh+>KnCW@d(x}t5FVoaJw$R(psNRd-oR&WWvTA;ofs=*qp@^A|*;h>3XfU5dtP}-_l znVT3It-RSQ7M82xiLKZ=pxU|;DA}#}Di6KT60x~v_rgnZiGJq_h0MB@87i&Q8ZlA; z2j8iyeEOqgIS!A237LQip>VOL@DCX~3Zk$SwQvg{3$nh@3&9W!z5ufPiKSk%XNFjS5OH+i&DNE98!9@EwDN%rqoez!#9f zyW=-jlV#g2miTv6=5x0?TRU94x611fD2=zOyf!s6?jC zakYE3X5W2=$-}KdJ!|DbXv0dVgY?v;u5p}EDcZ@nGLHM{&s26xLC=}DdX7|wXSUMr zbdcZ{sGhYZLuTr5>zd?mQO2W~4<$RM>5C`npw+CqmO7wUDgZ{kU7zWicwU=-R@C7* zwdm?}Q<(+b@zi3{br~Br7i0pLUeS$=5Fa}#V$NFk0$>Y-TB;E`4qj0pFW!ptZ8>Y* z^HDvE^uJ|#<89W80Suk5HUR9bUaY$MLX74aoBWONd{*yPiiw^z`~rQvPC8xW~5BqdPGjtDI$*Ja7l zenbD;E-#_j<~Qnjzs7ng+FBjX#2}{Az14(sR@7;CCEJGj z6AUVljBLq{013vk4LkF*0EKcr#+lX5?TyKAD0ppS(zD-!)`$9Rkn3zm!ga^#h2z{G zd;i+>YdsEFBTfjCPS}r+#-5E12_T1&z>8E);5ZFqz?asxN6gp`DalPT=ffm#7uWhs z>>Eymt;0nkPGQ$E`SVXCY`~gaq3ooLAlXf0v8zi$ z@V!iQq0Qa~ENn;d-qF0bXJfAZgw4Q;ZNO67%@@qTO6yIFzD*({&0>Cb!0Ppbe1cYO zO=*wn7kGy@z5e69J%{NuXUqss{SG73H81}@k7*=oq6WajY*i<$NX#0ecpKK$!}4W; z^__u%TrE(`FZx%_Z=AQMoWbu_EQ%f2Lh_VnbO0fgc0BT<0#-`_`Ab+vux1ZS{_@Kq zcFWf9D5FpdQQsFjG#5H_ixYhT?lHLOc`K$L&zYHw&|L<;uPDEpwh=5r45zS%hx-Z= zDhP4n0#DpxfDnc+RWzC&`iDBu6$jCM7QXOB#Dp(*-EB+S?W zdETdavSY98cfk$+1eYD|lk^xqWZGD%` zcmRa%o%1uj;Y7GtDGh7>3r4pBWn#sTs9fm|;@ych1LlzRY7mFW#YfzqXO>{ThoPQ0kad z!u}}VmEPjaW(MN^v3&KcP@(074>|IAch%Z1?eHk|L_O248ggx6Ldmdyxj0i^b^AR- zqp@(SmnPw>uyLf~NAq_O%X&}iNE_F*h;+w+7q<*6h}yMxOSX*=o5U0~l{7!Z`c1XK z3{%^KB#g5BfY>#L7j`9_Jk^6NlB~QHJBsqU#n7kXno1&sW6pBVllRnvG!73FrqEd& zt6Tz)dv_!|QI;)2*#mKiV?RD80*5l<+M6T+zvvT?56N<8NftK2!MK-jvxH0K2ctW^F&S2?l>uB>Wt z!!gb4!aT7lxA|scSL*eVR~71yg*f);EeWQY_Eo&INsM zyJiR5OuLrt&7GRogN)4c`ZFxsT5EpwJ5w7&V{Yn*y9{gQW~coMhn9clS#_t`5$>v9lEl4m!H%Q6#&{W10Ljqhj|*5YiU-|G0gs7o9J zByyoAe5hYY)_V}K^oQWuEogL9F|RxS(c@lr=U1JqjAFi+SoY$t(ib=MVdV@DQOCO; zU~<^FUk~%wo85?|w}07<|9z&pFXX59d?1)q_Iw!hThC=DKkDD~aO|Vs%gLE@GvApW zC85Q1l8UtTOw-zC%|si%eamGGw_p3ce=&XMRi#D|Fe{m9>!F;k@lB71u<@JX&pNrQ;g5k9*J>1 zCaE!6(%bT|;2rC@_S{Ws!#t45eRN#^r9MqhtEfx@Q|8kqOCl~g37y*L7<1=M%)X`} zhh4ETX{oTl9m7;{@Dk)xz9*KJmmttTeGu-jHi~hz4aRxbD8?|BUJL99I72N3+ zjR}Z(YEcl>Ukg|K)tSWL@;8<$M@8B7*%CJ}q*lx%MMDmGcfqE#sE97u8g>nQSlM=8 z<=~FLzMa$Dv5my+5hc4hU@Ye5>GD-lT6*SK=COW$kb!DGePiQ7z2gDt(tU7zYv-k< zvwk4_=~P?vD7CI4<=xunKz6=ibE)WIjvpB zE^tO-JY?k6^{jzgtXGmhKVUM@XfZ){NnepWrec4d2&twdNS z_L%P2e4KjheC^!E(P~_)N3ylINM9DNx?Ag)cg_5hec?9!ydb&xICk5026}YambL3P z7>=n(p8Qo2^%qud|Mjn`;(MzT(et7~7Xe>O=lOfLYYqB4SrfY9IMVc;v?}&i=}`-9 z$kvl)1JR9Z+S`J~w9m?~>_0fPEd9SZS7vHzPOce!a~TzG=PQU-cxqlDXJ3)MZ~Aj? zCKde;^5b3&s~%^)Fn5SBbaziB2u?SMyC0(V!0-6BAr$DZ7cd~F7r#!p7VU11bz#i^j&qqN8N+DoC0G?E^jAk(RQy_0^a89X< zCAEm}RWN|ZbRFAOOf!UeM8+*GL{=(T-ZGf?2|5Iu`+8VZ?burp7}_i8qeBBBo)}CdU)@?dii9XY1Ptvs7wmC*`!E5xB_>UlAYv>j~?N2hamT6X10mXn6%wdj;Pw z5=591cE;`>q^Vbv>K_L3iWq?};!!cU3NM2VNYD(h{De@w4G*c+w`{eRe++ow4hMaT ze6@ftl!~l0j4TI5R!9Z32f$-p`*oDUcsd3lgM#c@JzlASk*)CEu+hEYz$2FE(^7;~ zOTfCZTVr^TkVLpPkEXXa*ksE_0 z{1Hz~gGj7t5QW94=LOY}<9%m=Mm&%s9)dDmVmac?F zz5oT?mT(lGeDQ?RvW?IZkI;ge(#DdaI*Op4j?fg3&>4`@zKsCML+H3dFWQv$T0 zBD7z@)O|u|U_rp!iT5y+$;1h#`RFofbr5UAj2lUST}hL{O@YLJT&$9RYJoJLlLI0E zT|!uIXlY4ZQ{`wu-7FbJv?;l?1eDAAs!yuE z@j+-($*lPyJ}YU2E9p6&^w^*M^BbZCo5H4~oY;@tOas#|!;_n=GMghZvGZ9y4Lvp` z^xmGr@`bR@%F_KJvPR0Y#!o=1u;E=xupvSTJrLes{Tf(0M#w`E*{A8rt5$&Z2(v`m z9R0&MEZ*$-6{yDaQc;V7{?G`t*A&}$ZA3J;{j(BCJd}Tjj)p_`G9BDq@`eIb<4@pPJg}NqQ35Y)3cQc|?E{P_zVY?xYAN zBlZEW_TPyaL9#&0_doFhVtbB}+9DBdnhlr6k^16+ zcx1`GEa}@VsU$?zQ?a(WV#P?#VEA__w4;n{DNpmaQI6f2QbiQJ?->|Y(XVs z)*scBI`)M4Xr&r8hW*+Uc|Ig&;=f&cV@MZq0kKpYMI^3d|s~K{tdScZGU8VEUwm*njW+$ROY=mnE?~^wdCZ z5agscFBr#t(KuQl z^$C@rhlhMWUJT2sh<(oXdN79coys6i=_WjZXpZ1x>BrHsjv|Tp*-bLpFlclbxvr_rMHF39vom@>nsulMkWzaPbFrjuXtP@3CK_)$T0EF4U( zB^4ZvT;&4h5hlsP%5h271>8xBA0I}UWR(`(k))9`n6A)U;H5leP7XpxUtSD$1xp%N zkDZWo-q6W&PJN=ctsVFxdtN8f$9h)3x?)aWQYKPvQ`n`x2CNuDuBeJ%L8g_*iJ)}L ztV*ZjW6W77IXi1U$2zm;9E+v1_DV5^VytG(83(q%>5u>I_~Z~pffK|>y>2oa%ft8^ zv4;MGc~@x zUQ;-1`95Cme@zm6*;oDde0Ws&@8!H9Zu<4IhCSi#L}e?S6!bAg|8LIr67snE)sVBV zG%h~=G5}W2;1vsm;=`fjdxIV==^@_ru5}fZvAn*+g(HMaRulXcBlj}^By^Xe7EQK_9T*hs?(66HkW>C0xX|!8SP3ycBIRr}|KR~S&~=ha6#<82JsksdAt(Dj(tC9s4t_)wdO1Xq8!t9xEF^+&;bg*f3N7@H%Z`8r z4!qp*ZQ2v!Ao}PB6XEM8crV)JrqAf1gUH--j|l=T@gdaPs5f zG`_opqadZJ5`VmIb&(FOFyw&rhtS;0D#Y!f;lzasPW%-RUcl8PJV|GB&#NnrjNNR{ zVEf~#ZvBvLiL|-tui!aYbK^9)h3MMOTBCR4!fgq2n}Nw@PVf!OsK)EhYuvGf zd;8Tp!*lIg!XJ1wjHk&On$Gd9%dj+pJ*e7%uLOqsSXksI@>jMS{%^|a@fa)M z3Z;6`aF(gYND$hdFI&K$PIKBl90-+qH(P43zzn1NGx_5IbNcASzTh}$(i)i~?<;{Z z&v5$iguF}e4*otV|F>MMO$YZ!0rMa1xRW+mE}5K!h6JyL#JR|v-m~7vJoKvr^YWHb zB)&$Mkt=hx=FW^W49C<9Cl0o8sQNE?U%=}WQ1a~1?A(Hbhj$GVU+D%&NSa=P! z6LCs-$)6hN@Xn6war_92v2bW_pBoKpV$iL#HP3uqKkBY)lzg+Yd0lQ>@ndfJzWbL& zH3M_!p@G4=*Fn3Gf8%(OGt2Yug?nZzVHzkR$6#__v_qcZqyv5A_FwOW1R8wH=|m3(YpLNe0dTA7S*}$z8-MMAuj|;; z_tXvKmtIT!li9Lj3Fu!aWZeeot%aRh5D2f|y2Y6>m>=i3|BZS8rT591-Q20$Z-R1P zMkhNT@bNlalEZ%+-*SsuTcHPSZfka>Y-JA>v@A8kj?!;@J+I4a- zmMsJ}CKJ3s`2P34kNgk;5OJcW&imEON4%gM@_N?s1QM`0*|r1{^7xX$24R&32_6SCfS{XZ z5SX8WAfH@x3*1`LTzPqXTdzWpuLF|g&0H#a5<(Iw5o&u2ph^m&M z=Ha0tWuZDCK<=>rJ9d~OO&E%Dn7L)>ULKTaYZ&2Y-wte`Uu!T9D>9WPP%u1{{}+PS zNSGb<$HReskSEk$7O$UD;XjsxB8~y5X~8ka;bg}MIKpAaLZL}Ck;#@3X&}I9X|T~# zK;?2I$`dLKO?dKCusaQ~^a(|O85nyUS^b3C!V+5Ofn3BB-4`Bo91z;;7=@#Z@NYPR z^eF%VCuTGpkQ|RZ;1ToNJtmnYX6y+?0SEXYkamtl&Vm3zIFZMo*weDuzHsEdZFrdF zn9Y&!Y@XN$5MZG-_N6uMs5a&rHmId6>fSPLjwS}j2{Fhr=Cw7xpfx7JGAiu}Sfv?{ z(H4Ni>U9#IfY+9QI~sq&f-FH3=LZ{usg($m9#4>-NZ1zpP7_zl6Th#ShyV&05JJr5 zK|VImOQda!Cpk$Zv5ccg4-nx^7I}_XC`*!ROE?yS8#YWJ8;zQiN>)h^h<`%ai%-@} zPuS~0TwjivK1N`R2oTds;`B_^ib&BpNy^oXhr~zs8YXe{B075_4wE2?Iw4LdrETE+ zw*#2_v(zVrPig;w-VnGq_F-faerN!Z+=$~&-w*W?*bnIa9|y2@BU{+4un@5*9tPap zb{4A^2l&GQY>X8|Ve+xVjAlHZ$-~&4^|jtYQAW_0>Km`Q>{KC71I6`m655}V=q%{> zq(S((3VMhD(pVEc30S=@aslp7g;uU~d$gV`>o`Edac?Xee~G&AheU&=^r-rIu0p^u zJW+JoIxZOVTRZtO zWct;*DAzGTh{lK-pu$5Ms>m^-f-@xMu?@@)@W>0Lkg$vnz%!mVq96-9HjW}E@+iQ5 zEVfLrCG{KGjRjwo6~-zuSddE)fQ|PPq^Qb^qB)VJ0k|uSw8hD|3SvXpraaGzctdh0 zl!-&I$;GK(LVHPRi+oOsSq%e(sl=7Ryp*(xMWlzBUvQI3vQ+9Lj>OCajH2j*v1E?( zgTeJj1ui8!$GH$3ljEXrb?Y*^q2y~6T(f9tbIfoonaHvtbs3qG4DIyOc&}Bq(~9aL z2t0j$ZK4WP(U)=~M8?9^-LsmWF*=5l4-%U-Vf)JUC zDpu>V&$MZcmKAoG_C-6;Maz-&cAzgS&s42DLpD*JcT+Z(osO+h%6QgSQN;K`b7(a^ z->?~KyKeBv0Yy&de6_u(_yRSo>bjp#@Q@`dSqBtZJebn$1U^SI_ROf&NgFlj^`)iV`RQG0lLE@!hR0u-A zvA~dNJ2B-zMR>QQp+nd>H68iRIcm)Q-4#=hCA^f?d^o0g{YU@X5x&}h-Tk`xEu^by z&2;W_%Vx+~7iXmQSc3abw2m)5;TPe5hubmiMCJtXyPsheQqcW&@zIT{i?^p-^mz!h zrT$S9{76HNJ}d6ud^vY@Z~~qN;*-Cgb>0&3|1Fkn2qj2wxbVKLj(YDnE8F@^douo; zsDpi8a=L?6pXVb@Ua89Ld;f>{()Xn7?DGlXoE-7Lr-dk#XbuSIx9{Wj(scLxlwll9 z^+^|Ft@!%41H^&*z<+?00l9Wt6O5ir)>&s_z-WJ_26gCWfJ^!7b~(<#tSyg1C(11 zW}41ML9Y76L~w|RU-F|Fdw0dUdBP)SuDJy(3s9NaMk0@uqc%wf#63o`mX!8m}Hf#PDk07=u3gp%1JAw*%gNDLK{a}uBsH10T)y^1XO z4TegaRyqcw9xvH4B%VzxL9e<9FVE-T$AA&ME*3iaOmqn?3+tqn#BIimtr$5A0N##? zMZE28n5!uQ&N-GnbD5x&3ub51zerNFjiFSaC1TPB+>o_K@QrFw8G_<9UziKIqZWdp zQwscdn+GdzDYC?x;3#pMb;waFKny=A+#^czx;*@Ytz9|B`X@2uQ@NBVI4&_3qX>5t zMigpy#_OYI=qaRxl*K4KiincC{|)l_YY zGNr0g`RjgF524=jA4pK#EqH3SeWJv#EY=D_k*YBaoWxI>CqGoU6XaSs(euMAboXA= zTSQ#J#()ZmjP?)ZU)cE-T3%Nl^$NpqKBV?$_jiQGXJOJ3}g2{A8sG zb%%1ibuwFo9>ay4@akMfYGXzWy#=dv#!NkiJA|joRz7nj3UaeYMnhOGF6f;!BNI}E zo?hjs{Hp139!xwe&m`M7w!TTXXk3oJ?O58Og+$4Ps#!eZ(qgl^@b9pF1&PVM%|fe_kq{p`!hV5Zj& zLLdI-1rXA)P3rnM#NT~oZSl58t@zv_N{0iQ?mT2S@EqT>zRg4FIwbx5G#>Tu4wTz@ z659K+nA?5(5GFG#!Cj(6-mdqs(iqs#Nu8)3dOMrsoG-s zOmd6UPR-kr=@gT!a{|7r(%EE_f5N2ThNIa`lLD6Pk3VyEso=0uI^Q2U^)j8doJOzv zGZ}u9YAJw?Gh!Z}+wNGlcN2qbqxFh;=Pnl0#_xc=e+l3;s=S`?li1N9rz-uH2=cXO z6G~g7DF4G{-cDYoqv^mT%Qm0cNS(R>DUXOG~_y)?M%QlRl^u;xM7Q-TpHjb%s1XQ-VBBIZccV0|3WnrbX9rbe0O@W9U{P(qUQD<;D{+ z?karfIA$)T)U@Dbw9~SJ)b`^XaGtg@P9#`e0<&lcq7AMryeXv?FG|j^DeIWBw)Uwx zwU(_OK(?{1>sT!)YHLiSgQWL~Do5|r@SMIDeH_BC9 z{5Vt4L1R>F%`a;Mmw$$7Xk1Rb?0$I|cj!J}WviC9E>dPuwsEX*ke+-wyZoVE=A_aK zbJjS7KG|M@-mGXT>|ksE(-eUPDd}yxfhNjU4(rZOSF^A2Qz6qRM;yWJ2v_M@HKwi0 z(omD!=i9g$HA_IfgCv4!{e&oY$K42ZE@Ct*q*V?NAD&z9_KyfR1Lwf^*9QsA3v1ox z(Jw0u4HM$S0AQ&IioEi=jK3b2xWv&BN3+!uB<5j+etdRgnR=Gcbpyil-0a|@lnq$L z6292m{c!ZJ;0L*9&bFqjR<{YM%?Ja93X?uSpz7$3r)?R!nH-U`X|?u=D8Fa|d(Za2 zxC`gU3q%5^nVj4iky}6SYY}|%VZy#6V8`EPa{bw}dVWRj>kf@Ofvf(t*sh1LBc?`< z@!=!ihi#oZpNpEke5>oOVMY!Dm*eYa@g9!`Ng|KdnpL9Y@XeoD!V&yMK(s3INaBB= zDd(0AiStICnBdNZq@G=$=xdLPz5D_KcYy@{BnnsS4IHCSN zf{LjOW(yB&w5b!d?m8K&Z&8}W$7Rw|ZVxv_Gm&{rEXFaK9FLVpBCz$E!g-<)4|kdH zJ9rk=8BvsQa95J&OFiHVYoRadGl~S+O+vf?ISFmwh-d;dI;4k!N;U{i60aa3vPkm# zKT;W$*!tu$fdd-Xf>AkZH1w)<3QFAPINvu>;^u(^M!Rx!-~IkH>I6!0eJy~9BNPZ1 z4)*`r>ux^re){#v?Ehzb1U%4DxD1Yn8G$Ax`Te0txO@ccwf|vz<{^Fm5n6s&6Yx4p z^#&uNmxRDd7KnwLq{e4SHyDp(^6)NBSk963g`j9i5R9=LP8H()qQi`6G@edF4iz!w ztt(%MRH?V#7~?!zNQ4TNiQ!Wt8>~@p1M78Q!LRz85UC)Ip($jCx=wX}A8Te_^H=G{ zi;zvWm+eHl++65rDcKsa68sxcmHcVG||dBTB#}$MTDePvEQmxZoXORaf?Hp zV-uSr@7=um$5}&PeWKPiyR*)0iAX_!L%R=*{&*3yaJz3$2fwrU||5q zm1j6V65v-B8im=5v*+ZRwL=g~A3IAH_hq(pFj4M>CnuUiM2aH7?dS7wg22VdeyXl> z`nIPkwB`Xw4KJcdNZWMwAkiA!W}c?ub0C&XpJ-)~@=F)jIMv}H{V-Q2=wv55WQtV+ z%lqc!s6g)DZK;~cGAUKQ`xj#v5+D^FSz#8JwlbEaxC~{niMH2CF)-(ZCR3~N)Vegs z4?<~8Sd^+=TpqA*1(nL=w)4UEpwGaWdN~@DRZY8Iv?LR;bx<{3&>zx8Pxs3LhRH-A zLvgCx86!#bTLM%gnTpLt+md<5->Oo#j`RA7se}P+Co<2AuDOEHzXZ+oXN;W_Z20yS z7P~fAHN)wV79CsA=T|*oqUcL~6V0)jj)^aCEaU{l*Wv?ch2EQkh&Jaetpvahs1ZG% zottrkkn=MQ^`CF{L)0)?H&gx|pHDybBp4gV^<9+jW+kZgI8-=~PX7|{7Iv}^XM0pq z#u<3zH(|3ld~ckQGEieDN6HnrU-9=ryjwE#X1vq)7b0xxvA84{B{r;#rdacF{}5Wn zIflQxZ>YMXMGS)4%o4t>@S^89Q*65hwSXZE-8|abZvf7nY!BjZmdNRowuOl&hQ%It=b-+!HpI$kV+eckn2g&Qz^DUT_~oQ5QfmD=)w=6&&Z}mH85ZmU4I#mRq^KiBiF0Pso&uNH3f;&mnG| zbR;|0U0zWw6fKwqmGep}7d5nu-l{-G?FAiP#gdvU$!f+EYaXkaB}`Neb2d=~gZAuP zihqxG+7m32Poh@FI+GWc&^}VcLrAS6up2^N+nBeye#m74KNo7uR4QdRCaE4N=S9bn z4@XHSWnujXNQPO;|5r+)MQb1!`o35xg-*(6ALVL+;!GbP@T*c!HQP=5w zZKNw0xr#1yacrskhOR2kfae~avsFiSLl)|sR!PU~%91o4}GhTR_ z@z|L#$Yciu>uy*-bX=)1xQu&mzNm9ILc+hQ)XQp?+dp(&#xVc#te|_vYwdQ9|BGS$ zx&`vm=$U|mW(>GqU%oj;#+j-OxGDa z1T}Pw(fUb$(@xbAxpnSgwLB5K$1{ej^6$YaK8{0Qr4C8mFGWF=}<0<0c zU<_p?wY-@UpV^Fv3$mrwFc?`;Jjv-Q{7TZQWH$M!bw5Ed#FpwHfXde@HR*B4O7w8P zTN8lWO%cYPeqd{^cJMsIzsXKCvwQfY?K$C0#F32@V=3kjg`@_1l`!aYAUuwXV;k^W=bg!oZOYooGo{FXS!@}))mh$F;x;T={PNkYmUS2yh_SW| z>2WP@IoF!dI#{Nd4Q?p)#ju<%nxCI~P>7uTYf8Pgx{CZL1TB2woVm7!^|__B$?n1} zEt6tG=dpc5FTrD2XY*+Y_VgnA(ho(Qg1hxnX?hnOjQ!m#WRm*otr> z^5FWpaalI(2f9LQ?HONES+0#=wWsY$&hBbE2iD^=YS9ryjD;|N(~TWOT@!WOHSj#^ zxMIJ*N#heI#f=kGwDaB`PI6O2wB%g)u6F#aEVmR|;m~PJyMl9TlA)tEy-RB_WA$C| zi3BUL|Degm-xK}3nOw@kP!Zq`Q;JEaUNw1tHVY1*TyWi1fTM$j3PyCh|Kk9t7B>p@ z+Xx_)P_i4z2W|(#76gmDo0CPp>tPQ>Vzub=R2yl@aJYhavp_D9(k1Db%5B>j zn$0H`8eGwVsIKp<5uqRjzVf|T4|ojnT#Xmn6LTrF$O6!@5vxQ%3|caNk(dk}U0zU_ z1Zk3jdO{gk&C*)8G&TrAS6J4l@1$Am9BFP@0p#Nys;K=(P9NO(;yGB?Of`4_Ff7oX z2P+W0*wlU*)wazXA*+~2Y-L)ZsL`aLW2~(W@?ykXAzDj84)Wq(2Uos~S=IXFWZE}N zAAHKrsvsIW&7b=sTveNZ6?M_|L^XI3QCYCWOt1qjXIG}GWW>^Uawsd>K_l_%(AZ^7 z$I_+MY{gmyV^TRdracdYE-4_zV;=!#1cu^rW!9YxEWM;Vw==+0&G)gk;IU`ViV!$W z@vG`w55mGQy7&?h6J89HZhb62h$H&2H4p#Gs+w1&U$f6He^>?2arFl_OzH94onso4 z%Qnv!VL@F@Y%fB5eogVjv4*UxlF&bFgtyo>Z(3U*IZf?!SKV&+1|hlZy1UN~{>YpT z>0gn0L~2`0RJ?GR2gz1>9zDauU!4JL-XFFc5CpHf$}6g$u_~vNgU>!ib==JrXA&`7 zL|D|l+;l!(JmdKGBYR#q;S2v=9%Zh1Kh^U^W*XQYSMa@GB93aiS>v957t-+opm)r| zD84@N>G;24(pw~WzO1=#{*&Vm$ay2;{_zsi3o8SQHGW6Ud1s~QyZQ=z^+FSx6|c6t zL&$o^@Zg52Mh=>I1!5EfnlIUIsodGTE$(cc}YNg2cq&5%86~ju)Dm=9l|~%OR5*t-OJXD#*I>E2~ADlrmp$X3M$At0B!4Ye{|D!MO~J zayUd@(EeA#$j?K84weB66}F56T{8{+(NKf| zc33MZ8zGg%&AR+~n*y0SIGKRhd|`8AeV$NDB~t6;LMtgzaUr@n+~h`R_Oin@!Ic>$ zznk2(#(tcFfYO86q`dY~r**Hrwyy@f* zG)I3{*CVPofyG;2{^0vyS{NnG!?zyw(75x#O4ggMu&nHCXFZENsT2+KkO{ze|RsXIfQ z=Nob-Pjox9=kVjPir?2uaL;=*7Ms<}>tj^d;cV7Ib{`rbN}_m070a`H&G{uC|H04N zz`Yk&WRpCRQjm`3(P1-q9*R-eV@-1lnzJTR9Bkc%pidu-oifRJ?)i&Ok5lZCY_X~r z2M%OkltT{WNWDFUAW%|3zvScX9m%Ci!I#Cn#xPz+851>tq9c)r5B?sQy1>- z)>7Aai%MvT#>*{Vx&A7n*sgzDGeYJe5)J0ZG_n%J?xID$iCo$a!}^Ug^evTHsLOi~ z|HxxF=CqC(5Cx5il0ITTQZJ{U_4TtsL-x8ni;XD3F01Kh^~^yl-C4&2Qj2HEq&O2? zT36?YqO*H<#XD2_QT(?-N_rW}f3}$#h!%_vD=m6NwTWt(+o=4W$N^7Zlkv?o!P;u= z!9&jZ7D1L2P4{Mt+vH+pEfdAtx542bjbN9*Ayop=FUrA0Awgj1cZOVMiwJ?n5WW!oi4P4FHkmnsU?#z|w_{L!V z`xUE}w$=WJjY^o#)uOP~wJkTdag3!hgO-fdU)PX%6B2kdI{He#0_O?a%5RZS=`JssW z+ku{P(8#sGsiY*q9D1A>TJ&-m2}0Weod0v*4w_d%`wg>QnM48SQRt)ouU%(n_wHgo z64GlNsjEZckQcs6NE_dY-c1phD=qY2wN&;W;Kb~|z)9_P5Apx_K}T42;DS-fC87Z) zVS`beY}TE+&_Zz$?-Xr&8S;ufXAE>^0g>V-09QYqGO736i=^JA`7u{H9u z@B|%K7As(9a`W%2i}dTAgg7~3R*%CQonDXja;I4Ke~6sF{$cdNW;PCrOqjDh$8p}T zOQzT97I3VZ=;k84JnrRVw(JiRPvWvnzBK>ssP*`1x4m>@E5!oa)SKVcVo}IrJVl1H z`FOU$ZiyoYzwPEgRdgJSNr_Jqzg6Q5vWYY>>{_8}!e8SP^4c><*o#kG!{6pPK-&~0 zIJf!!V{*$=+`#vM5@;ZrT&02K|K6tY6^Uc?ana;!qJ_Tm(RXni+i5_rVQ}B~k!2@L ztni&cSEsUV;M;Qxru+v4APj?kC{YS}tvlZO!I|(;sK`-poD_Lp2V3AcudGQHKMJ=) z;U;=|l%F6ug{9&us~^6T#04HOij}C}-byhTwIq&LfF~_V{;52=gteK=!q;LBM3tuW1%@ic#~IrsLYs@%5*5a+H802e1fbXnu{y~GWq@?SR#^EJrB&Ty29*(0VU&3>Us%gf+b_oG za%zU)ZHkK`AIX!3p%c!*&aTHcm32dg<`&bKzlCBE9DBZ6*j#q43j)q<5lm?8t5FaL zShbTjqZ}&XF2`3p2AvUWhlzDCoy&f!ckYcg+n3*r5#65Bch`cZQU%-E_K4v)ep3b`myJep~Qz=64=cJYPQkgK~D-gl5nX=`tvD zNkg-$=RMJkraF$DDck8pWlqB zgof1eP1jeFKkKvzjq%O|qKZX*dsgoqRNL`dcbbE~#jgFvG~-SD%>Y*1gKsj$(F(hA z3%YH%2igx6UMQLb4&v|>f-cw#eQ%Ppsz1_$!$%q}GLiLGX)!=>US|LOjubZkDGt$N zHVPls1czTpg3WI`nj)(J&dCxp?_(hc^-Lcn8+HKKkM*lDh6(OuxI`;pHk`U~SJkJM z71PYN z+a23>GFQH}_rL$|+Q;*BK5tcx8Z~a5?3;Lt+Z3Wl3f5yrLl>7yV?n~Q5#H=?pXs|X zQiVb=wh6K@{Qkk$O>vMsU45L~tRy}=;h3@#lVy3Q3EBY@d-YhoLk|ufCI8DHmy}>i z5lsQTucSy1R6-IvAvvNFD@Vs?b+VSX0bbV4q;Db$)m$bil_G_JS~YUUdXO=0oMf9k zl~UZ7H92CD18_Q^umN^=|iuLb=dED(P!#LyL!L(|-5k?pzoyuD2di4q2|@TiAGGTL1-sPXaaY8I!d zeG8PEu~CYE#2nV9GM19G1!xeaBC4**r|4I%)Nw>;aZxH+@p_d^wkB`CP78U)2+T*1 z`yxIU3$+q~;6kdTGW{YWBo8jN`sAeYF;Xg$thVK}KdSRXR6hPL&m-rkeiG5wswotpq)chSSFxp@Fqu zf4ZL=Y`X&dj^7i{w3(1rgmq2A)V0y6$c{r|@E+T1>W zJY*k@QHCJlP+~EOOpSb_@IXvvDwEb5qQP)fS~FZt2NLlZctNQ~%6L-A1UOzXm9e}0 zi45*>gL?(dR_TZ)sE(>z7~M$_`mn2YTW>tvg!kBx2o+P5Kw+t$pD6bO#nm$ zoA&yA;{i&g%2*miQ~AihuSQ~ZM$G2bYOj3Y6>E(LL#)CxL!0ZYd-+M!<8)DNE|$~4 z=`%Iijh4%vez#{++mF_No5|rgcHQ}4<|pHkIQE9Rcjl2PB{)F!zE7@+ixBG?LVZ1_ zv#ttB`{OOVTaW&A=>~gyg3gDgskxDD{oGxMT+eqnixl6RaCQPW`qthxhy0(bxL!1! zxw}CYs*vcew6(E@LG%t5JE2qI-^gg3_LdEornr*)5V}spfgpb-6kX!sl_Yhuv43GS zOi+a>PI+Z%afs2UW(jh`;byKN>mC#iRR10x0Zu z(!zMIaDyD}EiB7oGw@N%3_Bm_&Ef~Fv$C?x@H2~&qIw|JntL!`L}_K%+#6Nd_oK9g zt9nzTu9SJh2Eg?mooN>hZoOH;jeR{DWEJ)!g2LuZ``OeM!A;~h@f*FEmxt_d zy;HZ1vuT^u7w*q2~yW7!WBYA3OH;F_f6H&sMe^f4A)2DR*I z*HBbH0)Gp#8DzPxg$2{Pt$-QoK7m91WRL%6N&#H--@?4DYTEWAAm!Nd0qSxHiXvpc zKtv)ezAS{h{qQ&d%0#zr!x&b39Kwp)-TljTPE=W^`@8kLUmU~oEL+Y!{VG|#@Rv)n zPI=l>#_zbBQ-(5J6%4(_{HpPSp-2aD-I_pz=Qb*#>+QmX^VjC>sCIXfu)GWK@mV#9 zzWZgy*pLr>_*(ky$~}CR_kMqbz~}Y2Ag1eTv4jWY!(xKp=krl|d*ddBXQmgy`wP_I z$F+L<8QP)WXF?7LMrrpcS}Zlh!}bTcMfXD$z31qqV<*-vMUgA8{6) z2zm@*@6udf-L>>O3Zj+J@ znUAn}z?9JAm=x2BPw5gdBTWIwX!0$@ugVm#w1~?}T`484PHwVEat_OJF(<7Z1YnFn zO(MC}$Dha?bDgG2xG~*jo=zU|Xs-dM1^e&QUsXy7m`}&UQ<<}WqEV8bpU&{)BW1pB z9uvS&A-(0*$0NX%iuk%o2eL62K&h63acj+y>@gSWaDXC$zeyLiIY&&3SV|3XDutw@ z77+0Uvc0a&h#@N#C-Z>H+FC9o2r=h!sg@CluPLX3u$BqDK=4LJ%oQ9dmjKWL1gxay zQnFEtBoBpHEtfd;XVq4N5D>$>Lwc(hgQk>#aET_oT zR@T)59#pO9Kh1?8yh4W2mup||tz{0|m%H#u>%%^&1u!bqN305?)4%|xIOm#wWfpQd zrYucqsnHno(etciPptxXknQrje>bQn(OTk2Z>%d-=I8&dvT>czPW-tLCvkaUH#4if zO$^r@pn7G;{iKr?;@Va?CFKf=qjD;z-XVzllda85_afU6(g@1lpD*z;`qzO3Y0bkwTi?%&m8SNTM$oTFIB4&kL-JKR7_(XrBpNK-onCPC z<{JU`UQmLM0SLS=2HTAH9cc4G2+C=R{~p}_!wF*j;r8EUD-c}2HLQaA6}#dF`0T( zV3ugb?<%+!cAH*WZg$$mCJKceJTF$eZ6w_SA5kI>`rTHi7N^gSWJc%_uR3zk$kaO{ zRBAQEX&#q*lNo=kP<&kt=HtO6)j%Jc7uK`IJoN-R+YRfB%{;dYKbkgXtBGE9ND8@@ zYL$cBz-I#=ty}Zixg_~en%eP%0M*tM;KLQ3AsWr`Pz8b1m*nds&W5xM0x-wx`H^#P zB&WxB^Z5&m(!g&UjziHMoV;`=0G90q0Ug!RFa+UsZe+&;ooiKBP{ZLn9tA{*GA>Mj z!y+UIs8C8629zi@3N*8@PzWdQr^pw?_gppdgLFzI3F3rD4f^Khoao1Z{5v7UU?PA0 z9t)Vp_V^jGAqx`_@-2#@WUvcO`~-X~NQHEM85*a+eZ80js9SNECBx>wnu%lKKAMHn znAZAd=^wTAWpf1s$kItqU(Ge$-(D$lVX@mOWu2+sD5Z_a$K%pKIp547sNvR+1$8q0 zV~cTIdI6HjPNd}msn8;3YLVi&Mw_Ou% zzb1O;om2*DY1?p2#Le@ewjW8_Y8|=Mduz@*u{l$OuG-)x$oOt%sl0sY4}T$ z+j+8nhCherVb-~_@M>Nrkf&i*9^;RTBy@%v>#Y2S4$Cyn?PmQ9(@GTUoCrc(!=hBq z5X-7{9d+DkrC4KG#yr+MD%#4G})R%vLFIWM2o96--79F>J%<T)5dE% zU>WFc+i3s>4e)cU<__G?a3gfV^StZ~Ao4L7c0C5b9K6dfgw_a0tZ2vZ2CsGS{<<^e z1}>`T}|?tovv{?}OI3u6AgUHbX`@PGXP zg8kPI7C$7uzX*B%{YCKSN2ZdII1nEQ6(N@55xUJCiUh-;^FC3?7mq+=jNmDa%Nt0* z5BK}USx?p%{~au@<1ttyn@Y(oSE#vQCjFPu7gutup+r7TK(SawGjT|<5ZaWER_b<0 zISMCbn#Ss}e5h2*P3iJ%iEyA6sVsn0J2_V+-wME|Ik&vC(dZb%Q>N8oAd+RYe`UJy zY`4|r8G~4j!)CwN#rW2qMWs=_g&q%K<=WZ8d^8E9tPtIN9fh6EYf-!UFmcpgQjz2r z%St~roRD|wpo@HN-rDT3e2%6~alKkDwT@#)MO-!fJ}g+>4$0LF%L?BPehGpDfLrK?U>_w5 zdr{ASGq;ar#f|?GsVRb59o9h>hBPLn7{;nXN*>sY;bRnr@bJABB&x7^1SY97t(l-{ z2MiMg%9@pt#qrC%9;PrvU>!#5v1!gix}K(Lr&*6n&O*8*n^Gj1opB=Oki9_dW%>JX z9zzCuHj&0ULQ^5;{pEYKD72>2>MvHugSO0${~9X{nG8QX;?4bQEHi!inI~jGt;KiB{794snaLUxDdFE_X2?i^m^GPfrd*UqStG= zToxbX`}IS^F0jq_tx({~~5mB;I>8T?eL6zUXQcD;lmx6ol4 zpz>Z`9>R!o0GYsc?i7Nd;W(@nWZ$Q$o92E0U=|d#=DCHYDphEl69*=^Ov|u;vMln; zS2^^^YU?(_(23AC&1$<{J}l5*B(F`;CfKm8TUK16pz9dyg3g&yWxMJb(OD2 zanfI$C%DtPT>k_R7cb6Y?=RktnMZftuUTdd0^!&Dptg^@pb+_ywHf zFK*fi`Vo}@W6;|VVs+z(Td5Dvm&*TnNgt5D@t@PzW;Ep4V4Oq(IAAxsF!*vU1j51g znM;^Z&*xNV#DoE2TPP3iY;B07h!%X>D03}uT`=P)KCHC@=#A!Fm`11J8Tn`}Ui}Xn z-tREfLyCd@tXm)Ppe@LvCnoYI*l3@Gf}hq3Jj6#k(S)cu`2L7Ni>DVs`tKVs8ZW|( z=<~5*lO(U$oUuhsx0Zf|g?r#0lFWLHL4rGl0z6|a{8CDZhK;yb_PGM@Sx(+jGGu}p z9!&}Xj^HLT26&NSVmL=iNkEPC72-5D4RGbukPic5QTIvRew#FVSh7REFzG35{9R52u7xO!r=mJ^tsBl|i8xVv zuU|-F{^-XDuNR<~p*yy~L?K-ls|y_ej{`v8YV?H*cEKxnQw0uEm~{8fYW zj4?^5ltPjyZHhx}-tV@+S_B0!Jp(QXnfKQcS|VeL9+>?Uoc?)YHMF9Y)2-GBGDjo^ z>Y;rp>)OP<^Yh;Q$FJsqrxM^Q7Uiz{+V-t-Nrf){z2~gX_Aq)H^$D44U#j4%p_@Of zPWJsE_68ARVNw&B9qKD!Nh@C+f?I(ec?~CssMU?|W~u~1GfeG$TEXL$wb)+ybo)61 zqwesM@)Nd<=fln|SNihW7Yx}zpDH;DkCYhRA-B_kiemr{{6>%$SJi$!Zjgx7T$_Dz z7pbC-yQ;N&}?M)g4YGj4%j(H&P+^}c_D@-RLD>=6`|Lx6o3ijOV&l&HlNZEly2mVGhE zj*+HnDia{dUb~BZ`n9afV&b2UBjY>%MOwt*mVbsDXkjg!9_IP{cr5Q|ko|B@&!tP% z*}YZot8l(g5z&iXz8D#z*qsiQ(qF_A(I1CU0r$TD-O&6$0-VYJzi;{W$K>^+K#)k8 zqz>i{1&NSa(X{U7iwBGN2yC|2?Tg2VFvZh&%o~j-lBwC*j4>QYCoz%yw$PY6M983b zmfDnDIGV{2a&2buWVVA z5m>>uJa4Z4*WrGD_HUxaUN94Q@`k7L2(g z(2E((>t;u-br(nB&o4}8>q%%nk_zlv#(A$ZpK3i_-tyvduv?6>&%vK=eRkL^qs0K) zcI?>oj}Sb|$zgHa4CmLlRrBbYK_U{0gaI)PQ&_)eGSNYukHYZ;+>?a3whyGBEc6HH^ zU$!s$p#%Y`tKsjeFL_YEMKN~;q1)X-q9Vak_d+QPWA}Zyvt#>X`PVJ_WBHCw_TnU} zWA`J;A=e6_BmZHN#S51U92$}9a26#qHHGe~5g4@vK+_g#79|Q-#~x*%z~S7(Ih@VpPP2|0OI5te0)gA4;T%#Gtzm7J4Q)>T6O z=@r#Q|B>B#mkBE?YO$p&s)XulZ3;U1-mT&0o26{(hKVySo9Q_=s2g`exM?am60Pl; z^NrT6Yc2z*Y3gpLwWymVP1j3do~L7LI@l1cFMEE#99r~&w|E7@vB^}{cHVPsTGY%n zOFIrhsh`siXtP3JwBW1DTvmMIOW&z=|AwW5L+zPh8WzYzV;*N&6lfU7h=CoPb^VkY zm}B*}sT&nK)@g*5pwM+5t&83aMBwB2vka^7Ov5^QqxGi=;kP5YtH=nCbQMYbK!R)k9@hyH}oe$G66@KT&Hw) zS2+9|43a77OgI`tEPTc@)&L!w4z6DBvW93j7{TOE)#dJdFrBU7|M2pxT&560M}#eE zCKepzQ)jy}++?@2{nh=MKcSK*t?{&?J@Vh3j;8&Ifys99 zp8Hg*fDN|wu0M7+yOzsIc0QiQdqdRvzqhkEKVASyB6=P~ilL%t4U%FiGNd=pc+P+y z90`7^y}z@KpVlaJ4By&B;{w0(V*8R-{4iwGt z(ZSEcM8EA+rZ`qtyrmmqY+GS-et`9s{AhkKfQh2c(1~u?e@=x3Da}p_qZf2X3}sL? z*Yv|!ms=0xbpzJ+BQ#QpiquV#HA#~#t=f(Rc$ZT0GI+qDM>3_CERVdzkIIg-fw4^_ zsq+0$;+bi9!5dj$fOa96C}fwdU@CAbi%cH1v%D;(w-nRAv<~Y4RjL5s_nn4xhp;lp60wHu}TzEh3W!;75p9*L{ZGSuS zcVMF_Z)u^Trtc%eO+PJvyXv6mxLSWBZD;|>|@N*ugul#Pg9V1{}P=X)VxB5J=ZC$3h5VX%D5C>oz zv08*^)rX$vQ%!5tjxYLQ7%w&%MrD2R9PrE-keV7EjxgS1KW1gIBuIxGt^J& zW3skR&|VM~{V?hcpKjkEZ5gV;U{Ku=L@>ReFP62uh6`hSx>If*sEtHE_WD z-eqOZ^I-v@rslQ)wEO<){^^SM-2B%!7$_s3hU;$Z8W6PL>^O3T2CuXUgJ+J_0nBkQ zW6;8#137mgQlBa}YLi?TUChCL#JUi$Ok%Vujuunf+EDEaLySYA0hc&L50yc~62A~p zxccc}+=E=a<(DM3=J7D2#6Bo%hrYJDn<$IPef-NGyllmQ2&InLp<)F+?u%VK z6wOf4^}fi(0253g`UuuyZ#<`oA$m%f7^^1}bhHT?CK*H^<~Iv5No4POvR0V;Ng*bC zlZ58|MS>msJ0-A#3{5^9TAJ5MC$`}%+P^FZAtbznZ&j$r2QV5f=%!J7$=A-@l ziEw{9ZZPd%!2WrHCLq;ZA71*G)Ww`hc5E`K9yR|PrXX69rs%xhnDhB72=BL6Y_?vw zRsCR^r1a>dGGAlft>D>zl3c-+lnb&4PjL&|mt(&5JbuxYxn`^0>T;KCcBfO3v3Ag6 zr@Jy-utC`kPo$YN8vQtwEbbJ|#n7W%5zj+w1P#rF#;5yYB{Ul`kqA|^2idyqi!*fs zn6<9qMhNcN66LCJWp2pdRq6jKoy5x7yMdOfE=7&!>PaT+3&m`4%RIu?jMS^EMh7xI z>ALHbnCrt#iH#m))KR<{J%bvEKl%d zJ++QnRy#4mUtAl+vQbg4)gmhg+K6Ejb6}U8vmbtVW9S;znkE$opw{VmDdUT*=zemUa9{r>S1PCE!|kRQLoBr7?SU} z;vPg7E97U#gHt5m1OdF)AFt}Vto~d_wQ+~aIjj!gKslb+oJ=9-aP(8@G5RWQ1k$-F zr4RhM4gtdn=VTy8R>_6B{h?`^uT~EPSC_k$#u_@L17#cdW=WBx+n7<7nEbX8J0-MK zkR&X4Dbm_fN|~7tByoPIH=?WlJ>hL8@Zv#2Z03w>Dqw*E!C4lr#!`U6sRK8_J`?vt zB(3E~Vuq;FEc4Do#(w6ZLZlYe394O)DUYS<3=wjc#`v!?nQ=+v_SqbhJYpMGyORy?YJM!?Un(on2Sss!{}8( zDDYQa2ro_ZU#>mASy%lUAA9Rca;Gr~RBIQ!8Li$vt>rU#jcP=sk1Ef`I(5 zY}owWX4w9h(M!SLFE%?e)ns4oZgeQ3+e50x|Gh_}O<#iy-5-v@=T1jjV zM*njPDluPf0Q85oM2TMft6cKsT+c$boTu&OBJ25Jy_zlO7`>T>4zJJbny#XYiF&o% zCVn08XMOHMuE&oASjC)VyMbfhg#QG6P>MJtjdLvugL!w*$Xx_Gjmt>4H=SF-wgp&o zu^jh#UH&ks*gi$i}|*6a$poP{H`)SvF)w=yj2!FhO{oKy{D zp~-T7++9f`PpSOq@EYIss<*Li{Pv}vER49+cfY$`Un>r4t0CC3X8n0NEYTN}lW4~E z`w2d(?cbB;rXK)J7ZzuS^!o*0Lj=ph&>VBGBu^5*SRxINCIC(S&!Vmdv7>0FMO*}4 zeQ7}?eYC`0RL+uxu_%X6$$lKI+ET%v{-2x&A)>_L2WV0eVLMTxCa(v70a9fogft*b zqDl0OYbN2ER&A!=3kOSxRQnLlBPCHhOx#$Z!Zz}_t2V5o97m9TV-Lo!u%c`)8u;v`p$$@;1m@ zWR?yctw-KTJOwfRpZ{AjKb9FwNM!`;oxusAjsTe^XK-vD|8|NY+h<_ZQY z(fZmnjmpp{KL2y)|HrzKB|_JB5TL#_v_XED_OK~Ud27EHxdK-;>n(5B{*9s0Z7P>? z-}2b|P0#1q=hO1%?NYT2-s!xmr`jE*e&)+{C2rHso1)GBis3p3XxH*@`t$AiW@J0s zLw>wrt7C7PA3^jXT}l5B#ZUr)2Wh!?oOkjhT~8NsEhvI0%JxW0$;)s`j1NWm%{CO) zxpmIFPD|^tAOf_Kg6xZp8~5kqjBoh~!H<;q;uJ=EC~%gYXXMgek-zf3h$15+$&hrUcC1|W;&{3KTOj+I*b;hJyMi>b2_fyNxdNMf@gZPXh* zOsm4boMwXwQH_8Wqdg>Aif9Iw+dVohqU2Apfp`xFs3q=0O!!DNYWsWetS_PrLUX=i zECslI^+BQGG=UH%c{sY1103UZQH2Vk*yYGfE4z#_3JxHczNG+?{OcHh6;V=9$q1HM z2lC%Rt3+O@;-_Cq^gE6O7Znnd>bY>yqqN>ONjAEuqFUoL1?Y{+h{Bo5DH#E zuv+_Fk~;1ojkTnV%HDjW=feTNcUv*PRDAqkVG)b1Axz}Wg#+V20iF8lm}qo3w0t}W zNEW7yB;S47d=xpWZ5%jjV*=q#0M?$0CcoYja^~b>%=eWsaKa}ZB>gn=h-L3e@p-DBD}-YFMT_gGZzxpu1$A<%uZ=v!6-qq4QkKl)`MrYH5mzBX;8p{ zwTj5zQzL?Gm6b=wnm0W0Qk8oVwQd@v|KCRz zTEmtOt>xsz${Dz7mmwI~(ez(kHdA)8YhJktB>}@Bqkc zLur!^5el7)|@i1t(>#y$$?ES;~e+K>5!rZ<< z$P7xIR)^eyP{i+zJ!Fa8P^1}+Sx~|p>-H=B#R5* zP{tQ(xm(J0$I;7B8jaxMbuF9eHXE()o2x*du7q=(F_!VXmun=u!v11MV`>l?_DAZH z%i+H6ZjQthNtEe0F&RyR`g8U1Xf#;PqVS%J+Ah_t%@yXQW_P8rig3F+R4hlVv!br1 zS}ru>%|+kt4?FKKXJNSN?xY1HP<$b_J)W;RHiXD&a9skFOVxoha$j85^INik`t)0Q zcml(_DKkFZUT=>t11%UYeBHpW`!z>V$tJj@Et^-e)*OMGpYuC`*Q}7au9bL{q5+s^ zEBHb1VypV0$Wj`4ZdgZdL*X!7rNm@}A)|)ABtGiI?i9-$J3jDA{b3P2)vNiTTDj!L z;cV-zx#+xir6h#XcP~VQ*lNXFQKIN=JN%MnWu~Em0mWExsv&86$tHKB*r|pQZ3HAX z&8Ni~CfR9(XqLquhZ*iiZ3StihvMd0hQHg2vxEAf!ZMXVpi2L0v6PFV2PmnZ6xxoL zo#aQeL7!$N%B6!@rKqJ@7RPdpTT)hSn6LvkR2!xh&JrAuDdU9VR#^j!<+9YZ~fcDJHlSt0?I191E_ zwHUezI%x%(n_dk4+6otrL;K&Bq*25a+!~Bev#6UMXzk8is;pib=6dEC9;f=sGMcMl zY~S14q;ipbsae($8<#nxhGn`L>37(A4459CheZ_xyoO03f+>0n?uLuT5&a-MS1;8R z+owgb1b?l5Jzv+;*6BBxSO5hnTQB<=&T_BEIr@ON^YY$m=+lM_xu*Ft z-#L%H%7!b?i^5*I&eO()Y;dcxggKAv$qxLF`(^=x_lJCW{?FT7+v?7}Nw@2E+8uFv zzK1?gdM-d=LOl3Wl4Q5{^VT)S*T=&O!PiA$?eCYfn*sfhk0%&|ACDvKUyn6zK<(Hc z7!v#-K89YM+=L)&EBN4Av*^Eqa*s)0+L$V10`}^_Xz3^gJ}ngj2xN#L%b5GoBM`kw zyz^ksTT%zIYQ3l?4Y3z%2hajS(CJ|FVS&aHgEvbjbRiu?ST3U?_;(Kc0#Qb&`jmr2 z0X2&1CwbWY#B7JQHGwjdc_@D@Z~*DIQ38$mv@(wfv_fP7llKOg${fSAbYbYd-&yB= zb>c|*iV;301>eGW!q=E%wASV>_Ob&R?^#@oM^GW;tNSpkm{qJCjma}Sr#MBqVO*q* z3F&*PI6!GWPRS-w1oAYVgP18U=NB2tGfJrV-feR1FC%~>mZ+*+P!d_10Ywv~v;w?I z@?aks;CXaH@eDakx0O@`*%Eo#Q7P1wrkF8K63;;7E@SKA2;aGFg6D0X-T=24+elM} zz4cyd7xtKA1Z&3e?k>}fXn=L76)5+cZa(YBpJSghEO|*GrA$aLaK7vLL7!@r#Gijl zadtFkgU}PRA#GJ~(F=rFcvO;+;Q#^;ZKZRd&Mog7lU#wUi%nIoab6Io5#k-2vh?=;jLoO;2XKgS!Xjo~ zMZT#kMBbw{KES@vP@0RLMSuH0ZphlF=&RlHMW6(Oj|e{yUi!#6YyUtf8Sw5{6J7?_ zh7b@Ng371%!J$ipu*>X0dAaw47&%z2U_CJeX2#69K!z^|7Kj2A6 zcGnprJ!JMBPu)jF=<4DEJNHPru|@!9cTqVq2W09MV=6win}kM(Mo^p+JXiH~wXkMn z-yBKo`+hu15er!gc^{e3bFk9P)cXCX>5b4zMKXe1c+$x>D&-bfMy_qF zN3&IW`*fn3&DFX9;)VPnt0a4cR({CrN?t6%DKGQ7&SorUF~6A1je)O z#7f<9D<+^IQ>dNgbi#yL-nKLCaw)~P4iyP*zVULS=)C-EtgT5uQVS1Qz>Cy!yOHWv z@-Tr5f8Im?2S4WWePqntkgkXD52QmU>G{Sd!Em$V{3jOtr!b&IBBssi5j0JQDH3maEh^n>xH{P z)QjOUi9W!T@gPwJ`E@4_o~(>C29x|mUrJR9V49@dA8IPBWd|@$kq4JFOVx_fJW8`D z_Rx=)F>*Kbl=gc)$`Kluq!6}5_dHI=m_8xTjWT0A;SaX*2uUY3T1Ao4b%`4)c4Fc> zEQkvkH_g{KN<87v!FRk@jAP$EaEZWT+VBop`|El zM%&NMDxR~D3Tg+%yvh?h$TuqLCqZDU8t0p>E}L9wV65XCvj=Hgs-|yg>vz$)Eb*q7 z>n_^{nxRMAm)k3fu)?z*hI)XWbHTm85Nv9D%lJHN@L=|-t2_99(%cS$sc#OU>%n>s zb-}QI*rs2TuO*;-`Ropj>B&^qk3qQQF$^$_MA;Y0#_HUSljlS=3~3ucjm|umpWn9M zSZOj#aZpq-_ktimv&=fXTsXuh;Qw)+=LW63S>R{JZ5r5H_hwzzw4Y)fVW{A4Kn29@ zHg6aX(z;=q_!>T~=@r<9u8+L|AD*`T5*S-HQMms+EijxKsV&Y};x5E5NX5E<^ykK^9H8^I|G z>(M-Tw^3od=o{a-9|nj())(IOsaPNW1|ccW(LwTZLpM^~d{k489*}ZGZ-D_rl$KFp zRvxJcAy|?h=PQB>uY+(FA|x0sr6FwD0AvSLW2i$2$m`vjK#5Tj zU2+QdnMmP*e9u@w2v=|?IEuAGjBUvX({-ing3P^-HYT^cd#V#6JSWWUoHx4Rb`5_Rul5XtSPWlXCf!Ps?}Vq`3ir_73Hm# zqR5#lWP&BsSI(AdLR2e7$gDMy*2BpyTq|s*sMQa9)j1_x6q@}iG-%W33)h=UP}&CY z9>z7eUeNOW$V3gmv{m|lD`!IrR*IlbtWA41H+UUV7}yGG&G$FeQ&d@zGI_<%v_Caj z{{_vG!daaMX8$fP?4=RXdSBlPNUrcJ0<$Hf*2q_CN-o#vFA~TPJ^IcG=`Bid2-V)$ z!%s=;;FWZ4sR%u8PlgZ74|XWAULR9hE^eNr`)*-$d0JOG++HBu>qzx(*8@5So9Glt z=4u}6Q@XB(2Aqqux4(l{I*+?foIc;Tf#9tz=H>SOBht{jN6*c$ZL1BsYp8S#gnly?$OlOQ4Hnq2f~w;&z8y;3fR)wp0N)FoMqI3?=lBA!@=L0N{ua?dq>H9jp zA=niI5^uMAz0zRKU{%AFsuglY)Gn58hZ=!Q)@qe0PR7laMPbu2TGgjH#e&j`U0e+Z zT{U^*-`Qxar_&uCD`vc}dS84`m#({s1~-JQaQC~*OZ6Pz(<0X)Z;)*99V<&k$DzQV z%_TbyKo-TNK*Te40^d$rN^EsZqtadPWe-TOFrtvwoS+$xZ#*}#9i*O_rDYyi6k~j= z?q9aO)V!!M|6);e-nUkwKb=sVCUG42V>$6`Oi%?0l1^xcNqqS3g{TU89tAPf%@Eje zdQxddsmgxKU}>giSV#PpTuVcl*2%AA(bVOV6d4);n%UW2>!)U!I&)YS83qB(!FeHK zl4i+PbmJ$P(PH5w7J4p3r-i@M)6_81?A9$xh>W1iixZ;P$u0EVk#yaHs(`_R$o52x zbA~8?ZiDS>$H}M_P}bfM3{X7ksA~e3SSxBlL{$(|knu9`%}uA?k{d#i-h%(6KXU!6 zX+nNSNHKKSu&p<(BefGb6f)FD+4AvHl@K)$LBc9e+gR^JgJYTPdhK7aZtrXVwJs9p zawp#pL#?AMIVmL)L4_12q)1vWf~-h^?fii-(in}Z+66(-X(LId+!;TB{FAj_83oA9 zILv~Rl&DLlTv#umA*xzGgnZfQ5Ny?E6Nk>3u;e@_S)-ycD!cIDvdA*F!MucKO%u1I zVMrTaww#yV@WBAcb$xC#`4*;2heL=$a9 zwR_q9Gl9nrh+>z6Znu*TdN~Ll_&ziKD{S{H()dI8^}xq?`o%s&`pV-t=Q)dGGdiKW zMWiGryZtP(;mY;^X^7A3(3je7qPyl8KI*u>1pn=@r$cV;X7JpO2au9O?S2Df*!JEX zQikUR%$IcW+-IT0d|u2pfLovT2l9Ws94r{|wQp)pzZQ-x{`lG`MkWyF>UxsSuoDTJ$_4k^4bq628NRR>H^)Vj(RO{ES=?)Tc!V zB81)jLR`Udhl(Z!{1Ss@ZtYp{IPupHgMx@XfEV)AiF$xbW!DAw*%HDHb_HajI~Ulihv34m+y z-6ktkf|G!yNr8?Rr6BEs0&FFvB*__|hjfgv#|h)C7VFcTNDBb3m|$f6R_RMR#T@>U zW0*qBVNO5IMJhdH4WOM92BQv%GIFPVYa6mw28;32W`R>4N(b4OI!A;Wpct}-D-=-F5$m1x1P87X%yl^iRi0=ZdA*>XYn z;wP0t`Ji$YQ6b2RdXx%z+EWF95oEbmL%G@zmDpiER(j%6rJifKU;#8eTPs?X#bdd| z%G*d1EJ(G7Yz1}&W6(xa5^+!|mEHpMd<420oh?Iz(G0e_4e}G4ZP3jmlGs} zsW9$EJF>9M@A@RNL%|F}h`D$*(ugT*b7Ly0+52XHI2-o?>oKY5)qd3)LS74#%XaOE zho{C&QyRm+H!-76gN-AicBU1EL5w@iO)MTFE^*u&#R2}UPA}q)6!p60QYj_*HUkcI z=bN#Z{fOUaMDP2ZP@X73_@|^m*O4FKU(tpzUtodmb?2zU9|Z^@tARuhwGg}~g765* z!q(c68|M+v{W_qrUwAl$f{bd4cd>l=JK9TP%`v{4UCr|^OI5DID1af;|0{&E{r zqL|fDxvM*oewl>-7J>u68EoV~JpW%I_+qa}I)xkrjeNFH#{L&SDL|Eap<1s%3C*kNLakaZui8|4`BJ;l zX+R5Cd*y1m(W#=jD&x^sxmSrb8B1pMVy#vGQAj4iOiI5#_*&?T;?>X;kWA057m;Fk z9FkKKbd{0DViJPRA34nPcBAZHf~E%F)qcC(3gry5$qOcBzn*SyPs)e$YJ5m$yY|M; zYv}4<7}4EX{Yg}HwKJd%JfO?wqP;sLh!@h|LZ?-_wyn}n)!Ti3EEGvD1dHk!y1)Ls z&-QtAJ>K>Q6I%SLV_e2O7{LJ+6_hGLdg#z^~4|! z{p5^O3Ssyv$cupMf0_@+VZ4nGXZ{K_7RG4*wI9aI)|eZ(`sQOwcq?BA}$f`xoQkX{7_ll5i%!P8C%(R|n z=3$`*8kI|ueHxXcfS#6@z5`ZHk>Y%35tISa7k-ioeXFsR7XvRvA?GFZ8q1s@WK!@Q zzHm?^R6?F;m6N9h{H2?o?DS?8R@m--Rte7;K^ZNdypB=>Kct1MQu;fzGNTDU(gqvH zaSR|Lw|cU~KWpV;QMAaEr?0hIY+{oEqnlyt=@*=_Weu72j=)*7_pmN}qeg1mNmv9! z)%_ZvO<>T_Pwl{ZAmVj`$i>%`CiK|tRWblj)z%XJwGFtD{y~xID3t1;ojACn#&R=+ zj#bAff`&3#Bm953I?Jf2!ZuthH89{XbaywXw9?%mNGqL+lr+)|FvQS9cXxM6Hz?92 zoze|+<~y~%bN=r&YkutYzWa&$y5!(TvlO6MhPp8{+;V4rq22PjQ98l57h~*8}v&(wLW=0$3lyrh3bBxBfFgo+2*g+&XW}@Tfi$Ctu?exWJ8|yFe z83l$p#4m+?XHu!>Tk}3X#8#$y%n#-{iu1`U@Ac)YbK0)k;Q$bNi)F*{gLDk+Vu2CA&7W7+G!9`!e{h6`QGH>m>}v$$TbQp1Z(G| zpYxQorVys|@sm1eaTFCxAjchm;gFB(dzwvm4whkdJ_%)7MuKbepXOH(Cc*Qs-s&9bP+jCFHL24`A{+1x z{ZVhtXi_v~-Me7YSfze8?Lvj=p<2sJpJ;O58v=oOC%+zwm)eWZ{Xd7CLQk6Ri+(Q;l~td^J$ zQxy3x%b&36c2bsQZd^bR$k+YtqF?fOsOI>h@?lp1g;qY-Z-Gy37H-xj9SaN->x>Ne zRbSsRpKrD4+g~3pl#DI>`Zj>55OW^yS>_%#*{#Un+vT3>vVOI8&f^(MHf^ol_2cS# z=N~#VzQ-lo7U`GSivBFG5!+n~cja*Y&jDmqLaR31`?^zsPYt`P0R}j7rXj@i3Mqk< z?7M4LFIpSpRT$#*a>JWa5-}i$!t?ZD27NZ`kt7C|=HxP~tQbK@!t-$5m^(Na#)Hpq z5i8?dya|a8-`bMXaAUO4*Crm`h~+rB{i9~+Fk6uPCxFa~+%mtJoYdFUvoP6~yxuAS zSCx!8dj4v=KU*0k*;?}R(XdsPLnj$a^eYfMTRat&2$%_Z)Y%rMi~M5aO%DY|@)^F> zNg^-q^km3ys}R~FHts>_XvkClu{*3-{7x5D*nT~7Sd`-h1V}m&+8@<8HRl}FI+Sme zOB5r6HhFATb4$eYf8W}ZG`k&ESW))GmQ-ar*g3T1kjKlCAmbu{+QHWxRh|eT3NCWL z+Ej}SCDXEBNL@7)pTelNpktUdOf&8OdWLernxPS^KGvVxc;1qgW*B0 z26>*S*S)FYtLU_J*rjYkdn&&&W57M;=bcFpxf}tBemR=q8RY=~ep95BKmHh-a^bgp z)qXXI=6&4I%N~PJbz5-Fes!_<#qg0i`$4QZf5jbpxnY$tsA60E2g9r81(mX=`dZDl zCzcd!ha<|(C_fIQ@iH4E+ydm0LFT~BGh1qdNjgJ!Av_*iB(Ch0g!^I~)?Ae_Wt}2b z`K_N?wv(lg-qvN585EoxoSjgZ>*3ZnoG#=3+t@FLRF#~0^E}?4*Zh2Vtj*YrJ_~HW zQe&Oe4_bbD>h%_?y?rba6C0k%UK78}hHO7od^s(p+FfL>DCyyOV*>k~?QhNTs1NgA ze3^x~-|Yh3mwrc~%f`eWde_}BriYTUg7S@oi+{aLLC{d$icvxG*yuF$&T!1(S~rUN zTHS|wEAcI&ofn2je&%1x@e%lIK+L;=_w#J(2HK%62c?0N!)Hv?+uq%uzn!K$iYY$g z-63nGq*GJYN631%b&dBdj?-vL?)9QezX<3XMC>Ssq@`IBgyBeQv4u(&vnQBT!1w9G zEE|=kIh|*IJQ{`s!`|%4Dm_n;nGq_`0u+ZvsGOtlp^MmS#6MfEIOB@P%t%>d2R|O1 zCHly$fM1pXB%Nm>_gv=jb%x}AcGMU=3p25QXpz+=cM1CRC4&JSi5C7_3u}FZ9GMXF zmpq*Z^o$vB9hk;=P32K9Us?%uEvPz2)TM8#u!xM_ft*P%GAdM7z@lc#R!P(T)9K9o zOGyY(N-hk|(;A-dp?=M~Q zaV~1D)Udivlr4W9a8ClSRRhvmU%+d;FZo&NL#S4L?!U{dx4l!bl8*I}G$B+}QeIM@ z8r8l0@iFnp8lzJxwF~*9>{N=7Ldm~`nF&)UO|9!6qDA8UtFcQI@D}<6TEFQ~-UCQ6 z@G%mVt}1v7N{yEGCt9zkGIYO(zTNAKt@OGoGciullTTG(X~hdI)rT1XX3!G_E^|P> z#TG2e3rIC)rTciEaan+_u9Z$+(COjlE)fA+^7Ah$Mkd%R0P)wHA8Dh;2hHi&b(;~3 zZZwZ30AYcpg|S|js`szH+Q=Kq;YYuU>POiI>SD_tjoDE>`j=Z4DI1TTZ&Gcqm%AM= zF0AgvQUzjGd7$Hkog*p3yHwduF`^%9E2pZVDr%C8IjH=WJ>CvG>RhHKZ3l*yP? zj04J_F3E+!Xpeh$FLqaNK5}+ej+4JTfPP*!5Najuto~jzy7FXq^D~7>o=w6OOVT5- zd*gkz=PZS`4LxszWdRw^Cb8*&T5~V?M0GU(yM^VG#!9M_Z|;MdKuJBbZdSFk0DT|G zMXV|aZf|gD;!&3%C(tT9!6)80w$1JBIco6dpMx-k1@2}dRwI1WjpRO?e^be_iec)zhzFHR^ z^+nE<+Hm%qalFQMXy5oX8AfR7<@Uu1Ii(R%VV*_s1_$t)29@2(L~eNgYM!`CdguYE z$J`C(K7WTT1ng-SE%rq)pVFFg_3n(P2D~btsrasXEaq-76<8@(96)(Q9oRIV$$MR@ zxojsnAGc7Wma91)A*#IOF`0G(5Z^LB=6PV4>Yiw-ZhQLb2zgj@aJXurdfLk`sY)KJ zxRg+t*7LA7SVbr=}dHh`)WWEtUP&~aNf7fD*Fqhu2Qyt;8 z!KDT@UAI3-BAqgiJN#Kq6T43!s5#}*(ztsGp6@}lH|6>!=-<%f*FNI4mm}uJsqORK z7_wUWy&y>Qgww=TJk5|X6E1e@# z<9|jOYZG(nP3zn-V}VrhIJotjr%~DKwkA16pW z5}q%IcJDWaCmv}CM6YWBvd6;I4$Fr>)~S38%d?LA$hsbHi*Do*;(hARXK9}wNB*@G z%~jp+ptk)^YDQzt759yHd89G!_qpylI9eZU4tRn7LrC`rn#T_eJ^wwyA4mS6<2nB$ zdC-o8+eEfojG*5+i|4iOms=8p`zAjc9Rb-Zj1CLEVtoH#h(7=xh%WTwpFim6#{Y!H ztbo^>nA9^mIiR1}h-y!Ti`bUFnUj6c!49T{66UqJi>m++R%#AbDGrv`bK;r*!F%g+ z#2ZxW9un;yBvc&avKtWM%BfYv$-e8!6^tQM9Jo6dY}XvRI~S;V>)%NX3B>T$)q|Wv zg6s!EKFxY_hdN6%yX)wNvdOxzD*Ukb2vhd>u@4S7ya^3NGyR?N@FZ4)g}I;;6rbl^6LNa5)*kBR0K zExxUJL<$h!Gm#bw?gzx2+eCFXNA-}#Iye6)V2)m&kFkf?gqmPh%}0#QyQ;ez4D$yz zUEl)Qz^C1?S1r&5y_hT3*u{DO35{4g>)5Aes}~5{XcT?*j7wKK1uZ6zxN=w=2V2a& zMg;dl*tgq2q)L(`Jhqkv3vC*+SJnu<>Gf1|IHyG%DqjM-enQxMoZ^054{3<%eu7$f zEV^W3&Md%>37V!09qV<+QUssANIJU(?eivG>Ln?WMJBA{(U@Z9(gIUxfrVgTL<&}9 z3Kskn9_o+v!83Xc?l~m`{pJWW+w(MH16MjGd)P+p`-676lX(`B7cl{}rtmOZV0a1~ zx(|=RN zOktbWo0#@448R$mh%qdOz5zU^O>ajuhxOa0n=68bhw;J|Qme7jBG@uw6p>G3HVwy9 z6UB)&yJK5`H`p@U^dkCfGZhuF$Y;^Zs)2kAUCA>1cmKdgA)VQA{6;Yz_GvkIGeAim_ z5K-7-kp3d=ePIM4Ot|FxVp4J`z*9rGzE}pE0_Xmq8f;j*EnL%Zid!%O{6Lp+F`R?} z%_tWU(75sbhN!O2iU5Jy>hKIftcEp2hxn)ZMZI<NSciwivbqHRN$Y`BtS(*4l z*-T0W1y+^V_xkb(00}$5&b97_9cL2;+C8n;7_GAL2E8b&Wm6^+xrZM|REUY>c=A@= zl++KkR(J6>T4OiZ0IP|X8WpDDsG?1ktU0LR%1RHoPPAYXdp3IIMiKi)U**dEMRZ>S zY)N~9V9{!_!-)A|fSYI)S7Ch=w9ZGg#j>q6p{*`?si=~+S#r7srifW$kV2mTa4(W8 zqNp?zP2B^xmoBwdDr2FV7C2A#+U=eS+3?akT#_Yqd_R%(Nq(V#|mI zm&+ocX?+p(GmPM0hi&HA?SDpF%SP)4+K6%3(@qZZ^bU31C^{5J>jz<-bKV_Cht&zy z9m{2Tk^7jWX*It7&4JoYH}>wTR-M>wUHiN}1j}8|ht-=J*g6KpQwuE@ikK3q-B-wG z?r?X#tMFBNh}%2o56d@U*tMcW6N=rnp55Z)205Y%j7A3cqyI6$qHka$vh!t*uv=i* z2><*h-ahZxyiw7#i zk!8&T2fn5>SWs$jr}bNZVT%w3M{A@}z`Kq6yKfB#{W-zshG`IJhG+IC)L=k>Mf(t{ zBqqY~Ctq7P8Y37uF!Ws|jUwDH@DjJoYpBY67>YCCaP%Sli#kGM0E#_gz}X*`mInFa zo>)E-Fcttbl8Jciu5BNp5_Xn#9cfMnKNW)v zl)OOxaRk=?ZamH`nb&2WBIGilx!fr8N%c7h?w1Sz46s(TJB;t3r_UqVW3IHKWR7wd9L#gyRc3htQ zC36r%EVT@S*@M9}(_i?H_d3V(O_p<{s(Fo-5{;i$IztST3RhY^G7eTm1uECNOi=}O zD2k9y1@Bj%3!r)>W?7Lm_70ROd*b|w4WCX@JnO7_wfI9Qkx+FSE3>^MuKK>hnR zHUJP>U=nz0sUS}Yk|L%HsMMU#3?aELG7U}j4buvvr@smL!IbJj9~52UfiJ^FebXP! zQy3y2`Ff(+)LekLNH)6qtT^AmYkh+eh7DA-h$Y^)ihR@kB4|6wz-@ml*(6jEi^_1{ zv@k{OnKTbZ(aG4K=GZCRpZ>v!uSkhw8)J#s(c`Wl$uN{{FKhMIl$j=sxzr}tTHs(W z&pK(SFwJR1aks!Dx-pGd7X!$e9RyMer}lxh?v+5LO4;)z?G$Vaw2Tm5)`eate|EES z{-z$nBXbWp^2#tM_J367q8$>}j40VxR6CV&6t{p5RA~yH?Y@@wmKyvma~d(&t@TiK zx3Ay&A$-uVSIBV`f>?IaDi~tNu5=o*rBiLW)rvdm+`}kampCzSEpLBiJh0k)3o?j$ zlYsM=mj)z{+`7TLC@b!I>LBOoK?j7cbzsSJOfZCLeK{W{PHrttec8ofT?;SmD{rO~ zt*agv(v?H>r_VURf#*di5sbLWGH)vW5GJ z>6d^Y*94l0BZNqWC50|w!AsvF7=`Qoaf?qFwS?zM2HI%g?6yN@lYl>PUF&aH? zSP2u23SW&Be|MGg)T~F?I|3=OX?d2ys-0yp$e%(>_n_R3} z=l;}bzL73?EWFbAA#ixV{U-W;k{FRUs90g$k+D?kH!ZvKebeD#Hxp^_rfYj}c>k}v z=mD3ePubzoYng3wbK6LqM&NSKT`im~PuK7LerWro%XO#2+S4L6B8#tnxsdaxe}P#P02*@BZq#V*0P4$>T(sVfxS>+K zD>wwW8{13#XETI1G6%<+Robf^Mt$f3x!}co|MDQ(pOP^fjDRS}payFEpjSy)JE@QM z7Mc#fZ3c+t3iY!aI7QqIm$5bEVV$(8V5CvY;!SgeO3EUF0e(kJTc%tqUBBCFZdSb9viw)v~%hkf)vaU zDUwo+U=i&M35&vg*6Rs28_CS8`dxn6g?=Be*tDm|UEUAEGZRtf;600CC5nToq}Ja# zNn!geVw&Npi@ynku7Vlg(P3tKNwMg~voP~}PJTJKC^mg-!Kciw5my+O&1zhtT~w+C z38XK4T~MNGpZY7~q`nAo%f|FCSTmQHC_zD%T>-lPJD@c&p9R@?*ab$Enemqij+dz2 zq{e4Y{G`6w+hm@!`&}Oxo25c!YlwRP`zqyc4J@kMVs~V!)!$_8In>`v+^BBJNpA1GbRd;f*|zdk#T)voI*=%}Hw3_3r)Qv^N!&21T4iVW z@TaIYj}rA2tvQ*p;Rlo6*4qL*x4N{2)sL6JbH;Dn({@I_rGg!&9)tF~qw5$1mz}p! zj^BA|J|ABvmmxv|Jw~D9>bU|90JU!}ONZtHsGeY2fd<_RR+&u znEY;(u=3Q+@|`mIxB70A;99SOc5|9GVZ}4{Inlf4@(NTzr*#2C!nBTL;U;N4G8Kn!Zv!@J(2p54Wle{BXRk z6T?7Qo!L;&r219FyM?ex;JlD$dQSMg1$6)yrxtF-vP{~;@}mTQo&NhZCyCaHnM}8a z-HvUod5Wb4&_$-x>%kWUBI9N6>r1A;I%vIan?2$l{F1|EtJ{}GbW!Nu@gK$QT;kI5 z&RfEKMH5s&`}{ETZOd$iUC5h{8=D9r*#_et=OpQOe|d|V$Bw_+8k_qJ5QhM0M7@?Z zX*|~H)m_DBoh62 zZO;n;mwVQNZ8MtDz>+qj1IL)}v%Alh*>WFt-?O;2L>W6&<39Z}6TJ1AuDtGL$k;E| zL;r1j1{@ImarO=Juw3zJE5DmyJ_po1c>}tvhCW>c&;T~(9BvCZd?~*|+7EPjj*HcQ zoO3p|H|^HA%(`i|r2P|}4*_{iVP{@;3wG>}_FQV0Ki>{!T^)Yrd8k90pQeE%2W!-o3h@94S`Q9^pBChQ2 zdcK%MJZ&N#HU!-f8bDN5@D{-4MI)%O$lYhoa}UGg6ySxG92RAPcEQ;tVDY=w$KgmG>bP@*!35*@OXWrvgOw0-opmxJUwD z3xcmd2C~HZ_azw&61!#z`f@AyVz2~}==o{s`E5=C?}`FyVIc;^Ar$jLpZ0(fq`?ef zUmpw6FZ=`T3xieXy`O2_z6!a$v|&0=dfVA*Ji|5I8%L@1)5IkZ?WvUom>Z$9FK z5UB1ng31HCi4;oZ0U$nW+eI1JbVI~Izn(+d~d zbBtxN|D8nO^#Ye&$Z-|Z@7rGJOEy@)Pyo6os82plAPk0+6331O^~U@@*9=6V0}AB; z4mIKhJmZBBDe)q<@dwqQ_az{S5>P`m$W#KWtT>WcF-}Ps)RrBmRsx%84vDgk;sL~q zgxIIR!&~4{DTGr(DQv<~p3NRJg(>Gh#fkB1v zB@=fLWaVPP7uZsn0$E@DeP=BK`T24*h~n z;nI4gQdlZz6NY0LTiPCx^SKmKtpv|vFKsj^9f&Av1rqgCmyaP$7k0%OEhXvXC`JhsR4hKcFx))qk3QR6vM1l?QHmfU_4ywQpRR)sPg!a{?sd3m)FtQhL zpIU);ShWd$)eEjB!ma`wmL0)s05t_Dv89N0Y#z~C%pROE+Bzj7NgN?%9CTzm=Cs0z zJmni%iXtBPzhaMT$V$=mg~R_>DXPW3E-?Mcfm@}}9_P58`X9cL(TD#f!WE(1cg*dJ zp?K4(-|{+tG?|wuF4870S3ZiUd6++vG294Ak2P@d_m7jxj{#8B= zHJvVXg`vMDdM8w6+8K^FXW^54y4ewnNX<7|INR<_*)`Z+p1;_g%I%5cUOD5-n5)tp z)#)Jr_DQ&TyL*+&uyJ8A0Kfk0+GSXj5hCLoygFNsbFu|RB2DCLOkI)skB z*hErLL>gJA<=@iKAkPItC}F3^MyQLYO?DKPfbFI@JqT?q`u#a39gQB4j8RKQYQrp) zLWwV#k6&beD+;lN87Z-P2vvHd&;!&q;T)4Zq)+!96l% zY2$sF_ln-&07Y!ljb`tdLc=Bsit^IM4%nnt(}md5gK)IjlZnYwN+fWYA_!A5yb$+n z*?DHdLlw=L5v9;%>XID7@YYmqBH#P{;&L3dRQt*h;*x_Zk4APK5({FE!#o^N+;;7< zz)~3!Mli~*YrN-q+yc6uE4HmDZGUOsh+sSZxU>3T z!@vKGto9zcAGo_;A{dUmugM>+Q!%l(RQRz4mxl(U2<=#MU-DQGQxZRvoQNMZzMJZ$ zT?3wv(LiyWx(T{iqWZa{m8J%4qoo1kGLuLD>V#00d35!&IqfGkP%CO$d2zKa$KaTR zuagDkIp-!09Lj6wxz$x+LWM@JUNh6$kMqONy~byW)u5^Z3$qsK%#sP!h>FHFx^GVc zp+RHjw;N$B(Z59w`+i-lc{2!Ba&RugG)mohPr_|`L0|VBzlAyRVROSRM$1TyX^kY_ZDj#^;vRYGN}E0_XgMI z;YHudgAbtn_7yHo3CHTY^)rx(Otjxq9;KvJvZy?ohJX9T@NVd!B$^kDWgrM5g0y`H z>_t&hzL9<}OT;aMN^Hh5RB4J*9xFMQ_w9^)Jn2@CH4e$H=Ebd^qMXM6A9OX3g4Gy((cbi z_Vp3gJDDMM{Z^;+1dd&Cp@lJZ4DIZhc5@y?_TYck4v?y zhU+|&1=KEkOE&JV8H?dW_@HMR5 zGOAR@a`%Hl!Z3RSjwEy1O^JS&LDAK<37ux% zf)eHH9^7jnW83Dsg9YGx1PG(V2(7S3y?>90Yr>3J!eJ(l&?>=Qv46G9lK$ zzo=CtkU{?Aa74{YU?c+(H>ft$MPKi7;w_DU&Z)$;sd3Qh&%WjNP7#(6AYI!nCn>Pn zv8e_3>z~^Wr61qIhaqOpDxPicLH{_)+du1@kRgBytj=b(N0!VCx2=zu!$DW<+fKO) zV{t1dF>^;ieZu>xP_;{#cI3 zzR>+|=N4EJ*5iianlPj1#HDzq%8t6S{%;Awp%^@4n-33*b0s^xWlXRB9){}E9;0Jb zWGwEA=e1C>B^_n^seVPSQ!l#2atGMrm?^y>TUdL(mKQp=NV@%V^(Bw7Gq#!)OIHJFJ#aA%wzS|_+0wpLHt(j zu8SnND`~fijaU7)?i=-4?GpN4mDv4ES14}PS=%WSBDTI@oG9?H*Wj(6cYP5qN!yJu zccHphUp4hreAc5p@$pA4R=-o4Z_kKvmQ?6UOy^D5@C331eZ1CXw6M+F7Dr)380D7eM1y0;DGKYd8IO1p_?lLiZVPY!yO$|B&Lm3?vNF4b!lJSa^hMUtvetg!~{47jyD684B9rjYtj) z#|QvzW`{@LhWYM=XB7t}+JqOt#rnG=8ZpBwhX}H5!V2c0mV4$69?%##l&|OWtu^HP z9yB=&wA&pyAq46fis+@q>C=enlZfQg#2$o)4HrkE^h6RQ;QSJb-cpF33yb2}0B+Jk zSLUIJQ)nx5^tMpUudrwyP3*(s$b!8{lr!i)FKDy zacj{4_h`iQI7S0ZqcHXf^dM3HJrr3%68PQzUzHSc8MUG>XhS9uyuU(?0JensniwJ2(AmTPqZ|9;z!lJFSAIMgTF1vN%{^Ke5Py=?Z_;@lAu3k`)FKg@gA)j({qTa(}n1y;IHGUf&vCp3H( z(=fbN;@l{_MtC0d9rHFVOb`@q9;*=GVGdIQ4Kr$J z$dNIzm8#suC+aGN6(or{r7$Fw&Pzpb=?9X<7|uA9aC*bGkqqo z;=|l?TddQ4h+B)YcsBMeQz8#qc2h!6N-%O6*%tRw;Bw?_1&MKS`$ee^BPFsQ6!`ij zk`J(Ki+yIyMvL>65R%}Wl-k9E%zDZ#jB;c=5mu4YY6q=uJCA@>p}w?d<*Ixw`lWJ! z+7Mjbi*#-^jLC5vSM`WNkDC_k?7_7tLWdl8@{XHPhPCj02+~22F=fve_eL!6wSSKDsWOWat zx6f1^KJ*UuS{ z^li}CiBblEkiJ>r+d$5BK@i3Q>i-)lO&7AMCBuD3n4l}xPXxD)ZXr&0c~)Oj zVR3C*o1n~xPq(_!6Ei zc`%oVCGs1qL~dXEHbxEyg^ye&a#73%4{xH9T#%EB=98Y(@Lmo! ztqdjz@s(AI;@KShPKEZRFKOT6E6os2!Z7Sucwa-GMyRR^CLxwq6x+w?2<3#0{aUy* zD{&32aRR**P7Yz;LJTeC<;XsY!l1|rEW$&^jNy7{P_DZg>l@*a$d2TY6!|#}QVyUa z(vOi7Igf?q4~nds48GXmi}5|$l$;kL5(MRAT~tF@<=IBO=QpW~RSMYu1>k=CyO~%W z$;5dfsqBN67njt|Nc3h{o*x(-pMk@`dMpX^c4eYD%$8>Q9xngsdM1VojX^ThbHwgB z2(CB`5Myppu>$p`cvE7&El`AM7<`}|7%Sugm<}oj*2TcP`)G>DMgr2E+3Sr4sSb(} zqhjRr@n;DvIH-5H8mZ^mgEEDbC-drJw~roskXvM=9m zi_a+H`)vKBzY`je69!KEw`ymn_|r-v_;Ah5esSExKfPJIo5_4;D0Cf0qs7+x5L_LX zC^ijveNp|vTCBc^`xQFE%0N4^GN{CBi%lDq99Y5(D`lj@)Iv;;BWSH94y{i@x6VO8OG(xvZ4mvh*aYI zVk&!mTyGtzde^cB-!Hn#_P_wNKOE9ryAB<-F?A;!C5A-Yw%@Sf{dlw07UPv}`-{up zk9zRDiMXAlC71tV4785OvbzEPE(UKg6p`AVh+m(Eoi4hyZ_DC%A?V6H%iSBa76!%s zOamH~n%cLRDu19Ztm(aW??(So;)*a>1@d^%zWQ|R^#)3aX)aYyQ0eF?D`|$Wo7{sa z2KcKkegfgjlrWK1)7Vffqb0jFGjN}UVCDY3dX`S(7Q^%rd~LG!$D@^=`)jyvEIj2J zUM?vI6u&;hmASp@6jXcdq}yZ3eAq;*{#*mcJzq^$@uUiy3ihZgxBO5Zh#+$0j*0-_ zTLzf?8AJWi7tp{N!Ra}IyX%Nk!BWJX%(O)KavZ=rw zCvT3p1-frr)3MYQY^+8bO7ZiP-$1T~=vpyS))v!Qp{|ZgUn0bi0GCR~5DSzAyWrn< zOi%uo%=76M;;8rYEdyf|hEIpB?0vsbHsqxwDzMCSZzl&Q1UTY44nASG&?5^Rx!dWO z@7mtK3*;IaU63d>$2Q_xN7?pWu5X_9`KyY<4Sc=s1oV%_TO`ZJuHJ5R)#DLA#MDG@JK?TZY;}yG`An)Z}pKHixoiO7n1c zAZeMF_x`VlJmxTf{x}}dzT6-tR7)WCP2XqbEGy@yh*3@Sh~e`&e6oE<(9cu3?QxsZ zy?w6>bUoP|@XZwSC&|aj``>M1I8Oe)NBa^Fi@$R4ngG_eZ%j{>Y2MFOfqhr6euynm zAg)^`pG2R8)B+e6F8rT6HX&K=XORSVB1@^)cv{ORY3?VkfcJ>O9yPCnxt-vm511Eu z!#@Jyy)mmX;&c6<|FtL695pq|+H1MDU7GV+5uN=&na5n)wVJnbt#Wja0(|=g@w+SX z>&Ou(l75Hc>a8UsfN|!Fw&#;2?{_ZXb#vp7yGQx^jXZil0IH@DT5;eG6PT+B*frVmmQd~@V|-+Ewo@CJ9#QoFtdEB^L5xxq!*^WnP1-2ix95WBr1 zb)yf%meC7d2nZ6s#U*6Y*!k`+Hst?HHjQIxHk&58FWK&FOW(n=r_od_>1OcJ&^%>IcZ1J^y5d;2Kh>YF>l{ z90C^#ZXv~K^YC-`z^>Gb=mg`8AiEz7$cFzn$y@(HIJCMsQq>$176z$Oi0T=N92fE} zhleaTNA}R-%;`nq-a=;;qW|cLWbPS~E)`zBECo{_oEsKJRCo`}(5ULYb`Rbi2gT z*)lyAkraLY;<>8NKO+iki7O22?O50=?i(GJ1HNB$c5rBX`y}fB^5SW?$$I@K1b~no z6FN01iuqp-1{n!AUh`-7?TGEkY-y-N>B2^<^kCn!{n6wXq=l(A*IE13lKy$X)agkeDB6LE<08Yzl5*F8xYRcJ+lZZFNO37 z5$9VoOA8gcewloWp=7T5x7!$G2dV>G;*HIk)8vGSv2sDSU)W&QUEj%wxu^t$En}R* zg$Yx#O7t~TRMhnKlRpIpTPb%>p{VG&D#y?xrqQivnC)_UpFoH5 z-?p?~B#qJKh2H;p;}uTV;@Q4+JPD$Ks-HXM)FBQ(gD$Qm4o>K!4(-$!+oRztCO#e&(t zTN=|M0(U}E601J4!JeL17U~>j+Qdi>-ye|LZcWB*XmyTNf6?ZI@V`0vLQsD=WvhOF zsoyGa5LQf7M!ay>@UI_Nb&lJI;_7RAo2U5olh+90I%^1l_$wCo^VrOkHn)lQJg`u= z57&rG&qa@`It1)<7N+cj^~q_5w7X4Hr}pN~9MqMjtLt%i2Jd6K=RitM<`49{owYz+ z55T9dzm2Uj$@Ji+rg)ei(G~-rjWMur};GqFSkJ2S2TPD z(+D=RW;03dUchDyb*MsS@b?89xd>tdkM-#HDEs-5!J2}G-{n7gSj1tR44FgJ+}O-L zZ&MVQk`#M$f|Jnt=eAR6fNad3=yBn>AvT5klxbh=UNWW2WeTw*eFp{arWz2IS`!;s z^blq3YVPkQI%BX;Wg~YoS#!Mw>?~89QP|lEboEk;3p}y#b_z4xfRKCyjvZTW?g4_0 zF{J(@mTjqHdJlU}XfL^a4s^w48(xy64s)jB$NG2A>r`Wjr|KzshzkGg$1X#@Nn`hpt2qNH&hHD>ACA!%@#9MzN51eNR`|XDO@h$``$`%Iq+#1Kjsq7I!ZR* zP6p`u&|)I*osXJRPJsXg6i{wu@fg*>j_@YW^EZ9H9 zju94UWG;;AoP&dV>X{kp;o}Np0ck5o`CLE4l?5XSQaj7n-qr~rRKTx$Ga~oU-pw(n zYplj)+B*hGK>{ajP|nkP2zU5JUxq2XkjggD+I)wXsu9Ai&H8GVg=5r4Rm6ZWIF^+; z_1&FnwA=4I>;@JUDWHmE=XvVMQJ=Wzbhro;LHcEIiToxQ;zvlta=W#mAn&Ehg`!== zw!JTbbw3`&tyL_=RQi!@QJIdjAs@fLP&Q}em%@;pJjSf~d*pbb!r?oc@k)`*?yY*l zvrAD1Z&}i1@kg=R#0m#r4qc`N{6ccKjQR8+*$*T0wHOBle&co~E5JELVu6fm?Jve; zZNC(@_%&kDk1Wu=f2W|lWDWH#Fe4b%pKKMt&wh2RA+M|-fJnGz3hpRZ)r=S)-~c1`144Af}18;@&ssqy4G{ASA0LN)xSIUrHmIT5#OAi8>B za8u>ri|V#50r6W7XbX{L`S$OAc|9(MeDO&2({+W*&#@#@F=+=wWLz<-9Hc;4#eJViMMqrWq$theZ#>^QY2YG0Qi)9u4& zcJgQAL~}*CY>DvYf($DIb7sREd7rByS&YE%FbgnyRn9`)$2Jv;|I%O?P1^(=tlfX|1#Z2O@oE;h?O zHJj1Yw9+VKiq4D!@n|Hau0vY6G6}rq4wtul`9pC+ssrWCS{u^I_%TP6c6@;GQ~~eE z%bK?=;9Lyv*J$M0tiQ`pVwll~6WG92OhG293k12+rQjGnD&>ToKb4FPusA`}A z*k0M%1zc9ePIheDHY#>1wkx)6+qP}nR>ihmv6J07-F@}@^ebD?^IzTe}G&sd74bC6nnq^HkivY$wY(+8>*9S$ZWJ4K5i%V+W!i7yVJxJQ09~DW$H|ZfOUrs(%taDEp)6eh^V!qbX9^^96HhS^y(O zm7Kbdxm7cHw^r5I2QjJYt~jrGiPCykR$aR_0P~GLmXjuHcP<#eY&ol-p>fzle!uQK zGTE?feB`I8Dtfz~wC$?SiL~jH-`vpX`L;k%4*)^5Yf<2NKI-xgu)Qw29(3V`$FO`m z>zj~0wM~a%OCy=a$zq!`lJH95Y}08u#=)w1K;N0i5l*xmCkR;9$xx&pHd*Qzg^5IG zDL1-o(b%dkE#@WfvuqX=dHERY0j1i*L!2b}L8VfJ)y}Q5JX@HsS5nqDtF1ZSE`<{R zx|~qtKY+XrE4B+#=Br9dlFr#K7g=l@-j48YdUhDJt$V+5b&t2y|4q9dFuH!W>BJ-Q za~&lM#Dnh3mR!-I$Xk6ip436|H*Nlj^?p0zX1Qd&?DB;7s4h&@6-DD%d@aB3zULn{ zZQS5>IaAqOH*2kO&GA}MqTNxyH&o;2y$w_P_wuN0^p|&U#`E82wU*Y7=hIPUulG$7 z;y>>P=a%0NcQ>XCzIqRVx>r4}og_>)z8{gfz%-1mpWC)>mw`(!Nhbn8g*}-2!t5Ue zVZF>u(MEE+JE*9f12pSfQc8cxI;dTX!4p)L{}RGfc1%RbzO!r(;Yhd9jHf_~_hiI5v27wy3;D z6arkM^4La6?u&&~B(I}5HFw{ycLRZIZCqsLmeiH@h(2?5lF0BUY~LaQZMnphhQ-gM zQ4w;g{+BVOnd8u;lVW9@pJZkIm3->O045$4eoR zcB)yWx4Do+)>9Ui4uz<1-rVx#_c}TEyv<0X({I``sa!=uz`$%i;j|Ej8MZ=Z#-bgi zvk96q_e@StQ-G96k&Lj^V!?OnL=WDlPJhdn{aVZ*+!~P2Zy0skekkHTvQTq{QYx=$ zgf+yYQJAn${fX{WZjn68*h{Taf$&(XvNf)9<)Khg<0PtVRf%T$w$c`}1gmp1AWyEj zqO3Sy_bgI{>V`SkWAU>tFWSl|-*DN@WGOYxy9A51Lls|aDNV?lR=<@oWxhYBuc2Ip z4t*#5;1pDi)|_ZoYCwC5 zox_{YBGB#Tkil?Vil$5K4kpkfQms`>-5)2eBJcif^wBZ?4_%rlsMnSeK#Mn+``RRL;o6JqZ+KNoQVD^E`}YCQw~`bul*E zM)^r1Qq;`8Sd4uyfXbb27HhP1@Ql`NdbL|k(P`agi?BA4#KhWV-f)vI#7kp>1R(5B8bIah@(j8UUFht zmwz1Uav+>3!cq~J7e(W6htIvA2(O3_oLrkb6% znIu@Rhnd8H;N1?1I@)NM#<`Zf2IY8sDV6dh{{~H z*;&epZl710QqU`N%9<2>oJzw9hc@a)eS{>-`uPD>y1E?0B4YSbb_-#I#hx~+I<0E@yLt`h<5;6yi+(_G z=U8mnA@D+K-DO>|=G+dWxPIJ7w?ueZ%|u< zXgRh%q*3|MreOmxHH<+ZB6@=6PG$oKbBq)MV0p7(s{rDszA!#kDP*R!I_fqg5|JQ7 z)Z$Zt{xz#`H7f~p_cl?|k$;h@UW8H&P@=2yOnwHag$T{3Bh)Q+;q>VwSb=$%fR@<^ z5-UTvW_7Wqwm$H05g9RBVwVsE*#8lF{Xg2=wEq)*^7{SpkbTt07=wgEiNz$c)C&y5 z12I{sjoNOAzM~JF39g16iFho6pi~oO0;yyoJfE2I_+7zdDlX52GFO2~I0}d4u?SW` z>F+#2mg5gU2lBB($>f|($;M-7R0SrvN3*0O6;$;`{HWJi^RZkC89#WMmb{q;o!?_B zoh{Yf#K780^e; zL#M+j3qo)@S~r}U<4X%d=(~^xgD56ibD~%}kOpHpJ=%m|s8QDfU>K^*4q`c^QVwFo zsLP2G`>@hL;zcLM_LGzyRQHnQ6I#hqb%;k+lGRMcx58+dp^H)-^2^iXkz&qF66Hq1 zO`Jj2-6`zIvj{2TK^i2FV_B4`DAT;=Pbd;uNMR@np|LwiixRlQ^>ekhvCK!6G-Op)o-daRWfhbRPcSr=UT-> z+i&LZ<6n>Z*+u^ebaQ9?tm=y4CkvVd4Bu&+8qYZ@LUy^|Y1${)HBF=WnW?Vp**5J4 z!O^ti`g;ubf-~(rMJ@ip19vMKdNuY`&;ltIdFuM#iL;Uhe!DlP4uT!v*bgaCrC>PW zp|js~qghSa%i{yzb(}o?jcxnMGPC-Jv{j~VG@p+1>ZfqPj?$-zo|EtUd7m%m{}SS~ z4NQvIcJ(iCEWy>qaU9CmO=0oEH%tHCR2E&)!&r10(zK;pLs9t%bP;6N&vsr53#M~j z0XNWjf`ITn8*BIdk6Mj|f0EQGuMa6bgf#I)_e z8q~NS!HL@3ZRI&8DX-H33qqmw~ zH(fFoYa^{&5{U5LMkRK?T^ezLZQhP)^&|`bb^<;=s{}Fhy!`!Rz>hxiPx|fJEqs>m z{$P~A=k=s8w)=Xqlo#Z~Y*N7I^HF+d<0h5&Zy%!97pVS^e`+1)Xh(jZiMb#cWj$wT zaWs$*J0Ij`JrC6kzHb+LU)ByS(bCh)E zHq;OGTN2|oBJ?yD@#{k!p|wn$Ui~i4GU~9GoJ&IdZVrzB#Srw9O^l8jDct@Lgn(dN z1Tw|J$C%d`S72O<(c&&yG|8Ac(M?jJp*A`q>IjUcT}nD+KEmn&Q$m+>N=!2$wOho5 zG?hw5gMT4mRi==&Ra{o;S}}QbYLi`(YebHlC3)>I0Amz-3gFa`a4K`ceU>KS%6yk~ zHg(LawFaCK9JtSTRW2o9IhzPiW6Al6MoD^c_LsK+koCHGLI6t*c*}1{K!h(7@pY9B zWM?UaRw)DL(VQdMXDQO=1Vw^)lP+p^jF=HImm20$49P$(B;pHXe_i`4hOAhU!V4;E zZN88w#FEFYQcfVgrj!Q4R{rY+k}oo1uJBl?lnO22mxa_^Y7T0#QFto=StmVu=d4rBtJ4Tx-T-C090$7Cf_5szZFL`82ue%DQU6gNg;ir>PL6XUGWp za^35_rOZ*sayLF{L)a(HFN{jHQH!FObZ{zToC}R;nT0&gX>(&b8Z@Q?^n451GmF4o zWSfE>mqxW@I&&Q9jdjJUf`aI3E9XhAq@N4%5?7Zte`mFJh~ZlTRIY7!p0v|LoZE}0 zrJO-=l+WbUIt6imvbTHcT;>=+8A99I6>g~SC!lwqeWp5hcWS+qxDsD1UD!=qf*neb z);?@m`+jDwG+!$G&$ zOd-FE=gDTX1JEh-5hdbe*lTlWb@=Q|VS*X;tS1+ZOuI8grBOwi;dQz<`sx66j;~!gjuxua-z}yVTuC7HCHeY@vmq^m2+Z|-e&pI8&F%HweEtHb)c4zg=TvZm zATQeufMb6_L`StZ2tjVu4x|;o(qKd? z%1cv#59X4!1MBf=h$)Nb0?q5#1{K_o7Uz&C!F|a2;LscWkV8^U$G<0-H!cN75Q407 zG6uM58)rbIl_1tEXs((hBsEmq>SCm?e=X@&E)*0;@Ypot4rriv-AQGlmbH&GoApdl z9~q0}hfK_uoXyZM3SJwc{cCx%D7NTlHSe?uLljemJ5S5`W@RD$tu{*OZYc z?j)E3ym7%fR@aHN@@o+6d=wUNUJlI!oLp%Zh+XMCmG5y|^{rUay!F~Y$cM|(wM6mld%TR0j^C>-J?$Q&|`$)Z?N)!#4@oyy?2 zIVR{BI*rHY5w`hiPbdh04rDiaVKjt^pi$Pgs*fiX&yg4J;WSq~`nLU;&Q!Uhl+Kh9 zdt<|C8t%=8A;l^xN6b-4V(1@y(YVi_N2Smvn6szkSlQAM^zpNy9mZsnQL%#BOC=b|pIKB)jPhY)&p6?_^a8;?mMS z(5??tt8==%w^3ijDJy7pN42+H_5M=-cdX-LHWwxl2>bhLF?i{KAdvxRiqCRyaym!$ zo5C}#X)c^P3C0!fHCX2cpCIYPS#IyQV;M2^k0*MOBIwXV@%H1ZTEa5y;rd~) zitQxQdf)@={#Iv2JtvgZ3)LP(`X<*(b!=5{fH1&>lJN z2Vpk*#)Elk32DYzI@6M-*$UwrcnTi)!xZ)wDH5R4sfN@V#nd&xwxhUQ5F(K@aBiak z=whjLkP5)I=wL;_`i-J#MnY&=-02+EP__P6IZbWx9aol8{{$m#Wh(x=MY0Cn##!); z5Dv8`d69H=`tJg<)R^@eP2oz8)wn>TlwqljszdbG%SOel%I^qRV|lLFw@fB1HHf@% zrTT&mbJFlZuX)|51SKN`eRgfZ_yJuZzKWd8M%%Q<>%T^Y?gRk6;)6mL6=EVX&K_0y}Qe+7`13w78J69c#qIBCKwG$wu7>F8LY}L zdfLd(t-^SwtAKXAq`wBCM~+4{?#F&k{Nm`mf_Tj$5_FH1TEU}89IIaA(3r|%mhKRT zN#gvYSm}B_Tqo(`%%NzSY2J<>I7WZ$)>%ZpFN-;9XAExz38t;p0ICK4y;ej zh_sdt>8dVqfv*~fj!&HggkC3|pZ>N)E6|%j)S~#3A_Ry!D#A#+z&;KPlNG5A)n|fZJ0RQjP4Xa z^Lt(b0`D2Gy(K0E9|aQTWO`~G9$V_GCq*Cq_0{Gma0kq47Dvw;(6Oaa}X2Vm8CA|YXa#n|DBEc=$L zg<|4Z6qxcKP9+2+@atVsqC`k*AlzadoQF(-L zqfiN0CE$s~#Bx1tXeb=ySI)c&hahKeqfjtP$&AWmOag{eY6A)U73GTc8Ip794U&~vQ7J#0k)jF|^ZoGDvtCUtOyT-9DX!`j+bFsE4zxV zb94jBRd!#;kn29KHNRTjc7tjw1wHCQg^Y@LPB*@)lK4>Rz{}f2JEdhN>jll$F&k$c zJjb>59KMcMQbC_t&e{|c`Y@o`gn5luyx!AGib0=n-J_LaMI1&N|xTr2$O`O9>xcPq)m2<2gYkXxj*L9l zBy>?RpSAO!DFZTF!Kt-9$2*8s`tOYD~?n;cl?r5e$;H_EwDOQ>Jr6U~3 z@Y?Tl*@a*i?MRd>V=)d7SOfM)thtvVj6=J)ucikm_rA>^{oIp+%(Z$m9oq~%nW)9f zY|PoXV?snJWC!24Shu)+3_PA0+HFA_&mZR|6zy}-AyWMA)g$F)L6&PiNo_$`9((P< zBWfnWW_J{w)SVF^zApa8Pb?G8z4&QcySjolmeJxNQD?I~%g}QgyV8Buh~z%*N}6kf z^0k*21IkwTQpPXQ1H7ZMde3CVdFzP%dg$K`W>yChsKOIo{O$5ina_LQu61Y~%>7Uo z*1i^5af>naxWI5X&hv;SGF-=S7%Z?>L01YS2Wx8e`apAHXYv4{^zMR$(9-wwTrq-? z@Xb)6WpKtBa#6N@qRn}B|Fxo52gp}~B*I;yVQwlxF5#9z?oXrc z30$F~febts_mk`c)8F-hJOvOQ*bk8fXrb7~4TElufd2CH5+n?wNVT%3uvI19yG19CSa9L-oY{z*mC^`z^W6!qx*E4~ww4>p&x+R3Ddv1sTC&DUHHR zgFuc$eWAkeUJwIT0U2fb!7R+_D=Gz;5j<*E)}`iU>SkdS;h!Nv$&`T*VGslgk-wkV z?IgT%%RuMbKsUuAiciDJF-_4Zoj_9jLCwNTQo-bY1x}m-rox0do`3tP%5f4#^T|i| zQ2O+jMbL^x)tH6sO2DYbMNN*`OsB;Rgn(Xgl4hrRt(8R|QFzoq#iT&N;Yq}Nu7>oe z`eruAfP{ly2AQisM$xDS9jAJpjmAlF#>lG29IuAZGkPI_nqhD`V~_hnP+?4&qO_|- zxwuB90Lx;RD3Bps`AH$P5FO(SC_NdWqeO3lUycI^U!7kh{1DFk$=+}OJC({qiU4}*I7h1gPuJ{(R1b5HKEfEJaTFfPG#U-B2oQft%G7&G zj2NZF)6hhZ@DP1Jh<_BwS)2jzP@b=$dK8#S`=iO(XX$PWXhow*9?)=2Kj7j`GrY0T zs@0fp=lwv&X*Hnydntp;I5V5tF{VvXj3_hU+cUKoArQwQEb<`w&RkI?vtC-QZ`?vl zfo)lkYgr3J5?n~x?d_S1?%Dc&+4{F3Ds34rtz=H>(ORo^$PzibMB)U=IgBr9anNwT zp&_hqa@Mgh6rQ509Srj&qF=^?SKG2a+m(NKBwmzfc2cEVAvr>(<@LR?tP3$9SfDtY zMK^NfOi^Lcjs4Q)NLd)qdB=3Ydqcdz!XT!$vS5#1q%`P-iYk*xt=h{1xaOZdM=X?Q zf?>PkO+ffyp}}>;9Fa!nL&f4i7wNnbY8<-FQ{+iWxKe=mI4_4}noTXkfK-jvvBD%rRfNn{i`1EpYB z){1uL6t$h>LDJ(x+k@*RbHwt%G&`g@{cPH(67=4RmqsCEJ0Pt4u$x56F~`ZqxXLEm z%d@$~b1QrzVbU)p^ZIt-3@A!0{Iacn;8%lq3YnKvLHGz%6bKVmW@nV`jKxWqZ47kzuR9Dk^7Y{d+7L@a-9N{DVi`i+3%+LM9rk1izCrxB?QmKp&_=9JuNYsBj&) zMjV(y9=tt!TXXswc73TFWNa zcSKeB&LWr2ACMiUIF9}2oyF1-6*RF#3hjsm%}GwJ=tEuYS{0as8#UNk9r6IYIukcJ z*v^;uuJ=Ek!S80V5FN7Ebs+DE=)u?T{XQpqXtjn^+%by=$=jx;%Yt5IwRM6}=XP^O^m;{dJUGty}MA zZYN#$uvH};1FTjJ#VM9crWqFcDeM!aY#)Q80Bd}Jdrl;T7_Q?Q^pKQQLxQQFY+3f& z*`PG-t_`9x8`G4zrPbkz=(6Ii%Z<{^sKpas* zC}OHa)=Ta8(ibL+AuWhKbV4{G1v{1`vJ?s>rILmA_j!VbM;-G?+rE@}_J<;5Rc-@<$boSVqo`4Hu3=Q|Wn*EIRt1y99FD3kE&dbKH-TIsEA?2PV3XlU>z4aM7Q#V`Dq^S)qR zrrUlfPw4_JWbR|Do*s*;ipXW;%qvuE+bJgLh=NeV4w74Hvk^Mrq9_Jkv*5(vmN>)7 z*``%Rr#Uek*~xinrGjB8O%b}sMWugMk4x%W)#BBP;b#P~RBurA^~kN4%+gv`bMrVw zv&2oaBCXR8n=+unkqh!l)vf3n&p_)(3_aRrqe9>`n}bw>Ts^~#$zT$@v|Qbl%dAAF z?DLV!LG|3W^7|FXu0PH2PT730jLkGDjhx*9qkI3olw1^Gd_(yA-*w9cw9s8FOZv)v zCl9n{F;FkGizbC8HQVu`)^aiEZ_AxN; z8#rHIB?4eQBH{o|L|fuw=7#hu7}XcaXI5k$74;bZJ4gLTKZRZ>7n=Z`vRx>HfJ&6| zQdZKyWJs-VU9aX1v25HRG!QF|=k@17n0Qgpr!J=;*33;n5DGz&ZZY?W|18Y!z;TSO zS!AMuS${DRVq~o}j-CG5@ZV0*ZODIw>+%s)z`PQNs`8lVjEEv3gEldXLb*sn6rzl1 zN#Op3jS#eeX%}@6NxFg8yTnh!ICTXq`Xuzw%hiU7e~=LBBy_W&&&Sb*8){D!F>opV zOu+8^vq%X&5ph``>w{WIt1%|o!*-iky(odYc0eMdu$S6fMY7cJBaxAkl0^Q7_*yY- zTq7nvF=y!Lrq6V6fvw-f3gj3!n2XJ@XDE%%-56BubV{~`G-Lh&U--tU_KA>Qtj{QY z?NYtj5TAu)0@svl_!J1I*#YL;2Di;BkWyJE3ou;wT7Wz|_B-`83qI z)6D7q0?u?aRd}WlTz8f| zJnopk#Y=_d;|N$0K}|f&Di(cT3wQjADPe0q6Tk*Y{g4YwU70fYDeW;z>&8Z9gn2Hi z{fLpw%u+5@Z6=Ck5aB$VUv2ALsr@>;>{~Th<8m~p^K7vqcJo;4q5}!kP3W(@W>uVZ zSb-!vTN(*asY3Gyh@`J6YCPRHd>W1NUB}1z+O-hBKwSyk#UpwpwKSEGRa>Y{t}mUF z5IkTG2|)Nm3jv#o>SD}eQCu#vlj)XWbej)m@Of0#@`tKWy~`b#CS&GeS{k#vB`mex z*S)$_30A+aVe2hph4l9ccDk)|umfwwR2A}hgN*E&>w@=Hn@d57MZwoXa92OdcPL4{}jG_3@#nw0+m6xXyz0x`)ZWL~!<+@GC zjN11ua{~et`0KRCoT>FJP?FV^kCyPCx0#1lRNN^k(!*sA5pvhaewZ}6e7khTcrxZ5 z7>5Of_V%-w_vRTUO4yS_MOmcM{xVPnrjlG_Ft$1k3ez{{$95r$+OEt+$2=D9;GPV3 z9o2y*4V1K|8}AguFXrPri=KlXHkD{DRf;uL8cbh`b*@dv*ECmSyw2p1H}%6cAJn$O zqbU3V6Z|vF7#hE|XMvkRRx@&4m3?(-x`0jIk`l?oWoDgAubiyA)w1rR2qA#6#5s(9 z*EX(WV|og@b!OAriS}jXQMFHT>w-?wjS{SuJy1*bfk@v&3J-zf5;|11{7&CG ziw~?B31xAxi)_+ZzK&_1dNqg@m3Sjt7{TZ+mcNZOIAp!+63u;G4k8t`-VE9u&`>!n_= zb-!=j&&1Ab93Uq7KnFB8Y6YQh_lNFi?DHWcjtG1)__x@y$$veSVsv32x7bKC*S@AX z_T2ZCa-AB?GrFeehDLxAovW;EqQG!F-X(wWrm5XE8VzO#x>5-o&N^doAA09DZ9At~-!E`)WRvr|!Ot zFheVTa(1#khEj1N;_l?y70;HlqoU?X0E=0wj}yEv4jVfRzqV(mwiRu%RZpt6AZj-l zI!>Z41&^^mQfy-4aA*c^CjNebinMcqJIDSq;_gIdK_oB8D&jsetB4m{An(qkbW%`ent`@VCsHup?)%LA)m8h(ZIHl+)xbBuY34%JYyVq=Xmw|)``z7l}0y0SiH7!hT_)`@pi3-VrT80BeL-6~>kD$I>) zxQsq>pet^tm|}vF_-jfiQxd=7j|lHDKp|AvHWS1cdx&USgz+h|O^RP6X5=DgWOJCg zvKVP*h^}*zJ$7p78Hu;iuP8eEC?FE!*NT%!T0}^g=f^B^ma8+BMDznxWbQLeGpFr3 z=I>1??a=3FH#dL%8}LEQ2<+R?lQ8dRwjhwOh?%gUo70F#&iGtN*c)`k_cm@8Ozp5% zV=hW>Fv%D?|2PZC@6tS~94ek>FCv>G{^1nyDG#>k1=&E!y5q%}63#hEfuNx*Q<=-4Vcw{F+5%e1)w4fx@=tbFKELO#C;Rng7`VxBzsL zU_0^JAOV%PK4FT{ zt}TOq%un?&%Co3LdH8>r@qHMnil$XB<1C6F@e%jVk9F?&!DfmA85Oc!XB%iDlr@laQYES;rrBVeoO5SFSTk^_xDvOri? z&{)RgH=eT@ai$!wAep^vp1oq8*&ZHCzlXDFP7YNZUcMN=E0HqNEh_=f!#%xi5BwDr>p6P9^B0%sB3DdF@3+K{7iFWT*8473zG|352hk z7*7v?_gkr+6ygYDS(--KlfAVPW8jyB|Hg76;cH33Q_&e!`H#_pB#ZK?*MhV+#0;ri zd5uD+vvPlK*hat9vcl94w~EQoKb0Q-(%fl7FBNg;f7BFJC(@Hzq!14E5wc4wHzNSi z>eywJLp9;Dqk&%S0@mjZt4kf8i;8c zUVb6I+|-kKHjrf^KGikQX*ImvAe8IZFxrQE044uuas?tiMPI|z%X*Nad)6ngLA+Gd zrbJZF+(1foHc8{aN>#!dVmHfI!YcDLt9UjmTf%kd!)d=mw#T8tNV{d3|KXWzl%h@( zfNf%As>YHoUh$}Gm4Z$8gHA_+al!E@jB9nzgz?IRsh)-TF4*gDTD@RlA#h;p39AAx znprDRPc6zcUmZ;{*{iVY<<5(6+FCHBn~*x{#UrcxZV;Uf5i^(pDm>Rbk*l>|h-D!s6sDw0-ouyFDv= zq!Ie!pbK$eI4EEWcDsuxd-@Lbza;W>*D4@AIxXsYGPH1)aPn<0I`5==V;MWp^Lszu ztvg*RaKek+#=1Zx(>`1LA*Xt-E~u9#JCWboS7AE_JONu;{pbqzw?P#gDMh$&-nZ1X zpUZBL+Vw!f0T>TdSg(N}>;(;x zEqQM3=aGGqb0aMtO_VZ2GqX@GK(A4n+iXzkKHc`BgO}0SPJb2c;TTVCc(_(O-rgg^ z(e%2ps4T!A=^ob2#K!lM=1d4euW@PrVX@Bo?91^-nu$W02^Gw~QtkE%?KHF5iPTL9 ztGLdLkCDcx>Lb4QcB6kYt}ENv&p zWtnl_2+;?kP2Ef&t_l2Q-bWG*+2=C-Q?dana z@-y7HiPs?4)Wqor;vn2?VAXW)H+wcyos1n&aYE&aAxOBrs$ zkXdJM6vVO>`UvAJM)Z`bHNp(if|xfzLT91u5`54tPtJP0KWkn(9@3o=!hsROoDR~u zdijq&ls(@{^bKUl4WzPYzm^Vw{$53@qo`XOq8E2yxod{^3fXK6(z6fJs}3@H7HZuR zD&%H0Np`IuZ){y_l)qyIeNT4B48Zq__&@(5;d@X)%V*b3_nqOcJ&Br0i<&OiLHA~a^1eZw{6tKk+xV-q;fA-+Hoca; zwbrv`pFbTsK({)yk2eRj+f4tt5zDyI%(oFCvsFX50C^P)+?9PV*-B>3_0n~>mYBM?m$L!6pNJ;3>p;H+LeqJE&Z$?v?E=f*r_Qk!on0)VPH9cR zp!&E`H-xo3Aha3_Rd+8v4;tvV?-9L+)ni*VvFH1-NU%*65>0?s0}V2>Z+6dFhP(WW zYqdo7fTZT&2E^itVp{fmYsqWf7HLn!rwc#T*Xw0;aca=gZ~k}8P?ag*{tfZz$}KJH zsI`h8Ze{}YV#07{EE(*efq2y@`&bOG+KwLce<5)H@s4A@uO0teXQ`E+a}bT}4}@rR z(ip4TOJUIMaC^Nw%KfkHWwGg2TsRs7B^&|Q{+}6#Qo#qeeAYlXoRP{yQu2OZJdVUM zqUxJ>ES05!)MC_jWIPncO!LOuu2`xRBwZ*5j(umW5Q@}EszR+&I9jR??}8_dVmg-3 zfWa>U6HlzxfDRi158FyV8YHxUot(xRrN?Y^Ig@SKS|>{<2+-W(i7(jc^#@0Uuv}%7 zPKC$m^u~o?)E`gGR;7>Ptlh4*8RvcaXty~nExaP^REmJ?_LO?Bw3IIq5sjehM)mZFi9gr%n|0~TVF z6HHZtZ5cP7lWf}apqfE$yj=3fE&!_}-f7*vG~JzE1UFantrRP4IhwKY zowAU^x?VKOe}s#qxCmXd6sN2Nd$gjerGpx;ZU7h&&ouJ`RHnLZyP}e%>*>6bHP?gk zvTpy#O}x~%1cC@F0Xa;pyrhJhuA-)cTD+=Ww+S4#^Ui~&rYB_M+uMqSlUs7^<4-8H z;EhSG&%$qcj=dnKWnH;qNK+}QISX^$x)VWD!=#^=NiPcF=|&)h4@0>hm7=Lx+il;a zVBJ%{ozEn;=|NLBN-!9I({B^4&76V#lX6E-kD13P9+1n;)QqMl6FS0q;HA(@2>DUp zHcwcUJbsoDL!T6W+3uctTEsxU^|Aky+-%;OZVT z&0)Wpos{7mm_TMHVjxA!mPLj)UKE ziko>2ciwv+@pjlLsbt884@4zV@h^*?C<+a?O6wS6K7;Z@vt_{WdXmYE*La z`RcjsuP{UP;+vx0=P9snuI=W*RuBF>$?go}WlssLSIibhD`-}n`msF1dzE?f-R(J+ z!Aual4_5c4$y5Nw!Pfm?FACy$R3NDRhyXY!Q3j>nS6cl~*S>Fc5&eaqKdRP$qaYWI zhEouRo8AFuYVQyCDPaLL;>+G3eBo_1y45K8>M* zZZ^sfSMRRlM?ZE;eDrUbB9Doautw^aTn8smad3TjA*WZb1b--p;MOHTcBKP6z; zgtAN%Bi`7WarDt9WF8flH9{~%Ixh&L^dFyAsyQIIU>xQcNDP=*zMOc-}W$Z2WNU2_o=D#326e(IBd=A~j1?(o4GF?nFijI1w$rX7M-lqE>cCD5J2NV_P)h->t2TNVi%Yv!E@ezSH1<7K+Y0k6=U$%>mrX;x@q7FlEvd_` zk3P4mT?;#B58#|1v(mNi+}Ju#Ze+!yH{+wxz6)t>t)=G6Jd z4RqK@maA|~>ixS*sXcX00}wcSLWSChkdTSdKsl46+H0e)=9?Bl&~@t zE7rI+7w7VjNl|Txp2{&oHD1WFwX2QxwD#Ax#g+ujTTdpbYL?{ts8(&-f`x&5zAnbO zkc#h2^BsMGl4>cY8hqunqprsvp|Kp0vL)>5+S;MQ#x<3%#y0u3R#)Pj860_$c*>n( z<6X6W2qS^u$~l{Mb5mCyc+T9Ku{2H}+L%9m?b7+W%-ZgvRs3Wwzu??rz%J5O85!<_ zvc9^**V?xbqv1V&CN~TC`%Tf2Ur#9l4&KTAV@uCy(IrGvs+I8*+`*C1#4JjZZ zcNd@8bw~*mXe)Znw+ku#w|B8XT6IWh@42&4^t#;kEvvUu_4L{$5@?@Q%5g|$XvZto zZ!2E?aer(WdCZ@~;C*XtpKY2oOYqmD68bvU$L;e%AJKCzdgiXEkknB2#J(r5rXDUa zexDPgW$E)O<C0e_dtL!bMzr zTyy__VZyTerZ8nWE^Q)}_d*M}zvbE)R^|3c$m zqmD$O;Sc8?2xIPXdg#km4~>i+km1Z=?Z$;Z?6vd<#O zA+m&f@PA0&FyB*k8>(Js406v9Y<0U9gK%nFp5dVKrGUX<%g;1{`ci?EWx>W8p%P(% zvNW#p8fc0*p264>Y#JedvD`F{VAJY+@J0eWr3f~zz$tM6GOobG9wbwZFv+k`+9wyQ zR@9b8GZm1i-@UraN~xbVm$#ROw+K#XK$`bHlW*u#xQTn9?jdqy8LH<&Sly0m7%RY; z#@w~csW%niITC`g?UybUIGP&Sx*QG#8__KlswWx2M#^vl;}Qq%W`8m*bPd35^&?mg zY7BGnld|9ofJYS%8uNf9!rc5}rj9yLc3i9v-_9h6+OwVt-^3@CU|WI4ZF$ zgakyJK&~0tv7AUl8+(KjPu~{J;DL$-ml(f~5nsB#~AWxd)cHE4J=gb}tq$R1q1EGkIJjL^wY|9elZ4h_P z)-kfBM9!gyB6JAyWghZFPtM5<0$Y75npp^#@l|LG(#FXqQu2!O$bPD$s6rQ=DN#)UUhDxvWx$p*C+TGExeSeCYJ zA+!jUC!Lhou97`}Dbs6%NpDL}(=SV_^V7*MIDQJ!0g;0lZvT&5DtW=@s2CmA`qAs(7lX z<5@iv1LWGO+{4ORPcoxqs`uI}mLt$~+j&j*%JEiUgYya$JmRKKVh;REqIs(KD=K!c z5Dq=jvUp)NzxVZG|%JL)J&d60g@ zjCy*$r+B`!h1e_AV`tVL`6J<0*5lV#e_DZ&<+j{11rW96GJ-P7c03!vb`bAcBP}n| zU{3=+Js@W+DFd#;?I`|Cqk+4!kuS4B5ur(>1GVxf^^7h~YR#_xDXK6J0QCdzNWXsn zrHL1zSqZ;Mr4rTduw26`rZ&xiyfVgR7D_I&#MrCF1flsqY2|T1OZrSd3+2pFJ2bCG zd*K$oAJqz0z^KdyueBE6Ow=~WMo#lgJNgDiZg^K_Btxr~=-0NRt5)!Lazv^PNL!a= z-pJSvZ&Y8@9o`a&(C*2LG{MwfG!Dbuk-i}ler66|>7S+Z85mCA;Ypu0)X~yx)q&kx zGinKY+1?Sn(i}S4ZqJM~aN0VY*)>wxIX(^y&S=&u&uq`1X(laCS;$24Kxkj}>imx; z)YApp>S~XKvx|gt=m;TuMz)Z~>fS=Yn*IIh?Dv}>vj>HtAWc0lDir{y@EOm6W^?mEC zdw)RA=qY%m?s`GUVC8F1yF%u}>3v=62hvAoAoQZi4vbZ{XVCY{tP}kA>mB#A<0psz z<0JqZ3?3hgi>Tgt=mZIo?irc?nLk3WOWV!A{i-?Ey! zxnikOL)(@RAFXt$QNLe{VjO5R+9dml#eXG>evXbu<}>V2xb#PQ6{s&Q$>rO=>kB*Yl`UcCWW{>@Jo5 z9g&bNb-P>uYVR(#^TuTDI(pNCF8N ztyNaAN$_6lczZQj`yrC+`!aYMqU%Te82P1joR zNn}tF1hjh?=d(tu9i|ay(;k=ReP~)_2Kfe9NLAUuC#2^A@s5d-VnCk7Y^77>Z>IRUks_KTQ5GV+m3s&)J)T<(>YU9DKEpa`W_8Cyf62FMefI<_$ zX0A_)p=hxL;akfY(Wx!_1m4M6tA_YmdD~${B_r@}_bFqGL?CI6P2694vgQ}6&hPbz z$ZPiOXUb%kosgW(mfi5wXE4PmyolHRB*+LglIWmB1AC2tV22?%m{*5kMn7-sel!3t zdITn@h^6)$Xmw;-2>%Pr1WW&!!$hBq%1}P#j_jo=(RCHm%un@mmRTtPqQfK`R9M3l z@qLEt=Mz#!o?!(bc5iXJ2vIS5n<8z6Y=YcU2Gnj%)~mZk;wYA>_F!Pub>PPHTpd zUeCO%Ze!1ZnF+5v&R0_%7tU!c@rN&gA5TY~Mg@GUjFs{+TPVDnovfEziLnAphx1AT zV3erqe#^bz=y^xHnF|`fG|!zCczGHY_z38_ zz?|`dmDPW`afo$6yd)nC$|YrD?tRu&#Csgy`Z#OpwY+2WC!PhsN=k{G5i$k*)y{)h z8*UZunGOWIwp3Iwt$2rMiFwHQ1F>y>@R2T*iAjPnr>+0AL-0Oww9qfK8tvcVi z#(X4hslkuWOu>{BWGG7tPQ%}B!^VF=+obkRm@+YMM=Rkqg!;2eGIxz4nF#Df zlv@|G`biC6H20G>7eRzq9S>7k-sa>ph0xM`2FWWE&F6A?1Gsq`Vgs?9v(JL}c|q~R zv1g9HPZK5Jgt#&Lh=zi&w>4&{c3I+*+vrI#8f;L!glTP1UojX$1uXj(@=a5+ zerYsAwVG-4n*rze3R<@cO1Ns3XcD!O59mOp$(W(qg84+a$1|8XZQ+|0GM(hKtuzpn zXQQkWv9?auKrkJBL1SgP_`46Xbs6fy9vNO}NyNB@(1O+}lYX&Fq^01HaNnamQz`qV zkoYp%PLLqs?^#7kvmpC-se!e1)u+ebAQvdXc?6v=g>LPfI;Y-;_{%S=*p2;|`M!b; z>-7;keK=T9{+t9`pA!pvh>@7XgnucW3K;i-(rSa$tNy~C8ubyiRoj?UO(U+Q_2XmJ zg}Hg_q9s0g@Z7@&X?E@`=-x*&Au&b|Mi>zAuKfNi~nu#*YhMviy^NNJJXdj+zO z;xZ2=q`nxdr9DrWyN1vYC?U~yc!0)cOoo#M8}@n7SGx7Ef`18<9dy=wne<1xOV=Sq zkilr3Bo=Tk*p`iPo6sC_S-i<6wpL{_8tB8vYRX%fIHsY;o6QrrE8Sm5_DjN>iw~`> z=s?^K^yHvGZ>|poRUQkuX-$U8JC|XDg$dr(KRw^sgH*Ckq=r)mAAQ(!t-OssLA)%^ zs5vnp5}t6VzpgqEaa2UwoJm`$tq?1nRIyG*m}h3r&jVd+tE;VO8%4(nuK}X1I@Zq( zp83)K%>vmrr%s~UST#~D?J)B8ft*@vA{^{pZJm}+JnqC#i!FXuHl}`VT3F2^T+Il! zSAoBIH~Qoq>M*Mf$CMx12U4XTJy1EfC4PJqA7P$&a36CSVw^R>uXnwrr^(EmTQ?HE z4P|WCI&9m^%K6|$OwLDo-Oms0OMJVA)Lv6yD6ss|``mi^Ld0P1QhRv))Lo%-=UN`l zDXVZYmQix={sSrJ_3vfh2Fs{QwvM}yfio#>XU1iW+W@2Qbu`$uz27*H=-a!g%Wa?D zML_09B&7J}C(dBr{ZyALu-kGZenPC^z1Y%rQya^F@LA99sjtvEKlXJNF511WfBm$j z=am6C?X#U*__U=5j&RpOcG)lOI=nj=zBN;}?O%F->^bay3(EBzT@$={((~Dyyhiq1 zFZ8|xKWzMwKXdut#UVq7AwR_VBP{zPJ^3S*A^8fS&q%nH!1!Hr`rSSHJT3)nWBVq> zLAPI_41wP{SIAUl2y{;{bghBkM*^A35SX7}*rb9A>tI6_(Juf2;iUmL)ZQ_N0U}QU z`zV18S18rsmmd>C{S3S;EP~83eEAIgPnr*Y|}<x41RTOrB64*S0 z&>V-VYew!2lJZ${bMxc!YgG*Ix)Lyxa<=E8_^pVp4A!w zNP`Y<4a;9f?OqBJa0hEe5um(?%8~HhJgA5#)0XTz7<4`>3HOqMeLeUkf>`aeTE5ZoKdI&5pBLCDhv8OaS(p4k`Bc8b*!15q(ZGeVgYWxQZrY&JxYg{c^p*& zoZyy?zeHUqDA8yxJ&JXjEAM{`Ed3nWO`>;XoXsUoUl80>mv<4hUKYUYcptg^X5YhaWv6)j;2x*3 zpD|XT>m76-0MNr}FKgIz1*=lHzIeyfzbKF;mf?cYWw^G{5gRZuQ0BqaP)Wnq(m(J%(-(d|VccbuPuRT05#@+K;QYZ#+Bm>-;g zc2bs<5NJ`NT0m!<0}MN{tgPz>@f=ka{k$#{vcwUMECb%1oYvMudzDwX6(~W~jZh(c zD=}ZMsBD<|&^oOK<$WH`n>DqH!n5RSr({?$)dqKUTCb0qwxY&JB}7@m_0&CGwhj@UMCxVSd?l4oTga6STwsy6T4-w~E44=WCbfM=^W5LPyBp zHN{u>WQ4%f6ld)SjwQ`%7$KW)xaezd;JcY%S^9R_gPzK9Fh~ty#4;{4AH~7|+*lo| zr<#{_nxsiQV`+|i`E@fb0KtDhMu}h8m?;Hu-n^g+k=@v6;KlE_{Nsm?I5xtDh3txb zE@8_wyH!=u!xX`_a znSDPf^Jz#d)eN_lH47aHfEE7=2beB`nCCgJZT!yrS9?94XKQHS;^m^FUx4>`&YBeF zpz?9b>(ta2rJJb-jo#D883YB!o|K#n`rtAzm|i zkhFa;7C-v~Jk3dAK(q}oTwLVTl6NG;!ABwyhKd28gq9qe>bF$0fz@2_g!^McgTooRI*8 z{-ll3%NL;+zDz#o~e~erSR7+e_a7T(YyUilLGzX;LLDashCrEGp?U zvZmyC0pW_Wto%c7(KI08Nejci%)d#dY#rQ_!ad}~FH)sEOW{-Att!Nq&ZT^R!(+Yw z+~z!ulnPwegJQx*ShD^^QL&9a%UL4zWxYH}iY&Fshw!lF!%q$iQqawY%NG@ZdL$)o zR}=!wNu9qaQ3;L0%>>Ax6JZ6E$zVsw0~!W$@T<)vLG^M05kK=F2ZKqOgkh7qf0AI@ zP|F*iC`2sZl}X8!D5!s#4O27D$DS<{I)Ou`ac?4%o}^>j&X4sWDbBt^td!u=`dLWD zim@PDsn)W(P@+p&h0`S^U`jVCyUdQBKT@fC>#5#BBx3blv-gz zaarNDRnTe*uzd2=GFK~p+P9eyM00*_`{UPI0ao#w)UjFD$pY}Auu>AWT2MuO{bYxu zvEx13`71rjsV8>hN=URh1nOFZ`(r2YYpuo5_}_~H?5>l2L@#>YwMQ-W7M$&2fxGd| z_m>BnD*_v@aC&&9}L3~D<+EWV1PyD79vAy6;g>!Fgf40`yB+w^n0yH zfY-v4cp4^+JaYuMw=VKy5HVwngQJ|&_JfGVAeZT2s2k$;D%Df}Q@KMB$YGbDG;LT) zS3Crl!dNM1c|`i4o+c#=m87wF6l0~19@uF@D49O|Qx`b}D#7S`N8gBIsC`<0W2`G| zAgDv)f+gdy^We1Uc~bNPh939^uYT7yZF<0xt>k>j2O^&dlfO$>J%dMnEhLVOxwBhc z-w>sLnG2I}$W9kM<}-Sk4~PK>vWQtQ^dyjhS)~f~>Jzm_y!p(JuY&$omXUvU7F(z8 ztF@yoJTxHZdSck>v<>$oCRS%aGtCVS=O?D6t4p{U_msLpk^v)RD-9z+U~{yUnpeld zjA>jGL&CYqspr~}t4nJv%Sl$$E7^e>NBd#d#iqvdGER6)ce2jq)m33dX-!y-okOG# zW5?#wa|;n3=}0(D<`yKUdyPqe{lQyiCRRY}5a*PGhYErCyFbjgQfbtf%(p#M&~KOF zWSawm%hn#~?i$^}aMYwVf*t5hjy%?L6WD&fgA%DK7AyHHU7Yu$u2$|TryNW1TCP5( z+H-^3cC;ex_Y*13wjQhPE8|_5Q~l}o$rjzhIwL}CbK;K7i7D5l*U_Wyu#WZJDc4H$ zH{zDo#D!zs$4bEp?CwvUTl)e}-H$tJPT;a1!tOzm;o~|^;jJ)G_<2mb`zAh@xB2_@ z^OSbZHQ;yhp=2x=2N1yNlj=H=%=HL(GL)@|?K)H6^qB7mziEu+KW1d~G<^Da?4cgI zpjW8g!UsKdU%pkxO~0*=f5`Ve4KtT0yq^&FKThSo7y8=yoRDumk0bj+%lluJ`u~^T z&IP7{zJ0Rz-_qzEUj;^?mB1udlhwvTF_8%l>=NT18kI}nb~_=sMIM`u6b_jpK;JJLq%k_9`O6&| zF`uAZI#=b1S(sg=rLv0aBrc;KVDxF>c?@{I)XX}Z!tX_SuGQjx>-#=`cP1p{3DH5A zXi~J2<_|^xVKjKMBItBRk@J@9xIv-yrX_vaLY6lLY7&BGm_ag{bNU2QnOvQ+T&jk_ zddLh$6_?4e^Gf-4HGNj8E{0HK>~(+WHvsiTD<^9wjX`}1D@Uc%$>p~sjt;et+SAQt z&hJRjp}fQRZ>c?Dko@K|oY#yWkBy&SBf|TXAKB>UblLpx570BrmVfpeIG0_=W1C18 zI4Y@3;pcC#p{nDZAL-}&8D|t7*0ovOckg&k93UT1PhtTTxSbku6c60S2E{!kVxJuw zZeYP2EJMXeHXjwLD0qL~^$|QSMZjTkEs>%A@!f++T2=s60!Pf1lESM(tN>nIQ#p8B zFdHX`JX$p-cq0@X!oIIM6ep6ytc%FKpTU$qLWH9~^Nfyb@m4sNk{5p?hW9f;iAuTx zr?4OcumLH7Yt}3sK?hW{v?xw{IWD2gRKt+Sl}}b0EG{zCswlQ=r$wPnYmh0gEHMSa zXOva1_MKD%448Xcm+m5U5@rxFqhF2n<#nz8mylEf;dfoNVYb>Va zTX1c+72jv;R&|EgV5~#keF<^kCy2U15Nsv$;E=I{?EvTX4+N&aTGoz(SA&SbM~f-yGHLz^+%n zy3se3F^WWQCjtjC8K+5%=t-wP>MFskZbFP5_bXcJ>-7X?s_%&_qPg!1aRzQ6alkBv zg-!ex^MlU<{$-aiXA_oYN9*>CnlKFE7bRbezwSX)Fnj7I7pcr1BlWE+DNARF;!~dz zUj!=?&)Zq;2b6f+*yh)HPJr{)Q3P%iQ#vQ5xixO$d9fcIE6t6%s8{v#zMePZyVX3C zb5}^Kw_}oas8u|4Gms6+H$r1m-Rel2JK7v*#+5W?dhyHn5-Qp^i+tJq+0w5Y`tDSx+V= zyF(J?E<%Ym8^RnYOP0qzEKY1w0nH=jzkiZ$z_HsN;LNc9qm^+%N8*07N6ZK?D#`B;`HIU!!1}+=u4(Z9 z+D(F%1mzA=y+MfRCBd+g1!7@FDREiSjfNwcT-=LQ7IP$h!N}?o1Y=AGQ-yd=beQ4J z#?z@tAtJ`y_2ml@$_-0cbi;quGDne9mQ*u$CYb$Hm=U2 zSD+lXcRC!*9_ISY-`I4%23#olKGA-Ax>$QVR}O?!1qX(x=DPKM zEiswq@$0*b{iFwY#bDU{HRAcS)nXW`CY|+c@TxF2oJFAU`Ss~Gms9?OF7bZd1N*N( z}C^XM0&334$Mm;#hhdqg0tTz8-_d^0Lnb>F&DRk|~s9IET5m zHOIwiWCs>U1V+ZQrMdnbtHl}C@EoCpe0UkuB(9$ljtX#iz<>~zNx))}v6dE9NxEr< zd4{~{_DQ9^FX+U`F=^4@q+GoKek4cDJlp`g2b%t@u5PG&BN@0+VO8SK#yf=7{lRnA z^auX+q$*I3d5Br3AVv8Gt0e)CZYZ#r;&=h>!W3!F7bAnnau8g+cY%V2)C zlR@9P&9QdYTJuqM+1pD6sL1&=P7k)5O2g~A`=bMn39eX9nFgYqy$7(-6sl@Gael9z z4IxLaUAJlnuMc7~4Znqq^vIir4C3WxHT2Lwz5%ccK4@-d#QM*~u_dXa@8%?byWG}n zP1QG!@w=^$4*$w{3c>#6Me4L9j$Ykl#L0?gKc-sx4l^PGVBlC5Lw*GOQ9;gfosNI| zEHTc~4my8a`qgiJyY8~7<3b(poprDoh0L#sC7ssQxJ@rfW=ri^`mC@U9aJ(%tb)G* zM_!n?Ax*7N$DlaB+bcVCYB2Eea+)=KrhyfF>-~6C%8E96TzcBad3rx-`*uAtT;qKP ztc=0h%Rbs*y)4Q^dOJ?{GT6CUcZz*`tPgsSq;NXZeZN1FycswU{GRLmc*TgkifW-P z&wqIYQ5*TNn)&n&s*BXafn*WteIxZ$>sWujapS+&Df0j0p@TcZ)XP?65Qq-Bb(RE! zw=QmI^5>QC1IL}m=;~Y&OEw=~Jxus(!nW%jLjI*xT6brDz8{rVK9XBm9~Ry;^KK*2 zSCGPE2bqKjrh=4chWp3>)dxh7*Gk`0C`}(7mJ((*6Eu>^pMmcub!6yb2=P{sp?ORg;Uyjo zzkIrh&Pz8UoOK_NIk`?4`qYmG4!K>m-iGa=C)=qrAN`S$5N}~l;qoUgl)d#PxkeU( zew!=Iimv2szN6>g^OZ4J z8z6?2SQOACA8D_y#Jf!;=G^~;5|tcNG|ChHN;Rk`3%HSwlZlu=Unu4 zfj}X(JvFxVXZnNjkqEZupZHa_QdFH2d7o9(7}wh{ILZpyQmuvfxxV~r>tgxco<(50 zYUQjoon+A!B!4J-g)u{=Drv;ROY42D|NE&}+gQBdGFgdu@`>!d3<4LT{Z~QwDr4$3 zwKmiJY7NT5%X(GYYHBKd=3ywQi~r1Dm{)t1DA#q%|yf)z&K~IP)MGVQk~S zXO`Nhn$t3cU*n?B^^S!AD<923{C5Zjv<{7-xt+F|5C|?g44578+T?}R*Kd$htluUB{UR#G>g0OnxzT3z-1CYF)`bkXdT-NZnKC9!jV|Oz# z_`Ze`2Rscj#nb~@5DdOBJ`T_TnL@W`^sv1&kcFTdqDlN3`HWF&e_-#bHbkf(Mj=|+j_H@CDTQnIFx%eh{~_Dz`54yS?ihGuTknb-Hf z-@21H_b6sQ5*YJ6c?>1evihj-9r7$`;#sDk=3;*}7To>J=1_B)ax81c=Jh-tWqM~k zqX-4Tm_C}s(Ugx$2oNI=LoSnVu29Lgn5pW;p<86m7neIl6x5WcoN}pol*Q)|`tud1 ztyw6T-+J=efMi(WLC`tclF90VY`~X8Ek-=%*M|96`#D~^zk>0016N;YYT!CyoIW3 zA3%_`{iwz@fcpJ9obhcND^=-9BJetjJS>Rd@#**db*y(BA2AuzW6P+@hiziVFJgML zwibgA{TMfc#wnel`amNbz*^{JE zE5wle8mTkrr!#lnqWPbeFJvT!a9_RAFeQm-1V;EZSyT`lVTG{<)HV(drO_Bc>ulk0 zJeN3!1xsQcLJ}-yjrUWL$v`-NqH@zSv)NQOZ*rf1{NC_PGDBmGLw*yzaEVmbPB5M- zUBowaRnti=2>?>9u1y4?G**Q=j>%lZw|3x|TB|+x)Pm+xjWRCN5X!7}660oyjq}x~ zDz-EIxR6uVvPb#5kGm;P33Vfy9sLHJIJR;TEH%3~XZt>}RMn z(UReC1afDkIY&sBq+=?zZDnWxkImFMq5@D{-kHNg(&Tx{cVpb)G01b(Uucg_rO+Y@ z(vA$6CH$k&lJJYfWa#Mf0z)N86Xn(7%PLgOEq|591cK-a%bIi@G>RP~OwB6+JlsQ- zbsyyPK}|0ngY`hF!F^Qy0^yFQysCpT*sPoRrv;|7LP5z|?nq@I$nNM&i}3smqd%sY?@R!CVbvR5duJ^#=f5Qb3BwIs(WD2*KsZtUn%D zdP#R|{{~b2r;oV>k2QN%gur2nS4I1J5Eh2P*@u9b@M4&Bv+5p49MPKvIQ)@S{YQm< z%{IIIVYOn8qd%Z=N{83x4AYSO2k=i37Sz?m)*{H;X^JbBIe1-#g#O`gSc^4q!_w@l z!_;k0V^vKj1)YA1?6{jN&LsMF5pGuha?|;E@r>iskK}RPj4yn?Jjz)6exl=p^nGA! zT;At?i8!+DW{q?DT}ay-6}@8?M&b2|N89fWlin=e<7Lfl<3pC$Kj)2zQ}89a7gh!q zYy6Iy{mw$cXZ02E>WL;aD_&!BhmiG-;m!$DgA_RN3cyZM7G4Qw3~K&C(#$jR`_88q zAv1GJ){{gi^S#<1mmmo3Cu}A319EW2Yaj~9gbRgCD>$?|gJ_Gz9XgxYAVm09AEb5| zLW)#RFU3X*PpJ+=EyC=_@FxdzxD11W4i!*rRe(Fi6iO{}4KO4q#O$BJB#G*^(;m>o zo}3xvs8Nh~PuwNw7aC^SK#ks2*~LBS847T?2+-5WCILu6i=f>Q8%sqHTBS$|IOZei zRQ2N!a1WBm-ykG6QQ)$qV-T;`C(0r2leru~=JZq~se0#=Fi4N6HZ)Mzh!yP#97`+S z#78$5EyCz6hx|HljOx7GXAF3jc|mQAH1mfbujhuQrg3tca6b61N-L+QtdeF~1;K3A zCZ)vFo7r+E@~TfW#az;mx_>6aq!b2{6R>rPANhH}*TFPkrp%JD|I0*OcQk}8V>`nN zk&*^?Mb7eTQ;u4v84jAIeBi)VAuFtfl$DTj!bW}mAFBeHdN>*Xn0#SVLtU;Ab460i zq(TcRQE?% z^SRJ2zBH;u->6rWi&@x9GQ8;I_BBR-)-)ihHCKqYzRcr$W11N(>@sUd{Nzn*R=P1h z&;o=_JNB{HI221M_-R3O?)~EC_Y1 zT{A8soZ3?7r4arB@;{F_YEyFrIsR$Pojm^4p*4pehgJN(UV?kpqrM1KD{qKaW`(m_ z3*LEX1SyK*6;&?J@&NNoqRquVYXNp&T#$_NL`u`NH4YDe6@Q=@gx%LPHlf*T6T~Yl zyAX8gqp*`F+0Q(j=yce{9?2G~dvWmaew+hY%ZGH%36d`E_2SEer9+AXE7@fH=)5)7AHAUMvIkgeAt*9?%jh(v>UF%2vP zu)AoHZX%YpLa~113_+$a3Uzty;vc#XN1xO)qDDevBBzhojx@;XWWM^7%c^azTp~QAeMsk^z6$_}*vwP@m${;7!~TIwd+xSQBLOv?=j0*1<5G zkqv87HF5y6LC@PJoS7?8aZN$I_bV1HZL9qcf2&|RSBpYd*EU^U$1#@5^jb1jk1odA z+l1CB>2Wr$k=(G(5a_)sNteOf!+n@FNj{8iv#quqBqaO*@~Uqd4(yM~AzfEoCRXi>{$BnWN$aDLBy+hmSP zAg^h(>3ag6Yd`>c=b-@1OJ&H01NV$DtvK>Mfkd=(gaQFdd|B)5)d09NpLGJCDmnq` zg~V)EB9X^=6ar^dwrg+i++F;M0QDM1{L&_|%L`j2q>bxD@1_XImHzMIG^0YdxB*?FXvYm8$p!hAP?H5!)zSi-X%71;({CFURZU zaMxXy2QN5LoW#^TK1rZH&?^;f#26*han(XM7bty3J)*Kttc zZ24#&`She2O|LP+c~It(hGtdAYXXR-GL8vcP-g_4x2$szXL5{7t!KAvctxH+?wGt{ zKmA5VuIJbQ6q@YyMkKzsfE^2@y1hikdPsB+osZLHA4Vjuzv2kiPiS%^Lu3c!^wsUV z+Stqk&3PSDz$2Lf-4{Sp>D1GlBeKr-ORLCkv8z6E-}VI{@n);nLP3SsA0l2xPxP(v zDgEn3*6!WHRln~{R~w>!D^K3)cKlyI;(yq_bWpGH@Am`|cipAYZ@#@H(*0y$)RfTp zg4PMc3wlO|cU1cPW=JJ8q?&KMzLNA=yG3Y>dnN!yEE4irt#?p$+jHGv4*C|m4)Xhq z7crzBthhVRWU{>lcGV_y+i(xGFABU+6bT&2?kN~upcneyC}&l7qz8wGG)!b7>#fRc zfZ(jmmj8|vHvcIW(S0@&AJzzmS4e`zcPok_s{qcy95XNb#1!RJ7dabt0N0lp!Vtp< zcQQ<(6?Ha@x@kwnyN(&t(as0aSOhUsaTwPXHOgb1oLG=#5I^TC!TdUv^q!jiklDc5 zxyneGqStAQ-MW|5c5q2yz0;L147?5y9y6)t#SJ$ZW?nT zaSLf7wB!uBozgtw&5n{h6ktwn^HHMB8GUfS1ZbfEmW=mJ@_=HSvkCb->(o-EOivZ!j+49Q=vSj7)PYI4?9JtDrRnqVUs#Iix+WfCo_WBM7QCc5ot$LD z&n%8+Z~snn1?C8xdym^<0cUfyQlXF{y5w@bVnb999<_#)sy&?vaF7s@60rn4t_xjPMlfv{8^m~Rjp^?CDFTz)zUWj#qHsd z-}H-HNuP<8{1>ZVb#n`K8Y4AcD9`*|J7~a$Y#aF~ZOzCWApDBzcQ-WdpG$_#wSDiy zn86|&iMrU0$M@4B{VR|@-H(knU4j0GuSq9bz*0j(E8oA3o1ro2oj-Bv{AWe9tP0qA z;dSf0&Q>=W*Y@(14^@U8Hhc|bSfA~J;_eI->!C7PC z7`2va2wg_G-61b~JoeVx(3`u-;$gRbf@TS0i4S3E&WGRg(_n{{)0x<%^;#L%L4y6q z+x_G1{_%GIc)NeR-9O&$A8+@MxBJK2{p0QaKhN8xeFA;@2Kp5KDe{xV|BRDrVF}8L z^Lm3|(Jhbr>hk*mi1%-q|M!BRvmbmo%XGnz>Kx9nG2N%1(lrJ*i?lw$s5 z5Q>w)TS0xPLauwD@0(Nt#aJPgI-O5?{6TW2BKFC|bFt+@u14d>e1G$)VvM*X8Gl8R z$#@BSAzhZt!ij3NJ*#Ur?~;*5yyFlR!#G;CP_xy_h4U*%jX{Jn`VtgAN3Cu*J#&RL z0#4~xXmGU*pSMQ68NVJbFA>5@^yU~WqtVo_G^bwzbw+*%c4`-_+;yDw9Fpl#Z(5kGEM8CM!cLrmZzK^YQ50%aoyMgj`|9YyOtqAU}*#2}g zj+!a{pxRvRRJc3luLa>@70*R&OH1l`Jp2Xd`G%i!{!}XZ9G2k@fu@ls5%kkN&-x`~ zh(r@fjY>cGUM@^2ghF>@*gB74nMj7P;+`~&FMJt2oHD~a%XKuGEkl|?Pcli)zD@kHX%lNb=yU|Rati+{8{ZCSDPUZ>8wMHo_xV3er0&c$!r*2dy<5}VT0^XAuDE#yLS*iITc&dDi z3~8#AqW4kiuE6!xXpWSreQ(v%8L^+*Z zujCa~bFA665I(LuEmeDL1U{X6kZ2#*>or1~=v=o0=wt3qqFKKKhx3EKz|-VP2|TYk zj90%NWVwBCZ~m%&bo!lJ@#C%*FX(UUO*Q@3j`J|{8#jgzO%&5lZ=0Z*(r!pHMaN_-{f9m5uuhi{z3AoP>o_;z+s|>t zOn1aDV`?-iX**~{ZzQk|scooZ$ad7L6OW)K#hQZVItRw6e6(j_WQ`end5+FtjN-KZ z`|}yc$LzFljXB!;5jz5SV^jKCcm zqp)tJyz5XaL}UDN^{#IMSHuHtx$udc6-*J=eqQTF#2}mznFdr0l_oM$`fCZ8ov-oE z1Uo!uWn2e3ObKOdyTs6C@v3Rm(J2^vc-14K9rs8{-a>niFU>qE4+^nmXE1`n(h~*+ zvB~HT#ZmgW{f3xkAk3D#7IFA%1?<|`<;8-3sM~lWlq^AZ$<32YCMV-i8)LZ z2mF`m(>@Qkxgf+NA-IgGAkUv@Ab-{G05kXxD3s8+^<6P_86_POblFM`C<(KZX;Z_5 zyvEluNl`7*XtpE|V??SSfD`1q!9Z>1;&Nr1jM1!2oZB=#>w5l7f3$e*_7dEA^o0WJtc?T*v$JCjXV1I! z;%i;Y%%g-J1u5j|!&6qMH=cjBS8CQq&}{ANfpr}e+@U9cn18JI?iz6S3xor=Ji8X| z4@{w=bi7d9fz9sr?&EOERag1H|4d$ma`XN2eiO!CPY@3i=QI3aS}cFcWhcfuu8U=a zO}yGAo^MRLtF_)Y(k#`GU?r@rHo#W$h7t0$ly84IWXIY}8>ee(KFqGfz4!}OP3*A& zB6Lvrh`2n9&CNXeXh(We<~=rg?%o=E zR(iB*bL#Px(0u=wE+q6i;~;3Dyi`*%PrA%~^ZhkR(dELuuAC zV(p9YuDw5Dl9_>+_PvAOoqHnCzneZELlJ1-z4z_uo6H|J2%lYVAL@_Mck&Pp$o@*8Wp#|EabA z)Y^Y)?LW2lpIZA*t^KFg{!?rJ|E<=B{l8FaE#I(FM+aijGQ$Yqis6zHY4W93zyYA+ z(GYN0Vr7a_aiQWQ5|E>N#nX|z!tw;tY$h_aioSF@FN_BhK|+?R1LgC(VpKmoSzL~1 zD-;VTqI1OB9V<1{Aae0!H4-bPC}om*2I+3jBx?0~!C9e6*2*3J^gJPWE~HagD7#~m z8O^r(c_M&72HM5iq=wi@Bnrgfa|1y5?vxG-OQU!v@%_ztrSkqhQ%TE1S~>9CAUlH6 z&;+d3CN9TIpJMVZ-kZ?Y88NC_DOSYwi`qx3iKNn8jr6NyQ+pA#-4qMKzkuv*m(Tmx zqdZ=*jwx6lMps+h1V40+g>UxpWm13WxNFRN$f>0}+)Bqo4f6RFb`r7`ATib&75=Mh1RrDr~7}y z;tGjmZig%o5yp5c*cad)?% zK@!{{IKdr~;O@}4H16&m+}$l`aCdjto_@|gv-Y$1%vtNq-CSh#8|bV5s`^#c_hTLt zMRtIL=Ovo8)e}t{@KzUc`Fyt#t8AgH{#kS~D8_G>v5(v*!M_O4M#0f^Cy5|GNzwFs zt%gW^X79X_lqL*tY?*XRrNYiv;Hl5Z%=x^S`zVafZ;_XJR zQOVMDGskKUj=;5bF=QLOT3C?&u-&1M*0_ZBd1O%%Dxhhx zd95i-zePJZ@wi|Ku<|(Uwvx*>3yacu3>c<9db*5DifB40)n#s3S9fAsTJBx>>5s+R z&PQ?@2gqo9m^(#k4*ye`Qm}EG?X8iep*isRS&WNhA2Gt=aWmskPLxL0#_Cgr)Jhc+ zx8Pd~eIIFDbj%T)+Jk+F*GvjY-U0w8*gR7EUG8VVugng#WMiS`9D-}PpsvHBarxuW z#Av9yh(8(jgdg#f9(G+cDGm3y2~}9;+iINV(dm)v<&uZNJCO#;oBj!ei-->FXG z7nqVISd%7K>4LlKKzKaN^eqJoZxm2+MqE(LIs?5`oP-=T+$^$Y{e6r>(x+tfn4}RS z64s4DdA2Q6O$^+p+_hSs8TvTg9>Y$iuY=S27mxw|91=uH%APF~uAGtV3%p>dcP8t} zruxS8x-K$8yqhUU9sT7Y09h0=i27>r4rgWKkUm+jeZ?ONw%x%9x2;X(Et%+n)DEcp z*>bstYJ&+}v%+wO*;j~h%L=ivOP>`SdFn>4vH;IJ@kNg^mrIO7>^h-w$Is?qk1buc z-FsP6uwCk+Rv3PJEI&vGGZRba=}m}C;tEmQj&CBHbnFPIW3J#bcV#b zOe1VgHv-woN}-shthDTR* zlU2U|VE4vsF+_?K$u@U~8KXgNYV?X&=Z?{6TT)}g@wTe!8p96DX>mC7Hm|+L#Es`b zozs`qko?=8hL)S|@P?CG`g>g3U@U)jR=5S6qiJhH(+B@MHr5^&b!*LLt)&gsH|;bxUpJ__$GjRr`7CWzI*8vl@%iW) zy0?D@6Moll+~Sgbo-~f~@9VvPR}=8Itpq3e=^YD&X(@MvEu`Sd5TL6HB^K^uQ=Rwg zWt5Nc16*B@S6j~}Mewv)FkDi6K`}l)nd|@g!pgV7u>0+zdUS6qM)6Xn{Zn9VrPqxw z-q;a_6A@r2aOd1Z{CShBJ4va!gdMxOSEWhQb&!DQQn2kz-;Zn#t;g6dTl#s&>&S0{ z2v1f&w50(g=UT(LWoO0u$wV{IXNnoIGRT3>LZm)vHU!==a+3Wh>m^j%?o+XvY15JV z)B|#b@VI<#_~B5{q=j@D!A@OF{_Z#4deoCUvF*%nKG_EaS_s292Y)Zu``5cg&> z6FV-yz#er%&B9p(*RS@HD33F8VH=yD$F^Ek%>B-N`9D5_xaI7$_~`n%OzpZhWl)e^GWebp6$UEY4j>D@91&pUoGhx*I3@Zwtvdd_|0+s|w71fAnCb&!s! zTsBrmo%;)dv!i#7OXxF>D50$*dTac+L*wS3#XYW+f5Gz0-`=EjQC z42H+@GePhtRCjn$0CG9I!o~WxZW)Uee5dCI>#4&VK{Eq4>(ylD0!=0S6bDdWyuDeo zjWwL9VomJ(0$n~Nx)bdNMecc}s|LsgdB$;j?{u)z#JKKrzO%1&(ya~JgNLtF3xRM; z8gatM1_daZ`K^;FV-&bL_qj?b2TB!$rtSurouOHqAFFh$**s{6KgjI#Mz^ z(pwkcZcxOb8J;M%yBNopxB#2%M0b}t(y4|(7u)cb8}LFy_|hHPTaC!AJG30@h=T#7 zQawBj+ptA7FJ|hHFLz<)dSEk!sHi=>hlY?Y=pIB70p&F=5)NxbjzTn*d2}VIOBUxB z^ntM7Vm=TvusM1-i3x#6wU1|F052j+k^)e`1z5rot8-5npe|w`7t6%s^GIziwikPA z7WJ_aQaa$XP#D9P6i38^giRVNyrJ6yR%eOxmAG|s8i*Bl23u6XTShuctjF)qLZAat zcDNDP`Vj|-RCoFQL3;^I=8n!m@#5SuFuvn^QX=kPV%UD7I&So~b3{Q^LYRFLtJu#Z zNpQ6qe7Z&=UAnWcK~hZ#WEV$H`>N6i!OoIi9FMs*FOm~l%|Fz6+xk;0*2_f;}^nl`~)9d!wmabXVZ+Ko)aO=;$KW0g$Ipw&G@%sgof-(E`r zxB{=lzZlVirMT>d?lalV6Zc$FFf4-O22$QiWu7HvUDC$i%tt5H#irZ`$TpslU1nwZm>;PpuG4E0`mC!X+M*$+L4!;we16_l6mdf{vRD?Mzt3II&E3{U`4NLP{b)gW6&2tER64olwi2^?Laxx6c2 zUCgZ3C;+-L^SJ#(VSdsAdZ5>kryz=I)qHV_m|UoUqRX^w*PLBfv4zGD4`x`tDu!Cu z=ATzX^bmxQazjawAl8wRmUYlGV^b}liwe*fQ2p~THq;epZ;1y{04AX~dRRsj1y^~e z02vQ!91&orsHJ`y)mZ1b;rRGb_>Jz5XvqqVP@&iaH()3?7;D0YjP94LCNL|RWF9xE zZ1_XLwNqtD>Y`M0pi6c0aDIMmo!3n{TtO~pXgao53zMs+C33aQeO+i1yz>Km4st7# zg&`|_^$@#x>ljbT(qe_I3DE2wErc(8K(j63Q9u1Lb|Nw7#H}&e1W0&`wm|pmda>PL zu00=!{;$}$4H$zN{>uJ8_TkKMC9L)0nP8B{(nYT{4zn(v=e_uUBUY(Go&TLTZ)QRQsUyz7D-FNX50Ez3902u6`q4wWlr;_E>_KjR5gn6Q+(Oq5xK{PwgM$z9K5wU`F>y(odDL)yR7?^Lw=lSv5&a0*()>7|f zg5jD7B%KTrcLOYoD~(friqM%8#Hw1*=Ghw+(-N{NN$wS75@DH2c2UkHL`3926h=qO zx$c*w{Df*wkaci>J%q)^9gLL27)%-J>;SqWNG_^rar#SE)*3Mb9*!=47WU$U6i>A;vQDZ7J7&fjX@aTp`d$e&O4ur;^OMIA2T=#}A;wfn;b+4OH$31nCTlc%JT%_8Bn+U6NRJjCZs zpwMcBg-6xRFuEUZheaObo&63&PFl(Jlg?+$x2tBzCt=$Od^wKmR>-ampDCkAxtb*M z6`h*L1W@g^qQ{=bh!wS%+;*nzt8jML;l2||{^12 zhLdF#UYt|VjPG7*h@s0b+JDR2yf*F4{IXqKvCLnXaoNdd7)Dk^mph}|zCTx%@H_AU zYH!1T*L-mbz4OHn1dVbrc(2QoPui_M9_ZY z*08BWoF7@KWW z_?;?&qN?~B50iPx)Fu(2b5Qu|JlITxoX2b+!eehUwooRIPAz!IJ#{kf!8(t@FbSf$ z@J0knWDOfbRg$?+*nur(iRgY@QjTaFElb9PbBb1M-()uhh!JCL9r|N&Q(t7;!75y>>e*Jo;+zb zi~m&*<_#HwoCh|0^z)J#yQ$`TTa?&Lz;AO2hvcs+c*@Dw5?{Vln@^HvbD)a#;J?-2 z?bKJY&hYcz$9Y0jh?x0P{Ms1s4};YNNZ=ZMv~eiDd~2lSM}3Kg{Y_5&+Iwba zKWT^(XcnViw%nC=vbOdkOVgx318bR^cKD=y^Ii?D&X0p-kMGy*FYnJ(d!_Zp4*ZDk z8s3VAltkU+p9M*@n0_sxA3aq1*t}dz%YHq)YLS?ef3yei7H80dOL4B*ZXK{uYx!2& zgrj)_J_IMIuZw{;ni2DajL>10JcSK1R=gvJ9rU}jI zIS@N%hHYADxN(XhVSi0OAu7Aq{V*yi{{4ukSXHtl$`Yp526Pa#PiDDnA%8FCm|@?_ zn$YYnL*zFx+%V8mfgG8#!GxRs6gu z{c`?Y=nc<;aeiHko2->0S|jlt&AWQ>D)^7?iz-%ge;TMiYD?OESU%8kYR-9oY#ZB1 zj1Fn&A!j9|L9MQ*YdN_zrX&79DmxUWH8@E4t9Obk4uk|mPYhS`zYv$@H@l~|R z7^3swdgnIj*GSPEB}3(ejg4qbTAwMNPQ7uOcZNsrW&P3#%uRWEWOW}lFrZgKzZwLk zw2@{YTdNW(4(^cWKaz($%fI2>ci4$TmJOS3JJ7tK3%$&q6Zp`lenGDb{S&m5l!O!L z+Q+MKP+6qz{NcvYn~0RM;3cc}$FUigbuRBsHSZ2n)Vy6Zqy}%4Id2qo_d*<-J0aki zDNrZZ&Z^hJHqJDD#<)?|X__Why`rU3=e!WhgwZzhnr+yL&IMOBzn zPZIICRFMflw~tBi(Ao=%ggJBL{vUe-4a|ZQf_!(q!70w6d%I|lXTcc8Udr4dX+|L< z0U=Jo*4FY2Y{+aZCj)6(?m{4gr6ij=qX#fR{(hKl;*fBm*+hCK)yL7 zQ6(KnO#30f&7x?`P+u2CdEKG*LNk#oULhA{0#CV_13}StDk0qxVUWb=#e^`X#@Nz| zFt+_Lka8zMN24iZHn5958Dl z3DiTV_Wd@^;}wF_-zKM<k)oy)1^_j!$!O)YHL}9) zvO##M?3$S$53)uTQn{r*s8K<*<^lO;v7&)lJ3KiYLs{aQp^{CxGR2<)@9mJyL)L@c zp1JbAO~|W;LK#+P{= z2zd;2c_f8}X-LK4A+Wa~lr-ETJYbqZHlWbeRKLk7QNcc`sVEhxL?Z+h=1T5$pu%X) zykwx<5Wu4&BXq#e9%kKgmsVJmF1VI1CFhPTl;WI!CTooRcAxV}A}}(jY~HnWV4-}k zB5y4ONXk=~YgX>Q>$k*(BuR_idRA=NRCa<_aV7<B!IwSthO^i-$NEoXeASU@p&?^2eT|S z*UJT3SJ9yvm~&P^9a=>4vrm|!=}}${Crr2H;ml1 zR>_K721uwt#f^vHVt1ZZe+@0&SEw_wtP`O};q|G-%&zrQ2norh01s=%ko+Nd89K!Y*`zM!+LFLKj$UHjr9Alr6Uv(8tLz7RxcggI!aoC zh{@_`k6amo+_skDHf-4jJVa^=ZQBn8enM^+{_yXvnE=L5{)GMhNj9F&1s0lw|8qq~ zWxu(T@r4nc9L7&ZWp{^y2vG_CgP&ynpe*r$v^xfcS@qi>n}J05Tiv15`(Jv4{xo*^ z?sHYUBFRF2o-O7I1rsrJ9(2=WHRfNl#dD~%7p96-k|}d6(xl?Hr+<-RSr87_T8dVf z@g){=aL<@Ly%To243dN?;Faj$*mim`z!FX;Ds`(n2SM)1sE^KIgsBP1gD zytnR$qq>VDq84kmfral7o8?WgalRf3q;sANqE1Hm;B;3D<0q|OZH_?xAAWLFqFPiT zXhNM_;^261D|8Z_HZRtiMP*qgYp`}pT;B1XlvwXzVl&nV4o1)fPUI%)YPoJ1C+GzX z1`;X8YfuqrQ^0}>H5c|2@vJ_Bb~C}gh=FOwcrM%N?v4&*5`5Tn`?>aHQdH@>3=fm0 z9y+i0Lt_G@_J{&C>GC*|hu&&tWVq5;6#Df*@k%(R|D$Wxv@CCVK@cxaDL*JI_}275 zmsLfzC|=aOac~6r4M!^rlE^o~uKX$Be3Uup$ah%1c0l)&vwf#1-y*`ZiII4vu9=}` zv+wbHl%8@ZlS(Af;z`@;%E7NPsOlRg%AIs+{5Im&A?9{Z0y>rsH~>Rs*_5lYwb&5p zQB)x^vy5dAnjb-BIrM`}Sto%0-G@@b{)K^I7JNAI0rEhU%7I#`ukaE$ho)&mh|*0g zBO*A@tiQSC87c;adUx^1@yVO5CY0M@)FeA~8Rw+v$x_V}ZGDYxzY4~Wf#Jjs_p6zs zNOJ2%GRT`TUb|V@+hxbi*3o76G3f8xRXZ*+pv2dNA0HP)VCdvbnBNns0P40~)K;{7 zxx7H)t{sm+lHn+iKMOC$<7qYX*)_AdmEdhF0FCz?9oMU+bjK0~o3M6V;VR%AOY1#tnSNUI7a>Lu zTidP+6dVhVuzQ;Fg|bESzi~bDOIA-^6r&ORpb7y`I|puA-wGjq9`|g{$$a+(r!D9^ zI{6U!0>Ejn^Exfkho)2q2}LY~F#2oY|g@`Xi zy(fYI7<^lz2Vdm(<@IOakFO(OyxBxV8E^%7lDr>b-9+?5u{D)0zX7NbfJP%?#6`eC ze(5;S_Zj;G2ANR?0Tyk)=*+|qr`TYDo2Y&qUskUZbTG+7f65N`+i;~35gIYcA*J{a zQ6WY~h+j4OExxmo$A)cFm`V;xk=gjRSoRCPUGJak83=y2l|>t9E+ylf6J<@1wK$SB zB${6liZdVh#f(Q< zXpuC?OU5UKIEjp^iw8Pl6I~rOY(ycnJ@?VR?M*U~O96v1?%0vOTmsY^fzZ<>3N64O z_x`R<^K038w(S!OxbSzr_EjSW<;yhO_HoYz@P5EiGJ5{X}~(}y9p7ufZugl6`6)N^YKx5Uo~ z!f=d z<-D2M_dzRNds~mwg*NjeBu`oa#i^&w2liZ}=JrPtzJc6`(>mBGb>*h~uAe62jPKhw z{ihAC_WQVVCv*2d_@>}eeiQ%L0vThqhR+1sud3onM^MQOMcO4$tD_&ARb0h5C=~Lm zl4tpi)dqZ_AI^SX{M_W_1wLt>VZxyP@`-9X9!>bw4hUU!96mW(II- zB!2O(@uV-^JwDOsd-0&o6lU8HE~p>36sw6_=QkCbo&RG?1xVLbGXG@iG?EmsC(WCt z#~J!Cqgwth6*tXT=Mk^|D3L=#QyZ42=tNv4R$YMj8|fS0<9O2vXR(|10Tw`O4(GgI zH0b!?nC?Dz5FWAm$Mccaa2M7@d|lIQ>rWNKNAe}?>O5A$6G$oCA0;NPY-7bx&(q}P zV-u$eW3qjTe*D3TpZ%0Z7v{Fj8(2Z*y^Yi-J0X`^vpcUE`tr&S_{A620Pf!ihvaf8g0@MR?V(qa$gy|h5tY25I}t`MN9ogMWuynS<-sOY|* zlJHbbH<|eQMj|EcIYjO4^8wE3?RaRLO;Wqa{yS6GDQ3d!2pR1^7|_O<*-^)`uU!PY z1GY=UtWM>~4pbatd~;DK7X}zOL}ti?^JS?HWhJf0KfIckaK^3~s{N>3A?`2@$ijIf zcOLDRfA1obeb4P9cB_K>lKAQ!!|;2ei@QL6rPIi1T?(QLZx4PW!N-Ngmz#6%z>{4Q zgd`FE<0sUn9xqSivek{d0kmfxi81%S>P3QB=drWO7dtf$Et>p009D^TL~+t+Rqgf( zx*H|$IZmH`vX{~Pfcwi+3hbjq-ks^rm*vjaUL4VU+^QAbi)0RH$>mF_?n&e93&QdH%ninO_Tx_U!v(s(%=&Ey zBFiQEW(A^t;r3^d@Z&-NO9TOd17NH>KUxq=TA51YeNGbcVZJa3%me$*Lx$o6$ZAUqgdSqeueINUWf;Q z6n%pdgQ)kA6N7@SX#5QZf+G-uqq&1$@A)UGhvWwZ!&*?Y{w#-*f*90O@h{ zF90&1dQjdPo47WJLfb6_K)_^dD|LY~2tT#TUD z;2!|8C^w7~RT79h&j>5Lapgq%aE!R`(L5MuM<;ru&EX>;B8^H}w~g{edp zi+Lz%<#S1QQs8i7@>7+nf_FuX`SnBT{II3=viypxcC+pC*Y`4@Aj7@fAXSS(y1v+R zG+g5_NfWFfY^jjKTvaKl{AA6fgGko}wu6%LJ}44>Rz##5UPl0aTZF9?>qV7SI1i%hKkk;JaS;J%@J=!Cptd=FILrW zulMm##YvAAK~D%L z{Iata&Q4@P5V`RhFdc{Cxq*+NU!J!%YOljhpegY}O(2+n8g`i1z4CD6U}Y0{;Db;8 zc-V4D#CM!0UF}bhRDI%hS|0k`d|0^pns$GC5ApE-Ca$O-7$p)JcNf<8D)pS%78oE|BPDo!}b949Q%*TcqLk z(-}{N4{8q)5rRY~JgI^Y#zcnt+PME~>^M4wH#4A z3aJRhxr*WM4?1~Nj5b6p29g+%jL@vD#pM1Z3JZW(!eU4b4Sv!@3R?roM+?P>rVIPM zt|~*V*S?5S+4Zui=AxO43=!qA22p-cBJoc(6g`^jP1!q#K+oQY648obA=xn6j~J0@ zMfV54vPJg;=hA)J@2LbwM}vxtM5P+Vt{!@(SI!P-WKl+6REp~`k-5gigtJd&NNWO+$&tZyl4$fSKL{0QKRws?YRBgHsA zrwkEnQbXWIz4Q!HJO2bRln6r+olL+n!yNv!Gr|C0)L2viVIlfkr7^eiT)ZiUUBMn0 zy|CAv4QkyJz3iNbaJ_UIoEOHA$#!gXdTJSN)Rx`GY-haV7mgP(A8Mt)XlAq`a!h7PapV>e`@RfO64oN3@$02;x^$A*5&KWS$n!&-zO;78LNeTdSxPIT-je|izQ zi>Q>AEkvlPv)`RCM5*wRxHhP9#FWS`rr_I`=Z=2LmkEHfDtJdI;eIfX$u_K8Y!g%8 zh1OXIsL}BaTLI$w$5`j0IAv+?&5#Q%iatUH^4kO9g2q4np0=gLy~N^*u3}xNSC!4n zM~4%0dN8Ab38%#J`S+re48rbt;^7ZtMI@{9h2og)+9=GcO{LO=bR%pw zs`vUbCDbDB0lkG&DUwkU!54qbV_6-u;RwIv6@M+&bg;d)z_gsHU_1_MB=avFWA#3m zOOmetIaAFvUFBeTiS(_}@eOkNV<4SwiZx7G<)cFGs|#eN(vi7`#Fa-Wz9bm}#=niF z35H^)ib$Kps;&vVvro>C|1E#4{!`X2V%MwQZn3jf>sF}0hLcKPBuYti1}^;TRoD~S z*&6n*7CAWrE?cST*XI2?HY4%$q*>VVj@ zJmWOxCGdFy(d`xXw5X5!GjPxwg>7IG&1SZtOqGQaUJeOK>Eu2)3GK>xl$Cxh5MU=v|Z*h(W3bpUp*P3 z@8y%Oalc5Z^f?PtCb`2qk!$FAE1EeQ<(@<6e&C711n^kNfV7WA1|tz}1_u}**L346AS^xwxz#f1g@3H+R9ZsC}iF&bRu(Li*PLQOWnJ zcGdkt#=1<*vI1x!toHk}02afVG6_|}n{}0*!m}1Rh-LjzSQ+5CHtBoZ4DARl6RS~P z56C&JD}W~$pEL+fEbXHMXSL>`|xSMw)4N!>WGMoF1LDs8&qq;xA#p8xa&& z%km$5U}YR1;vy$x{6kYc!p73~#Ln*eou8q0RGFCZd>RYZTjQ&YJXS8yBiCI1=AtJQ zC&(rW=MZ%il&xF9WQ6|M`Lob&mJwS&?FuEQTz;5{auEBWrQ8@9IeQzR zWktYrBDv?9e!q*Y@{eno6|u4&ici_UcU^lD19L6cUEGSvkN8Z7kJ%E-tKn0%6#%TF)0LDyIV=H0$#UG zMFd7(85XykITF7I5W0^4+TQIr>m#~YYk!z9L5rgG;CKXTj7*F+}Kk(LM{n}W=-<(b7hzd$`;Y1M8BW_Wn|Fz zEIh>EFKl>uz{s#%3ToUzb`vm!`#UL)$LB#gSEXpG77B9CeX$hxi`ZCxM5^b#f#l5S z=zz0a$%~0(HAlAiaC8ZBc*VSLFWm`^DETbpxYB(38^rzm`C=@uWxhO3CYVT3vBd-< zn$yLQMKXj4TvW<>r0yhRW|>&FNH%#{U#4OU?}}ddpgB%X%557?bT;5ftfuVtdJo!KU7S1OUy=n0kBEzv~6io;nzx=zc_sQ5ht5GMNn`TM@|B}VSgl} z?htj6|73zdQc@GL>hRjW|8+MY5izS*g0i~7jd~?NF}A&a0ZM;S|GQhswKyg(sDjI7^FG*S@XDXT5}i%X_`Hz)Sva?pEPX4yZvn1 z)8rHXpnH_0-SWyVG`GR7f%dTUPN(FoslgTJtb6dr)jAiUpyaIUC?8?+ItZH)Q?T;bl&@$+bfH$icgbOtc#5KTh)k8#ew#y1hq#s zjyB7&{geXx`;0N~k*M-%7PL?H)YOpuB^({_vFNA)ecII&%fpDo_-D&cSHv{LKW^rY zsh7`*)w>C*7b(S|7XT24Dc9|qQJ{z2nDgO#gjG$a4}*jIKqj6^K9i`P1r2sNTZ&Mp z3oiE<`G{O>uf5;S)M1(FuGDG#z|q)dp2zzo>>m&hOAkLd zA2qC(KV6J0p0pe{x2LCXr#-DWAIxF=dfwIHzJ0n~WoK?XmUsaU61eA-x7{qj3{AmF z=#Bg3+ANemTD;+Rp5FG{Cmifk|MtvrB6X{>O&Y44lP{8^6H0D~RPPe}^Sw6U41<0L|` z?`)uudlm{b4nTfc#uV6tpZ)%q|r9@y5X<^-eqF%k|J45;h-3AOk5g8FZJ*m zp11Qzl#I0i% z2=o_0kqi~4_zqDDg=+6doj-RXN;>b5Yelhz36 z%~Xi|{HYUHHt?i6tFFSIl_5DjtO+ycEXh>-AW7cil}A9&6ROdjU<2fXW> zKx%@l{P$S9-2FvUv2vIKpTp_=1wMZ@yZD+73^)7wb!aL>hoe}S(n4H>SB^?RxrqDs zf$CQ&*uRV&A3uVvn(Z!4)N+j&LibK^vPB_7{FCgjB9Mm0q zIfB^X(5lDFU#z(No!8>eg1+4A~2@4Or8jHv?m~X#usRKn6B`=E{LjuH|zingoxFa z3x3-^>Uo%LN3~C$(^KTq%bkT2cC1?O4)ozzoQJ-uEBU>|noiTafaCH}^2+=8XQ1dJ zPh8R7uH1QYNp6^)damNHVg(boKg(K& zxBOgtC*L5t5n%1lm%5G$xf3N}IuGfVCwX7*+)i759%$IIc{C#~aK(xq4ej0{395Gz zfM>giEBLlet=l-Dt78+j*s@JiaNl5jVw-l$w+q*KFX(!5$pL)c!mi{IJBvcg-^|&= zVMab52Ae5i-kJl8LGQZd$H-F92UMU$fQA z`DLtkX@PSiJC1&cDXh`nd=xr*penmqf85^XbZh+MsbP63J{bQm%lVh({L6CwWjX({ zoPSx)zbxlpmh&&m`F}mjiTMx9=>=yB+Xj3M+jV*S3i|HtzkPX$SDdf1{^t^mL`7z& zkKhM78Hp|N?m!VTDgMvrnZ2R!aG2cp6tcxbuvkO*3!}2SV~B#i-||#Zc19DBdVX{1 z$&*c_;gieNm@<(LXZ0eG9IP&oj}lVMSJsH_Rm?>)W@3~&@BJEvpD@Z`ab4V7sOhA1 zd@xPYT>&ierO=AcRL+Kpk{S~;Yl}5D5dI>~dOeXegUu7;#oM1Nt*#LCa{P~08?CGl zO=)!MX$UFyC3`gcH;1@1a3E*i|jbixZ`KOVF4*PYZ9R8-TYH|HX}da?b#3S619GoK#iu zjm35)LT*4!T!Mb23WDU8l^79DZUDc)eNL?MM;E_1HMV&pEG^$YVn11vBFZR1x%=$| zmJriCRgPLz3eN_VLElaV7^m=oyrEh#P4>o;CrFUd--t>_B8qbgR6IJk1Xukb-R=9bewc-+qP}n>DcMmM#UA| zww-ir+qP}g%Cq)f>v{M712w;JSe&B<^8X269w!w5Rh0!v zU7}&YSX|k>YdPm9L$+#M{cll92#Sow>eORk(8Id=XQDuF-8h?PZw>9`D0Slx-FEBx z)uL^s<{7C7Yr$PpZ8}|IlV8QP`b6pH0vBX`pLs6y?aNZ*^aH5+P9)v(xEs}Z#}%3m(6-RJL$fpUh)35({g%ZL zBA!j)UAoYYE`D^&F5|cX=iVFN=ksPC>&W!fMRj(r{2cf)y{1CGGUveki5g5dOas(Xg_bk_BR=LOe` zY{zrU$#K`n+q}69?Rt-$@|qRi+ADkP`UVg5yNv(--n7)Y%lNehLWBPUG{axixE=H@G9AXC zyBEyz+7G8fAD%CT|Kox_AZ-m3S~;Z&6=^ycI{_aK^p9N_VzK5I!v5B&6F{izVHe7>S_syF3M?S^@dEZ{< zjgNTHCS>6w6WJqdv`>8gcPj-RqQmWI0+eh#f5f2qlk*_`w>21zXW=g^Ef6qH{DQ>^ zENr~7@GB_Tg>aW-)?*A3+%6E{8ENL1Qc5svz`?Z35qQgV@QRcn71VHVR0#MBVJu^S z8vzi*K2%BsX{0R?rLt*2D5r$H8xV=QjqCPWr`o}i9{7#$ng__I@ox8ki>62!(~a9# zB^2z^u!|Y4Zl~iLZxW5E%LNF)r|Ze!aGTVCcwKw%e7M{;Im$VKo=r^I^ajO``|5!^ zzppZz`tt=!OQk&>=;D0AGa+6^6hdcjv%_)BMPWP?)uC%#u`i0n3ER5;LK5oa6T z&33gQ7xJp^qtk*c)V}&URi;zr@Dn6x_<)64Ejarco^q*B@r6H+4V7pYTHp3w`5Ja} zs#Lv85w4|Xi=1x~17s+LEw0tO$sD})v1!!qpd|%_W{Se$@T9|DG)PVv6NO61B?(g} zIMinSZt|@}kSQmpAOs7l3|hvd*l}Cgx=}7J*TuW@nAX`EL`$VUCUx#f5qvRp^@r8Ty6eYUBSb7n zY$UZsd7)g;%2WTvtw4{of*nNI;!1EmQH-DoPD zw{^{tzPR%JiDaNpl@y6fLIiK0(_v4=(FX@{Ey#%|5<^+ErH#340Uq zcRElc+-VS^wsvcOv%{$c>w0Pm6d>jitDCEG+ZSQ;3-;XQ)byDSSXCqmu5t z+)JhUOsg@&Q+m21zzJ$+g=(MjmPmR>Txr#Q2Y10swa zs)rBrL}?r&nf%pFJw~d;@^K@4@U)RGwg9A#Th)N4=c&6zrZQB$Bz9yRUxE%N*OLqV zaCM$aA6q>u1iG6qw*ak0K5Y>X{ls4_(B3}mkz>Y<+m2H5`T>2YyQZm}qbU9J5*!{F zQbNvM`S^8o`(mdB6F@`ei83+M1uvQU-PUHP^Q=ld8Q zJ>Thzo-T^jVP7HrNi-JyegGA4=lkRTlUq2yF@7`t|K}E+;hNlDq4Z2vSxhu)(QA`r-S=sPvIUm#EY6y$ zHrn032r*;Lc7hq8<5ygrhhICXp})!X#=o9A1SFQul4-rw?cvPEN&T%^-;EK?>uO7_ zbsJ0W&o4}8<3V6HlmhBp#D1$an`k*%-1OwKx1Eo)%f_2*d9q(Gr9}tXv~Sz?4>^ z$zgI_59U?7R`KYXLLw4~06-Xq$*hvsJEHwM?**grILAZD8u&>K3fFt$jvw*!o{#El{Am8EfZmdKVa4&)ka-{$| zVgrLTPPk0q;18J&XJHakW9W_={-4$WXxakJ!UW+e;9+tLAx*|4xqc!)8}{Vdz=}PLzqE8_i*8zKr8A4BbFV zSf&E0KDdfaU|)IlZ0o#%z=3iM6+ig9Ggr-9#66Cs$!?n@tfe3sY-ixpbPc*E<*IM3<2rhrooJ9uMWEB2qcir}@yZ-l^>VNWO;c;xvUOr{IGu>5oE6ZQqpZNnSY1|4|E80Ep&Eas;p9qv>8|Se{wM@Cj zw%X}!d%a_^m}u+cVYE9yt?#mx$@%_FnJA*?PN*0vidruzrXoXf{e!==(CA)rtQ>SGWOXqrle~Iy1>?`VCeUG zDiCpFPHnmckjL@!$m{(aN9ilRBKO~LSSRG*hth&M4Yt^?hRQ2i0i5>Bob7aqBRhDQ4WuC>b{0V8o4h zIZvvyvfR7PXgncsQhWG_j%fi|cNZTC7i{m# zxe1Z@RJu|d=fLP<^!FmxhWyMRLapRzHnFJ*)jl^wKM?A3ibZr+={GF)3lW8@n+(R; z&%s@MPGoBu1^h|qfwHpiX|27EG#}r?yZFY-Rzw-D^qx*2F99x8q@c%rzJrUb87jKk z6EPoPi~&L$!kq7p<1{uzO9qIsdN4sp8>3>7{tCqCCWuZH*}WRC5$1kWh{;+frg?jo zV8^OX@@*$Yl@F5=qwH~=tPg~^0}L5l{)JW|DB3g)lTjLsO+{ZPpl>|ph0}73aU3pU zivX~6$;zcBRP?~vGE|s-Ub=SCkRwi6fI>Ong)>1MiK*ic1L>^>Hk9o4jO=^`}Zo z505MJHRRq1o=O{ODMBbI=V$ew;1ski#$Xi~^NTLcG+B06l{saxJDiA&w1F2n+?L|} z?3Z2h_&t?MqaTZ$$(^h@A9|Q0;&EVwprJX}@OW3Ggla7&60VARFI&5HeyWZSv(h=( z@QZu8Sh+GxnH$ojGHs*6L9C4ZAIL)0sj%TpJ<)h|u81vmkw@5yk$QRg&%R7on(itE z#_AwbLW4UgwWV)_nmjamW|eNa%lGeqC;}-L&wSlK;!8T!TrSda8$HIE9uSLqYV9?w zwqgW7xYmedBO{%wM3(loACeqnFM>}E46*euObv;}!R%moU|Qo3n`+t2DV^*R^co;E zy1@r&{J-}A!0kv}8sV-Sc2c&KR|$IAYkEXps5j>IFfuI{uB}?Bm*q4J$+n$w_M?jw z^0ML}$dj&vD7{u6E^9k2y{{r$xkKgbm;11x{vKN&PatJ;^it_D`YNsk(zz<7^?6@~ z{KO99WFSIP$$`50rfHI=RtJJmm%EY195|o@XX}$OWg`qK%>WE_^V2=EY^9zK+l8?@*1J}ns75hyjwfS2@ zx~S4L^Y(rEUdDk!gcj8?ifxDqkA>>1?rkU^7dG*bv543aw)* z_uoTi&)^9Lpnokl-2PG8qgJ2)eO0sPoJBV0LTt;u%yNZ|;OJ_{6sc8l8UqdizGH$U_m++pJ@&EOl}J`Zx&arWr+5K=`C$5_FGe%MF15boD%(>zLfUBF zC*TsZWd;zi>=~U z0p6=K=W<=x%r;uT4x;?e}5s(a7tY7qSu%`lG*$E_>L zkD!m1*p19yFgFtA@G0JlrBz$V_wN19xgR1*6t<5l6%N>r6g7U?kD`<+B_^N&V-iiI zXIwE3)3j_g5ybPb_?2Q8!g;79ii?2*6e?&Xi@j{cJk0(J)@$U>_z5V?@f-FNzq%c*F zQ~NT*%L>J4a!-mR{$WuQ)H3B2q_)C`o+3(Uc$`#sgPl^;&Z|k&YREwR{^2vmmR?pi zEyi8hxDVC~S*vAStCG7$wp>}iEreZCaiBIf+}W?@OdWFN)85~;<0EC)`Gh7@QLDO< znp0I$7T(|W?~`kw*m2&|zULV&gTemdaJ8ndObF+uIwvmTW`x`bMr3GI4ccLtC?=z1 z;BYnKwo}`Byn2j&2$o^wV3Wp)yy0;kbFBUGynftMi~4^0iERC*YKyDmekx7r?S3MY zVb+Lzk9OFY?cD)6Kd1jUU zrqkSVB!~d5q#*lj?aKY}Fy&izjQ=e;t|*z&4hn*0`w6L}TO>-}7f~b|lDq`v@#4}O z!npTIEk(dwl^$t8dEnDnq7Sl2&QD@l??|bo7q01Ay@)ys5oE+6{99}~q?LNDi)mT- zhr@I*0m>hc`EVDpmLjTw#a5S2vnbgkFcA0N0HxS%fC=w6joRKWJnOS4gV2nx7)w4* zPhC)G7){_W<6LZAiaw6f+Q}A%HiFPvvp3P0PGID`l)-9k zw~6XF2Q*faGAg^X5gzyZ{9dg^{8Djo{RM?AHij?}*XQ<(eff0i%Oj%EVbJn%U|^XT zGLn3Esk4z}tTwR_tPSx5*8!NjDw_Oyk4PEg^D!Jf7@#qqIIy&nj6<%K(va|e=J<8$ z?YpKEVFtOKTm;=YqBr+R-#CXH4BaD9wWpfR9)v)*^}?^Q(oZTIi@d`h=3?qnvXL1; zzYXnUDrAY-xHOiG_xEBs%{C>ihI=CV2V7ocP9=ceP7%k!Hb402ob&5E8s7xq(Ljqm zm}x$Yg_IICI*kHejxep!no4CzDxyw`H54xjpQ$!YHQ&Kmo+S}X*;7h3JL#dS0Rwc_lz2noU8r^VHeCc!|ZS}s=O6Xiz(^9>J?XjLQ z_f$W(SXvDpEl-=a!q7%Usg3Ee-t{L0?XCe*3dkciIjPgy5c%iVdKX$#EiE;J5VeZP z?qdUjY^9}p`-(qUb8TIrsMDUnT4cXdkzQkkrE7cfX3|3aRAQxDA+>HQg@4oo3$0;u zyVhb-Ld6tZmD2zW>~PwTPU{I<*%i;=Je!gB8&Z02oA0nUll`9SJYOuCvn`O`_l{}Q zYcF!0?H#=5vX%w9z{crq!or=B?x;&Q7@BS9rvfMpQxn<5HGO#3XGwx+26sxCEof~w zGNK1E2l{k6^e#6E#=&xcwDlg5x;ojiO}Vyq#!q|%Ic0T#eN=?Z0rnO7$kY6VqWAa? z4G*WHVl=Jyk@f)*J!vP`pVv!G>Vir@e62Yr5hfy4g0q~21H^F=~Vr_gD! z&*=;O4+$BvSZ*M~l;(?7Gy^-tg~u(FD)HqH3WZdrGaRnl8A+xW96hI~-xZ4@;O|{; zRW9sF5=g(s!K#g($rq>AVkx`N8;ljn7rMt}Ip)t*3MJZTYdBLY)TlR=)nuhWDf#2- zpgY!JqeN~o^hq;zTd~n%xpL~PO-`ei_49vaBPlE8(>hQdE`9_%R ztLNzvy4BOZ#h>N*{_^cpJsVd&!C2euJa`D-cYov;AP{lzD93MUgIys&iKfKRcS`g* zCkW)tu@i&_-M<;~uA58biqIqx1|ar$)(->8gywlt9cmajBPjJsLWi=arNjMFs9TqFA_ zk1`yKMh*j1T3*O9oE}fifUa%H#aUV*nwi;vPbi6;K%}&MG@xZ{aPB`+OUg`FHYxK0 zpq$iZVGdKAXjmHBs6|1%*efM*X8#IRc~!vIlDc={S7<70j$1mds<}P2s&JU}$S!Rz z@~}kLJzgF8I=io()pyiM<;OLv!BEyMJ1m_yt<}9+mCu!#UsNt9rCU3%7p;ALe3Lln zS`SUjE8Fhbs4LsA^suX2?-tMO$XUJ&LH|BJrR}=+{ z{=%5Rdf$yp;L9>b@wVgCp~Da9+|R3^^D<9}ki*%B9lox!P80YNy39|her=^I6U#y@ z4SVQbq8S+RJdPPkL_Kb(GH(R0*#v@ko0s*12%9$C&?i~8bl)r8Fd~`d+;&{gZ0P30 zV>X@-VuXE~_LtS@9uK18YhA{hP-MeTN`&cJkFo>tLXPv|)nCucrmIFznv3OF=PG=6 zUe9WVCO6Itrft1WTlTWV!Ybmwdt6VC>Al}KDd@jF6zcna+@g70dL2)T^LNnhtK0EC z3@l~wQ5MI?K|GzPetJFc#OQy1JRj+Ey|K{2^L^}43p?M7f4N}nY?HwazL}_ZLu_98 z=|AJ`p+I&rbzglU8gppjDFn9_fv{*^+2`iDg5XTmfhbV7H)MON3YpdO`rpxO{hkbZjzgltaZ+$Tg z#zv^%FJk`vGfdw|@^NokLRcHFW4zyq@kybCCCX;dfC0mVn8N&`NsQr^=ElVMn3DWu zGjT};f5?dIM!Hm{qZK0aDa181IYb;{S`rEnUs|Mfp#LT!S(s=A97*CaIV3f_hZ1|o zOADMj#7&%&(zXdus%0_K)leVenuLuj(#>&nrxbAXVaoCI#fN+SDEd1HDXrk*2xki* zcORCNb4-iRIvgjZoj(C#BQ`0+eG@h1`9(E#x*eaDkYLP-4h`$`dKmUC%A5jQayq=t zFbmRzLg=bhL1Mt4n_EO!z|3MM4t_odQ}#sgjI-{v0uk;l-p=6E z(QgN~0=ltqL9k4w3rnpwAiiRUhFWI=I+AXhkay$$RB1~f^xx(}jtShk&cUflLy>BN zl_kqPL&u z+FC)s#;^;B!2fRT^FD<6&4=;a4chJ##u?lW?fBc?d_x~4$D|LY{*3QIaIO2YU;yB8 z>qM5D3TEU1LL*xf7-J8I3Xkt1#Xk?+$)a_A{%%BpF&?0`y#a{RAi~4+4;HA}MQc}V zhc?U)u{_oQLvjB6czVVs7G?te9p5Lzb|X-vQ;%!T*uoBM8Pz$fO|q&m{s?FtJ&JQk zm3%v3-XaH07=6~pb)K8DL~v>wyVRtfWn_s-{Fro0s?S;(H^W+(7^F!_Sa=5V$2oRJ;3u5At)ako7*5 zS@R&s+?3=qmOVqteO;>ZfvOhdJ#|)@tL*&eR5MU#?N7kH68HC^P8BZR6tuT8%_mdL zXk(KyZUhD2gAhw*O^8h_vY$8nV#+ z`5?Ud8?uC?T>E_&W2$A4eex#S^L>v1p>>#e7QrXs zegB;lqjgk$(gEus|9~Op3&DgUZ;wt?v#Cm#l4ve(z%tQJp+%p$w@31+%CKJPLFwU4iDD)f z7^6lRcUyB%8;<^@JGNAN)Pg~opCQ!7ax!MjEN|11da;n~TZ{4=ZnoiKt?;bubELIV zKSB!^l+XLS`DQJ}wfKGv2mY*!-WxC5R{O;vxf9cFaJ9*B8KB;)56bmf=Ndg)PH&Em zBq@CUI$z1NBgBQJa;>JCHLuP_PCb7EGsp5q7W}*A0_oDU<%<0Cn82$rlV!kGq1%7U z|MZ}F#TUT^1J56c(|-%_c9D#S11q(k8%iKH-w!~;bIbL4`THduq!nW!3L_~JCsyOL zAS?i~4<;K)IG?*2L_QlH5$jW$FzzR)AiZqI!jqPg#9)ve>r1IhQJN$w_lBAXYuQp7 zCCfudnx<$)Y96MV7rE=l$^3CM^pN&@Im{Lsl_VFoK=U|CL!Ue*%ZW5)JmwF!bPq`* z`Lm2HrRx+sP~^bGb&ww$GHQ~i|0nIFw8XNFGACx0(6Yp;4WuHTT~uUgRh9|OS%TZ~ z&(b^&Q_Y9(7ea z-*=ju{-5gW1891%9s`{)?C&;dS7a;k$e%tt10#Ae6?G%OTyq)v7=|M43S@ygx1(g) zk@W-G22jIOPi1E}ZP%8X%u*cWmCW5>2+%Ckj!x(Haq)QGjm?Ywx~)&qGn zI+p6w*90*v6W|Q@S$7|9`+2h2KlbsqtE!IMP7odsX5W~e$IZ}G?ECF9{g&5uo;a8U zxqOT**R%zw?@@B4IJ@)CcCJ;FJhB@f>cUTkpN~LazxwmD9mHo&{w)%pxC1?mbNR|1 zb`Br(yu{7*ox$%qe)E8#xcg_>l_CP{_IvkHC;0A_1!{xABg0qSBC#s)zFcSC2TkZV zT}%)u&i1#X?w)JG33999TzJ=EVcajWNbENQL=fvU@9G55hreD(%44{ntjy4r1Sb#0 zgrf_r4AD!V&k(tJSeTVZDqIMb_}kf%;M_|;+?Om6y}2ZWEsGM#9>oai;1}f8PIaKf zFfmei&Cm)DNtB<=9#;EvKY0^m^xw!m98L=1cTHO;k8`8nRo6oTT1r4GV+q1J0Rq($ zBBbnd5h8TS0WL5wDBw6TzD0hUbQ=;-)@hh*Vo&lbnI{PT*!w2?%q&Jh7+2;5xuz#6 z!+wuQRId_E&Tk>D6RrdhrZFK=fEov&)TeMKNH8(ie@%Lslc&56>3%^%N)$20Ahs59 zIYP$S6cwg#iWCqzpLEJ8+-3X@3*>vk1pRV`aDXFUDL~(n3^!R-%F55!eNXCEu#^hQ zMvS5mp_L?8MM25>C0fATXE7Bbqy+PlP$EH^HW;pVpNAn!!jT;&6~pILz;Hm0b)ur6 zl!KDLwQi26JvtrMe_#CO)R$^)`6WKMOTUFBmLL21JLl6$fvvJsk=Aldo`^LWcH&gz zxLdV~i#1Ons!UPdav_q8saz&lLVf9Up*lphLWI;x^Y>~PnYnYh^#ry0LAN@mgp)#( zU%3Wt+HApUV=;1TAMX9A2G=uco*${G!B1_KUKiyoNWlsbl(CgbkEVLh19Af!L9N-| z#yav!OA;o}xT&_sMyn|BOeyT;Sx}ZsSwT0Akk;GkW7T8wOzdA)OKD;$L8|TO{6n?IwJ{m0cavENY}QaOd1m#%dvB&4bU9IGj*yAP79T@$WT|zB5s4F+9f~~vTrKZy;OB2=F_3y|j z-CMFX0XO9t5LZtf1&CF?cGR0$l0gXQa*W;92SDYprg_Ob;vaqQm^5^(aIgV zVWbrUsUEe?#_v0b>Pv&{Vo>-*LfgK_JA`x*ObLNrTjG>vBhsJ0k{UA($kF9S5&!;8 ztn5gqwQ42Q(9?|QlR5Yq-wGNxi@uAyP~&)8#T>@=xl262F$?k1?697!&r)TE1jtNI zA=Nv&-O%g{nwcU3Z6PyBGtGbgYMY7naVq$bv8dGa7!8Ncn^7PZW%H4Dk~h|7ZH;g< z3!3j%*3PY*dqa8T>E8`wOv7yM7Si_?hrLs#Q$-@qmokSC9bdt0E z@(zYLRF`)gg4?td%&QaZODxSLki$>sfZ*0m*!V4myE{YR#XMAi;Llxpalyt3yhk(s zF1#QReV_N~Mg9{m*5!v#x1@TTdj;+P#@lF2wJkPJ{y%t|Vg&wI#>cuR;xD`n_u@`q6*zHXoO6SFbB}c!>YKLQ4vfMs0504Wm6M-|=xV9Xy3gyjdrq^u(ujHf{N@EWem8%t(@aj zXGW2hAdAfoH#?Idn*}M%%GUe!IRW|5q`I`m!x1k-;Y`_fwzJtR_ot?fG$u9DGEao& zPK+k|gMZ@fwqPurPOJUJ{9SSx_kYfoYRy38I3A-3*JG)7aIypM?)Mu@<<53^-cBc; zN9lGTzK-~tgVv#JZ%}FRBI-RHK+nITRCE9p5&C#Dp#Nj;t5+=6g75wDFt}~5Ym%}P za1$tnd_zl5{1hvh-Z;-(PY6XLTo% zDSBleJPA-xS1zc+BQsT$T4#z#?U-MGy*agd{=1b`El31AqYEmm9Ag7l2&)1YYVzw5!Hv$o!UD61l|PPg)X2;A1l-4k*m;Z$I;LW(41 zB18)0c!BQ-U(Tj}8bMV0^ZAhMTOcJA8RwN{GDfGRzBWV zwN=p_FI&I5KA%mKw|L(pinpHM@3cO?h8Zwf9mma`zTd8Wj^_0D3<_!9a24F=sWCy zvlB}39K01<6U@$H_zp6!6~4V!AmVp2d~WcK+DU{JxsJYfFK9x@Y-o?+xe@kg9Jpf)Jq2(0mN zR*d_TF$@i5|HqTY5Z}KWAc6{s4@Q`XcpF1hEDaIq$+oEYznkc9#sPTr{X>>+NC{Hs zSroz;5PV#H3B^JCA9)O;YH~l4T6p$I6;nG@ne6F|3HoUDzk*2bZLFcO5Q-4RxZ&Y# zO8fin_xx>X3N}JGla@lt7|n4@9HiK8g+pYcU|BQU`jlf4)2EWs5i3(=q6Gjs^mL` zhL%=oVt|96woITfefUg(?R>V(GsRn#g<_l-OJ;}+WuPg=Y;4>Cc1u12_6H|IA6yZFTS}Dq-peIe%k zcw+A{JQ5sVLF6VFRJ(Ir7W@zYun$j0=MV4x&LCA1c*ItDBc^l;0*Ba5_{`a#>H|T7 z_l3XVKX*4;B;63Wl7_>%-w|H;E`~`b|0W>gH2W?;57HEUwPa;}5`d$)eRTPU4O28R48T=JjuITVbCzeFujKmAWy%ZB3v7%_j@ z91fkjS|YI+Qf0RLWyQiVU&B9aK}dCkBgtS!A+fVHMY0*7;r@Ln72?!$p)5%$+hQ``oQ*^o;vjzq;FcNxi6Rr)*N>*UFgF5-^6eAJiL7$$22$FJ7>F+L zsN^NV>q;udquD^Iuud9lewi+KEfiBhDH5haqI9hVp~n9#Ow&nAp?>3=B)t>~k%1}0 z0d_Vhfy|;<;d9yE&@3gX0Yc9uIS#YtB9dWs?nNn3Cl)i=aF|*L{1Ptg`#I#j?xm4X zwc(_B25O)ai}I93sG_oZy8SY-@Bs6mhzg-6suFlrqaVmwLaODWoDkGBBG#5tzw3B; zx%2a&IcHEMMvD~VDp7dDfa)MOPn-1R*-@Kj%8fKKYm3BmrKBjXenf-YeOJk^3shH~rWPoFeswtSGet`|t54L!=+C^QO>}=Zph% zxbHcmP=>oDE~|suGyO>E*0H~7gpD002=~qxu;F8g@26SBbtY!M@Usn5`w+Yh{X$FD z4YN`RJx<61+_Eh5toXdF3u4cajyUkVLicl`%9ZyE4mCSKGPC>(=OxR~4TcqH6Qrkp zMQKo_3#%Icg3Fp#_C@oIJ~1wbur2$Kr%elD_@*gq#7mBS#W@+*Sr^cr%K_X;C;NPw z-9IN}vEiK;;XL6<=dG|k8sI5Hk1qV7j_U{OWZB&3^hLf|7TfGT1|!6Ad8i!xb&Gg3 z3wEORC6Kb2d5dS`H$MH)BiKN!Gd9RLZiILb`_C{&$T?#O&RO%+;LWu#{>Nik^G>@! zDuC#dIEv+u1Tn}w2=9~dmoN&@2XY<{Op~1N!=%?M=^GxnFT%CsK@j{y!^OJ@bA zh!<2?j=*g5FW5goPsomJQM?<-y9+@APYOdkDz|QAB!yt?Fa!KqazU6ZhCufeTzGZX zUVe;!3?VEm28f>Q0vQ;22n;e?uuv_bltkC?crqi%px?rnlMD#-?{zyw^^Dqu?m_q^Bi%(8)*ut}VhIy^!Ki6E$HdP>}zP;3Qw~n$Z9IuEF`wEbxm} z{W;fLlPeseP9&9q@pm+l5}KLlytj5NDH^AqCkP`}YJgIuNMdHV&SWr_p-~~jeTGyT zh{GQcDfu^CKASBNB5EYQNF*1!b6baM)^IMBf{`e*4ESXYP%ptd&qFDgjF!d6N-S%v z5GYrRN+T_4uo|kyiFm}3aJf)uu%KK;eJ;FE0vclSWwxqQ>vbSM`J9YB&>N(%z$o)Z za{R$+H$+;7w zE!16OQ*1YOF}v(sA)eeOAx5IN#UZ=hZ`ZVXJXv`MfCi!+9k*)Vj$% zNAqt#W-+$Y;>jSE+hJ=6mL)6-S*%Gx3l@gAp?guX#pLo~UL@Vm;ta=C$>J>c$Cab( zKf5WJ=ov!8DtXb2RHr4lywDanahsASSzfy#7CC9QpjApUdw=NJk`}tvFy;=hy~yhB zPbwOQZnSnt!Q!kh{I#3bD0vZwOG_%cwv+0aK=WZ4ZTjBx=vnhN{F_y67aq4l-Dr{4 z3BOkpHdzIw>Czh7{qB#`rsulBnW`P=v+Cv^Fzyfm-FM+ooMW-J3U?687&(@qSUHiS z)J(Z@-iv7kX4l8-+SyRgs~{roFY?IKIw!V@BMVh2n(8<-yV#;ZmYBJl=1m_OI);dQ zifLRD;tYmS+ma5ZM3e3@{Xi6Y$~yrTtM#8l>{~eJM4B}BQ@A?d-ly2m#jgnU?*Fi@ z;yO9i8RiwuWSkdN!I`f$b>pp@GYqn6*jC`tL8&ah#!Mghu0I+xYbWf)_S&sj!_}i27o+*%IdL7rd0h??_4G(nVVcx$R=u46(RSs8 zZe9^--9T0AD+1~D!`BD^1O^UcNK%sET)pyrjW@i&3)ba?l=o%;BLte=%XZwB2nZYA!U zes)2~O$p!C<3C=C_e4kSz<|#L;=Mj~Dq~j5fs+u-?k4`zq_tOpm)Uu1aO8!Oy7oc- zf&TQF+k<60?dyV^mhl6L&9w2%keJ0F5F|6qrdWCnK+usfRZ)y0WBVPVP(jf0DS(Kr z#pnhKL_v6f5DIODaTFStDVAHtBS}-V*M}7TadOoE+R7N-n!hXXY#@rgs}TAZ5wQPb znTz0c!eovpA8ATr_<*7|Sl-KsXaz%*6FLY1Sg?nRi{60y39fXim3lUt!$N`?=lC!k zN^!?HsuX^kP$E-ErOqkk(r}X)9`xtKZ7Ehl$|0_>-WcaGWrRm?+%6MEXQvl&R5@-o zp+csJNqz+0p&>SEN~VAa^bJXSvn~XOWChK0c|aDY@DrBqW| zd+{bD;hX@yU9*V*nlVEG2Ap?%1SIdkhMYMaS%iEtBp0o5m$@>&`<2Z90Yt4BbJoTA zNu?CMRqpdD*2TFDF%{U=jDG8z7jstveqC9_8=vgvv%|RY!5%thm-d^Bl7CJ8l! zCn%3U5tRb*5(>x)1AC-GBom3Qc*4E_6`T)nST9LoUJ|Z_CM73)`>1lAy;HS_-T73vfih&lRpqMahG-5E3&p5c zVb*sfg)+@)%@-sHPaskiTIaD2q4dJAoLZH8<)CW1+rmU%d>SuqKf(K}y0rsbh1(Bp zGMIKr@HoTTi@RPe$~U!9(CU4iW96AF^V!OTM^jX(2C}$_w9c$YqiyMhA--q|B?)RY z?ENsU&0pz_)4|46_X8Vj-!%~hw_fA`NIN%h!Oh#Wrw%L@%5PDlWwKPXuzd}oCY91# zub1HMD+@Gc4`W+wNxSXas8?=N(%S;&H3c^)H0X<=Rhj-CL~)Pr;Pg6A)N(fhJ^q#4Z~)|^}2m($ghd0lgh?WQa1 z*>dXBR2E#rBuZ=W%m6$|FKY;ORI#;@kH*WW#+TNqGI9%-dk*Jyg27C1XM^CE z+i(Ddeb`Q_0ncL{NE6=2hVO#V1bfYWRBMts>1rH-LI1h;{orp(xnej|;M2G{on6|} z_#rpEids1U zx=eQ2GcBW)sq89CYU{Bau@FtWHvD(L=7ziV7+v4jO}7c#Tz_0^ z!*tDIVX|t1;V5gV0Qthxq=pR8ZwPvg*NvMj*P_y>E1f;<`e3s9<`1|_5l~;!Pj-&Y z`@s+=@w9joke}V#s;re;JI^kC4ClDnrGul&SBv7p0Y(b zYlA?tShW!HdYmz)tI+vkx(7Gqk5k1Mx9D>3yYSFd+_;t?(qY)}EQGfsFnBKfQJX$u zbY2Hu8LmS3F-cDLsaZ`|&c&xm*NUOF!~JcKCHjAN(m-64xRM}}ZrU)!@{ibN9*67w zoIVpu??S)0JKJ-^hqANItDIlF$v^qsBI5I}lNop@_-?`m==p}D5U%$EZHL^H{@vQS z=;lE5-cG-LK6x~|H%jWi@?YVgl(O@j>4H3#LR}w$Kdj4jZEpGDf56^<<6HQcLAdnn zdfNu^ffk7A-eC~Wdh69=mj?tW~lpli~E6N1bkoiKD75a zu=nvT@_SY@M*w)0g}VJ7_Uc#lpK zu^tY}9)wrG2t~jMj8G4LP!BvwH2CY_q%#~Wbrg)l5wc?z5@a4^J`8_U6VlflQ%WuchoAxiH2`@O;iMRDWGz8D;$Cu)(6JO@rQ*R! z!>TFfT+KtWIvSMv%Yly!;T;^|4@Cg-7Jy7jxSbnR<#Bj5q^}EyZ=v%aL1Fh7aZ0Q> z==qJwHS=&w4fywG03&7e2)Zx$3?wIIggZdTHpHpoPaKE<27xkR zQ6fRqJ>j_|E8@+dfQHGJ4hwYa-`acgmRcZzFp5AG1$9f~`}TihLryOcccvvJ>e{~=%YIcLu`SBms< z(w>vpZ6REt5z>2GSAi2aBLSQdh!|sy02T$>^QE3dhQUjCJLV_IdV1?c0UiR=7b8)9 z@zad>q^L1)4PwTj&i7-lFqd)(@NtBf8n7`R(6yY^ZH?T8nBC8p z{nZG0SQl<2BYQY7dsrpAw;ixBoIb~wx!tbEFZ>q|_O``!rk4ujXt zpekqhj1KsO4(R*~B@*Fh!Fd}|=*kJ{x*X}^bk7ttqP@1~z3KueR|?3V(Ynd< z;Z_Ra$I}tV(e>)neux&3MHxv&gz%5D+Rg%CW(&Gi0L_Z z1&?qa8e=tm08*#U}eU+OO_|Y$EM>8XX*i`0#T#*D?#HB zBzf!@z7ovmM6b5EV4sXyJzyWO@<6m~m_Og0prTbCJ8lciIbNBN0?$ncamJ|nELJt* zQ`MYV{Fg9a;%d|~w-jc5knStMpY9gSjrp0OSzO94yq8>Y;TCTPVRi@iSH&Y!U4dO_f*V}u*|+8@xF=Gn|9TsmNJXRR4y_lZJx_e?X*2-E;_1aO1kCbIwhcRC7_n{*xv#G*IFWsl6 z{}RAmh3#C?t>N5{_MGYWj28Z(k(sHH4Vkk&y0x+#G2(atW~^RcVGw~^h(z>rH=~C$6y7j<80HEbuG045sU?9kOP&#EP&KT9Tp+rZ zc=Nu!d_eQAsej2_pXQ2L&_( z-O+@CwEtkqG2r)L5Z60gGzcj*CE&6a2N7A<7mp<)67pw{CQ-|$5Sm)tBDheErSrNn z*ex|2O6K6KBc#4}7yn8SO+MH=ZakJKK?sv4mQSG^&7>%>VQ!x(*Jl2Ps7(Cr_sK|> z@jS-sv*uY(z0*VuTjp@Jev83+|2kuOseY?h&dEAqYt?3t@h2X4!m@hP5kC~e>S&#E zle`#GTL&WD0}-y&W`pw#??#J$HLmatem#@)#S*1FX(6}fqlsGA!#L&_Hv4jTu~qIU z?bfSx8{dagd(}s$P{VkIi~es{S(l7RQwmY!(}Mf{)Yb9!^75C zI()9M<=6YQ^^N6esIuRa^NjYU0`qoyp58y|qfOt^?(HnXPdkH2LGYy|M!}cnvNA-d z;yC0%HL6RwVYv5Y#^IUWuwht?^4mMn>VtHqF$~q5nQpwt1-o&A_eVu>)Suh8qBey} zDWbp7&=1A1|M8Nt)r;|(i`UR9rzFuq8Y4|a=Dx>BlJ6L$iscg5-A>UeeWFbBvKli_ zboN^=OfpR>pNp-<-$iEa{d;Vg7syX}lpiXeEJI>LvqG6A{u7^8-e``mG}+6e9*)TG zx!gK0)PtXn$nCO#lC(I@#-<$frn8gf63#c2q?iVc`sSc_)Lx#Sy>oJ$Km4~~q`dbt zqfLcyrtDt2F$ll1Du_6uye9OZ?#PGKng7NLIKLLdTZ50RmYL!E?IOADU4gu(_ zqt~X>G-^Yhpr*}E?t!V}5eZ4A`R{$SeJ1WOBTbtJJ6DbK{y|nPr|;wGWsfEU?+h_D zwZL%>$l0^Dzf?#e8fo&I%9 zwf8x_p5V5LC7ql1VfLJN)82Kaq)4yk89yzAR^QL03{S4(a$xd%t{YKq-2U?AF>u+` zpy<5s`rP@Cd){rax@}!)^{V^!{`HXAWi}KzyHnP#ao^sjua=UPd>OSrx%J7O+RwSHrGFrRQ zabUy&^}Cspy%{Bo#S50ZyS!j&?&%xom=bzCtQC2CyuE-zp%d`Ju;6$Yg3G`gype

g1LhzPk30AdbgIT6o2GQgQH3zYE1HMTR0LR1N-3s20LEzYt!#)d2<_eS^>?VOe~Vu`C<<=0ru9OCyh)bzG|xHDn#%KofO?WhCMGnX+oEf+6Stm@brKf}(Y z6RmW}5;lUqkh3y@HF>QMvyoF-#>DiAOBVvkh4XZ$!9J=-_f+hKA8oeQ%Svmt)BYFp zCtGxUvF+l=8y0O8rVZHS)`C)MJFdA-1MJqN_UW9um?B?9z$Wg1>~DvdCMV5mq}JZg z-1SitMk7QfW85vwag4^g7SB2{n_=Y%tzGfgEZW_&((ExAg1a#t z_hVM!E-B39K!#OkXg;``U0m+F2@5T6kklJ{boxY`3(+!RIk=WCMbToZ^l65xrB-z5 z@4=f1dhd@C*PJs!gD*T@)5hVfZra-`nqHanVZt1RX!@(PpN3j*+GL7D1g+(7K22xD zxx1PIPQC{4FO=flLBxU%0s>)Zm26;&*E7s_JA6oAMY$W8nQf`E2DG9dp%}T}(3LiM6?K4s40|)Ur)drj&BDrV> zQ+Wl`v<0F-JU^)-m3gTB^fZ!y_qX(P8!QX@2zEP^2|QU05%LQBN*gS`Qwr80;^M7b?9JrXLw>MCYkd7Rq!KESebbVrjw^ z=`@V%qX7vjdGH`z@)OpH_^uP$kPzVmju5vB_D2Xe1G_SVv6LP|w>^U#Awh2{e$fyo zLFi+oJ6;sR5OqXw18kf%eZlagQBebqT3?>0V71{qN;eK(jGz0 zfl&=~fUMCdTy0=pB!(L++S6sIE!bh`FucSH^lu9-782sN1WJ@eOhJgA@``HG0ko3E z8d$lva9f31An_Hzy8%HKmO*y1pc1Q?y|zd#ufXvo(Bvbil{I$SD%3|Obe7inwltQ% zfbwz{!R->wEk7P+Hoo;!LYFD}b`e}kLL5SS+`>`Z+)^C!Q`{9oysYex+ao=>Ac21f z3D8Hh1yiJ0qxet8iEtl<4V@AYmO%%ihzpn6jUrV%wfZzYIv>1-6Q&vf!t>^QC(|#rX32&P3SfwxqT; zCSLC9>EkDvS_7q{66D*#_U&MXv7~MlbW}N@D}B1Ab(A+kz)}l#&~Yj;eu{xy8kuz( zbw(O!8GM+Kd6=K%VvX(;1^jXx(-ax1GlrxmCMJrX3CosQ9FGHfS4WIo>q~Oxx0m=QI0ioob)3yiVix8q}7W3R|44a zDdof(+!X~J-OUn4$nJ~ESG zuf#|G_Awp!oO20@@RM`5nazOCNJk81MOdTHTj%tTYT3<<0GlE8{Dk5j%#2{E0oqDTO# zpbeNz!5huQPeid?K&zTb-cd|ZkyKlb^^>*K%%^Z9D#G`XT(qym;H2cJE~oplSXAu& z;!@HrTJlT}u&KbbTPZD%LOuKd3GB$U-UfJ#7p2pO`c`1-Lq!pfj8Oe6GJ`>=Dg3BI z<=Ad|rQsb#>Y0V??GWBsNWw~KFaab*zC5%8JENn5W~E$+AUdC*B96aeS+}CarlQQI z+_=7?3sh+7Q(h0kXk;i%_Nf>KRiro}e?v!}T&emcUuGd+(&vNWdJGx#saldRKhCe5 zIH}qoK#l-qQ}9;P&H@^JDu*(w%QCB6GO;#Ks%FN^k>zS=jB83jl_!~~&mFa^NL9R7 z#r?oK7{a>g@d`D)^f&oh1UA&;%<9+YI>(ACJ+?ZmZ*^5j$w;>7eXOX*fwfQ1buav= zGi1n^-|8T)CFOCy&8vOIc5 zTLR{Pm(Op$-xl5ezuTg6B72GP03%whtfH(_?7K#SLv3xezDOn>Rf0c-x88I(#zC#) zX|$n4A(TQUiD?YIWIT(}@MLY7?I0zCN~oq!j+1)2NEQHsFCDaefrk$Bb#oc{?MKdbK2Gk=-yUgUj)NXynEqsz3_fLa~gCc;2a}wDg57 zE_>DG`>8)l=U=CCR6_VpM-Knmp>m9Rr#tq0?yZg~_NkG#Sai`X?k&p|t zN7-X6iRNft!WyPT25YguGlDNlMW~mF$7jp_yw1gSeO} z$)8+O^c_PFk`qxeQsgVl@T`?bB)n2ylt8hk6r22qZ&al0pp7Cp%^EPohE0Ld>2 z=NqkV+lksNIWw=Y*3}d|IV#I{;iIo<*BWOm6|otgsg-fRs;FxSXE-8rqo}m6=wMMO z!P-KFWmeO_)wOR%(A-6)UTyKUO%Z5VscKZW<2q}v$JkTklD=kCra8CycAWB);rXxD z!480-=jEPJg)4;Qr&gs--5cD=H$=;W=4WdNu^-$3r%oWW0hkDHmHkb zQfh(;_{;oYQF2aE!2VvyiZX0ku-Ro;zPtMf#leR_r*W=&2#3&rg?e5`P0@XYy&Tu$i_2|Y1e`EOVLIo zPQFDB^|&!DteOG7l_1}@uM2|PMZCMD@MsU0sJNV{q`ni%>@<_p=YARpHgB8@Dgi9O z3l{Q?`_;Y+U-vzPC=Sp@xRILw&E$M;-a%l1L-!H?)6cfu3N%L%@jb;UKgy$ruUfY) zfbVz05%IIC#cuF@Bln}*LN9zkzt4Om&}SL3yM5ZgbIL6dBrD!@Iv~l#hv7?tBhlc5 z0aMygybbUn0#fM(X=4bQNZ}QQ*(rKI0KdVwzuIIWa9$A}yve;X8V0f-6l)oS~Vez}I$kIf7#Q ztH2#WT%Z2nI+xg&7&<=dCV~-rVRFpm;mwNSGc8E}HwAo`!q2N2B16p}mC_;MGnbP4wR%_~tbot90X zNa^8Z;U`TfMvap#-!^CpV8d19p(Jmxc_q`7dlv)WS0=aL7Rl6*g8>Tr8nn|ffJN@N%9RYSL^RfXS$?7VE#*C;Guf~I|Gwzp1TKhz|J(pnvnvq&-$JbaU z+V2yf`;Le1v(y5+PQ7mjNP9JHzej|5)eO8KMMOtu%;FyesB*!UMMK68zw?RQ|{cTXUX~CI4Mh7RKI$&pOL6|Vx|J1yia9UUb;b4ql zio^%b&n~~MsKZ95EmhKT(>Xk_?FAeyQto4)d4G8wz&C9m+8uTB=XS+|vSct{xyFNbSf?lpa6UUpjH#Lm-+2FW z@MvUuV>^r_n_*qsh`FYEv&o<%T=!HU*!Ucx`fW zzdUUz&6W2%2Bgp_j#C@QRb^Ri8b9;=rx{0<$OmcTkVbD|X1!MUF=!P*hL`*mh#+$C zE@wP>TK0b%i78XE)){?XX=7^L3Og+C86vb2B&g3p~r30G!^i<_2hj(s;fak9e|@V5GN4L=cX zv9Nf6AHJPCx1JGqr@HY;`-^)uHe=sG!`sHSNv>L}f_6mj@1mlJ&VxdqC?_0R@>GeB z=UWPK=q=mF9~#0r_rg%^t(A!MB!D|)p^l&A09bQ7C>}S0zY_oP%^WkkMLIr{GRMnX zhwo-eBggV^hWN;I2IpltQXATFKBJXCx%_xvmgTscO4VUc)bIRofnTo=Hs3nh0=+IA zXQNNhigBIV2Lgi~pVCp@sGHFKLC@?1*7X(hF8+-Cvhi^V&cDSQ30>2l{Mr5q;!#-uK=xLPg~D zne#y1-wJ{{q3#;_FB}Ha90d-EkzyhQf@wKmN2TG7k#czg2zgydyh2DHgKAO$v`Zmq z2!v)Zfz;}pP*zP&Ozlu9Tuz-3Uc6vS57e4s0QFG_-4Ot46qfsuS{%&dge@UurKw6A zK+qOMrV~!XgW4q;hI$0B8x5bS5965ss;;SKu=MpaUBGQbh&i6F^-{S1V}!#JVR^70 z^?GUY6o5sZ>Wk6wxdd7|qVpAo&@-T%&km^LY;OX`xMEj3M zBW_0%k%x2h#tg{D49NnISW!oo!Xe<;GDwWfc1)ve^dK*2C_i?uEq1L9a|$7DjyHCg zBW@oOdkDcK9*&%8i<^r?Jq(P0=0!c1jq4{v9t0)~0^`4^0%E*E4vgaSd4Z3kT4R^- zK>S4Xa?F0GxMo(=CM#6L_BfcnxSHDp4E!W)xdayH#KE@22XMR!Z|pHE>exGfPM-iH zm&D8lXk-P};{yS$`M$m*f#vCd&sXt;=n0$|SU+VF{`<7N{z3MG?+5Vzm9G6SSQDpe zpspb2Kf9Gs$p4hCao9*M)lCh?lk&U=w;QO$!pTHneA-+}aFSU~$Emo5q8!ST<&EaEX=2F?N_dHo*|e|vEIItCCBF-0JkMcaBP$k*`3J;*kGnH2*61}n zzK*9AFV&k*kEgD-)W}siAHtXnwtm^H@%ZEzTG3j!_A?mMl(Q>+_Ir;%wt|)wUW55) zG6$ibUpt4%uY73Eonoe=)l96y%h_PMd)a&@pQpvI(PrDF49)o#{mxe0wIsQVnzKx= zGUabSy^b5Y_-+n+Qw>;@*B`HT$8w-?Z`dw(yMJm8p_~2sPNy52LzN;18}DfO>27Ol zC-u*NFJ=de-P2H?VrAo_MXi8)sp~w3oITnt?bm;cV*x-4$h&m}at()%Yk;>EELMK_ zu3C|oHKxVZY9o(OfAU-l8qt)c2%{c`kbxAc+X_R!DC6zMRZPm7s-d-jDZ^N=@pj|Y zrFe_uq|YPw)F@A6&61^s%NJ5K)Z{=6S~RI8Y1j_S<|>BQZ6ypX2_}Ga(>INSG^d(! zn#|&+V~ZHegYxlg>y@3uJdY`j!d%;Dxx>83XMBjFZ+O%}(U0eHi$ed3dOF2e@rr}e z6g40E(qbnDo3dR0%vmfoMYe>}AIkD4c}+`Dlaq2apc`FTZT|@^GkiN+rC0?<3S)Ww zidt1|j~3Qn(E%EHg{oejF#s#f+Z}FT1BTMT#O;eR4SaSqF4N^*|VimcyE-V6vbT7 zvZB;<#*O7Pf)a-1s$l%EuD)08xuJavJ$t~`gEdH44*gUVVPP|&VJim5sNuCZg%|gT zktsyty4Nd7^0b{novSkk)ro6A$WYke+s{LTbr;WwIG+^rISPU&N%CgFJE|nadJ^d* z-J2xNUW|J-Ye$phKkmYpeF@ z&A3h1I?uN;n*{Hh^J-_-R8*RuZ-0M-g__xG3k!?Y+UAKpii*CC#e2b{Z;9R0X1tlx z_(3}nK4I^Q4y}m+KE~urBU$x^&crj|x`lt{*om=mstbZonM7bzi(PEKB#p(Bv|xbr zW8)Nuc2!EF8jir@d#JG0p9Z5q5ep@V(tr_Ayihb%x{Re`~NR8YaT z$RD}qoxs|Uaxqzw5u2^MM~lS>{c4s@Kl&av7)S`m@L@BlpYJkCh4T}_e_al z1b49F=|-eA(8=c(3!IYV2o*?_9xB2mU6=Hj0xbtX82{x3wu0GTFEyigYjeq zFYxz{Ee*-xUeq+7`BmP6*i&v~X*K`g$2c*d=YxTCVuyUwOe7j9 z*nJ~HoS^umBXzVIzcO+Pq_4qKmxYMy2O76mBLZ#e#ppRll5k0gNF=wUi2vY)yRSzC zyEHP{QBFi`R&WacT$j?D0~8jw)tx`P7K`Or(NUR3(U7^98P3A1=MYRn1>sXlTyiS6~~2}I^ZGKcdbb%4i;M; zQ_3s1>-OLoODZHnSEu51QXH>(Zb+u?4H_n=eJFdrGYY(D+W77 zAd#W=2!nLw52^n6SBk<;R*x?UO7$QHG<+WEHyO)h#e`pJ#bc+Up)~%4Yf$Bk@hVwY zD^cqm81*nH>8s8NrT<@JRh{;6Ym1>wcoP$1#*7K7pvLSXfEhu^FC z1XRbRn5_!!RSR|s3cd*_A~KWM^v1T?aEGtWTC!+mv~ji#kntf)GH@w@QwBPh`E2(ZjMNb;n@TFY z?yW+@m1>f!oMZBQcHyEtq@GnBR0CW0w4}MmZT}&y%@mLrNRQU?u>j*I{K#HqA4RQx zqGrK+VgVPQ#vV{EW@e0un{^`oG>b;m%#))Upa~EYya%_F|K;RxN>Nq`o!Z%Etv5iz z*65Y5X6pL1jS(aWI^NKJ<`IYYuk9@%s!auFdz{&McD5L*M*B^7pVx^I^1b+bWa{Q# zA|PIfC`U)3RSN9muMn(qLHfhHBb7GwZ9*kw~tEoR(sqdl7X7|Gchd>bT)sLkj-R&>IKR6i;cCPQeu4z46od84) zf)@im^_H@wz^_+S-&b&*W6~W<7JtC%1b%KK+kHTTHIv0O^U7)U$l(D_!239r`F@HF z!lNVet`n(D0kYqr9Y3I#gN<<+6)&SCA>ztH%!#JBm-;w+>-zzO2 zfu%5oN2(Z2MHsfPrBcBZ+`!clhuXm4c-#oM$1ssO_(4e^&2KH!du=K!pg`+GgzRV- z-eZ`e6?FrrS{$oJA~kSuKav(VV52NJMK&@GL64J5@6jXFkuJdbC@kd&VD!jXz>0)J z?h{BC6?_Eh-U4(T0UDN~;IASacs-pTLEWR#syApwtzo#lAVsg3zJ!Im!rQbnP{!u_hWy-A_PbOv?=9OVwc>ZB4lRF%E*E66)^Gq+VvSS% zt;vR#q58SSVJ*o0=4Usfilc!*;K!SPhpm=d0}=30sY%{Tqq6w_Rns9U>cMLI=D82r zpU#(vcBojM>iGqcvV3dxxw8s_C^cH##^0Z=Dp`N3Xd`UB*enpR{)oEbp(C9WNeRC( z_Gq;?ll5L4Lhp07$J~v44h!jUJ1uBcfetEnb?wQHjlD{5%4wF#_Bke@5s&>7c^uP> z@~DLxzC7QcU=14`ty^x2zV^Y-1s-r6ZAqFZs1BPV30rNe6u%ZB(YHiO%LkCUv>8WK zK**OPp!s-(%oR)h+m6gObSeQU_K@uerj8>M5V4PJHi+Nl(Zt+Lk$gz9*laYNxruZC zGyaLv@SaFZo9Zk9R%)Vjh_xMkf@P08J`OW6H=lXDa}*y|MqatDYKEe+u5P+PaHxes z?+lEhj+?x+LbA{BtVW*mae0}j_kr94Mz3 z1}pV!lc(~c^cp@OYj9FWc&dUh^q!&0Lu;Y9)UUmOvBX!nqr$9X?%BF_Fc^oa+WRf} zuT`IN=&8PE=x-+TS(6gm%0c}JT-GT`9Qc;OAAobmolI?(+$ks9j5g;{v60S;4f0x& z+YPac?#Jr_neUq&j2As0b{Sc_pWg-|^sZp4E_-24D@Xbe<_ny9k$L=B2X*8Guez`? zCr3u`BATy=z1;q?jgp%-JC6|;#jqP9HGZ$3_#*LAJBd91-Ss=PrK)ivWNrUuS`?mm zaZ(ajXsKHcDmXeXJyLS9pcI14wcs}-#x<+$`R`W0539>j$B@TdR_dv$$ld$#mE+ve zI4hl-n7oWgZ`BdJ=n?Wrglzf{Rj$0x^MS}-ZYDE)MJ1_v zPv#9oXx3r<=L3-fDX_Cx_t(D{d60bp5kY|DgUQJCl2sJN`=jZsJi*y~m>?xEE^eV@ zIY#t!nz$2EwQM7uOqOf`a*34-tz@cGg`|6XQ-x>|S+Y&D{AGc1_^^ij4~*aBI8@)O zP3#Ms&we#QRR~t`n;o#5oFZ`CC$!}^!U2cEp$zWk`ee}HgRqR$S}pp7e{bu{jZTuC z!nmhGCwSI-(@EQEKPT(#G?*f|IL_@bn@(q}zdqmUc5t6WLa-}wmYMehIkjAL!lg<*=I(0X1c=4NzyObLBS2=`FGhu(Uxc-=KZ6AbeZq+Tq~FLNY3 zty+I->>eyeyOH+vypGMGYh`;6XB6c6!#y2r25Wo48`v-CTjb*FfQ^mO5wu`eg5UJF zjYGU=E$}UVr$%OmIeiC{OC>ljZAP%NaA(=WV#peU=uO&8#8~>_cjHOIWphK_m#w5h zIC@@NaY8W1#WA6(Jm1`9w7krcKA(@8MkssGn|eQH$Wo`t^%sPu!456%XObe((|E%r zMHPlwl^zpi+1Y%g&X&&QrA>234L!`%!>X{v(KGAA&O1~+K1_A_%rKKLLZC-i=*w+m zp5X$+KwqM*lL;yDMnpd-&GA5rD25{2&=(e-KrGy4aaKzwn7{M* zN0+p1hbx?y^ics4tik*c&3`!n+jx3je{~;y z*@l9PbTwe$HhVQf67gCut3yFg+p~SY3OnHbPLOtg^ZR%`d5Uz$JTzjE?Mf_IOLR1G z;vnWa;*B43+2?dSaWkhR+i`|NIHGuiYls!IKfB{nfBVOBp^rUNU-Vzy3`KHK4%7h#A(Z_JF5fyme>T7 z%R0MyoTr{m^eWfpw;Q{W!-NRtr;*TaZ&G-WvN(Qx1?un4%O=mp)7)+4=D+LK9vGKe7=o@vWLhLF zHJ$UAqP}!Py69Fue8ywHO{Ozy%%}xhY&oeJgL>j5R*6dP@`UC!Fto3UhO!C#OLj6S z>)pG`JP@V86N8!gvucyGkr%26Wbe<3If4~jr2ML~k(6ue6e1oGJZ%MYo!y6Zz$Nf8 zQuc#*zMk5yAbO@s7>foS%5Pf62`eRjJ*?0~I+{$uC#5)#g(5&Rt)e)RqS(*t%=5p4 zA_B8f{M4A)x1r@SyTFJ5ENt4xy=_?;A0=iOjWYWEV^PHCUm+}N5OL}XE&LS)a;D~D zjGU43 z%n9A;4sMKmlrt3>1>GQM$~|>xca@SV=-01<-;F*0>~hRbKd&g?le$2VRJv?_C3U#g zdo!Op8Z)*NkNs&2N|kU)jb3T5Nh^$nbD$a)*f`O9sCD@9$zxwMB4913Gfaxs@#1-H zD=EDz34>Ynw}3AHV>+rQ!lmzarSg#0LhEkM`HxEO?_=i=J;3m~!1+1-4Xvg^P^?4n zg@8ejXo2;ird0qXk?}_~Fe7uuh3l7BJ-E#WQqr0~qAQf9zwpurF}R%r>6u{NU~bz% zKbRxN6p-X*aYmrOuR;OA@C8_6V8)HhgeW3J%|Se+BB_Re)ULe%PH%dxUZ<3^31dx- z46F*3Ara9S^H!S-(+Qfl2FaSQ2229O{+eUprcp81!g_NoYRT>dX6Qi0#V` zOQ1owPze)H12>jJ53HpQF;ZH_ER?7K#_JF(q#XRIq3VM{7f-kEOBItTOYx;EAjHdB-HRAw{P5#P1-1Kmu$uOVXo&F`M~dT$~_TjRvd z!R>hPr4%}qlkJRrhSd(eS0;G9y)+$BXRdt_^a%-4_>6nLachx&>wYf@c)-71^*={> zSPnpk8(qS*#ipAH>Z6t=!~p1xWQNFydPySR%RQpGo#{rxhR6LIF^;eiLnw@dIeyR& zrY*Eu@+0y&qKILG(as2yT8JFP0Kl{r#>q_f?neGqwJ1zb0A`qIqEb8!VlMYB6(`Rj z>YApgZOEFZG8tr)L}GhHg`z8DBUpe<&ZTHVwLRMQM2g`)ZbaF2Je3BZOzF~u%3sUs z0DaEeEwUt73Shy34zi>852RarJZo>6uK(`+-> zAoO_|RFo!vlJknvYExPfnVC9y2Jp#FtVb7pt#ZzhOo-GP)+YJRoehmRWts4 zd|EaoY`a*@jG=In>Ny9gu3h(eVQ!nlQLu0Cy6>>>IBC$#O$||dIZwLEU1jRNGZ}LD z`FuXH+b}t$@CB>!B;2tNn0~t7QdfEkJAfjPebI*gg^z8hM-O>u6z`$Lxde#oXW4%Q zQgj(R6<#Xrq)$Gr?{Z{Eubk>Ncy$@pn)`k;{>EMpJ1zL>g&j-nL#)fMXD!u%U#dPf zoOA0e%u@6HAOKgh=F;SDl)P6(=&XQc^_?Y?*FUbMQWjm0TjZl5Y zav}+$drY+nrH5IW%I=5JZ?5(_t7kt^Jhuf&99kPGzf8I9`mZwZZEJ_;gsf>6{ouj! zKKHB=VVmCg}c#>`q*^51nPk4@J=UUm8~5YJGh0A3}0O1*@NDaF;;}dTa1dN3baD z$z@n@GU*3%UI~(*i$LCm?e}wV5~|MCC!IkPgqF4;bT4OEp_l?>@0%}{i0Gl`gyh&w ztWwM>=#<)%JMe9I!C!ppEgI&@FtZ*r=(d%tsR$`vFzAN3e_l~IPf`${Aq=PNJIAjL z^rMbGj?gfjhrclHA*_SLBn%|uT)*$(Dg=&@vZDk1{_gg}APyrsxRK%1^(x#Q+XwghmEiF6DVl^QMaNK?_i-bP znX_ODSqze1OX5vh538l+by?ubl>ZuYR?paYwcs#)7Zr7=Wgbc%(#9S`hcKGdLrO!- zcw`2#7H<`UrJC|N%XNR{T)M)(rR3p##s6yIAI5k0YK}EAro!W4O!sfHlF44VLWQo?!5~I9o{)=g!xQg;jk&bNPeWWpv+U(HpFDKi*H| z&`?wdcV-p_!cJVlsm%DrjMMgk@=wQ~vON2Ys%x$90V^$88T&9elf9Hz+c#x_%#@Jp z17>#Mnk7y%HhPk>1)%AKKUF554QoGyr zlLE^4Ha~_`}?foK$5 z8r{f5vcV`UMh~KP&U!xdVRm*JI?R{(bsfWTns`(g%<1~u_OXyMj ztJGHh6hVNYf^+Tl~H(Umyc(y)j?TIy@zwLx*b>JG}< z^34_)OuT3h!FIMBidLWrlWbfVUWJq(I&dg!pK$_D_xpFz>V_}x&PBI zm5@lP()X!G_XBSLnNt{#9Q{iNmV`CS%+W50Li&*+hLZU)H=gs)hdl!x)MGUOJwR;}i#QnKt3fGO z2i^Cgh|;IfT%R{}i0BuqWsCO$aWa#9Ya9)_7+03@qmTp){-b>8U%BE!du|YYF-szT z1;kgZqrB7`$BdzfX9>DxRZ)TA2B~xlXE?2LDd2;YhPHqz^SEYa=qkGXpBT$Nomtb> zq>&I-nvA=&F*F*Xrr6fc^=mQL<(d>zpp1h06Dr^`he|)nAPF(PngMzyPUq=%0#fD(Qt2sL~nSQu}@-rTL1< z&<88Tb4kadjzV$$vNR}tdog%$?}?jd4CrKVY()9=7}eaB0#rC-l495a*! zIV}T1w{_f$`aMt-&$2h4S2k&`y{g8I&&_A=ci1Q)o@Kh_*jrR@o`sf8Qa@np7U!Zp z??xo;`Q2)UE$ZV^4yGB0n1`i)yRu4hZo4Q1a6WgK(&O;7W0)>1aM)5L$&MPKef|k3 zOcmFDLB5d7FYOsp^KgaBZ0K{-D0H<*>(dL^o{*?B=~l=p87*V)i-W6YED?e4&` z=lKL0stBCi2)IyN*oy#)Tyg`9%8-*n&gIa&Urt4#ZzJs=keGjbo+Jj+fRo|aXG|rE z3?*o2#gMds{5!g{@qztS`pa%8Q3Lsiu>M3Ax?P=HgFw78<0{m)C8;KNThGsE=t=@7RS3y zifZ^GTFZ}2z5zjMNrf%Y7^?`i`DmD-#VLvBc%Y1wR@LX)TvJPro4woCH&e;;NGB3&oSchpx* zzKJf0N-h~iNLpj;`rYwLBrvYQS7;H1$s>0li630{HD8S5;5E>NX0%8yHFr&}@c=v>5QVWNf2u+M>!@aDOLbo>z2^A(OLL8Wuwr@59;0XV zW)I9K5oEbw*7fFh6yL6+q0n@IPOU0|326Q`I`+v#y55AtvPSDk_;clQ)7}u5#PrbG z3fE3yD&sgyOuL))6m;rDOKG+Btf$}e!QB3}ZG9~*iqPR_A)MvWcr>A-vHrDXbb1*f zRJ-pV|HR*L+gdV11DBKTN;${F4dN^B{uPBrM@Q1G+vZ=hBb$c#+wl25FDO>&0hduc zq@G{edY7FFKQ0mZGIix|hgxYO;J7o_B^ZZ(akAQq_!UK07*5#Hy6V=PSXLO$(ghp{ zr5$h0jp6734#e~Nw231zU@ZqDeW|kAjpvb1+l`ZEC?`+u#RtPAN{x^1q-eNkZKtXv zwNj_+Qw%SrYFmu0M>4S^7N@%ulxHLY^A-r}E>muE+vSe2DDKpB?3 z!h}JPs>s=AhH~&Y&>E%sS&Oks@tJ@grT5_ETgl+Yvo*@t+nrI)JC6PdId3Y^uC4@S zqOe)SK)&u#h+8 zP_WDyJPox=Pux^R*IyUZbi`V3E!h)Q{DXEuHej7~*@%TLch?1BUG@eE0XLG}WhejC zf!-MLt+n5PA0#;5e*axKK}8Rq_y>y*)cDhhcK~_h|4fd!-wR=`dF2d6Zt~rrbCgut zE{)#zJ{aH{ga;p7pT7J6_6_j^xym@XukBVFMs;$ zUj*YvKLwgW2hz*l_HYxy5t46s9OS|dQb@p|)Xaq>gdqpbFvAKW&xVT`0r>x1_&gof zj|*7ff(KQ&LWv;of5S5(0Fh|C4_+{cPlRF&lZXW&_>h3wtKLL37)1`64~a_r;_t$! zKPPI?j9f%x6)ng{q`gs!=R+eF%#g+b*070gBw-2j7{?^e@rQsEq89OZ#zOYdia`8W z4!5XBE?DxAYmDT-COJq)^3e=F_+kV7HAXEe5Q%Z*0v{jALK7)V|?%tl(0m%T)0B$p{nSw7Q}*i54|w?|D% z?oyT5%-l9fImS*pGnLuof)~dL%n@|5lITq5I_a25cQW#v>CEOlTiO54LBjKz`BbML zGwI5Sm@}RM6(}U@>CZf(5uEwl=N}6y5&EIBk`E22M1OZngEljx300^CJ6h2r;xnXN zI0Fy{`b(s_bBfMHX-dU8Qihroqai(mHu>4lMiNq{mOKMZZE4e!LNlN`RjD6G*;AMT zHK{=O2R)05(WB;5rzsVJKx#_Sm!1@*N##Nj27<`0`t+ezO=nWipjEPR)TUJhYf7_P zkhhxkt2v!3TMaTwmvWJpY0V~9*V1u=E5^kctcC%NNEomD|+uBmB zqN0thY<0_9lmXL`NbT%y&(K@nA`P~JRqk#(_FS2Ub-AR?N_7JpROwDvyFnZQHo1FU z?4Dr=VhL|>quW^Gk`}$`{g-vUyIc6CcOvW6>u}9$1ms90uk_t*fBl=+wYrzI1OAH* z3Vh(@CfF_uX0Uk?EEyc&zy=n!@IZLL10Vdu2Oa(}ZJYbx3TMOzD9%Vg001HR1O*fT z{{Sp#0CE5|0CxZY2>$^82^>hUpuvL%U$}_DFvg6B2qQ|Ic(5VEhcjwW+{m$@MHm@t zXzWOGV?&WBZNCSEju?Y z)U_v2;2nE4Zr>4IqkcspI4|M2a<_8*yOuEu$9u6RMT?m7ViYS@5Y9Yw^JLF~8HXNS zSTpCul~sd&Z1^?m)S*|CE^XUu?A)Pu?0_t}GiuAgR|qFgx2{y=po8~dep>No(9xAo zhb*wllY&*am;dzc9bpwL=f$fZO8!at^&8tuOb`E`d-wG@;>VxAf86)}1t?&E-wilX zcm^h@;DQV`_zxBoabboJ`O(MVc@{d@T|roI(cy;zLMV}lKsacIg#S>eAc+4+sA7X= zXlPK0Cc-D8K^}V8Vt@#8m?MNa4itnC3F_!yj{@E3AQv(w`QwfXGRfjUF&YS@lMkY3 zrHo7(q-20VerO~@Tm)fbmks{-WP(>}IA)d%qWNY=865Ryhb(2Vft_FGxxt<~g()SP zBRY{X{;2=E75HAV0l6#tYk#->FC^2tX* z9B{`YaN+XHFP|Lh88p{i^BhBTbTP?W!5nkJG|y}^&2yY#1W7w{%(BlvpFH%?bF8H9 z(oBOqv(Qf$eRN3*n^rZ@PupBH&MfiVvd=Qtj5X0j50SIfN}t6v*lUY@2F`Cwt<_Rr zJLDbq-GDPO#MUeAeRk7o|2?+RgVWS;-+pHuc;k*M)il_O10IPFMi4%e<(L0`GvH@1 zA&}>VCk3<9b&p4lY|Ax#Tp%zPaGD|AfOoIM|@W z^UpgEy$(G1;KL9;Fk!v*f(zvPPt%95LyFg1k3EIiyFCQ*Wj+7T^ypWAe$EuWopbW- zzyEyo0-0Zaibi;w;Cd$>>hXY8{xhFI@;1Bgafb)|BcK0hhrjip&w43xTR{exp9`u; zgQwe_hB_y^e<*=LygM5048%Kv1Oxyf`2+<70RI3ie*$L#0RRC200;yC{{;j9J1=HO Ar2qf` literal 0 HcmV?d00001 diff --git a/jevdual/results/reusable-bench-20261011/ordinary-score.json b/jevdual/results/reusable-bench-20261011/ordinary-score.json new file mode 100644 index 0000000..de0b7f6 --- /dev/null +++ b/jevdual/results/reusable-bench-20261011/ordinary-score.json @@ -0,0 +1,207 @@ +{ + "continuity": { + "after": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 29, + "jobs": { + "ordinary": { + "completed_generation": 29, + "completed_native_time_s": 45.39800000000952, + "job_id": "ordinary", + "measurement_operation_id": "ordinary-measurement", + "measurement_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "moves": 29, + "phase": "completed", + "reset_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "block_home_verified": true, + "generation": 29, + "image_sha256": "8541989ea39a283f4a94c00dad6404c12083ec3518652a863b0aea9f1fec18b9", + "job_id": "ordinary", + "kind": "finish_reset", + "native_time_s": 45.39800000000952, + "operation_id": "ordinary-reset", + "pusher_home_verified": true, + "reset_contact_samples": 6757, + "reset_native_steps": 13709, + "state_sha256": "716fba0b934c91016341803c109073fafab195b147eb3670fa6cd2ab8f693833" + }, + "reset_started_generation": 11, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 45.39800000000952, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "before": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 0, + "jobs": {}, + "native_time_s": 1.0000000000000007, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + } + }, + "job_id": "ordinary", + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06765083286533137, + 0.0012302134613647513, + 0.03499573045536985 + ], + "external_force_cleared": true, + "generation": 11, + "native_time_s": 17.980000000000913, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 2.7238600186678546e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef" + }, + "motion_count": 29, + "native_motion_steps": 22199, + "passed": true, + "planner_role": "frozen_deterministic_color_RGB_host", + "recovery": null, + "reset_contact_samples": 6619, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.117918137735966, + 0.002774860913929776, + 0.03499573045536985 + ], + "external_force_cleared": true, + "generation": 29, + "native_time_s": 45.39800000000952, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 2.7238600186678546e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "716fba0b934c91016341803c109073fafab195b147eb3670fa6cd2ab8f693833" + }, + "sqlite": { + "count": 1, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "operation_id": "ordinary-measurement", + "receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef" + } + ] + } +} diff --git a/jevdual/results/reusable-bench-20261011/qualification.json b/jevdual/results/reusable-bench-20261011/qualification.json new file mode 100644 index 0000000..36cfad6 --- /dev/null +++ b/jevdual/results/reusable-bench-20261011/qualification.json @@ -0,0 +1,727 @@ +{ + "attempts": [ + { + "all_caller_and_worker_processes_synchronous": true, + "attempt": 1, + "before": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 0, + "jobs": {}, + "native_time_s": 1.0000000000000007, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "elapsed_s": 3.7799429579172283, + "job_id": "ordinary", + "returncode": 0 + }, + { + "all_caller_and_worker_processes_synchronous": true, + "attempt": 1, + "before": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 29, + "jobs": { + "ordinary": { + "completed_generation": 29, + "completed_native_time_s": 45.39800000000952, + "job_id": "ordinary", + "measurement_operation_id": "ordinary-measurement", + "measurement_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "moves": 29, + "phase": "completed", + "reset_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "block_home_verified": true, + "generation": 29, + "image_sha256": "8541989ea39a283f4a94c00dad6404c12083ec3518652a863b0aea9f1fec18b9", + "job_id": "ordinary", + "kind": "finish_reset", + "native_time_s": 45.39800000000952, + "operation_id": "ordinary-reset", + "pusher_home_verified": true, + "reset_contact_samples": 6757, + "reset_native_steps": 13709, + "state_sha256": "716fba0b934c91016341803c109073fafab195b147eb3670fa6cd2ab8f693833" + }, + "reset_started_generation": 11, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 45.39800000000952, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "elapsed_s": 6.2080469590146095, + "job_id": "disturbed", + "returncode": 0 + } + ], + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "limits": "deterministic RGB policy; axial force disturbance; simulation; no hardware or model trial", + "passed": true, + "required_cycles": 2, + "scores": [ + { + "continuity": { + "after": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 29, + "jobs": { + "ordinary": { + "completed_generation": 29, + "completed_native_time_s": 45.39800000000952, + "job_id": "ordinary", + "measurement_operation_id": "ordinary-measurement", + "measurement_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "moves": 29, + "phase": "completed", + "reset_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "block_home_verified": true, + "generation": 29, + "image_sha256": "8541989ea39a283f4a94c00dad6404c12083ec3518652a863b0aea9f1fec18b9", + "job_id": "ordinary", + "kind": "finish_reset", + "native_time_s": 45.39800000000952, + "operation_id": "ordinary-reset", + "pusher_home_verified": true, + "reset_contact_samples": 6757, + "reset_native_steps": 13709, + "state_sha256": "716fba0b934c91016341803c109073fafab195b147eb3670fa6cd2ab8f693833" + }, + "reset_started_generation": 11, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 45.39800000000952, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "before": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 0, + "jobs": {}, + "native_time_s": 1.0000000000000007, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + } + }, + "job_id": "ordinary", + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06765083286533137, + 0.0012302134613647513, + 0.03499573045536985 + ], + "external_force_cleared": true, + "generation": 11, + "native_time_s": 17.980000000000913, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 2.7238600186678546e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef" + }, + "motion_count": 29, + "native_motion_steps": 22199, + "passed": true, + "planner_role": "frozen_deterministic_color_RGB_host", + "recovery": null, + "reset_contact_samples": 6619, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.117918137735966, + 0.002774860913929776, + 0.03499573045536985 + ], + "external_force_cleared": true, + "generation": 29, + "native_time_s": 45.39800000000952, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 2.7238600186678546e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "716fba0b934c91016341803c109073fafab195b147eb3670fa6cd2ab8f693833" + }, + "sqlite": { + "count": 1, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "operation_id": "ordinary-measurement", + "receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef" + } + ] + } + }, + { + "continuity": { + "after": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 70, + "jobs": { + "disturbed": { + "completed_generation": 70, + "completed_native_time_s": 107.93599999992985, + "job_id": "disturbed", + "measurement_operation_id": "disturbed-measurement", + "measurement_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 52, + "image_sha256": "4a3a1f6bed1d0140562fd77a0b71d21f95db426f05fa78b77eb692fda4e44de9", + "job_id": "disturbed", + "measurement": { + "block_box": [ + 340, + 155, + 382, + 197 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.006666666666666666 + ], + "centroid_pixel_xy": [ + 360.0121880441091, + 175.5113174695299 + ], + "footprint_area_m2": 0.004786111111111111, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1723 + }, + "native_time_s": 80.51799999999375, + "operation_id": "disturbed-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c5ba99a999848efcde59f32b74af4fb92060efb468ecbe76c78767bbaadfe99a", + "version": 1, + "worker_pid": 58726 + }, + "moves": 40, + "phase": "completed", + "reset_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "block_home_verified": true, + "generation": 70, + "image_sha256": "502d9069172166fc632ef00f9983fb5c5115b043a0ef20ef7cb667b7ada67b40", + "job_id": "disturbed", + "kind": "finish_reset", + "native_time_s": 107.93599999992985, + "operation_id": "disturbed-reset", + "pusher_home_verified": true, + "reset_contact_samples": 6764, + "reset_native_steps": 13709, + "state_sha256": "0dbadbe16adc1b92eaf1474894ad4ab0548428609d59a3e570da804614ca423d" + }, + "reset_started_generation": 52, + "started_generation": 29, + "started_native_time_s": 45.39800000000952, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "ordinary": { + "completed_generation": 29, + "completed_native_time_s": 45.39800000000952, + "job_id": "ordinary", + "measurement_operation_id": "ordinary-measurement", + "measurement_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "moves": 29, + "phase": "completed", + "reset_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "block_home_verified": true, + "generation": 29, + "image_sha256": "8541989ea39a283f4a94c00dad6404c12083ec3518652a863b0aea9f1fec18b9", + "job_id": "ordinary", + "kind": "finish_reset", + "native_time_s": 45.39800000000952, + "operation_id": "ordinary-reset", + "pusher_home_verified": true, + "reset_contact_samples": 6757, + "reset_native_steps": 13709, + "state_sha256": "716fba0b934c91016341803c109073fafab195b147eb3670fa6cd2ab8f693833" + }, + "reset_started_generation": 11, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 107.93599999992985, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "before": { + "active_job": null, + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "diagnostic_enabled": true, + "generation": 29, + "jobs": { + "ordinary": { + "completed_generation": 29, + "completed_native_time_s": 45.39800000000952, + "job_id": "ordinary", + "measurement_operation_id": "ordinary-measurement", + "measurement_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "moves": 29, + "phase": "completed", + "reset_receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "block_home_verified": true, + "generation": 29, + "image_sha256": "8541989ea39a283f4a94c00dad6404c12083ec3518652a863b0aea9f1fec18b9", + "job_id": "ordinary", + "kind": "finish_reset", + "native_time_s": 45.39800000000952, + "operation_id": "ordinary-reset", + "pusher_home_verified": true, + "reset_contact_samples": 6757, + "reset_native_steps": 13709, + "state_sha256": "716fba0b934c91016341803c109073fafab195b147eb3670fa6cd2ab8f693833" + }, + "reset_started_generation": 11, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 45.39800000000952, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + } + }, + "job_id": "disturbed", + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06769387394718734, + 0.006864712111564605, + 0.03499573045536974 + ], + "external_force_cleared": true, + "generation": 52, + "native_time_s": 80.51799999999375, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 2.7238600186678546e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "c5ba99a999848efcde59f32b74af4fb92060efb468ecbe76c78767bbaadfe99a" + }, + "motion_count": 40, + "native_motion_steps": 30689, + "passed": true, + "planner_role": "frozen_deterministic_color_RGB_host", + "recovery": { + "after_generation": 41, + "before_generation": 40, + "rgb_displacement_m": 0.13333333333333333, + "stale_refused": [ + "move", + "measure" + ] + }, + "reset_contact_samples": 6663, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11790274447954756, + 0.008162951649690725, + 0.034995730455369745 + ], + "external_force_cleared": true, + "generation": 70, + "native_time_s": 107.93599999992985, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 2.7238600186678546e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "0dbadbe16adc1b92eaf1474894ad4ab0548428609d59a3e570da804614ca423d" + }, + "sqlite": { + "count": 2, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 52, + "image_sha256": "4a3a1f6bed1d0140562fd77a0b71d21f95db426f05fa78b77eb692fda4e44de9", + "job_id": "disturbed", + "operation_id": "disturbed-measurement", + "receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 52, + "image_sha256": "4a3a1f6bed1d0140562fd77a0b71d21f95db426f05fa78b77eb692fda4e44de9", + "job_id": "disturbed", + "measurement": { + "block_box": [ + 340, + 155, + 382, + 197 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.006666666666666666 + ], + "centroid_pixel_xy": [ + 360.0121880441091, + 175.5113174695299 + ], + "footprint_area_m2": 0.004786111111111111, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1723 + }, + "native_time_s": 80.51799999999375, + "operation_id": "disturbed-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c5ba99a999848efcde59f32b74af4fb92060efb468ecbe76c78767bbaadfe99a", + "version": 1, + "worker_pid": 58726 + }, + "state_sha256": "c5ba99a999848efcde59f32b74af4fb92060efb468ecbe76c78767bbaadfe99a" + }, + { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "operation_id": "ordinary-measurement", + "receipt": { + "bench_id": "92d5adce82a146aeb8df71651fa03959", + "generation": 11, + "image_sha256": "21fe1a646ee0bf63a025ef29db8bf162ba5add5a1945981de7aca61ee448de16", + "job_id": "ordinary", + "measurement": { + "block_box": [ + 340, + 158, + 382, + 200 + ], + "block_center_xy": [ + 0.06833333333333333, + 0.0016666666666666666 + ], + "centroid_pixel_xy": [ + 360.0243619489559, + 178.52088167053364 + ], + "footprint_area_m2": 0.0047888888888888885, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1724 + }, + "native_time_s": 17.980000000000913, + "operation_id": "ordinary-measurement", + "source_kind": "mujoco_simulation", + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef", + "version": 1, + "worker_pid": 58696 + }, + "state_sha256": "c60f9a77a055cbf592c8e6e7180701e833e78c31afc648f53808e0e4f38fe2ef" + } + ] + } + } + ], + "source_commit": "0091e5f832a3aef24ef73fdc9f1ee76bd64b7e46", + "source_unchanged": true, + "successful_cycles": 2, + "version": 1 +} diff --git a/jevdual/results/reusable-bench-20261011/report.md b/jevdual/results/reusable-bench-20261011/report.md new file mode 100644 index 0000000..baa4863 --- /dev/null +++ b/jevdual/results/reusable-bench-20261011/report.md @@ -0,0 +1,62 @@ +# Successive experiments on one simulated bench + +Frozen source `0091e5f832a3aef24ef73fdc9f1ee76bd64b7e46` completed both preregistered cycles on their first qualification attempts. Each used RGB-guided preparation, a separate computer measurement process, and contact-driven reset. The second recovered after an external force displaced the block by 0.1333 m along x. + +## What ran + +The actual [bench CLI and host](../../../tools/physical-workcell/BENCH.md) ran with pinned MuJoCo 3.15.0 in its existing environment. The host chose motion from exact rendered PNGs and public task data. No native pose guided it. Separate native-state scoring inspected historical measurement and reset states; read-only SQLite scoring checked saved computer results. + +From a checkout at the named source commit: + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/qualify_bench.py \ + --output tools/physical-workcell/output/sim6-qualified-20261011-v1 \ + --source-commit 0091e5f832a3aef24ef73fdc9f1ee76bd64b7e46 +``` + +Use a new output directory for another attempt. Both host processes exited with code 0. The source matched the named commit before and after the run. [Source hashes](source-freeze.json), [qualification](qualification.json), [fresh-process status](fresh-cli-status.json), and [cleanup](cleanup.json) are retained. Full private journals and integration states remain in `tools/physical-workcell/output/sim6-qualified-20261011-v1/`. + +## Outcomes + +| Job | Motion actions | Measurement generation | Orange pixels | Reset generation | Reset contact samples | +|---|---:|---:|---:|---:|---:| +| Ordinary | 29 | 11 | 1,724 | 29 | 6,619 | +| Disturbed | 40 | 52 | 1,723 | 70 | 6,663 | + +Reset contact counts above come from motions labeled `contact_reset`, separately scored from the host journal. The controller's reset receipt also counts contacts from other reset-phase parking motions. All motion actuator-force maxima stayed within 4 N per axis. + +One bench ID, `92d5adce82a146aeb8df71651fa03959`, spanned both jobs. Native time advanced from 1.000 s to 45.398 s to 107.936 s. Job two began at the exact generation/time left by job one's reset. Integration state was restored between calls and never reinitialized between jobs. + +Separate native scoring found block x=0.06765 m at the ordinary measurement and x=0.06769 m at the recovered measurement. Both reset states placed the block within its home region and the pusher at x=-0.30 m, y approximately 0. + +The measurement worker computed apparent orange footprint areas of approximately 0.004789 and 0.004786 square meters from the simulated orthographic camera. SQLite contained exactly one row per job. Repeating each measurement operation returned its identical historical receipt without another worker or result. + +## Recovery and guards + +The second job reached preparation generation 40 before a -1.5 N diagnostic force was applied for 80 native steps, followed by bounded settling. Generation 41 retained the changed state with the force cleared. The public RGB center changed by 0.1333 m. Both stale-image effect requests refused, leaving durable public state unchanged. Fresh-image recovery motions established placement before measurement at generation 52. + +| Required criterion | Evidence kind | Evidence | Result | +|---|---|---|---| +| One body across successive jobs | Historical continuity | Both score files and fresh CLI status | Passed | +| Preparation before measurement | Historical state | Separate native measurement-state scores | Passed | +| Exact computer result persisted | Current saved state | Read-only SQLite scores and receipt equality | Passed | +| Stale disturbance evidence rejected | Historical effects | Disturbed journal and recovery score | Passed | +| Fresh-image contact recovery | Historical motion | Recovery-purpose native receipts and placement | Passed | +| Contact reset before next job | Historical and current state | Contact steps, reset scores, next-job start | Passed | +| Final bench idle, evidence retained | Current state | Fresh CLI status and cleanup | Passed | + +Fourteen final-source conformance tests passed in 4.266 seconds: replay/conflict semantics, job phases, measurement readback, stale evidence, corrupt source/state/image/model/measurement/SQL bindings, and interrupted-intent refusal. See [conformance.log](conformance.log). Ruff, the notebook checker and diff checks also passed. + +## Recorded observations + +The replay contains recorded observation frames, not interpolated trajectories or continuous camera video. Orange is the block, blue is the pusher, and green is the measurement region. The displacement occurs during the second cycle. Exact frame digests and RGB positions are in [frames.json](frames.json). + +![Recorded RGB observations across ordinary and disturbed cycles](observations.gif) + +## Limits and next boundary + +This verifies a deterministic color-specific RGB policy on one simulated axial disturbance and two successive jobs. It does not verify language-model planning, arbitrary objects, non-axial recovery, continuous wall-clock physics, hardware, power-loss recovery or a production Footwork capability adapter. Unknown interrupted effects block dispatch and are not automatically repaired. Physical placement and computer persistence are separate operations. + +The next extension is a host-facing prepare-measure-reset task with different measurement requests and the same bench ownership and evidence contract. A model can propose a bounded next action through the image interface; the controller continues owning freshness, limits and verification. Instrument and real actuator adapters remain future work. + +Development evidence remains under `output/sim6-backend-probe1/`, `output/sim6-root-dev1/`, and the conformance fixture directories. Guard refinements preceded the freeze. No physics/controller settings were tuned against this qualification, and no qualification attempts were retried. diff --git a/jevdual/results/reusable-bench-20261011/reset.png b/jevdual/results/reusable-bench-20261011/reset.png new file mode 100644 index 0000000000000000000000000000000000000000..8c14be822fc65086c62cb84914098dd26add8718 GIT binary patch literal 110107 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�_`a3_B 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°6wE-q#{F z=Y1GPw_m7VRJX&^cyaX5NZ4Jcn)@0y5?RIrn?=O}ig?@gfCyf8 zXnW;n8#+DH|FAK+>g`HNg*Ky^=$D<3uz;^0-Cw~{1BOC^#JmHk1xYih_QHt$`st(s z=K{+QS{Fc4vV-A@$

Waf%@9TD%~dcw)4QEi%jS*LqzoX5MbglZ;{I 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�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 MwRWt<8 literal 0 HcmV?d00001 From 7dfa39e6532da0ce829901c0ac882e37a70b104f Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 14:15:34 -0400 Subject: [PATCH 094/216] Persist final bench conformance check summary --- .../reusable-bench-20261011/checks.json | 72 +++++++++++++++++++ .../results/reusable-bench-20261011/report.md | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 jevdual/results/reusable-bench-20261011/checks.json diff --git a/jevdual/results/reusable-bench-20261011/checks.json b/jevdual/results/reusable-bench-20261011/checks.json new file mode 100644 index 0000000..253df40 --- /dev/null +++ b/jevdual/results/reusable-bench-20261011/checks.json @@ -0,0 +1,72 @@ +{ + "source_commit": "0091e5f832a3aef24ef73fdc9f1ee76bd64b7e46", + "conformance": { + "passed": true, + "count": 14, + "elapsed_s": 4.266, + "checks": [ + { + "name": "test_corrupted_image_refuses_measurement_and_does_not_create_a_database", + "result": "ok" + }, + { + "name": "test_corrupted_native_state_never_causes_an_implicit_reset", + "result": "ok" + }, + { + "name": "test_corrupted_retained_model_refuses_without_recreating_the_body", + "result": "ok" + }, + { + "name": "test_corrupted_source_binding_refuses_without_a_new_generation", + "result": "ok" + }, + { + "name": "test_diagnostic_force_needs_explicit_enablement_and_finite_bounds", + "result": "ok" + }, + { + "name": "test_exact_motion_replay_retains_one_native_effect_and_conflicts_refuse", + "result": "ok" + }, + { + "name": "test_external_force_invalidates_stale_motion_and_measurement_before_dispatch", + "result": "ok" + }, + { + "name": "test_foreign_or_modified_observation_cannot_authorize_a_motion", + "result": "ok" + }, + { + "name": "test_measurement_column_corruption_is_not_hidden_by_an_unchanged_receipt", + "result": "ok" + }, + { + "name": "test_measurement_is_a_separate_process_with_exact_persisted_image_binding", + "result": "ok" + }, + { + "name": "test_measurement_receipt_corruption_refuses_historical_replay", + "result": "ok" + }, + { + "name": "test_measurement_replay_is_historical_and_does_not_run_another_worker", + "result": "ok" + }, + { + "name": "test_retained_interrupted_intent_blocks_all_new_dispatch", + "result": "ok" + }, + { + "name": "test_successive_job_gate_requires_measurement_and_verified_reset", + "result": "ok" + } + ], + "raw_log_path": "tools/physical-workcell/output/sim6-final-checks/unittest.log", + "raw_log_sha256": "e5ca1e7edd35ec49a416c78bc5f5cb1534e037d6f0f506221ee194f4326a58e9" + }, + "ruff": "passed", + "notebook": "passed", + "diff_check": "passed", + "redaction_files_changed": 0 +} diff --git a/jevdual/results/reusable-bench-20261011/report.md b/jevdual/results/reusable-bench-20261011/report.md index baa4863..18b231f 100644 --- a/jevdual/results/reusable-bench-20261011/report.md +++ b/jevdual/results/reusable-bench-20261011/report.md @@ -45,7 +45,7 @@ The second job reached preparation generation 40 before a -1.5 N diagnostic forc | Contact reset before next job | Historical and current state | Contact steps, reset scores, next-job start | Passed | | Final bench idle, evidence retained | Current state | Fresh CLI status and cleanup | Passed | -Fourteen final-source conformance tests passed in 4.266 seconds: replay/conflict semantics, job phases, measurement readback, stale evidence, corrupt source/state/image/model/measurement/SQL bindings, and interrupted-intent refusal. See [conformance.log](conformance.log). Ruff, the notebook checker and diff checks also passed. +Fourteen final-source conformance tests passed in 4.266 seconds: replay/conflict semantics, job phases, measurement readback, stale evidence, corrupt source/state/image/model/measurement/SQL bindings, and interrupted-intent refusal. See [checks.json](checks.json); the original test log remains in `tools/physical-workcell/output/sim6-final-checks/unittest.log`. Ruff, the notebook checker and diff checks also passed. ## Recorded observations From 2c297d45b453e3db47b9b108b389784dda728b01 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 14:21:32 -0400 Subject: [PATCH 095/216] Preregister visual AI control of successive bench jobs --- .../experiments/SIM7-agent-visual-bench.md | 27 +++++++++++++++++++ .../notebook/2026-10-11-agent-visual-bench.md | 8 ++++++ 2 files changed, 35 insertions(+) create mode 100644 jevdual/docs/experiments/SIM7-agent-visual-bench.md create mode 100644 jevdual/docs/notebook/2026-10-11-agent-visual-bench.md diff --git a/jevdual/docs/experiments/SIM7-agent-visual-bench.md b/jevdual/docs/experiments/SIM7-agent-visual-bench.md new file mode 100644 index 0000000..36996d3 --- /dev/null +++ b/jevdual/docs/experiments/SIM7-agent-visual-bench.md @@ -0,0 +1,27 @@ +# SIM7: an AI host controls the reusable simulated bench + +## Question and hypothesis + +Can the multimodal AI in this Codex session choose actions from native RGB images, complete two successive prepare-measure-reset jobs on one bench, and recover after an unexpected block displacement while the existing controller guards remain unchanged? + +The hypothesis is that an external visual AI host can use a typed observation/action handoff instead of the deterministic RGB coordinate planner. It receives images, camera calibration, task regions, pusher dimensions and bounded action descriptions. It receives no detector coordinates or private native poses. Deterministic bench code continues to own effects and verification. + +## Predictions + +If true, both jobs complete with one measurement each and contact-driven reset, one bench identity and continuous integration state. A disturbance between the AI's observation/proposal and dispatch causes the original proposal to refuse. The AI inspects a new image, proposes corrective motion and completes the second job. + +Against: the host needs the baseline coordinate planner or native poses; stale evidence dispatches; either job cannot complete within 64 motion actions; recovery requires a reset/teleport or controller guard changes; computer success is claimed without independent persistence readback. + +## Design + +Add a small source-bound external-agent session interface beside the existing bench. The agent observes a saved image, writes a typed proposal with a short action intent and exact observation digest, and dispatches it. Retain proposals, receipts, refusals and fresh observations. Never add an automatic coordinate planner, model-result success flag, provider API or fallback motion path. The existing Codex conversation supplies the actual AI; this is not an unattended API-backed service. + +Freeze the interface source before the AI trial. Run job one with target x in [0.035, 0.105], y in [-0.025, 0.025]; job two with target x in [0.045, 0.115], the same y bounds. After the AI prepares a measurement proposal for job two, the diagnostic harness applies a bounded native external force before dispatch. The stale proposal must refuse. The AI then receives a fresh image and chooses recovery actions. A separate scorer may inspect native states and read-only SQLite only after both jobs finish or the attempt stops. + +## Primary metric and decision + +Primary metric: complete job cycles, required 2/2 on the first frozen trial attempt. Each requires independently verified measurement placement, exact saved result, and contact reset. Disturbance recovery and stale refusal are required guardrails. Retain a failed attempt; any subsequent repair is a separately preregistered version, not a hidden retry. + +## Guardrails and limits + +Keep bench.py, measurement.py, native controller and image gate source unchanged. One writer, typed finite actions, exact observation/source/job binding, retained intent before dispatch, no replay of unknown effects, and independent effect readback. No keys, paid provider calls, real cameras, hardware, production application changes or cloud deployment. The trial establishes this AI session's behavior, not a repeatability rate, a deployed policy service or general robotics. diff --git a/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md b/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md new file mode 100644 index 0000000..aaab8a2 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md @@ -0,0 +1,8 @@ +# AI visual control of the reusable bench + +## SIM7-P1 · prediction · 2026-10-11 14:20 +Hypothesis: an external multimodal AI can complete two successive prepare-measure-contact-reset cycles from images and task metadata, without detector/native pose guidance or weakening the existing guards. +Test: freeze a typed agent handoff, use the AI in this Codex session to inspect each RGB frame and author proposals, interrupt a prepared second-job measurement with a diagnostic native force, then independently score state and SQLite results after the attempt. +Predicts: two complete cycles, one measurement per job, one continuous bench identity, stale proposal refusal and fresh-image corrective actions after disturbance, with unchanged native guard source. +Against: native poses or the deterministic coordinate planner guide actions, stale evidence dispatches, either cycle exceeds its motion budget, reset assigns block state or guards need weakening. +Refs: docs/experiments/SIM7-agent-visual-bench.md; tools/physical-workcell/BENCH.md; results/agent-visual-bench-20261011/ From 9a5d2f8bfac8088b13c63052887e0c0c2e9d5c7e Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 14:28:51 -0400 Subject: [PATCH 096/216] Add guarded visual AI proposals and post-trial bench scoring --- .../notebook/2026-10-11-agent-visual-bench.md | 6 + tools/physical-workcell/AGENT_BENCH.md | 57 ++++ tools/physical-workcell/BENCH.md | 3 + tools/physical-workcell/agent_bench.py | 268 ++++++++++++++++++ tools/physical-workcell/score_agent_bench.py | 85 ++++++ tools/physical-workcell/test_agent_bench.py | 219 ++++++++++++++ 6 files changed, 638 insertions(+) create mode 100644 tools/physical-workcell/AGENT_BENCH.md create mode 100644 tools/physical-workcell/agent_bench.py create mode 100644 tools/physical-workcell/score_agent_bench.py create mode 100644 tools/physical-workcell/test_agent_bench.py diff --git a/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md b/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md index aaab8a2..90d49ef 100644 --- a/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md +++ b/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md @@ -6,3 +6,9 @@ Test: freeze a typed agent handoff, use the AI in this Codex session to inspect Predicts: two complete cycles, one measurement per job, one continuous bench identity, stale proposal refusal and fresh-image corrective actions after disturbance, with unchanged native guard source. Against: native poses or the deterministic coordinate planner guide actions, stale evidence dispatches, either cycle exceeds its motion budget, reset assigns block state or guards need weakening. Refs: docs/experiments/SIM7-agent-visual-bench.md; tools/physical-workcell/BENCH.md; results/agent-visual-bench-20261011/ + +## SIM7-DEV-U1 · update · 2026-10-11 14:27 +Observed: source review required stored unknown host results to block future proposals even when the underlying bench was ready. A new native-move/lost-host-reply check exercised that gap and passed after the host guard was implemented. Public CLI responses now filter detector coordinates from saved measurement/status receipts while retaining full evidence privately. Fifteen final interface conformance checks passed. Four initial test errors reflected exception classes from separately loaded helper modules; their fixture evidence is retained and assertions were corrected without changing native guard behavior. +Inferred: effect readiness alone is insufficient to resolve a host's uncertain dispatch, and measurement output can accidentally become numeric perception guidance unless the model-input boundary filters it. +Next: freeze measured source, initialize a fresh bench/session, and run actual AI-authored image-based actions before independent scoring. +Refs: tools/physical-workcell/output/a7-suite-b8f88806f5/suite.log; tools/physical-workcell/test_agent_bench.py; tools/physical-workcell/agent_bench.py diff --git a/tools/physical-workcell/AGENT_BENCH.md b/tools/physical-workcell/AGENT_BENCH.md new file mode 100644 index 0000000..f4ea1de --- /dev/null +++ b/tools/physical-workcell/AGENT_BENCH.md @@ -0,0 +1,57 @@ +# Visual AI control of the simulated bench + +An external multimodal agent can inspect the bench image and propose its next action through `agent_bench.py`. The controller still owns dispatch, freshness, physical limits, measurement persistence and reset verification. The handoff supplies no detector coordinates, native body poses or automatic motion planner. + +This interface works with the AI host's existing image-view and shell tools. It calls no provider API and needs no model key. The initial experiment uses the AI in a Codex conversation, rather than an unattended model service. The `host_role` label identifies the intended caller; it is not authentication or proof that a particular model authored a proposal. + +## Start a session and task + +Run from the repository root with the existing pinned Python/MuJoCo environment. Choose new private output directories. Initialize a bench using [BENCH.md](BENCH.md), then bind a separate agent session: + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/agent_bench.py \ + --session-dir tools/physical-workcell/output/my-ai/session \ + init --bench-dir tools/physical-workcell/output/my-ai/bench + +tools/physical-workcell/.venv/bin/python tools/physical-workcell/bench.py \ + --root tools/physical-workcell/output/my-ai/bench start --job-id trial-1 \ + --target-zone '{"x_min":0.035,"x_max":0.105,"y_min":-0.025,"y_max":0.025}' + +tools/physical-workcell/.venv/bin/python tools/physical-workcell/agent_bench.py \ + --session-dir tools/physical-workcell/output/my-ai/session observe +``` + +The returned challenge includes an exact image path and digest, calibration, job/phase identity, task region, home region, pusher dimensions and bounds. Open the actual image with the host's image tool before choosing a move. Positions are meters in the calibrated `sim_world` frame; targets position the blue pusher, not the orange block. Native contacts move the block. + +CLI responses remove detector coordinates and private poses from measurement and status +receipts. Pixel counts, footprint area and receipt identities remain available. Full receipts +stay on disk for the separate scorer; the internal Python methods are not a filtered model-input +surface. Use the CLI when supplying observations to an AI host. + +## Propose, dispatch, inspect + +The AI supplies one bounded action and a short description of its purpose: + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/agent_bench.py \ + --session-dir tools/physical-workcell/output/my-ai/session propose \ + --challenge-id CHALLENGE_ID --action move --target-x TARGET_X --target-y TARGET_Y \ + --intent 'Describe the intended next movement.' + +tools/physical-workcell/.venv/bin/python tools/physical-workcell/agent_bench.py \ + --session-dir tools/physical-workcell/output/my-ai/session dispatch --proposal-id PROPOSAL_ID +``` + +The other actions are `measure`, `begin_reset` and `finish_reset`; they accept no target coordinates. Preparation must pass the bench's image/native placement checks before `measure`. The measurement worker saves and verifies the result separately. `begin_reset` requires the measured active job. `finish_reset` requires image/native home verification and retained reset-contact evidence. + +A dispatch result includes its outcome and, when available, a new observation challenge. Inspect that image before another proposal. An exact repeated dispatch reads its historical result; the embedded observation is the snapshot from that earlier result, not a new observation. Call `observe` for current evidence. A new job can start only after reset is verified. + +Proposals and dispatch intent are retained before effects. A stale challenge refuses. An unresolved or unknown dispatch blocks new effects and is never automatically replayed. The AI should stop on unknown outcomes and inspect the retained evidence. It cannot declare measurement or reset successful by returning a model-written success field. + +Session evidence is retained in SHA-bound challenge, proposal, intent and result files under its private directory. Source changes invalidate the session. Keep all failed proposals and outcomes. The interface deliberately leaves perception and action selection to the external AI host; its records alone do not prove image consumption, which the host trial must record separately. + +## Trial and limits + +[SIM7 preregistration](../../jevdual/docs/experiments/SIM7-agent-visual-bench.md) specifies two successive AI-controlled jobs and a disturbance between saved proposal and dispatch. [Post-trial scoring](score_agent_bench.py) reads native state and SQLite after the AI attempt, so truth data cannot guide its moves. The [trial report](../../jevdual/results/agent-visual-bench-20261011/report.md) records the outcome. + +The existing simulation pauses between commands. This interface controls one known block and a bounded pusher, not a general robot or real actuator. It does not add provider integration, unattended scheduling, hardware permissions or a production Footwork capability grant. diff --git a/tools/physical-workcell/BENCH.md b/tools/physical-workcell/BENCH.md index 802ed18..acdff95 100644 --- a/tools/physical-workcell/BENCH.md +++ b/tools/physical-workcell/BENCH.md @@ -4,6 +4,9 @@ Prepare the block in the measurement region, run an optical measurement on the c This is an isolated Footwork experiment. It reuses the pinned MuJoCo model, native contact controller, PNG codec and color-specific RGB detector. It preserves the older single-order routes and uses a deterministic image-guided host. It makes no language-model calls and controls no hardware. +For an actual multimodal agent choosing actions from the images, use the separate +[visual AI handoff](AGENT_BENCH.md). The deterministic runner below remains a diagnostic baseline. + ## Run two jobs Use a new private directory below `tools/physical-workcell/output`. Run from the repository root with the existing pinned environment: diff --git a/tools/physical-workcell/agent_bench.py b/tools/physical-workcell/agent_bench.py new file mode 100644 index 0000000..839db59 --- /dev/null +++ b/tools/physical-workcell/agent_bench.py @@ -0,0 +1,268 @@ +"""Durable image challenges and guarded proposals for an external multimodal AI.""" + +import argparse +import json +import uuid +from pathlib import Path + +import bench +import order_protocol as protocol + +BASE = Path(__file__).resolve().parent +Refusal = bench.Refusal +ACTIONS = {"move", "measure", "begin_reset", "finish_reset"} +LIMIT = 256 +DERIVED_LOCATION_FIELDS = {"block_center_xy", "pusher_center_xy", "block_box", "pusher_box", + "centroid_pixel_xy", "block_xyz", "pusher_xyz", "block_xy", "pusher_xy", + "native_pose", "native_position", "block_pose", "pusher_pose"} + + +def public_response(value): + """Keep detector locations on disk; the AI plans from images and known geometry.""" + if isinstance(value, dict): + return {key: public_response(item) for key, item in value.items() if key not in DERIVED_LOCATION_FIELDS} + if isinstance(value, list): + return [public_response(item) for item in value] + return value + + +def sources(): + return {**bench.fingerprints(), "agent_bench_sha256": protocol.sha(protocol.read_bytes(BASE / "agent_bench.py"))} + + +def initialize(root, bench_dir): + root = protocol.directory(root, create=True) + bench_dir = protocol.directory(bench_dir) + if root == bench_dir or root in bench_dir.parents or bench_dir in root.parents: + raise Refusal("agent and bench directories must be separate") + status = bench.Bench(bench_dir).status() + if status["state"] != "ready": + raise Refusal("agent requires a ready initialized bench") + with protocol.locked(root): + if any(p.name != "app.lock" for p in root.iterdir()): + raise Refusal("agent initialization requires an empty owned directory") + for name in ("challenges", "proposals", "intents", "results", "events"): + (root / name).mkdir(mode=0o700) + manifest = {"version": 1, "session_id": uuid.uuid4().hex, + "host_role": "external_multimodal_AI_host", "bench_dir": str(bench_dir), + "bench_id": status["bench_id"], "source_fingerprints": sources(), + "sequence": 0, "challenges": {}, "proposals": {}, "intents": {}, "results": {}} + protocol.persist(root / "agent.json", manifest) + return AgentBench(root).status() + + +class AgentBench: + def __init__(self, root): + self.root = protocol.directory(root) + + def _load(self): + m = protocol.decode(protocol.read_bytes(self.root / "agent.json")) + protocol.fields(m, ("version", "session_id", "host_role", "bench_dir", "bench_id", + "source_fingerprints", "sequence", "challenges", "proposals", "intents", "results"), "agent manifest") + if (type(m["version"]) is not int or m["version"] != 1 or + m["host_role"] != "external_multimodal_AI_host" or m["source_fingerprints"] != sources() or + type(m["sequence"]) is not int or not 0 <= m["sequence"] <= LIMIT * 8): + raise Refusal("agent identity, sequence or source changed") + for key in ("session_id", "bench_id"): + if not isinstance(m[key], str) or not protocol.UUID.fullmatch(m[key]): + raise Refusal("agent or bench identity is invalid") + for kind in ("challenges", "proposals", "intents", "results"): + if not isinstance(m[kind], dict) or len(m[kind]) > LIMIT: + raise Refusal("agent record index exceeds its bounded schema") + for token, digest in m[kind].items(): + protocol.identity(token) + if not isinstance(digest, str) or not protocol.DIGEST.fullmatch(digest): + raise Refusal("agent record digest is invalid") + target = bench.Bench(protocol.directory(m["bench_dir"])) + if target.status()["bench_id"] != m["bench_id"]: + raise Refusal("bound bench identity changed") + return m, target + + def _save(self, m): + protocol.persist(self.root / "agent.json", m) + + def _record(self, m, kind, token, value): + protocol.identity(token) + if token in m[kind] or len(m[kind]) >= LIMIT: + raise Refusal("agent record identity reused or budget exhausted") + content = protocol.encoded(value) + if len(content) > protocol.MAX_BYTES: + raise Refusal("agent record exceeds bounded size") + bench.body.create_file(self.root / kind / (token + ".json"), content) + m[kind][token] = protocol.sha(content) + self._save(m) + + def _read(self, m, kind, token): + protocol.identity(token) + if token not in m[kind]: + raise Refusal("agent record is not owned by this session") + content = protocol.read_bytes(self.root / kind / (token + ".json")) + if protocol.sha(content) != m[kind][token]: + raise Refusal("immutable agent record changed") + return protocol.decode(content) + + def _event(self, m, kind, value): + if m["sequence"] >= LIMIT * 8: + raise Refusal("agent event budget exhausted") + sequence = m["sequence"] + 1 + bench.body.create_file(self.root / "events" / f"{sequence:06d}.json", + protocol.encoded({"sequence": sequence, "kind": kind, "value": value})) + m["sequence"] = sequence + self._save(m) + + def _observe(self, m, target): + try: + packet = target.observe() + state = target.status() + job = state["active_job"] + if packet["bench_id"] != m["bench_id"] or packet["job_id"] != (job["job_id"] if job else None): + raise Refusal("observation and task identity disagree") + challenge = {"challenge_id": "challenge-" + uuid.uuid4().hex, + "session_id": m["session_id"], "sequence": m["sequence"] + 1, + "observation_sha256": protocol.sha(protocol.encoded(packet)), "observation": packet, + "task": {"zone": job["target_zone"] if job else None, + "home_zone": dict(bench.HOME_ZONE), + "pusher_dimensions_m": {"x": .04, "y": .14}, + "bounds": {"x_min": -.32, "x_max": .18, "y_min": -.15, "y_max": .15}}, + "image_path": packet["image_path"]} + self._record(m, "challenges", challenge["challenge_id"], challenge) + self._event(m, "observe", {"challenge_id": challenge["challenge_id"]}) + return challenge + except Exception as exc: + self._event(m, "observe_failed", {"reason": str(exc)}) + raise + + def observe(self): + with protocol.locked(self.root): + return self._observe(*self._load()) + + def _challenge(self, m, token): + c = self._read(m, "challenges", token) + protocol.fields(c, ("challenge_id", "session_id", "sequence", "observation_sha256", "observation", "task", "image_path"), "challenge") + packet = c["observation"] + protocol.fields(packet, bench.OBSERVATION_FIELDS, "observation") + image_path = Path(packet["image_path"]) + if (c["session_id"] != m["session_id"] or c["challenge_id"] != token or + c["observation_sha256"] != protocol.sha(protocol.encoded(packet)) or + packet["bench_id"] != m["bench_id"] or c["image_path"] != str(image_path) or + image_path.parent != Path(m["bench_dir"]) / "images" or + protocol.sha(protocol.read_bytes(image_path, maximum=8 * 1024 * 1024)) != packet["image_sha256"]): + raise Refusal("challenge image or identity binding changed") + return c + + @staticmethod + def _validate_action(action, intent, x, y): + if action not in ACTIONS or not isinstance(intent, str) or not 1 <= len(intent.strip()) <= 2000: + raise Refusal("proposal requires a supported action and bounded AI intent") + if action == "move": + return protocol.finite(x), protocol.finite(y) + if x is not None or y is not None: + raise Refusal("only move accepts target coordinates") + return None, None + + def propose(self, challenge_id, action, intent, target_x=None, target_y=None): + x, y = self._validate_action(action, intent, target_x, target_y) + with protocol.locked(self.root): + m, _ = self._load() + c = self._challenge(m, challenge_id) + proposal = {"proposal_id": "proposal-" + uuid.uuid4().hex, + "session_id": m["session_id"], "challenge_id": challenge_id, + "observation_sha256": c["observation_sha256"], "action": action, "intent": intent, + "target_x": x, "target_y": y, "operation_id": "agent-" + uuid.uuid4().hex} + self._record(m, "proposals", proposal["proposal_id"], proposal) + self._event(m, "propose", {"proposal_id": proposal["proposal_id"], "intent": intent}) + return proposal + + def dispatch(self, proposal_id): + with protocol.locked(self.root): + m, target = self._load() + p = self._read(m, "proposals", proposal_id) + protocol.fields(p, ("proposal_id", "session_id", "challenge_id", "observation_sha256", "action", "intent", "target_x", "target_y", "operation_id"), "proposal") + self._validate_action(p["action"], p["intent"], p["target_x"], p["target_y"]) + protocol.identity(p["operation_id"]) + c = self._challenge(m, p["challenge_id"]) + if p["proposal_id"] != proposal_id or p["session_id"] != m["session_id"] or p["observation_sha256"] != c["observation_sha256"]: + raise Refusal("proposal and challenge binding changed") + if proposal_id in m["results"]: + self._read(m, "intents", proposal_id) + return self._read(m, "results", proposal_id) + if any(token not in m["results"] or self._read(m, "results", token)["outcome"] == "unknown" + for token in m["intents"]): + return {"proposal_id": proposal_id, "outcome": "unknown", "reason": "unresolved dispatch intent; no replay or new effect allowed", "next_observation": None} + self._record(m, "intents", proposal_id, {"proposal_sha256": m["proposals"][proposal_id], + "challenge_sha256": m["challenges"][p["challenge_id"]], "operation_id": p["operation_id"]}) + self._event(m, "dispatch_intent", {"proposal_id": proposal_id}) + result = {"proposal_id": proposal_id, "outcome": "unknown", + "observation_scope": "snapshot_at_dispatch_result"} + try: + if p["action"] == "begin_reset": + if target.observe() != c["observation"]: + raise Refusal("reset proposal observation is stale; no effect dispatched") + receipt = target.begin_reset(c["observation"]["job_id"]) + elif p["action"] == "move": + receipt = target.move(p["operation_id"], c["observation"], p["target_x"], p["target_y"]) + else: + receipt = getattr(target, p["action"])(p["operation_id"], c["observation"]) + result.update(outcome="executed", receipt=receipt) + except Exception as exc: # noqa: BLE001 - persist unknown after any dispatched failure. + result["reason"] = str(exc) + try: + if isinstance(exc, (Refusal, protocol.Refusal)) and target.status()["state"] == "ready": + result["outcome"] = "refused" + except Exception as status_exc: # noqa: BLE001 - uncertain status cannot clear the intent. + result["status_error"] = str(status_exc) + try: + result["next_observation"] = self._observe(m, target) + except Exception as exc: # noqa: BLE001 - preserve effect result when subsequent observation fails. + result.update(next_observation=None, observation_error=str(exc)) + self._record(m, "results", proposal_id, result) + self._event(m, "dispatch_result", {"proposal_id": proposal_id, "outcome": result["outcome"]}) + return result + + def status(self): + with protocol.locked(self.root): + m, target = self._load() + return {"session_id": m["session_id"], "host_role": m["host_role"], "bench_id": m["bench_id"], + "source_fingerprints": m["source_fingerprints"], "sequence": m["sequence"], + "unresolved_proposals": [k for k in m["intents"] if k not in m["results"] or + self._read(m, "results", k)["outcome"] == "unknown"], + "bench": target.status()} + + +def main(argv=None): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--session-dir", required=True, type=Path) + sub = parser.add_subparsers(dest="command", required=True) + init = sub.add_parser("init") + init.add_argument("--bench-dir", required=True, type=Path) + for name in ("observe", "status"): + sub.add_parser(name) + proposal = sub.add_parser("propose") + proposal.add_argument("--challenge-id", required=True) + proposal.add_argument("--action", required=True, choices=sorted(ACTIONS)) + proposal.add_argument("--intent", required=True) + proposal.add_argument("--target-x", type=float) + proposal.add_argument("--target-y", type=float) + dispatch = sub.add_parser("dispatch") + dispatch.add_argument("--proposal-id", required=True) + args = parser.parse_args(argv) + try: + if args.command == "init": + result = initialize(args.session_dir, args.bench_dir) + else: + host = AgentBench(args.session_dir) + if args.command == "propose": + result = host.propose(args.challenge_id, args.action, args.intent, args.target_x, args.target_y) + elif args.command == "dispatch": + result = host.dispatch(args.proposal_id) + else: + result = getattr(host, args.command)() + print(json.dumps(public_response(result), sort_keys=True, allow_nan=False)) + return 0 + except (Refusal, protocol.Refusal, OSError, KeyError, TypeError, ValueError) as exc: + print(json.dumps({"outcome": "refused", "reason": str(exc)}, sort_keys=True)) + return 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/physical-workcell/score_agent_bench.py b/tools/physical-workcell/score_agent_bench.py new file mode 100644 index 0000000..93a3afc --- /dev/null +++ b/tools/physical-workcell/score_agent_bench.py @@ -0,0 +1,85 @@ +"""Separate post-trial native/SQLite scoring; never supplies AI action guidance.""" + +import argparse +import json +import subprocess +from pathlib import Path + +import bench +import qualify_bench +import workcell as body + +BASE = Path(__file__).resolve().parent +REPO = BASE.parents[1] +SOURCES = [BASE / name for name in ( + "agent_bench.py", "score_agent_bench.py", "bench.py", "measurement.py", "workcell.py", + "image_guided.py", "episode_cases.py", "order_protocol.py", "scene.xml", "qualify_bench.py")] +SOURCES.append(BASE.parent / "camera-capture-experiment" / "capture.py") + + +def freeze(root, commit): + root = body.directory(root, create=True) + if subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=REPO, text=True).strip() != commit: + raise body.Refusal("trial must start at the named source commit") + files = {} + for path in SOURCES: + relative = str(path.relative_to(REPO)) + content = body.read_bytes(path) + if subprocess.check_output(["git", "show", f"{commit}:{relative}"], cwd=REPO) != content: + raise body.Refusal("measured source differs from its frozen commit") + files[relative] = body.sha(content) + body.create_file(root / "source-freeze.json", body.encoded({"commit": commit, "files": files})) + initial = bench.initialize(root / "bench", diagnostic_enabled=True) + body.create_file(root / "initial.json", body.encoded(initial)) + return {"source_commit": commit, "bench_id": initial["bench_id"], "native_time_s": initial["native_time_s"]} + + +def score(root): + root = body.directory(root) + frozen = body.decoded(body.read_bytes(root / "source-freeze.json")) + assert all(body.sha(body.read_bytes(REPO / name)) == digest for name, digest in frozen["files"].items()) + initial = body.decoded(body.read_bytes(root / "initial.json")) + status = bench.Bench(root / "bench").status() + database = qualify_bench.sqlite_score(root / "bench") + passed = status["state"] == "ready" and status["active_job"] is None and len(status["jobs"]) == database["count"] == 2 + scores = [] + for index, name in enumerate(("ai-ordinary", "ai-disturbed")): + job = status["jobs"].get(name) + if job is None: + passed = False + continue + measurement = job["measurement_receipt"] + reset = job["reset_receipt"] + stage = qualify_bench.native_score(root / "bench", measurement["generation"], + measurement["state_sha256"], job["target_zone"]) + home = qualify_bench.native_score(root / "bench", reset["generation"], reset["state_sha256"], bench.HOME_ZONE) + row = next(row for row in database["rows"] if row["job_id"] == name) + previous_generation = 0 if index == 0 else status["jobs"]["ai-ordinary"]["completed_generation"] + previous_time = initial["native_time_s"] if index == 0 else status["jobs"]["ai-ordinary"]["completed_native_time_s"] + ok = bool(stage["block_center_in_zone"] and home["block_center_in_zone"] and home["pusher_home"] and + stage["external_force_cleared"] and home["external_force_cleared"] and + row["receipt"] == measurement and reset["reset_contact_samples"] > 0 and reset["reset_native_steps"] > 0 and + reset["bench_id"] == measurement["bench_id"] == initial["bench_id"] == status["bench_id"] and + job["started_generation"] == previous_generation and job["started_native_time_s"] == previous_time) + scores.append({"job_id": name, "passed": ok, "measurement_state": stage, "reset_state": home, + "measurement": measurement, "reset": reset, "motion_count": job["moves"]}) + passed &= ok + result = {"version": 1, "passed": passed, "source_commit": frozen["commit"], "source_unchanged": True, + "bench_id": initial["bench_id"], "completed_cycles": len(scores), "scores": scores, + "sqlite": database, "current_status": status, "attempt": 1, + "scope": "native/SQLite post-trial scoring; AI image consumption/proposals are separately recorded in the session"} + body.create_file(root / "native-sqlite-score.json", body.encoded(result)) + return {k: result[k] for k in ("passed", "completed_cycles", "source_unchanged", "bench_id")} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("command", choices=("freeze", "score")) + parser.add_argument("--run-dir", required=True, type=Path) + parser.add_argument("--source-commit") + args = parser.parse_args() + print(json.dumps(freeze(args.run_dir, args.source_commit) if args.command == "freeze" else score(args.run_dir), sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/test_agent_bench.py b/tools/physical-workcell/test_agent_bench.py new file mode 100644 index 0000000..d023ae8 --- /dev/null +++ b/tools/physical-workcell/test_agent_bench.py @@ -0,0 +1,219 @@ +"""SIM7 conformance for the external AI boundary against actual native benches.""" + +import contextlib +import io +import json +import unittest +import uuid +from pathlib import Path +from unittest import mock + +import agent_bench as agent + +ZONE = {"x_min": .04, "x_max": .10, "y_min": -.025, "y_max": .025} + + +class AgentBenchTests(unittest.TestCase): + def setUp(self): + self.root = agent.BASE / "output" / ("a7test-" + uuid.uuid4().hex[:10]) + self.root.mkdir(mode=0o700) + self.bench_dir = self.root / "bench" + agent.bench.initialize(self.bench_dir, diagnostic_enabled=True) + self.bench = agent.bench.Bench(self.bench_dir) + self.bench.start_job("job-one", ZONE) + self.session = self.root / "agent" + agent.initialize(self.session, self.bench_dir) + self.host = agent.AgentBench(self.session) + self.events = [] + + def tearDown(self): + result = self._outcome.result + failed = any(test is self for test, _ in (*result.failures, *result.errors)) + agent.bench.body.create_file(self.root / "conformance.json", agent.protocol.encoded( + {"test_id": self.id(), "passed": not failed, "events": self.events})) + + def proposal(self, action="move", challenge=None, **kwargs): + challenge = challenge or self.host.observe() + if action == "move" and not kwargs: + kwargs = {"target_x": -.25, "target_y": 0} + p = self.host.propose(challenge["challenge_id"], action, "AI development conformance intent", **kwargs) + self.events.append({"challenge": challenge, "proposal": p}) + return p + + def dispatch(self, p): + result = self.host.dispatch(p["proposal_id"]) + self.events.append({"dispatch": result}) + return result + + def test_challenge_has_only_images_task_and_public_observation(self): + c = self.host.observe() + self.assertEqual(c["observation_sha256"], agent.protocol.sha(agent.protocol.encoded(c["observation"]))) + self.assertEqual(c["task"]["zone"], ZONE) + self.assertEqual(Path(c["image_path"]).read_bytes()[:8], b"\x89PNG\r\n\x1a\n") + self.assertNotIn("block_xyz", json.dumps(c)) + self.assertNotIn("pusher_xyz", json.dumps(c)) + self.assertEqual(self.host.status()["host_role"], "external_multimodal_AI_host") + + def test_proposal_persists_intent_without_effect(self): + before = self.bench.status() + p = self.proposal() + self.assertEqual(before, self.bench.status()) + self.assertTrue((self.session / "proposals" / (p["proposal_id"] + ".json")).exists()) + self.assertEqual(list((self.session / "intents").iterdir()), []) + + def test_move_executes_once_duplicate_returns_exact_result(self): + p = self.proposal() + result = self.dispatch(p) + self.assertEqual(result["outcome"], "executed") + self.assertEqual(result["receipt"]["operation_id"], p["operation_id"]) + before = self.bench.status() + self.assertEqual(result, self.dispatch(p)) + self.assertEqual(before, self.bench.status()) + + def test_stale_move_refuses_and_returns_fresh_image(self): + c = self.host.observe() + p = self.proposal(challenge=c) + self.bench.disturb("external-force", -.4, 50) + generation = self.bench.status()["generation"] + result = self.dispatch(p) + self.assertEqual(result["outcome"], "refused") + self.assertEqual(self.bench.status()["generation"], generation) + self.assertGreater(result["next_observation"]["observation"]["generation"], c["observation"]["generation"]) + + def test_measurement_placement_refusal_does_not_create_sqlite(self): + result = self.dispatch(self.proposal("measure")) + self.assertEqual(result["outcome"], "refused") + self.assertFalse((self.bench_dir / "measurements.sqlite").exists()) + + def test_wrong_reset_phase_preserves_bench(self): + for action in ("begin_reset", "finish_reset"): + before = self.bench.status() + result = self.dispatch(self.proposal(action)) + self.assertEqual(result["outcome"], "refused") + self.assertEqual(before, self.bench.status()) + + def test_nonfinite_and_conflicting_arguments_never_create_proposal(self): + c = self.host.observe() + for action, x, y in (("move", float("nan"), 0), ("move", True, 0), ("move", 0, None), ("measure", 0, 0)): + with self.assertRaises((agent.Refusal, agent.protocol.Refusal)): + self.host.propose(c["challenge_id"], action, "intent", x, y) + self.assertEqual(list((self.session / "proposals").iterdir()), []) + + def test_foreign_challenge_and_unsafe_identity_refuse(self): + for token in ("challenge-" + uuid.uuid4().hex, "../bench/bench"): + with self.assertRaises((agent.Refusal, agent.protocol.Refusal)): + self.host.propose(token, "measure", "intent") + + def test_changed_proposal_refuses_before_dispatch(self): + p = self.proposal() + path = self.session / "proposals" / (p["proposal_id"] + ".json") + path.write_bytes(path.read_bytes().replace(b'"target_x": -0.25', b'"target_x": 0.18')) + before = self.bench.status() + with self.assertRaises((agent.Refusal, agent.protocol.Refusal)): + self.dispatch(p) + self.assertEqual(before, self.bench.status()) + + def test_changed_challenge_image_refuses(self): + c = self.host.observe() + p = self.proposal(challenge=c) + Path(c["image_path"]).write_bytes(b"changed image") + with self.assertRaises((agent.Refusal, agent.protocol.Refusal)): + self.dispatch(p) + self.assertEqual(list((self.session / "intents").iterdir()), []) + + def test_unresolved_intent_blocks_same_and_new_proposal(self): + p = self.proposal() + with agent.protocol.locked(self.session): + m, _ = self.host._load() + self.host._record(m, "intents", p["proposal_id"], {"interrupted_fixture": True}) + before = self.bench.status() + self.assertEqual(self.dispatch(p)["outcome"], "unknown") + self.assertEqual(self.dispatch(self.proposal())["outcome"], "unknown") + self.assertEqual(before, self.bench.status()) + + def test_measurement_worker_failure_retains_unknown_and_blocks_replay(self): + packet = self.bench.observe() + for index, x in enumerate((-.175, -.07, .015)): + self.bench.move("stage-" + str(index), packet, x, 0) + packet = self.bench.observe() + p = self.proposal("measure") + with mock.patch.object(agent.bench.subprocess, "run", return_value=mock.Mock(returncode=1, stdout=b"", stderr=b"fixture worker failure")): + result = self.dispatch(p) + self.assertEqual(result["outcome"], "unknown") + self.assertEqual(self.bench.status()["state"], "unknown") + self.assertIsNone(result["next_observation"]) + self.assertEqual(self.dispatch(p), result) + self.assertIn(p["proposal_id"], self.host.status()["unresolved_proposals"]) + + def test_source_change_and_foreign_bench_identity_block_dispatch(self): + p = self.proposal() + before = self.bench.status() + with mock.patch.object(agent, "sources", return_value={"changed": "source"}), self.assertRaises(agent.Refusal): + self.dispatch(p) + m = agent.protocol.decode(agent.protocol.read_bytes(self.session / "agent.json")) + m["bench_id"] = uuid.uuid4().hex + agent.protocol.persist(self.session / "agent.json", m) + with self.assertRaises(agent.Refusal): + self.dispatch(p) + self.assertEqual(before, self.bench.status()) + + def test_error_after_real_move_stays_unknown_even_if_bench_ready(self): + original = agent.bench.Bench.move + + def lost_reply(target, *args, **kwargs): + original(target, *args, **kwargs) + raise RuntimeError("fixture reply lost after real native motion") + + p = self.proposal() + with mock.patch.object(agent.bench.Bench, "move", lost_reply): + result = self.dispatch(p) + self.assertEqual(result["outcome"], "unknown") + self.assertEqual(self.bench.status()["state"], "ready") + before = self.bench.status() + self.assertEqual(self.dispatch(p), result) + self.assertEqual(self.dispatch(self.proposal())["outcome"], "unknown") + self.assertEqual(self.bench.status(), before) + self.assertIn(p["proposal_id"], self.host.status()["unresolved_proposals"]) + + def test_public_cli_measurement_reset_and_status_strip_detector_locations(self): + packet = self.bench.observe() + for index, x in enumerate((-.175, -.07, .015)): + self.bench.move("stage-" + str(index), packet, x, 0) + packet = self.bench.observe() + + def cli(*args): + output = io.StringIO() + with contextlib.redirect_stdout(output): + self.assertEqual(agent.main(["--session-dir", str(self.session), *args]), 0) + value = json.loads(output.getvalue()) + self.events.append({"public_cli": value}) + return value + + p = self.proposal("measure") + measured = cli("dispatch", "--proposal-id", p["proposal_id"]) + self.assertEqual(measured["outcome"], "executed") + metric = measured["receipt"]["measurement_receipt"]["measurement"] + self.assertIn("orange_pixel_count", metric) + self.assertIn("footprint_area_m2", metric) + private = agent.protocol.decode(agent.protocol.read_bytes(self.session / "results" / (p["proposal_id"] + ".json"))) + self.assertIn("block_center_xy", private["receipt"]["measurement_receipt"]["measurement"]) + reset = self.proposal("begin_reset", challenge=measured["next_observation"]) + responses = [measured, cli("dispatch", "--proposal-id", reset["proposal_id"]), cli("status")] + + def assert_no_locations(value): + if isinstance(value, dict): + self.assertFalse(agent.DERIVED_LOCATION_FIELDS.intersection(value)) + for item in value.values(): + assert_no_locations(item) + elif isinstance(value, list): + for item in value: + assert_no_locations(item) + + for response in responses: + assert_no_locations(response) + future = {"nested": [{"native_pose": [1, 2, 3], "block_xyz": [1, 2, 3], "target_x": .1}]} + self.assertEqual(agent.public_response(future), {"nested": [{"target_x": .1}]}) + + +if __name__ == "__main__": + unittest.main() From 3a3d01e0359e3175c715159e43dd905670a477f7 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 14:41:52 -0400 Subject: [PATCH 097/216] Record actual visual AI bench control and displacement recovery --- .../experiments/SIM7-agent-visual-bench.md | 4 + .../notebook/2026-10-11-agent-visual-bench.md | 13 + .../AI-action-audit.json | 870 ++++++++++++++++++ .../AI-observations.gif | Bin 0 -> 147083 bytes .../after-disturbance.png | Bin 0 -> 109794 bytes .../before-disturbance.png | Bin 0 -> 109630 bytes .../agent-visual-bench-20261011/checks.json | 58 ++ .../agent-visual-bench-20261011/cleanup.json | 19 + .../agent-visual-bench-20261011/frames.json | 281 ++++++ .../fresh-agent-status.json | 1 + .../harness-disturbance.json | 16 + .../image-presentations.json | 223 +++++ .../native-sqlite-score.json | 422 +++++++++ .../agent-visual-bench-20261011/recovered.png | Bin 0 -> 109582 bytes .../agent-visual-bench-20261011/report.md | 50 + .../agent-visual-bench-20261011/reset.png | Bin 0 -> 109990 bytes .../source-freeze.json | 16 + 17 files changed, 1973 insertions(+) create mode 100644 jevdual/results/agent-visual-bench-20261011/AI-action-audit.json create mode 100644 jevdual/results/agent-visual-bench-20261011/AI-observations.gif create mode 100644 jevdual/results/agent-visual-bench-20261011/after-disturbance.png create mode 100644 jevdual/results/agent-visual-bench-20261011/before-disturbance.png create mode 100644 jevdual/results/agent-visual-bench-20261011/checks.json create mode 100644 jevdual/results/agent-visual-bench-20261011/cleanup.json create mode 100644 jevdual/results/agent-visual-bench-20261011/frames.json create mode 100644 jevdual/results/agent-visual-bench-20261011/fresh-agent-status.json create mode 100644 jevdual/results/agent-visual-bench-20261011/harness-disturbance.json create mode 100644 jevdual/results/agent-visual-bench-20261011/image-presentations.json create mode 100644 jevdual/results/agent-visual-bench-20261011/native-sqlite-score.json create mode 100644 jevdual/results/agent-visual-bench-20261011/recovered.png create mode 100644 jevdual/results/agent-visual-bench-20261011/report.md create mode 100644 jevdual/results/agent-visual-bench-20261011/reset.png create mode 100644 jevdual/results/agent-visual-bench-20261011/source-freeze.json diff --git a/jevdual/docs/experiments/SIM7-agent-visual-bench.md b/jevdual/docs/experiments/SIM7-agent-visual-bench.md index 36996d3..48bb9e5 100644 --- a/jevdual/docs/experiments/SIM7-agent-visual-bench.md +++ b/jevdual/docs/experiments/SIM7-agent-visual-bench.md @@ -25,3 +25,7 @@ Primary metric: complete job cycles, required 2/2 on the first frozen trial atte ## Guardrails and limits Keep bench.py, measurement.py, native controller and image gate source unchanged. One writer, typed finite actions, exact observation/source/job binding, retained intent before dispatch, no replay of unknown effects, and independent effect readback. No keys, paid provider calls, real cameras, hardware, production application changes or cloud deployment. The trial establishes this AI session's behavior, not a repeatability rate, a deployed policy service or general robotics. + +## Result + +Frozen `9a5d2f8bfac8088b13c63052887e0c0c2e9d5c7e` passed both first-attempt cycles with the Codex conversation AI authoring 29 proposals from presented images. A prepared measurement refused after a 0.13303 m native-force displacement; the AI observed the changed image, corrected placement, measured and reset. Post-trial native/SQLite scoring confirmed both cycles and exactly two saved measurements. Native guards remained unchanged; 29 focused checks passed. See `results/agent-visual-bench-20261011/report.md` and its structured evidence. Adopt the external visual-agent handoff as an isolated experimental interface, not an unattended policy service. diff --git a/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md b/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md index 90d49ef..e3efe99 100644 --- a/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md +++ b/jevdual/docs/notebook/2026-10-11-agent-visual-bench.md @@ -12,3 +12,16 @@ Observed: source review required stored unknown host results to block future pro Inferred: effect readiness alone is insufficient to resolve a host's uncertain dispatch, and measurement output can accidentally become numeric perception guidance unless the model-input boundary filters it. Next: freeze measured source, initialize a fresh bench/session, and run actual AI-authored image-based actions before independent scoring. Refs: tools/physical-workcell/output/a7-suite-b8f88806f5/suite.log; tools/physical-workcell/test_agent_bench.py; tools/physical-workcell/agent_bench.py + +## SIM7-U1 · update · 2026-10-11 14:39 +Resolves: SIM7-P1 = held +Observed: frozen 9a5d2f8 completed two first-attempt jobs with the Codex multimodal AI authoring 29 proposals bound to presented images. A saved second-job measurement refused after a 0.13303 m native-force displacement. The next image informed corrective motion, followed by verified measurement and contact reset. Separate scoring after control found both target predicates, one SQLite result per job, both home predicates, continuous body identity/time and unchanged native guard source. Fifteen handoff and fourteen bench checks passed. +Inferred: the guarded observation/proposal boundary supports this actual AI host across successive jobs and a bounded displacement, without a deterministic coordinate planner or numeric detector guidance in model inputs. +Next: close this package with source, proposals, image-presentation audit, scoring, replay and process outcomes retained. A provider-backed unattended loop is a separate implementation and qualification. +Refs: 9a5d2f8; results/agent-visual-bench-20261011/report.md; results/agent-visual-bench-20261011/AI-action-audit.json; results/agent-visual-bench-20261011/native-sqlite-score.json + +## SIM7-S · summary · 2026-10-11 14:39 +Established: typed external-AI proposals, SHA-bound observations and source identity, durable dispatch and unknown-outcome blocking, filtered model inputs, actual image-based AI control of two jobs, stale proposal refusal and corrective recovery, and separate physical/software scoring. No native guard changes, provider calls or hardware effects were introduced. All CLI and measurement subprocesses returned; evidence remains retained. +Uncertain: unattended policy hosting, model-origin authentication, repeatability across fresh model sessions, blind/unseen disturbance recovery, arbitrary object perception, hardware transfer and production capability governance remain unqualified. The first narrow AI mechanism prediction held; no failed frozen trial was discarded or retried. +Decision: retain the visual AI handoff as an experimental Footwork tool, with the AI choosing actions and deterministic code owning effect authority. Use this interface for later policies or instruments without weakening the existing guards. +Refs: docs/experiments/SIM7-agent-visual-bench.md; tools/physical-workcell/AGENT_BENCH.md; results/agent-visual-bench-20261011/ diff --git a/jevdual/results/agent-visual-bench-20261011/AI-action-audit.json b/jevdual/results/agent-visual-bench-20261011/AI-action-audit.json new file mode 100644 index 0000000..f4fd28d --- /dev/null +++ b/jevdual/results/agent-visual-bench-20261011/AI-action-audit.json @@ -0,0 +1,870 @@ +{ + "passed": true, + "source_commit": "9a5d2f8bfac8088b13c63052887e0c0c2e9d5c7e", + "guard_sources_unchanged": true, + "attempt": 1, + "successful_cycles": 2, + "AI_host": "Codex multimodal assistant in this conversation", + "AI_proposals": 29, + "image_presentations": 31, + "all_proposals_bind_presented_images": true, + "refused_stale_measurements": 1, + "unknown_outcomes": 0, + "disturbance": { + "before": { + "role": "independent_native_state_scorer", + "generation": 12, + "state_sha256": "c5eb98e5389520f67d0a5696115aa8d7d7a2ae63ded866d4f74b1716a02128fc", + "native_time_s": 31.415999999993467, + "block_xyz": [ + 0.07578820807466202, + -2.3639510932334726e-09, + 0.03499573045536971 + ], + "pusher_xyz": [ + -0.299999969238987, + 3.5114932976316857e-36, + 0.06 + ], + "block_center_in_zone": true, + "pusher_home": true, + "external_force_cleared": true + }, + "after": { + "role": "independent_native_state_scorer", + "generation": 13, + "state_sha256": "1816ee306f82952178fe88ac2857976ccd1594d917628fad36a438f79183280b", + "native_time_s": 32.57599999999385, + "block_xyz": [ + -0.0572428260016602, + -2.363914289828072e-09, + 0.034995730455369856 + ], + "pusher_xyz": [ + -0.2999999999999935, + 7.426712930285049e-43, + 0.06 + ], + "block_center_in_zone": false, + "pusher_home": true, + "external_force_cleared": true + }, + "displacement_x_m": -0.13303103407632222 + }, + "actions": [ + { + "sequence": 5, + "job_id": "ai-ordinary", + "generation": 0, + "proposal": { + "action": "move", + "challenge_id": "challenge-e4339df93bb44cf9827aaa89ca5e2d0c", + "intent": "Push the visible orange block right toward the center of the green measurement region.", + "observation_sha256": "16db335110b8ec1dcb8abbd79eff6e896a9e2b202021915e1d08db2f199011f5", + "operation_id": "agent-aeb2273d6d6a4f539555071890b542f7", + "proposal_id": "proposal-5c78049d2f0644859cfc4f961d0e408e", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": 0.015, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-aeb2273d6d6a4f539555071890b542f7", + "kind": "move", + "generation": 1, + "native_time_s": 4.0999999999997705, + "native_steps": 1550, + "pusher_block_contact_samples": 3164, + "max_axis_actuator_force_n": 1.2780714513550784, + "state_sha256": "3dd31d583a8b7ec3f4a7fa51f403baa50fda8f9839a705a1787505c87464e425" + }, + "challenge_image_sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + { + "sequence": 9, + "job_id": "ai-ordinary", + "generation": 1, + "proposal": { + "action": "move", + "challenge_id": "challenge-0a7f171f17d0440aba49e0b394ca6981", + "intent": "The block is centered in the measurement region; retract the pusher left, away from the block, to clear the image.", + "observation_sha256": "440ac82d3e2e12b6ee77d2bb487c4b6b714c248917bdd8b336f6ce38c1bf30e4", + "operation_id": "agent-201690e6fe504ef39f50055e592eed1f", + "proposal_id": "proposal-6e348696878b4aef835229d6577cb5d5", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.3, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-201690e6fe504ef39f50055e592eed1f", + "kind": "move", + "generation": 2, + "native_time_s": 7.199999999999429, + "native_steps": 1550, + "pusher_block_contact_samples": 64, + "max_axis_actuator_force_n": 0.5633864611553108, + "state_sha256": "17c6620f9eeb3b3c3a6e787215e843c7a8bfa66eb3c56f8693c3477b2eb5d9c9" + }, + "challenge_image_sha256": "cb4221e600bbb24aec549f49924fc9224876a1ad8d04159fe0cc3798658d8357" + }, + { + "sequence": 13, + "job_id": "ai-ordinary", + "generation": 2, + "proposal": { + "action": "measure", + "challenge_id": "challenge-b946ac2ff9d74070b5f3efbed673b58d", + "intent": "The orange block center remains in the green region and the pusher is clear; run the computer measurement.", + "observation_sha256": "b302e99abe05b60bed706ecf0d96f6bd29e514a9f410145162091369562d8743", + "operation_id": "agent-62ebb86d89f941daab3a059aa53fd695", + "proposal_id": "proposal-632b712fdcd646679f954f6f4abb6e37", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": null, + "target_y": null + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-62ebb86d89f941daab3a059aa53fd695", + "kind": "measure", + "generation": 2, + "state_sha256": "17c6620f9eeb3b3c3a6e787215e843c7a8bfa66eb3c56f8693c3477b2eb5d9c9" + }, + "challenge_image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159" + }, + { + "sequence": 17, + "job_id": "ai-ordinary", + "generation": 2, + "proposal": { + "action": "begin_reset", + "challenge_id": "challenge-37730e6485b945b4a30e5ae544e5a91d", + "intent": "The verified measurement is saved; begin returning the block and pusher to their home positions.", + "observation_sha256": "90e4f830c218c32a5a548d2afacebb237f03e76a55d9303e71611a662299eb33", + "operation_id": "agent-ae2a5100d3fc4fbcb76023e5ced0f9a0", + "proposal_id": "proposal-08212ee8faa04bbdaecadb14da534852", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": null, + "target_y": null + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "generation": 2, + "native_time_s": 7.199999999999429 + }, + "challenge_image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159" + }, + { + "sequence": 21, + "job_id": "ai-ordinary", + "generation": 2, + "proposal": { + "action": "move", + "challenge_id": "challenge-fe85036078c24be39d7e21b9ad462286", + "intent": "Move the pusher into the upper bypass lane so it can reach the right side of the block without crossing it.", + "observation_sha256": "fe39e48543c6acc01d0c6a1517a460da78e39efff54d923177790c352ee6c2a5", + "operation_id": "agent-da74795104e8433d84ca03c55a5a9f3e", + "proposal_id": "proposal-0b967a31699f4f67aa758ee98001a948", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.3, + "target_y": 0.135 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-da74795104e8433d84ca03c55a5a9f3e", + "kind": "move", + "generation": 3, + "native_time_s": 9.101999999999709, + "native_steps": 951, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38448407128570206, + "state_sha256": "213816189f73ad2af9c338b8c204e0b238e4e11d6893995b1fead34a8a63d491" + }, + "challenge_image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159" + }, + { + "sequence": 25, + "job_id": "ai-ordinary", + "generation": 3, + "proposal": { + "action": "move", + "challenge_id": "challenge-859f365ee5294dac81a68cf58fb8d5be", + "intent": "The pusher is visibly above the block; cross the clear lane to a position just beyond its right face.", + "observation_sha256": "4e35f1762c23b98fce7181f23c806c6c8de3d4738a23170c60d70174797abb9a", + "operation_id": "agent-375e8bb74d4f4dc7b1b3dfabad8d83b1", + "proposal_id": "proposal-e1daead845b74cd68a6e2ebd57f81e17", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": 0.14, + "target_y": 0.135 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-375e8bb74d4f4dc7b1b3dfabad8d83b1", + "kind": "move", + "generation": 4, + "native_time_s": 13.036000000001023, + "native_steps": 1967, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38525092330498, + "state_sha256": "b36c073315154f2c4412cf7923dec065ec428566b7e7dccda023c35c90b3f1a8" + }, + "challenge_image_sha256": "09026909d3489122b3f84704a9072495ec2288b7ccd0e2d1f6029521293335ea" + }, + { + "sequence": 29, + "job_id": "ai-ordinary", + "generation": 4, + "proposal": { + "action": "move", + "challenge_id": "challenge-0e224d3ea5de42699bc1abc4e84d87b5", + "intent": "The pusher is to the right of the orange block with clearance; lower it into the block's horizontal pushing lane.", + "observation_sha256": "fd5522f5296936afe5adfed7d4ae8f736194be2af57d0f5e8fcd5cc7d5d77034", + "operation_id": "agent-e891c9fd8986410a806f80ba59238880", + "proposal_id": "proposal-e8a48a05e9624798a66b82795c401f84", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": 0.14, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-e891c9fd8986410a806f80ba59238880", + "kind": "move", + "generation": 5, + "native_time_s": 14.938000000001658, + "native_steps": 951, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38448407128571205, + "state_sha256": "451ed25d727f1acf2e8d38507093aa9de9aa8c055c51ffe0832c2fa72f225858" + }, + "challenge_image_sha256": "c62187cd908d71592bdd7193b83ec80666e6f350e90968204d2d87a7169d12dc" + }, + { + "sequence": 33, + "job_id": "ai-ordinary", + "generation": 5, + "proposal": { + "action": "move", + "challenge_id": "challenge-98c4443f685c43bca0555096bbe64d57", + "intent": "Push left from the block's right side, bringing its center back into the home region near x=-0.12.", + "observation_sha256": "a09ead8b0c746828364df389adba823a8de3851c166deebff772d7f06562003a", + "operation_id": "agent-eecc4e58e7ae47df8088761be7f5ea25", + "proposal_id": "proposal-92ef08cad3d549d4a63649d345b5daa1", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.065, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-eecc4e58e7ae47df8088761be7f5ea25", + "kind": "move", + "generation": 6, + "native_time_s": 17.306000000001287, + "native_steps": 1184, + "pusher_block_contact_samples": 3108, + "max_axis_actuator_force_n": 1.346867858248153, + "state_sha256": "a1b40541b3203c3066b0020b486ff538bdf4fee5604232eb0a2ab425ce7383d7" + }, + "challenge_image_sha256": "e6f35d68a39eccb69ef08ffb81de2aed231bbe097a530bc31bb48ffda662a3f1" + }, + { + "sequence": 37, + "job_id": "ai-ordinary", + "generation": 6, + "proposal": { + "action": "move", + "challenge_id": "challenge-3abc7266237042b68e06877018787ccd", + "intent": "The block is back at home; back the pusher slightly right to release contact before going around it.", + "observation_sha256": "27add33dac2fb680e42be390ee8c161959090d554e00e341b075af6b7dc828ed", + "operation_id": "agent-3c86afdd8a704441a66a717fabb9ad30", + "proposal_id": "proposal-b85d03dc400444c082fdecbab78e9a37", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.035, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-3c86afdd8a704441a66a717fabb9ad30", + "kind": "move", + "generation": 7, + "native_time_s": 18.50800000000062, + "native_steps": 601, + "pusher_block_contact_samples": 66, + "max_axis_actuator_force_n": 0.5646407287582988, + "state_sha256": "1302ea1009ef1d9d21b30ced5086ad9dc29b48de393d967df67e3ee5b7ac1a81" + }, + "challenge_image_sha256": "6c4785ad11fbf959867ca24381e9caf3a051c777b86c8e5357697aa2cdea5f67" + }, + { + "sequence": 41, + "job_id": "ai-ordinary", + "generation": 7, + "proposal": { + "action": "move", + "challenge_id": "challenge-d5633b65146f4065bb710dda3ee037dd", + "intent": "There is now a visible gap beside the home block; lift the pusher into the bypass lane without dragging it.", + "observation_sha256": "e21f0e55f8037de4d27502219301f2b0083a00a91c692b99ba9141591d2e1eda", + "operation_id": "agent-1f592c90c3b74e08bc1620fe7067c84c", + "proposal_id": "proposal-f07bff4deb78444898958ab4dc5734dc", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.035, + "target_y": 0.135 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-1f592c90c3b74e08bc1620fe7067c84c", + "kind": "move", + "generation": 8, + "native_time_s": 20.409999999999567, + "native_steps": 951, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38448407128570206, + "state_sha256": "3624577cb56ac84d63ed54a8a7d8d3dbfbb3cec0060bc2605f9af177790e155a" + }, + "challenge_image_sha256": "6a03bda6c21d45a6c0de319fa273262335ebcf36de34e1f4a41bee1604479d49" + }, + { + "sequence": 45, + "job_id": "ai-ordinary", + "generation": 8, + "proposal": { + "action": "move", + "challenge_id": "challenge-ccab1d2dc0e345ee9071c7fbdcb72f95", + "intent": "The pusher is above the block; traverse left through the clear bypass lane toward its home column.", + "observation_sha256": "432fd403dc293c58ebba6f62f8b83375a6912f1ebca74e9f1255e146123a203c", + "operation_id": "agent-94497e62b78c470588dde1d8788ed008", + "proposal_id": "proposal-7ac22a5b098b44aa83322a3b25eeff64", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.3, + "target_y": 0.135 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-94497e62b78c470588dde1d8788ed008", + "kind": "move", + "generation": 9, + "native_time_s": 23.177999999998033, + "native_steps": 1384, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38504787816081887, + "state_sha256": "0c6cbcb3b882d727eff2c704d68a051975a1e937c3679af12f3191993d40a051" + }, + "challenge_image_sha256": "fa76012ace8a01cde6bb10e4742798a428ccbd9a868bf7bc97a9447e0cfc866e" + }, + { + "sequence": 49, + "job_id": "ai-ordinary", + "generation": 9, + "proposal": { + "action": "move", + "challenge_id": "challenge-7851634f3566401f954ebae1f6e29e88", + "intent": "The pusher has cleared the block on the left; descend to its home position.", + "observation_sha256": "18828d79e20f454ceb7e1c0692b20736f6e8ce090292c6eaa4b838e9fbe957d6", + "operation_id": "agent-e088c59467614556aaea8da9b9c8d32d", + "proposal_id": "proposal-026bb7d6f7f340ed960566c81bac830c", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.3, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-e088c59467614556aaea8da9b9c8d32d", + "kind": "move", + "generation": 10, + "native_time_s": 25.07999999999698, + "native_steps": 951, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38448407128571205, + "state_sha256": "aafe7bd44fe197a436c786478e803f5600e9356a85b524d8f8ba32237c0f8efc" + }, + "challenge_image_sha256": "cda2378ead3e165186825aa560540c8495d01f07acff067406513a16ee92db65" + }, + { + "sequence": 53, + "job_id": "ai-ordinary", + "generation": 10, + "proposal": { + "action": "finish_reset", + "challenge_id": "challenge-93a8a4f678e947648e4fa8062ce4203b", + "intent": "The image shows the orange block in its home region and the blue pusher at home; request independent reset verification.", + "observation_sha256": "56b763e47095f854b68d2788490b3bb1aabd55b94628db7d191ba264e9125797", + "operation_id": "agent-c0a81c03a9114aa2b68b127755699f4c", + "proposal_id": "proposal-1d2f0b6f0dde4fd4af7b38314b3ee4ff", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": null, + "target_y": null + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-c0a81c03a9114aa2b68b127755699f4c", + "kind": "finish_reset", + "generation": 10, + "native_time_s": 25.07999999999698, + "state_sha256": "aafe7bd44fe197a436c786478e803f5600e9356a85b524d8f8ba32237c0f8efc", + "block_home_verified": true, + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8940 + }, + "challenge_image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87" + }, + { + "sequence": 58, + "job_id": "ai-disturbed", + "generation": 10, + "proposal": { + "action": "move", + "challenge_id": "challenge-4af4aec17ab440c48a0852b7041b60d0", + "intent": "Push the home block into the second job's green region, which is slightly farther right than the first target.", + "observation_sha256": "52fd733ecb953954823b1aed211fdab04665dd55423b11e3cb525d4b57f97264", + "operation_id": "agent-60980668f692471f8a01870d0547380a", + "proposal_id": "proposal-ddd3e71640aa402bbb40883d692c4f4f", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": 0.025, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-60980668f692471f8a01870d0547380a", + "kind": "move", + "generation": 11, + "native_time_s": 28.247999999995223, + "native_steps": 1584, + "pusher_block_contact_samples": 3178, + "max_axis_actuator_force_n": 1.3153962165348574, + "state_sha256": "3e55b7e0bf2ef8517aaf3066b75ee6a6433a92aa15dbb4f8f5d788beab29f821" + }, + "challenge_image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + { + "sequence": 62, + "job_id": "ai-disturbed", + "generation": 11, + "proposal": { + "action": "move", + "challenge_id": "challenge-1ce07c2c0e8b4af0897468a2d7aabfb0", + "intent": "The block appears centered in the new green region; pull the pusher left away from contact before measuring.", + "observation_sha256": "c385b080a7448784f2e6bbb13ab9a21a5ddbf8ac0c7bc2ff7d54a6fd361efd3b", + "operation_id": "agent-184b6f968ae04876917143e5a717fb7a", + "proposal_id": "proposal-4756082b5edc4f24b076334707a98d64", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.3, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-184b6f968ae04876917143e5a717fb7a", + "kind": "move", + "generation": 12, + "native_time_s": 31.415999999993467, + "native_steps": 1584, + "pusher_block_contact_samples": 66, + "max_axis_actuator_force_n": 0.569265513047462, + "state_sha256": "c5eb98e5389520f67d0a5696115aa8d7d7a2ae63ded866d4f74b1716a02128fc" + }, + "challenge_image_sha256": "0d42c93fef97b6bf1ded19965b65518e43b873916c9e8bc1d8300debf130f9fa" + }, + { + "sequence": 66, + "job_id": "ai-disturbed", + "generation": 12, + "proposal": { + "action": "measure", + "challenge_id": "challenge-c2d34501db714daa970aa0cfa132270a", + "intent": "The latest image shows the block prepared in the second measurement region with the pusher clear; measure it.", + "observation_sha256": "2a65106d4fae92eaf4041ed249ef41fb2c5c35004002fe3189977d8511f53d91", + "operation_id": "agent-1651b0bc149b40c5bf581c666d4f99e1", + "proposal_id": "proposal-28b240a0c5e944c8b2ab0e793835d374", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": null, + "target_y": null + }, + "outcome": "refused", + "reason": "observation is stale or foreign; no requested effect dispatched", + "receipt_summary": {}, + "challenge_image_sha256": "126a049946a82dda474c3ec72f2da13b50e2a5e5d1686cc4c408251f75e06d9d" + }, + { + "sequence": 70, + "job_id": "ai-disturbed", + "generation": 13, + "proposal": { + "action": "move", + "challenge_id": "challenge-0a4a355152664f8690b4e6cc5c4d03c4", + "intent": "The fresh image shows the block displaced left of the green region while the pusher remains left; push it right back toward the target center.", + "observation_sha256": "ad507cb4b1ecd5fac93a34b3680eb581d0eafbefea96e16d18ee59c4e916afdc", + "operation_id": "agent-069bca35f676423a99b8ce98a5fc1061", + "proposal_id": "proposal-b1d32f971dcc4472a9382e1c4303c4a2", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": 0.028, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-069bca35f676423a99b8ce98a5fc1061", + "kind": "move", + "generation": 14, + "native_time_s": 35.76399999999774, + "native_steps": 1594, + "pusher_block_contact_samples": 2794, + "max_axis_actuator_force_n": 1.371068465268717, + "state_sha256": "fec6ff3846f7112235a07ec03a974ba3468ba9852bc9e7ebf63f572dda064cf4" + }, + "challenge_image_sha256": "ba1d19598b817acd57a746150d30d4755b48a80287fd362d3a24ce6a0e244d45" + }, + { + "sequence": 74, + "job_id": "ai-disturbed", + "generation": 14, + "proposal": { + "action": "move", + "challenge_id": "challenge-48c16468357b44d4a3565bf9e8511e1e", + "intent": "The corrective push has brought the block back to the green region; clear the pusher left before a fresh measurement.", + "observation_sha256": "59569198225d2fcadd937aebee144237c640e0be9f328b072e7bea1fa7aee7ce", + "operation_id": "agent-47235fb2ba1e483db4fd3985073c7f12", + "proposal_id": "proposal-d31079ad8f9b41df9d9693fed7b1d10c", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.3, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-47235fb2ba1e483db4fd3985073c7f12", + "kind": "move", + "generation": 15, + "native_time_s": 38.95200000000164, + "native_steps": 1594, + "pusher_block_contact_samples": 66, + "max_axis_actuator_force_n": 0.5679920156839486, + "state_sha256": "4dd44356d2ac0116aed5dbff1f314ddf300da024850c26ad61191a1672b895c9" + }, + "challenge_image_sha256": "6fc50ac16b71d7a5f11e88c85c3fa2ef13df8374291e764e5e3c7213a38f8c25" + }, + { + "sequence": 78, + "job_id": "ai-disturbed", + "generation": 15, + "proposal": { + "action": "measure", + "challenge_id": "challenge-5a89495500094ccda58a991a9a27f494", + "intent": "The fresh image verifies recovered placement with the pusher clear; measure this current state rather than retrying the stale proposal.", + "observation_sha256": "d5e448fbe007cc42f9bf85384f5b77046b5b366b38f9016c64375dc832b5d10e", + "operation_id": "agent-5dd59ada282f46c6aa679674b91c2983", + "proposal_id": "proposal-653340c1067b4593b341d0a5c17f5fe3", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": null, + "target_y": null + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-5dd59ada282f46c6aa679674b91c2983", + "kind": "measure", + "generation": 15, + "state_sha256": "4dd44356d2ac0116aed5dbff1f314ddf300da024850c26ad61191a1672b895c9" + }, + "challenge_image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f" + }, + { + "sequence": 82, + "job_id": "ai-disturbed", + "generation": 15, + "proposal": { + "action": "begin_reset", + "challenge_id": "challenge-e8114cfa482c4499ada30283ad6d51aa", + "intent": "The recovered measurement has been saved and verified; start the second job's contact reset.", + "observation_sha256": "96291545eb9577454635f8003039c389aa429bc02d088dd420ee27f0da2f9139", + "operation_id": "agent-cd76880c390b4870804c1752de7787ee", + "proposal_id": "proposal-f730ddc0014d4c8cbc2ab377fc58d592", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": null, + "target_y": null + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "generation": 15, + "native_time_s": 38.95200000000164 + }, + "challenge_image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f" + }, + { + "sequence": 86, + "job_id": "ai-disturbed", + "generation": 15, + "proposal": { + "action": "move", + "challenge_id": "challenge-a5477a6495ee49c991b30693bdd152ab", + "intent": "Lift the home pusher into the clear upper lane to approach the recovered block from the right.", + "observation_sha256": "dffc9cb0085484f265fd45c35b1d5641912e2f85ee453cd5294d9e52dd017b44", + "operation_id": "agent-b2b139c73743438a88f7d8fdd6b69ae6", + "proposal_id": "proposal-bbfb051bac274a30a9883640b7163e88", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.3, + "target_y": 0.135 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-b2b139c73743438a88f7d8fdd6b69ae6", + "kind": "move", + "generation": 16, + "native_time_s": 40.854000000003964, + "native_steps": 951, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38448407128570206, + "state_sha256": "96ea71954529f457c436bd3374a38c98f1c8354db6ced335c39ae71a6d815a9a" + }, + "challenge_image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f" + }, + { + "sequence": 90, + "job_id": "ai-disturbed", + "generation": 16, + "proposal": { + "action": "move", + "challenge_id": "challenge-8132b582443e4392b135133800f6b3c9", + "intent": "The pusher is clear above the block; cross right far enough to leave a gap beside the second target's block.", + "observation_sha256": "78923d47db657e6c3f2d4793eddd26247e254bb64c3f71414cabeee413f6cc49", + "operation_id": "agent-31f5d3447bdc4c959f8fcebcda292837", + "proposal_id": "proposal-26c0c918565744a78dd5e62adca22618", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": 0.155, + "target_y": 0.135 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-31f5d3447bdc4c959f8fcebcda292837", + "kind": "move", + "generation": 17, + "native_time_s": 44.888000000008894, + "native_steps": 2017, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38525380916615404, + "state_sha256": "73f71645ea2ac92f6ee314c4208739ee09cde971373bf3afc8c0d2ca5456179a" + }, + "challenge_image_sha256": "9c6a5951995c9196fd2cb636f7cf6d44888a91202dc61bcf74b3097a0923830c" + }, + { + "sequence": 94, + "job_id": "ai-disturbed", + "generation": 17, + "proposal": { + "action": "move", + "challenge_id": "challenge-98023517d0234bca96066852a972469d", + "intent": "The blue pusher is beyond the orange block's right face; descend into the pushing lane while keeping that clearance.", + "observation_sha256": "19b732785404802032a73291f1b61efeb7b05e112feb65dc04ae2e71be48de0d", + "operation_id": "agent-ade0665e21b74c3a888bc087b70df0e7", + "proposal_id": "proposal-599e463aa13545c9961af251ce562581", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": 0.155, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-ade0665e21b74c3a888bc087b70df0e7", + "kind": "move", + "generation": 18, + "native_time_s": 46.79000000001122, + "native_steps": 951, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38448407128571205, + "state_sha256": "66f43add681d9afd93b778fee054d903b0be84d874a7c944b296f6a8fb14d418" + }, + "challenge_image_sha256": "184c403f4a7eeccbd82ba7247128604e475e92229f2db1d6c96595d7fbdd0941" + }, + { + "sequence": 98, + "job_id": "ai-disturbed", + "generation": 18, + "proposal": { + "action": "move", + "challenge_id": "challenge-4d9640297ce040beac29488d78a43013", + "intent": "Push the recovered block left from its right side until its center returns to the home region.", + "observation_sha256": "2edf60f18ae1b4be9e3536086c02d267ec09c2a972c3dd8da23fd679d05b1f08", + "operation_id": "agent-e75a593f49e44507bb78388cf36a687e", + "proposal_id": "proposal-b955e6b92c10430eb6bc1c05d15feeaf", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.065, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-e75a593f49e44507bb78388cf36a687e", + "kind": "move", + "generation": 19, + "native_time_s": 49.258000000014235, + "native_steps": 1234, + "pusher_block_contact_samples": 3140, + "max_axis_actuator_force_n": 1.2698356367073558, + "state_sha256": "a0f0ec383589971e1a03613b651bb9b030fb16d15642875f5554b664be229fb4" + }, + "challenge_image_sha256": "3ef275d26144f92492c90735f8bebdd5cfdcc989da6423ae83715a010873d5f8" + }, + { + "sequence": 102, + "job_id": "ai-disturbed", + "generation": 19, + "proposal": { + "action": "move", + "challenge_id": "challenge-20c6400e862f450684f04802b6e8cb11", + "intent": "The block is at home again; release the pusher's right-side contact before moving it around the block.", + "observation_sha256": "1ba35b89bcd2551e61231066feb5d688806a5be3916fe599ff08dd847518e5a5", + "operation_id": "agent-d2ea0866d79243d998331c5f7ba4b0e5", + "proposal_id": "proposal-8e37df41a1bf47c4bbbbbcf29266c18b", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.035, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-d2ea0866d79243d998331c5f7ba4b0e5", + "kind": "move", + "generation": 20, + "native_time_s": 50.460000000015704, + "native_steps": 601, + "pusher_block_contact_samples": 66, + "max_axis_actuator_force_n": 0.5646353795216896, + "state_sha256": "44f23a1582a444feccb9c870e249463f06b097700bac4b5a471964a8fdefc14f" + }, + "challenge_image_sha256": "bf70dba8e16f7cc3324ef2e5e39d2d5408b83df9f0c03f2f446a57659cb8255a" + }, + { + "sequence": 106, + "job_id": "ai-disturbed", + "generation": 20, + "proposal": { + "action": "move", + "challenge_id": "challenge-6ecc3179fac541d48f6c295b638a8a16", + "intent": "The gap beside the home block is clear; lift the pusher into the bypass lane for its return.", + "observation_sha256": "11c5e1c85f31671ec78c8f20be556a3940fad0a838ca924c53b9ffd8ed8cf8b4", + "operation_id": "agent-445f007c1d7e4533b5ca3e26c25b3f4f", + "proposal_id": "proposal-58c8f40bc83b47eb975aeeda1762123e", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.035, + "target_y": 0.135 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-445f007c1d7e4533b5ca3e26c25b3f4f", + "kind": "move", + "generation": 21, + "native_time_s": 52.36200000001803, + "native_steps": 951, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38448407128570206, + "state_sha256": "fa265d62672cca23c53812efa31387d66592aa20bef95347a97743dbfd86db2e" + }, + "challenge_image_sha256": "6f0d26dda31720cc658216254a63289a4e7804cb2339d2a7489e0365be6f3114" + }, + { + "sequence": 110, + "job_id": "ai-disturbed", + "generation": 21, + "proposal": { + "action": "move", + "challenge_id": "challenge-e7b2a397392a416c9bedd0dd02496dd1", + "intent": "Cross left above the block, keeping vertical clearance until the pusher reaches its home column.", + "observation_sha256": "ead667059eb30587f4e4644db3b4395669edd7ddb304978bac7eaae418eda53e", + "operation_id": "agent-4fa1490cdd1048ecb09a04719ecbb068", + "proposal_id": "proposal-c786d2479b654bb39beefb874fbd61be", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.3, + "target_y": 0.135 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-4fa1490cdd1048ecb09a04719ecbb068", + "kind": "move", + "generation": 22, + "native_time_s": 55.13000000002141, + "native_steps": 1384, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38504787816081887, + "state_sha256": "793337af114683113d0dbbb19022f7b01d00569444efb89c7f11f1b091b69c92" + }, + "challenge_image_sha256": "1505aeadca7409c872c4e3edf9a58508ad3c89e3f5911644449d5f542117d248" + }, + { + "sequence": 114, + "job_id": "ai-disturbed", + "generation": 22, + "proposal": { + "action": "move", + "challenge_id": "challenge-b0dca65c9e7a434a8dad5ea5fd803784", + "intent": "The pusher is safely left of the block; return it downward to its home position.", + "observation_sha256": "6190a3ace769eb3de80e4fdc76f524591d9072ea8284c233454631c21efcdf53", + "operation_id": "agent-6e0ac39e73c046f3b6270133fbff055c", + "proposal_id": "proposal-d555c91721ed4ed2992bb92aaf808a53", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": -0.3, + "target_y": 0.0 + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-6e0ac39e73c046f3b6270133fbff055c", + "kind": "move", + "generation": 23, + "native_time_s": 57.032000000023736, + "native_steps": 951, + "pusher_block_contact_samples": 0, + "max_axis_actuator_force_n": 0.38448407128571205, + "state_sha256": "6eecc4d33c156d2bc623608fecc63b5c4282a95fd37c531bf87ec5571d073f30" + }, + "challenge_image_sha256": "94f2de9164d14475774f68d3f5860562d35d3bd09ff9f26349f1d6a4008db583" + }, + { + "sequence": 118, + "job_id": "ai-disturbed", + "generation": 23, + "proposal": { + "action": "finish_reset", + "challenge_id": "challenge-9292c66d94af4c4b93b74f186a0262c3", + "intent": "Both visible bodies have returned home after recovery and measurement; verify and complete the second reset.", + "observation_sha256": "877139c7001ac604742bfdbc012509a0d1489d468fdebad0d2a39a8ad04dd793", + "operation_id": "agent-1fc92aa65ba3418eb400ecf69497e103", + "proposal_id": "proposal-dbeab904c5274b8ab4d351a2800ca15f", + "session_id": "e663f891cbb84bb5ba355213708165af", + "target_x": null, + "target_y": null + }, + "outcome": "executed", + "reason": null, + "receipt_summary": { + "operation_id": "agent-1fc92aa65ba3418eb400ecf69497e103", + "kind": "finish_reset", + "generation": 23, + "native_time_s": 57.032000000023736, + "state_sha256": "6eecc4d33c156d2bc623608fecc63b5c4282a95fd37c531bf87ec5571d073f30", + "block_home_verified": true, + "pusher_home_verified": true, + "reset_contact_samples": 3206, + "reset_native_steps": 9040 + }, + "challenge_image_sha256": "a834aeb17495159a215c0d6a51becde2e50afd38f47316aaa1a8c414d4af0bd4" + } + ] +} diff --git a/jevdual/results/agent-visual-bench-20261011/AI-observations.gif b/jevdual/results/agent-visual-bench-20261011/AI-observations.gif new file mode 100644 index 0000000000000000000000000000000000000000..c40c70f81599ac7405238280c8a084e7b1e9df8a GIT binary patch literal 147083 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ʎ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 literal 0 HcmV?d00001 diff --git a/jevdual/results/agent-visual-bench-20261011/before-disturbance.png b/jevdual/results/agent-visual-bench-20261011/before-disturbance.png new file mode 100644 index 0000000000000000000000000000000000000000..a911ebcf17c1822f4e3c27c1fb98f4c5aa4b94fd GIT binary patch literal 109630 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 LM{Vk@NEiPHY65?f literal 0 HcmV?d00001 diff --git a/jevdual/results/agent-visual-bench-20261011/checks.json b/jevdual/results/agent-visual-bench-20261011/checks.json new file mode 100644 index 0000000..eeeee0c --- /dev/null +++ b/jevdual/results/agent-visual-bench-20261011/checks.json @@ -0,0 +1,58 @@ +{ + "source_commit": "9a5d2f8bfac8088b13c63052887e0c0c2e9d5c7e", + "suites": [ + { + "path": "tools/physical-workcell/output/a7-suite-b8f88806f5/suite.log", + "sha256": "3741e670a91f357e7b81797caa1edba642e5a7b70578158de73cb429e148b7cb", + "count": 15, + "elapsed_s": 2.749, + "passed": true, + "tests": [ + "test_challenge_has_only_images_task_and_public_observation", + "test_changed_challenge_image_refuses", + "test_changed_proposal_refuses_before_dispatch", + "test_error_after_real_move_stays_unknown_even_if_bench_ready", + "test_foreign_challenge_and_unsafe_identity_refuse", + "test_measurement_placement_refusal_does_not_create_sqlite", + "test_measurement_worker_failure_retains_unknown_and_blocks_replay", + "test_move_executes_once_duplicate_returns_exact_result", + "test_nonfinite_and_conflicting_arguments_never_create_proposal", + "test_proposal_persists_intent_without_effect", + "test_public_cli_measurement_reset_and_status_strip_detector_locations", + "test_source_change_and_foreign_bench_identity_block_dispatch", + "test_stale_move_refuses_and_returns_fresh_image", + "test_unresolved_intent_blocks_same_and_new_proposal", + "test_wrong_reset_phase_preserves_bench" + ] + }, + { + "path": "tools/physical-workcell/output/sim7-final-checks/bench.log", + "sha256": "55d4c5578d868e07b47b1274c41d54a180c4fa3a8cddc6bde5af8fd29b81a8a3", + "count": 14, + "elapsed_s": 3.888, + "passed": true, + "tests": [ + "test_corrupted_image_refuses_measurement_and_does_not_create_a_database", + "test_corrupted_native_state_never_causes_an_implicit_reset", + "test_corrupted_retained_model_refuses_without_recreating_the_body", + "test_corrupted_source_binding_refuses_without_a_new_generation", + "test_diagnostic_force_needs_explicit_enablement_and_finite_bounds", + "test_exact_motion_replay_retains_one_native_effect_and_conflicts_refuse", + "test_external_force_invalidates_stale_motion_and_measurement_before_dispatch", + "test_foreign_or_modified_observation_cannot_authorize_a_motion", + "test_measurement_column_corruption_is_not_hidden_by_an_unchanged_receipt", + "test_measurement_is_a_separate_process_with_exact_persisted_image_binding", + "test_measurement_receipt_corruption_refuses_historical_replay", + "test_measurement_replay_is_historical_and_does_not_run_another_worker", + "test_retained_interrupted_intent_blocks_all_new_dispatch", + "test_successive_job_gate_requires_measurement_and_verified_reset" + ] + } + ], + "total": 29, + "ruff": "passed", + "native_guards_unchanged": true, + "notebook": "passed", + "diff_check": "passed", + "redaction_files_changed": 0 +} diff --git a/jevdual/results/agent-visual-bench-20261011/cleanup.json b/jevdual/results/agent-visual-bench-20261011/cleanup.json new file mode 100644 index 0000000..cdfbb76 --- /dev/null +++ b/jevdual/results/agent-visual-bench-20261011/cleanup.json @@ -0,0 +1,19 @@ +{ + "background_controller_started": false, + "all_cli_and_measurement_processes_synchronous_and_waited": true, + "measurement_workers": [ + { + "job_id": "ai-ordinary", + "worker_pid": 84953, + "exit_code": 0 + }, + { + "job_id": "ai-disturbed", + "worker_pid": 87908, + "exit_code": 0 + } + ], + "final_bench_idle": true, + "unknown_outcomes": 0, + "evidence_retained": true +} diff --git a/jevdual/results/agent-visual-bench-20261011/frames.json b/jevdual/results/agent-visual-bench-20261011/frames.json new file mode 100644 index 0000000..4be59c7 --- /dev/null +++ b/jevdual/results/agent-visual-bench-20261011/frames.json @@ -0,0 +1,281 @@ +[ + { + "challenge_id": "challenge-e4339df93bb44cf9827aaa89ca5e2d0c", + "image_sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "generation": 0, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "prepare", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000000-0fcba1683fc2ca06.png" + }, + { + "challenge_id": "challenge-0a7f171f17d0440aba49e0b394ca6981", + "image_sha256": "cb4221e600bbb24aec549f49924fc9224876a1ad8d04159fe0cc3798658d8357", + "generation": 1, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "prepare", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000001-bad2078e152acd7a.png" + }, + { + "challenge_id": "challenge-b946ac2ff9d74070b5f3efbed673b58d", + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "generation": 2, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "prepare", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000002-332dd2be629a31e3.png" + }, + { + "challenge_id": "challenge-37730e6485b945b4a30e5ae544e5a91d", + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "generation": 2, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "measured", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000002-d77f175856925cf4.png" + }, + { + "challenge_id": "challenge-fe85036078c24be39d7e21b9ad462286", + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "generation": 2, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000002-0d491dd460366578.png" + }, + { + "challenge_id": "challenge-859f365ee5294dac81a68cf58fb8d5be", + "image_sha256": "09026909d3489122b3f84704a9072495ec2288b7ccd0e2d1f6029521293335ea", + "generation": 3, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000003-d2dcace5d1bb6a76.png" + }, + { + "challenge_id": "challenge-0e224d3ea5de42699bc1abc4e84d87b5", + "image_sha256": "c62187cd908d71592bdd7193b83ec80666e6f350e90968204d2d87a7169d12dc", + "generation": 4, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000004-5ed6501f87fe26b3.png" + }, + { + "challenge_id": "challenge-98c4443f685c43bca0555096bbe64d57", + "image_sha256": "e6f35d68a39eccb69ef08ffb81de2aed231bbe097a530bc31bb48ffda662a3f1", + "generation": 5, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000005-b554100267ea777c.png" + }, + { + "challenge_id": "challenge-3abc7266237042b68e06877018787ccd", + "image_sha256": "6c4785ad11fbf959867ca24381e9caf3a051c777b86c8e5357697aa2cdea5f67", + "generation": 6, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000006-3a09bfeb46845bbd.png" + }, + { + "challenge_id": "challenge-d5633b65146f4065bb710dda3ee037dd", + "image_sha256": "6a03bda6c21d45a6c0de319fa273262335ebcf36de34e1f4a41bee1604479d49", + "generation": 7, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000007-2709c62d9ef39660.png" + }, + { + "challenge_id": "challenge-ccab1d2dc0e345ee9071c7fbdcb72f95", + "image_sha256": "fa76012ace8a01cde6bb10e4742798a428ccbd9a868bf7bc97a9447e0cfc866e", + "generation": 8, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000008-61b275312f5615cc.png" + }, + { + "challenge_id": "challenge-7851634f3566401f954ebae1f6e29e88", + "image_sha256": "cda2378ead3e165186825aa560540c8495d01f07acff067406513a16ee92db65", + "generation": 9, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000009-9b921e5067762a87.png" + }, + { + "challenge_id": "challenge-93a8a4f678e947648e4fa8062ce4203b", + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "generation": 10, + "job_id": "ai-ordinary", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000010-ea9e6cc3a19e8a18.png" + }, + { + "challenge_id": "challenge-34408876d0a34de0a98301cb7f2ef02a", + "image_sha256": "c71216bf1c74a28b5e7475bf9af5afe4a22d62ee1aeb31c3ecf8dc62dbb591a8", + "generation": 10, + "job_id": null, + "tool": "view_image", + "phase": "idle", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000010-38e0b9de817f645c.png" + }, + { + "challenge_id": "challenge-4af4aec17ab440c48a0852b7041b60d0", + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "generation": 10, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "prepare", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000010-5295830fbdea7b61.png" + }, + { + "challenge_id": "challenge-1ce07c2c0e8b4af0897468a2d7aabfb0", + "image_sha256": "0d42c93fef97b6bf1ded19965b65518e43b873916c9e8bc1d8300debf130f9fa", + "generation": 11, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "prepare", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000011-48260e325fc6e5c5.png" + }, + { + "challenge_id": "challenge-c2d34501db714daa970aa0cfa132270a", + "image_sha256": "126a049946a82dda474c3ec72f2da13b50e2a5e5d1686cc4c408251f75e06d9d", + "generation": 12, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "prepare", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000012-a53794cdf5f55ea3.png" + }, + { + "challenge_id": "challenge-0a4a355152664f8690b4e6cc5c4d03c4", + "image_sha256": "ba1d19598b817acd57a746150d30d4755b48a80287fd362d3a24ce6a0e244d45", + "generation": 13, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "prepare", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000013-a53794cdf5f55ea3.png" + }, + { + "challenge_id": "challenge-48c16468357b44d4a3565bf9e8511e1e", + "image_sha256": "6fc50ac16b71d7a5f11e88c85c3fa2ef13df8374291e764e5e3c7213a38f8c25", + "generation": 14, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "prepare", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000014-c9d65316327fa7eb.png" + }, + { + "challenge_id": "challenge-5a89495500094ccda58a991a9a27f494", + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "generation": 15, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "prepare", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000015-eb4e1af60ee1ae89.png" + }, + { + "challenge_id": "challenge-e8114cfa482c4499ada30283ad6d51aa", + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "generation": 15, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "measured", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000015-bb47387aad541841.png" + }, + { + "challenge_id": "challenge-a5477a6495ee49c991b30693bdd152ab", + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "generation": 15, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000015-56e663affd1e3522.png" + }, + { + "challenge_id": "challenge-8132b582443e4392b135133800f6b3c9", + "image_sha256": "9c6a5951995c9196fd2cb636f7cf6d44888a91202dc61bcf74b3097a0923830c", + "generation": 16, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000016-34800b2a5f2c8244.png" + }, + { + "challenge_id": "challenge-98023517d0234bca96066852a972469d", + "image_sha256": "184c403f4a7eeccbd82ba7247128604e475e92229f2db1d6c96595d7fbdd0941", + "generation": 17, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000017-83ca05ae26421883.png" + }, + { + "challenge_id": "challenge-4d9640297ce040beac29488d78a43013", + "image_sha256": "3ef275d26144f92492c90735f8bebdd5cfdcc989da6423ae83715a010873d5f8", + "generation": 18, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000018-4d3178b6b72ca439.png" + }, + { + "challenge_id": "challenge-20c6400e862f450684f04802b6e8cb11", + "image_sha256": "bf70dba8e16f7cc3324ef2e5e39d2d5408b83df9f0c03f2f446a57659cb8255a", + "generation": 19, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000019-bd8d7b56f8897648.png" + }, + { + "challenge_id": "challenge-6ecc3179fac541d48f6c295b638a8a16", + "image_sha256": "6f0d26dda31720cc658216254a63289a4e7804cb2339d2a7489e0365be6f3114", + "generation": 20, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000020-125013457cb8308a.png" + }, + { + "challenge_id": "challenge-e7b2a397392a416c9bedd0dd02496dd1", + "image_sha256": "1505aeadca7409c872c4e3edf9a58508ad3c89e3f5911644449d5f542117d248", + "generation": 21, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000021-899159eed0d2cf4a.png" + }, + { + "challenge_id": "challenge-b0dca65c9e7a434a8dad5ea5fd803784", + "image_sha256": "94f2de9164d14475774f68d3f5860562d35d3bd09ff9f26349f1d6a4008db583", + "generation": 22, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000022-a1d8394031a01bc5.png" + }, + { + "challenge_id": "challenge-9292c66d94af4c4b93b74f186a0262c3", + "image_sha256": "a834aeb17495159a215c0d6a51becde2e50afd38f47316aaa1a8c414d4af0bd4", + "generation": 23, + "job_id": "ai-disturbed", + "tool": "view_image", + "phase": "resetting", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000023-5b88ee5f2a264bb0.png" + }, + { + "challenge_id": "challenge-f8ee1d62647e4bb3aa8b348d9b7f68ec", + "image_sha256": "9f67472a3681ba01ab6c8ee8ce7ea2a34bd816ba9c67c1ab0f36a01cc12ce597", + "generation": 23, + "job_id": null, + "tool": "view_image", + "phase": "idle", + "image_path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim7-ai-20261011-v1/bench/images/000023-38e0b9de817f645c.png" + } +] diff --git a/jevdual/results/agent-visual-bench-20261011/fresh-agent-status.json b/jevdual/results/agent-visual-bench-20261011/fresh-agent-status.json new file mode 100644 index 0000000..982b607 --- /dev/null +++ b/jevdual/results/agent-visual-bench-20261011/fresh-agent-status.json @@ -0,0 +1 @@ +{"bench": {"active_job": null, "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", "diagnostic_enabled": true, "generation": 23, "jobs": {"ai-disturbed": {"completed_generation": 23, "completed_native_time_s": 57.032000000023736, "job_id": "ai-disturbed", "measurement_operation_id": "agent-5dd59ada282f46c6aa679674b91c2983", "measurement_receipt": {"bench_id": "3e025aca6ea240f29003b7c6fdc91a39", "generation": 15, "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", "job_id": "ai-disturbed", "measurement": {"footprint_area_m2": 0.0049, "method": "simulated_orange_RGB_footprint", "orange_pixel_count": 1764}, "native_time_s": 38.95200000000164, "operation_id": "agent-5dd59ada282f46c6aa679674b91c2983", "source_kind": "mujoco_simulation", "state_sha256": "4dd44356d2ac0116aed5dbff1f314ddf300da024850c26ad61191a1672b895c9", "version": 1, "worker_pid": 87908}, "moves": 12, "phase": "completed", "reset_receipt": {"bench_id": "3e025aca6ea240f29003b7c6fdc91a39", "block_home_verified": true, "generation": 23, "image_sha256": "a834aeb17495159a215c0d6a51becde2e50afd38f47316aaa1a8c414d4af0bd4", "job_id": "ai-disturbed", "kind": "finish_reset", "native_time_s": 57.032000000023736, "operation_id": "agent-1fc92aa65ba3418eb400ecf69497e103", "pusher_home_verified": true, "reset_contact_samples": 3206, "reset_native_steps": 9040, "state_sha256": "6eecc4d33c156d2bc623608fecc63b5c4282a95fd37c531bf87ec5571d073f30"}, "reset_started_generation": 15, "started_generation": 10, "started_native_time_s": 25.07999999999698, "target_zone": {"x_max": 0.115, "x_min": 0.045, "y_max": 0.025, "y_min": -0.025}}, "ai-ordinary": {"completed_generation": 10, "completed_native_time_s": 25.07999999999698, "job_id": "ai-ordinary", "measurement_operation_id": "agent-62ebb86d89f941daab3a059aa53fd695", "measurement_receipt": {"bench_id": "3e025aca6ea240f29003b7c6fdc91a39", "generation": 2, "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", "job_id": "ai-ordinary", "measurement": {"footprint_area_m2": 0.004794444444444444, "method": "simulated_orange_RGB_footprint", "orange_pixel_count": 1726}, "native_time_s": 7.199999999999429, "operation_id": "agent-62ebb86d89f941daab3a059aa53fd695", "source_kind": "mujoco_simulation", "state_sha256": "17c6620f9eeb3b3c3a6e787215e843c7a8bfa66eb3c56f8693c3477b2eb5d9c9", "version": 1, "worker_pid": 84953}, "moves": 10, "phase": "completed", "reset_receipt": {"bench_id": "3e025aca6ea240f29003b7c6fdc91a39", "block_home_verified": true, "generation": 10, "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", "job_id": "ai-ordinary", "kind": "finish_reset", "native_time_s": 25.07999999999698, "operation_id": "agent-c0a81c03a9114aa2b68b127755699f4c", "pusher_home_verified": true, "reset_contact_samples": 3174, "reset_native_steps": 8940, "state_sha256": "aafe7bd44fe197a436c786478e803f5600e9356a85b524d8f8ba32237c0f8efc"}, "reset_started_generation": 2, "started_generation": 0, "started_native_time_s": 1.0000000000000007, "target_zone": {"x_max": 0.105, "x_min": 0.035, "y_max": 0.025, "y_min": -0.025}}}, "native_time_s": 57.032000000023736, "source_fingerprints": {"bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", "mujoco_version": "3.15.0", "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", "state_spec": 16383, "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961"}, "source_kind": "mujoco_simulation", "state": "ready", "unresolved_effect": null, "version": 1}, "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", "host_role": "external_multimodal_AI_host", "sequence": 118, "session_id": "e663f891cbb84bb5ba355213708165af", "source_fingerprints": {"agent_bench_sha256": "e120dbfc9a96ca07fedb15226f27282265203755866210b86d5f856f6e3f5e07", "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", "mujoco_version": "3.15.0", "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", "state_spec": 16383, "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961"}, "unresolved_proposals": []} diff --git a/jevdual/results/agent-visual-bench-20261011/harness-disturbance.json b/jevdual/results/agent-visual-bench-20261011/harness-disturbance.json new file mode 100644 index 0000000..734f62f --- /dev/null +++ b/jevdual/results/agent-visual-bench-20261011/harness-disturbance.json @@ -0,0 +1,16 @@ +{ + "prepared_proposal_id": "proposal-28b240a0c5e944c8b2ab0e793835d374", + "prior_challenge_id": "challenge-c2d34501db714daa970aa0cfa132270a", + "intervention": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "force_x_n": -1.5, + "forced_steps": 80, + "generation": 13, + "job_id": "ai-disturbed", + "kind": "diagnostic_external_force", + "native_steps": 580, + "native_time_s": 32.57599999999385, + "operation_id": "sim7-harness-force", + "state_sha256": "1816ee306f82952178fe88ac2857976ccd1594d917628fad36a438f79183280b" + } +} diff --git a/jevdual/results/agent-visual-bench-20261011/image-presentations.json b/jevdual/results/agent-visual-bench-20261011/image-presentations.json new file mode 100644 index 0000000..4419661 --- /dev/null +++ b/jevdual/results/agent-visual-bench-20261011/image-presentations.json @@ -0,0 +1,223 @@ +{ + "host": "Codex multimodal assistant in this conversation", + "scope": "images emitted via view_image to the active AI host; not cryptographic model attestation", + "views": [ + { + "challenge_id": "challenge-e4339df93bb44cf9827aaa89ca5e2d0c", + "image_sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "generation": 0, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-0a7f171f17d0440aba49e0b394ca6981", + "image_sha256": "cb4221e600bbb24aec549f49924fc9224876a1ad8d04159fe0cc3798658d8357", + "generation": 1, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-b946ac2ff9d74070b5f3efbed673b58d", + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "generation": 2, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-37730e6485b945b4a30e5ae544e5a91d", + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "generation": 2, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-fe85036078c24be39d7e21b9ad462286", + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "generation": 2, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-859f365ee5294dac81a68cf58fb8d5be", + "image_sha256": "09026909d3489122b3f84704a9072495ec2288b7ccd0e2d1f6029521293335ea", + "generation": 3, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-0e224d3ea5de42699bc1abc4e84d87b5", + "image_sha256": "c62187cd908d71592bdd7193b83ec80666e6f350e90968204d2d87a7169d12dc", + "generation": 4, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-98c4443f685c43bca0555096bbe64d57", + "image_sha256": "e6f35d68a39eccb69ef08ffb81de2aed231bbe097a530bc31bb48ffda662a3f1", + "generation": 5, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-3abc7266237042b68e06877018787ccd", + "image_sha256": "6c4785ad11fbf959867ca24381e9caf3a051c777b86c8e5357697aa2cdea5f67", + "generation": 6, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-d5633b65146f4065bb710dda3ee037dd", + "image_sha256": "6a03bda6c21d45a6c0de319fa273262335ebcf36de34e1f4a41bee1604479d49", + "generation": 7, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-ccab1d2dc0e345ee9071c7fbdcb72f95", + "image_sha256": "fa76012ace8a01cde6bb10e4742798a428ccbd9a868bf7bc97a9447e0cfc866e", + "generation": 8, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-7851634f3566401f954ebae1f6e29e88", + "image_sha256": "cda2378ead3e165186825aa560540c8495d01f07acff067406513a16ee92db65", + "generation": 9, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-93a8a4f678e947648e4fa8062ce4203b", + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "generation": 10, + "job_id": "ai-ordinary", + "tool": "view_image" + }, + { + "challenge_id": "challenge-34408876d0a34de0a98301cb7f2ef02a", + "image_sha256": "c71216bf1c74a28b5e7475bf9af5afe4a22d62ee1aeb31c3ecf8dc62dbb591a8", + "generation": 10, + "job_id": null, + "tool": "view_image" + }, + { + "challenge_id": "challenge-4af4aec17ab440c48a0852b7041b60d0", + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "generation": 10, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-1ce07c2c0e8b4af0897468a2d7aabfb0", + "image_sha256": "0d42c93fef97b6bf1ded19965b65518e43b873916c9e8bc1d8300debf130f9fa", + "generation": 11, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-c2d34501db714daa970aa0cfa132270a", + "image_sha256": "126a049946a82dda474c3ec72f2da13b50e2a5e5d1686cc4c408251f75e06d9d", + "generation": 12, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-0a4a355152664f8690b4e6cc5c4d03c4", + "image_sha256": "ba1d19598b817acd57a746150d30d4755b48a80287fd362d3a24ce6a0e244d45", + "generation": 13, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-48c16468357b44d4a3565bf9e8511e1e", + "image_sha256": "6fc50ac16b71d7a5f11e88c85c3fa2ef13df8374291e764e5e3c7213a38f8c25", + "generation": 14, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-5a89495500094ccda58a991a9a27f494", + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "generation": 15, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-e8114cfa482c4499ada30283ad6d51aa", + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "generation": 15, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-a5477a6495ee49c991b30693bdd152ab", + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "generation": 15, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-8132b582443e4392b135133800f6b3c9", + "image_sha256": "9c6a5951995c9196fd2cb636f7cf6d44888a91202dc61bcf74b3097a0923830c", + "generation": 16, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-98023517d0234bca96066852a972469d", + "image_sha256": "184c403f4a7eeccbd82ba7247128604e475e92229f2db1d6c96595d7fbdd0941", + "generation": 17, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-4d9640297ce040beac29488d78a43013", + "image_sha256": "3ef275d26144f92492c90735f8bebdd5cfdcc989da6423ae83715a010873d5f8", + "generation": 18, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-20c6400e862f450684f04802b6e8cb11", + "image_sha256": "bf70dba8e16f7cc3324ef2e5e39d2d5408b83df9f0c03f2f446a57659cb8255a", + "generation": 19, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-6ecc3179fac541d48f6c295b638a8a16", + "image_sha256": "6f0d26dda31720cc658216254a63289a4e7804cb2339d2a7489e0365be6f3114", + "generation": 20, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-e7b2a397392a416c9bedd0dd02496dd1", + "image_sha256": "1505aeadca7409c872c4e3edf9a58508ad3c89e3f5911644449d5f542117d248", + "generation": 21, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-b0dca65c9e7a434a8dad5ea5fd803784", + "image_sha256": "94f2de9164d14475774f68d3f5860562d35d3bd09ff9f26349f1d6a4008db583", + "generation": 22, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-9292c66d94af4c4b93b74f186a0262c3", + "image_sha256": "a834aeb17495159a215c0d6a51becde2e50afd38f47316aaa1a8c414d4af0bd4", + "generation": 23, + "job_id": "ai-disturbed", + "tool": "view_image" + }, + { + "challenge_id": "challenge-f8ee1d62647e4bb3aa8b348d9b7f68ec", + "image_sha256": "9f67472a3681ba01ab6c8ee8ce7ea2a34bd816ba9c67c1ab0f36a01cc12ce597", + "generation": 23, + "job_id": null, + "tool": "view_image" + } + ] +} diff --git a/jevdual/results/agent-visual-bench-20261011/native-sqlite-score.json b/jevdual/results/agent-visual-bench-20261011/native-sqlite-score.json new file mode 100644 index 0000000..5a8f18f --- /dev/null +++ b/jevdual/results/agent-visual-bench-20261011/native-sqlite-score.json @@ -0,0 +1,422 @@ +{ + "attempt": 1, + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "completed_cycles": 2, + "current_status": { + "active_job": null, + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "diagnostic_enabled": true, + "generation": 23, + "jobs": { + "ai-disturbed": { + "completed_generation": 23, + "completed_native_time_s": 57.032000000023736, + "job_id": "ai-disturbed", + "measurement_operation_id": "agent-5dd59ada282f46c6aa679674b91c2983", + "measurement_receipt": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "generation": 15, + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "job_id": "ai-disturbed", + "measurement": { + "block_box": [ + 346, + 159, + 388, + 201 + ], + "block_center_xy": [ + 0.07833333333333332, + 0.0 + ], + "centroid_pixel_xy": [ + 366.5, + 179.5 + ], + "footprint_area_m2": 0.0049, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1764 + }, + "native_time_s": 38.95200000000164, + "operation_id": "agent-5dd59ada282f46c6aa679674b91c2983", + "source_kind": "mujoco_simulation", + "state_sha256": "4dd44356d2ac0116aed5dbff1f314ddf300da024850c26ad61191a1672b895c9", + "version": 1, + "worker_pid": 87908 + }, + "moves": 12, + "phase": "completed", + "reset_receipt": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "block_home_verified": true, + "generation": 23, + "image_sha256": "a834aeb17495159a215c0d6a51becde2e50afd38f47316aaa1a8c414d4af0bd4", + "job_id": "ai-disturbed", + "kind": "finish_reset", + "native_time_s": 57.032000000023736, + "operation_id": "agent-1fc92aa65ba3418eb400ecf69497e103", + "pusher_home_verified": true, + "reset_contact_samples": 3206, + "reset_native_steps": 9040, + "state_sha256": "6eecc4d33c156d2bc623608fecc63b5c4282a95fd37c531bf87ec5571d073f30" + }, + "reset_started_generation": 15, + "started_generation": 10, + "started_native_time_s": 25.07999999999698, + "target_zone": { + "x_max": 0.115, + "x_min": 0.045, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "ai-ordinary": { + "completed_generation": 10, + "completed_native_time_s": 25.07999999999698, + "job_id": "ai-ordinary", + "measurement_operation_id": "agent-62ebb86d89f941daab3a059aa53fd695", + "measurement_receipt": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "generation": 2, + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "job_id": "ai-ordinary", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 7.199999999999429, + "operation_id": "agent-62ebb86d89f941daab3a059aa53fd695", + "source_kind": "mujoco_simulation", + "state_sha256": "17c6620f9eeb3b3c3a6e787215e843c7a8bfa66eb3c56f8693c3477b2eb5d9c9", + "version": 1, + "worker_pid": 84953 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "ai-ordinary", + "kind": "finish_reset", + "native_time_s": 25.07999999999698, + "operation_id": "agent-c0a81c03a9114aa2b68b127755699f4c", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8940, + "state_sha256": "aafe7bd44fe197a436c786478e803f5600e9356a85b524d8f8ba32237c0f8efc" + }, + "reset_started_generation": 2, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 57.032000000023736, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "passed": true, + "scope": "native/SQLite post-trial scoring; AI image consumption/proposals are separately recorded in the session", + "scores": [ + { + "job_id": "ai-ordinary", + "measurement": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "generation": 2, + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "job_id": "ai-ordinary", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 7.199999999999429, + "operation_id": "agent-62ebb86d89f941daab3a059aa53fd695", + "source_kind": "mujoco_simulation", + "state_sha256": "17c6620f9eeb3b3c3a6e787215e843c7a8bfa66eb3c56f8693c3477b2eb5d9c9", + "version": 1, + "worker_pid": 84953 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06582866319694268, + -8.41323830075274e-11, + 0.034995730455369696 + ], + "external_force_cleared": true, + "generation": 2, + "native_time_s": 7.199999999999429, + "pusher_home": true, + "pusher_xyz": [ + -0.2999999692200571, + 2.026020754412724e-35, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "17c6620f9eeb3b3c3a6e787215e843c7a8bfa66eb3c56f8693c3477b2eb5d9c9" + }, + "motion_count": 10, + "passed": true, + "reset": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "ai-ordinary", + "kind": "finish_reset", + "native_time_s": 25.07999999999698, + "operation_id": "agent-c0a81c03a9114aa2b68b127755699f4c", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8940, + "state_sha256": "aafe7bd44fe197a436c786478e803f5600e9356a85b524d8f8ba32237c0f8efc" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.1158277283874742, + -2.3639748691543634e-09, + 0.034995730455369786 + ], + "external_force_cleared": true, + "generation": 10, + "native_time_s": 25.07999999999698, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "aafe7bd44fe197a436c786478e803f5600e9356a85b524d8f8ba32237c0f8efc" + } + }, + { + "job_id": "ai-disturbed", + "measurement": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "generation": 15, + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "job_id": "ai-disturbed", + "measurement": { + "block_box": [ + 346, + 159, + 388, + 201 + ], + "block_center_xy": [ + 0.07833333333333332, + 0.0 + ], + "centroid_pixel_xy": [ + 366.5, + 179.5 + ], + "footprint_area_m2": 0.0049, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1764 + }, + "native_time_s": 38.95200000000164, + "operation_id": "agent-5dd59ada282f46c6aa679674b91c2983", + "source_kind": "mujoco_simulation", + "state_sha256": "4dd44356d2ac0116aed5dbff1f314ddf300da024850c26ad61191a1672b895c9", + "version": 1, + "worker_pid": 87908 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.07879828608478157, + -2.364032708257486e-09, + 0.03499573045536981 + ], + "external_force_cleared": true, + "generation": 15, + "native_time_s": 38.95200000000164, + "pusher_home": true, + "pusher_xyz": [ + -0.29999996923881395, + -2.4295371105308154e-36, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "4dd44356d2ac0116aed5dbff1f314ddf300da024850c26ad61191a1672b895c9" + }, + "motion_count": 12, + "passed": true, + "reset": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "block_home_verified": true, + "generation": 23, + "image_sha256": "a834aeb17495159a215c0d6a51becde2e50afd38f47316aaa1a8c414d4af0bd4", + "job_id": "ai-disturbed", + "kind": "finish_reset", + "native_time_s": 57.032000000023736, + "operation_id": "agent-1fc92aa65ba3418eb400ecf69497e103", + "pusher_home_verified": true, + "reset_contact_samples": 3206, + "reset_native_steps": 9040, + "state_sha256": "6eecc4d33c156d2bc623608fecc63b5c4282a95fd37c531bf87ec5571d073f30" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11582602325339661, + -4.449925211827781e-09, + 0.03499573045536985 + ], + "external_force_cleared": true, + "generation": 23, + "native_time_s": 57.032000000023736, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "6eecc4d33c156d2bc623608fecc63b5c4282a95fd37c531bf87ec5571d073f30" + } + } + ], + "source_commit": "9a5d2f8bfac8088b13c63052887e0c0c2e9d5c7e", + "source_unchanged": true, + "sqlite": { + "count": 2, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "generation": 15, + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "job_id": "ai-disturbed", + "operation_id": "agent-5dd59ada282f46c6aa679674b91c2983", + "receipt": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "generation": 15, + "image_sha256": "b9a5cd587ca0afbcf85dbb7708030f9914fc7be82d9f29317563c4a7cd204e2f", + "job_id": "ai-disturbed", + "measurement": { + "block_box": [ + 346, + 159, + 388, + 201 + ], + "block_center_xy": [ + 0.07833333333333332, + 0.0 + ], + "centroid_pixel_xy": [ + 366.5, + 179.5 + ], + "footprint_area_m2": 0.0049, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1764 + }, + "native_time_s": 38.95200000000164, + "operation_id": "agent-5dd59ada282f46c6aa679674b91c2983", + "source_kind": "mujoco_simulation", + "state_sha256": "4dd44356d2ac0116aed5dbff1f314ddf300da024850c26ad61191a1672b895c9", + "version": 1, + "worker_pid": 87908 + }, + "state_sha256": "4dd44356d2ac0116aed5dbff1f314ddf300da024850c26ad61191a1672b895c9" + }, + { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "generation": 2, + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "job_id": "ai-ordinary", + "operation_id": "agent-62ebb86d89f941daab3a059aa53fd695", + "receipt": { + "bench_id": "3e025aca6ea240f29003b7c6fdc91a39", + "generation": 2, + "image_sha256": "8d5e38c9bbef1250112550bdea0dee41bd573dd7cb2d42278be9eeda5590b159", + "job_id": "ai-ordinary", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 7.199999999999429, + "operation_id": "agent-62ebb86d89f941daab3a059aa53fd695", + "source_kind": "mujoco_simulation", + "state_sha256": "17c6620f9eeb3b3c3a6e787215e843c7a8bfa66eb3c56f8693c3477b2eb5d9c9", + "version": 1, + "worker_pid": 84953 + }, + "state_sha256": "17c6620f9eeb3b3c3a6e787215e843c7a8bfa66eb3c56f8693c3477b2eb5d9c9" + } + ] + }, + "version": 1 +} diff --git a/jevdual/results/agent-visual-bench-20261011/recovered.png b/jevdual/results/agent-visual-bench-20261011/recovered.png new file mode 100644 index 0000000000000000000000000000000000000000..ff6006f9b7317dc815c847813d832f1e26b71956 GIT binary patch literal 109582 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 I9nnWN48{&B=*ko<6zQx>4 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�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%0AfiPzR0eTHI9KOOUCE12XSb z*a~YFyFtgL0W>w7|Lf-?{FJjir?&@nV~L3PN?=w7%D7MNmV{Y6w!D<9;E>@I)Ya?|clNp@BIfiG2d z=b}eibRx3e=Zw|-Qa#?{<Z(AiWeU!y$XGK3)!2@!K_kd2x z9l3txG>7^G=q}}9>qh_0hF|2ny+B(00#FuoMKj_eXAjqMQ|B#By(F0mANbe;$Fkl7 z2wQ@FQY~d#9!$rncYrB$$v+2YJb`&W7j;N(5>WYa5p45luCSX)Z)n|+HJ}I&A0*ok z$xIpifP_T11IYhUs>1+mWZOyAm?5(CF#MFaY5v8!qt;^M=)77qI3=Q!Rr}tKjAQDi z`bmV@j;HJiV2;$_h+($wtQ65Ko)Yf!4%Mk!CKEbSfzpc7h=jatFgsrV!tOyXYIfC> z$WqbKzZ>`{8Jo3f{2Ol}uea}(U%YO5S#&d%u_89lA2hSavm`uzCQU3tJbdQtkLy*D zihVila`|o|cY3XgKK$-czcd$(_vga5(Q@zG=cEQI-h?fWTaNv)!u8~rB5I`*R^BRV zrG5|%FjZK?lDvP{Ln%ebid)UCE@Bd`kZ?uhe6lf%w@d2=^I{M0*UxZ!d&1r2Y|f@| zr71Rx3EPN|+HS$}skYJx#QVU-U=JR*PL`Q>Sl~g?JY+Z?cHY;aiY~7X3LWwuM#0HX zr6z4j_-!g~@!C-k3htI@!R==gIyiD4?uy~MB)xM}ViGX?s3(&XFyPE22!{>8GezL$ zz0~l&x$R8|?PI9*g{%`II^HOm!6ag{+zT6Gc#R95)~D6}{R$+Ee?>_X$FTObHQ)e`Y^+WiWM?^MX0v#@&lMhTCDfYAnTvNUXsEMfEa64_TqIpBL(N-)=eZYX0p==L8+1yp`Y7-)P{xTK!i!XEt&N1g`{ zM|mDJNMP&5%61lzXdX(O-dI~FL5n-infCDRy^I*t%q^owdno!i?UuvemAmxO zhx|z=Gt!e~ME5B{#Y`a?c`4e`PB>|AFS@?qTPR0w=$;uj}AGRzW*MKUA-EQu+ZWz=%0J>k6BY56o>WSus4N z0XU+K+6Ymb3j7G|c|8@jh@)l_Fa}T17)AMLS*u6ULwvUt(IF-K3F6^1K}vy9*bqnN ze3{tUoAOABC7*FedO_qzqR>vwVu+FjMA4vRk;Q2m;RjrI`*wz z^_1qg;*pamaYq$)V~FMl!{=7|Y7>jm*SV*s=l=Do1kx#@Rx=RuaDeBVzM37+1C>;k z`*t|$_-?Dgh>}Mnq=*dh)#&2*5N49Ksu#BR*4dH2qH#MZj#nHvMZ%-A{A|W=9kLPUYOTl@<|O8B+p_YFyO2 z34gP9JCe^b5giKqW+K71eadD>WwHCl=o z(V02YKd5Eb8!6+ckr}zwY`WztG?)#0QGMWOwx*x4Ks3Eo=rjG;zQ+jCMIvWQTtmE? zA1gz{CWwH+-NVxU)TPIV@$>Cs9T8|7^5-RYZ5qU&zzDMK-0Z#`32%#m@vi2*;EVx3 zRCfdb?X5@*P4JXhJBATzbCZjG^AitTCh63rX}@Wcvu*s*V;<;b!F4;>;=1k6LGCNOBkl1gsE@MHsg4GNcvZ;T}s+ zMFlETKB3^T5@cN{t*Dh0XeFs>S%{zKHoueaP%Y!F@TX+l;^E^p?xb!bkEN&IPW-^s ztX#%>75p9+^%^qE!G*VFO}l^o@u%N?#%ZuS>n5>e&N9)usVnI{i^w|Z(s-(?l%QmS zn`z8cboG0RUG1+F)!5iTmlqQqu;s-oXH-SkE(=+0!v$Ie4^poC^H|L%DAT*8D{WQj z6V8g$w!})?J>DPpWV%rz< zgk~s+PlsoW_)%6H^51YnAwh|D?9G+H^QXcj_4M2Au7<3t4RM<&_tErQ5h_J{@L2t*{l(19dtJ$ArBt8*)->alU$zhnk#6(iI^I&}DB&*3YNg zfW2~2t0&ZfHx69ZA12NU7#|$asezr6jP7j#5V+%Kd@k3S>GKFeVX&_R%C6@lX)cf4 zD9|H?VE62vdAhju6n3;;%12W%LED&J6|A4NzKE%pzQ~Rn`*s#U=D`S^3AMi@iZ}V60S_I8X^?-_g01%CJv2)I|Kdy?iTGVSD|XYC~o6R9*t^DpL<(mKovO z#A|m)?yPXB$G%{gWrt>rCg<9bPigW=Sd8+OYX<9ML%E6=2LBEe37vSMedn>p1C%5z zRBv@~5538!bBFLNvECsv*MiRQX(_UHx*`)&@v1V%=6-0@CwAwoeY)Vk@m|C6FKHn` z`ty5!^_{W3x7{O(Lt0e*6~xHctb*z96+b&ii#PCp%qtGJ&yz#W6;PzPwm$jL_E zv!{!vE%Y(_pn>UMHt`!W_=JeBhAKf=e$`xqQA>UMVtCsjCifT=4x-4@R`<6#whO%u zWgkGo+UY8qBgAq?l1mW^DNqa*l-F?hf8!|Jl@KYpk>r6R!EOW9ZPnLuIc9>%5VB^T zKK?k_>sGC*pU@ylaFz{DE3-LMX|WX?udq!zz5JhT z^%W%F<$l4_Vc2EA^4)589$sbk{^&X4c&>lEh1Pwh@0ELK3!U>Nsl2o1ko(skCU@^E zJt#?AjN2ag@tP#ouV!>OEF-5xM~5uBqwX^)V(R5*Qp?a$0qy=+LwLk1s}ZiZ79N7Z zoEH`Q?@16zZ?I$`jXpOpjYjjoE*n-!{t<@3u!F)CCz4Dk+)mxMMa0e~@ z&!#?#Q_aOjz>x=v`JncnvOeMOXdHIoAH=v!pS+zG3Obay|7ik2M?HzT5fO;!;Q!wh zaf)~OKg48LDrQYti=NqoW`~c~kQ|AQ5mz3weULiOg?+{F7U)5%I*xgRy5d{z_(fto z-WOkbRiVzTlgdL#U9MG;T4~xsi!iwLBNCVfWDf zy}Nx}|J{c)ukOu~o8Gz8U%hr5a2H>g-sYVks9e46Z_6}qdO=$KhK!bj)U=gl=`{M` z;}>Mv$FmnH+Wq(X>d7nK51cw#X`&im7`roX4}M8%u~H5|Qz<%M7_zx@;k9u1=XC*i zy)AaG`}IJ{V~BCJ($=A?fV$HFzZXPMH8{mr(J+o>c$TTy%r}o}(8H`=^*m7A*7yS2 zl9yDC^=-mz8==SCU%ap1*4skmN#o#*kgYf(+maP11E1b(iY|h4KIU>wV`$7YLC_1s z{t8=RqcEEm4*VD-rq&oQJA8esQyj=VUoL@Uk0(fDok_s?$8sr$p>h9k{sI#nslO$Y z|K@cVg*E97O+>GFdzAm?&oCH&Rogy(o=08wl7V_ot#3p{NTAy{?}WfT*&oFfW)nUs zHcgnn6q9-4)u{dqUuGmcC%$qJP`7yBuBK+q$8lXG;%I*2I!NOi$d{-N?>F~nS8g_0 zMJ6y6eiY^3mdhF8Urp2X=@(so+m)SkxR`5O)S&~h+oI+M&D{^|Fqb0Sz%JM+&yrn5 z2-=7-K3WL3ofb)UmMK-2s??UU9Mk_o=a5bH=QR!CdBcp|Euq}h(eJh!U$~yS&$^p| zEr4v!t7ImxioFmhJe|_!Zi>F0!$<7$eWkdJT|3`W{&Xw;$P(?u<27*?U!A`ed_$T> zV$O|vSEHBT|1_w0`J&InZ|s4$h>g8e=RtYESLGKTRt=3Qn3X6T#jq7 zn5&gQXn7==ME80jyDZ{8#8e9wuo`<~pJvi_p8j&C#KX(lSD3pPKP*k1+{0_J??mq{ z?cCsAi37k-iNVEqLVG4rc*>F+%(y~!_aDsH*ZF{%YEJp{_;`H$B@(l=`%p%m%njcw zhrpR}{thgy#qBNa=SomF;;xt!IT{cSL0C`e=OcXVQ)%5gnC?o{sytYY6lX>ou?LnC z^#IkMW5dmEx`8BrenVnjFy_ipvh8=EZuknal#I{G94$$SWB!L2b;9NL@UmTHIMH8F z&SADS!e8A!CU@`34YS>!A$oxp%|BGCiyJFG$`Z6!ALjUZyB^Ta4vJ&CJ!(BPg}PiX zyR6@q)_!%D?fD*Jk{4M|cz$pKxfvy1m|vWL3<2dBJI#J#~+XB!)DUt`F6VEPP; z*qF2j6?5xJE`A9+X|;-e{iYku{kUGru#ePtUjf*=X;n-YJIFG$3=X7rAzH2qd#12l zY6|6$WDW6IiSg1ydUfB&&K?}1l`wtyv3p2eyk_a4wynkcKd+;0NOP*QJm7K=7`t$& zSa6YWxVUF;d5P}S3&Xl2i)#*{wr9nu*A+;upgRcWH&@>l?06_nd)13rzQIK`f=EYW zFyMy4`rM{&Iz8tR>SS$fcB0vj*tV^DG)cBbx5Zr^_A@2$m$wnaY~-vRL2_R4f~p&U z5tr(`oYQ!pz+B}G+mO87!oo1`;Kk?6e~_CfprPU@oJz06{R|G&XHVT@?0r z3G)n^c~*&W#`2U*UsOZw37xWuKk$orm*IZkdWOPHmTik7h?N(Co#tpep)sFVKdvrT}&LWgO3 z2{@6$IwDH38b@h5M)^*>18p{CD(S%_di86QXnQ_+I zbMNpx%6X>X#FZ{WcPPA*wS-FIzay;0QSEX=N<`j*TY716k*HiC-Ksrbhz;!s?yWcq zL?)5}@i(n1FpfELi`(qr6zZdTU3y;qd7ozu)z4I9l^Iq%3s`dXg$Xb1AmMoq`ay_d zv2s$qT(dC>gP1sNNfYB{u6H3uw{k8ViWj|~XMFB<-m=)wf%S>ThviKgLhJ zG4>w+Gje$~aSurR(dHAk@@q{%8uiy_oILpOV3rK&I1=M;Ho ziAnRBuYIwhR^-oOu?{J$CO3GrbnR0M4yB)4bJP%*ZYkSEX-gALVKKN#r^tbVljn^~ z4?jwZV@7R$FjOR*%pO9BxS^@9=r2~KUT0JfaqUXrZh3gM)_)r`63?yb!F!EAqp=07 zhI7$c^DJ#xmmVx`mXFY2W+1K^iWj-5dXZ!h^nI+GNF*LL0XG4Mi;Mbus}geF8opx@ zmBbTUr*0t17Ba>*?;=K*cOhsaPRvET83plmnD$Jgoj}H?#7WU2N?{}tIC@p#xjp4i z!cOz*c~mF1Y2b9yfN#q!JSbBTm>7%Uq&;qYnor*~BMBay!kXP$-ViJkjC zU3F6DgmTZ5k)^(~CIT~?f%T-B-+f7{gcqnjTt|N28slJjU+fC$UXsyn+aa}JBFaxF zcGn`JQ8a3pO=G^-E4dBU~JAmj_rwXFSzis!@vm{V!R#}X0DGdI%p7Ep`N zcGNlhKyK%1T9-u}IO74lwH{cU(!!%U?#3d95FL`>s6O~;&gKQ~Q#1`gvLY8;6sMK+ z5SUvQ%S|;AFEpayqJnrisrm?h+L&;{&Od8S&ffxCSbJt%MX2J;Z^6BK0BXMknDMB^ zI&=2LZb9P*Rwx=@H2q~OK8D=={g@J?qdH8^bqXczDpn83hl~4;_hwo&wV~O%f)s^5 zU*SPA9uE1>3YHyYo#w}`(Ao^^xcNHL+TD(&?r~s_vRAj7op2!-N8$MZJ4)EsCe%V_ zw}m7>L4~1;d~4i-r_ES%$^9`p-TzQ-Go@i`o==g{{R+W&vZr(TuFmGK+q^G)G*(tC zoy`}+J`{V`ETs43^mz%0?FkiK*r)t~trEN%T0kP?BhrvaMUI+_R znD)Y>CWr1hz~(K;&gdh^D~XrhK2T`Ny+R8RBRY|N1c~6pZt;DF5GtvUU=eT(f49&B8;` zhp}?M_Ej?RH_(T+XRHkW(tcmhcedYZq9I@S?vVe5nX0_DgE6VvV=4NI))!LhS~rMg z^(4`LJ=a`Jig@3?nN_iht?77yh3d+_*R3YaS{$D+Sef~8A7rI3ZO(xc#c|494=y)W zf0O29zD0T63bl3lD&d;a(~-73FV4DPL$ddtMk%kE?}%d_e+Puqk*k(BYf1Jv_8c4mSc$+-#eX7SxhQJ5R(Gq5?0Jb^ImU1mI1y5df zg=zK7&cqZ9v+Timx`(jKm-)NKo41qg^cTX+7qwU`#_MB;ddvQ5y;35l_k`m~Iw$H$ zfjGy#x!?6Lxh9%9zBX%wQ)C(4^xI*PWHZ#0Nb=`P)|pA}COrRv1|c_!&KuP#WsJoY zbBw)Zqb{e=!#dURiMpEO`kK~jA= zFVw+GDNH9_Z|kx;;}xt2x?>6AnxLD7W)`IVRikYeg9`^^B9$f&$sL0>zz{B`0dRgf zGqTvy!pmeJrrwL)lVG0cbp>Zc5?X2nUL%Oxdp3C~EwzvADe98K!s%g(T>$`>fE%C( ztP>mTP3Paw?iS`gmgw=prU7c5r8h+UE2f5dDUl5M8eDw(eEN2w9%u zaX9+tzAl%Rd@$DMna6+Lmvj`HBWI7hlau^MrHA~67rg7C_giHGmr zOWr(#*!%EWR1ITQQaUc{*{k@e_350rw|^vD#PWXjP+vTBzg+Dku^^}uNpWE~`CThO zU9L{;kxLhgCVe1HaP#{Fm^6Q?ClMN}#hLzB_DC&H^RD1Cb6f!lPd?ux2LDiRk(2z_ zmLwH#%E=`>lV-5aR9v9_SI(HsR%|T|vF}K)PJ(e087NAvylH zMn>#61ZK|6uP|}OgpMLc5OPLkf_D*^uYSG!zz9DCR_~#x`yeK*e_{KC{1AV~tM#@+ zBBzxxF9m3jMmK5!s8852Z%b6>_sobOIv$9DBbfVt&vIb~^)LwNT3iyl$HN|1>Uel8 zR~*EFiw+#a061;y4!Otk0Y936+qG#e&1}GTEXCEwXMM_{U-^L!gG}Ucb)7FTj1QM} zZbMIM8TVTCnL6izE*~3JeC+>t`toq7-}n31Yi7*C7(0VO_MNd)QDey#6~$;_CMgm|C}bH7LPXh0 z3q>kZrcx;JGNfoRQK*!`yO2UfiRkzA`CixWAAfYYDxP`n=iKL<``jOuT}w{CH%;Bt zw0dL0Q0;fys{+m)g{fS3>JBT0Yt@Og)O|h$v)(=G?}=eDIWhE0%dpLou=8Ms%V0;m+@)H~?aLn!l|;+dz|=KU-aykDWea%Nx@!zo32hc%d}C;uMldAQe9nd%e%1!T({DNz z7#ud6$y;5GW(Ny983WNR>1KfQS>_$-xYombI6;w@N2^ukANEQYoK64G8z=AtKS9dF zaqH@c8=9L{Jv7GzBPtVTx#~BdWcN;3$>;;xPeOYZb`>AEDif{8o;WNuuOh;ep=~L- zUigY%6erbX&)AiTng6)fQH+t2t}1FH?weV>0RK9uFuH>Yn$N|xfvL~QpvMo2S@F6- z)X#pM1aTiBMdp8j&Ho$*Nq1sDSTMpD{yf)y7n-?>n@bSkU4tWkisnPD zekfKwK;%ps0pJf*)5KZ_TG=u{*|BYqZI1124@RWZ*r8D#2z!V&=kmpez;(&ZHOI|S z(ebho#mo{(_!%t}OU<#B-`IJJtx>?s**=7}4tKLCM8-~Dw+eOQTWLLSF)~q~=ESLlC>%%kahWTzjH z?Z$L`dYCR)wUiX?65=--)xFdS-aRkUwEa`wW|CM$aawz?FUiwKuxyErv==cB2j&Sf zCo<`=qsr*c@e0MkLZy+fOQl{ddU(}b%w%?rJu2rRjR0D=*zpphN8I(+s)@cX1Z}RJ}p4E?iKiI z^WZtm@5r9Dp@(Ug31X3md*?Sv>mrr}T@H>GcgLW*A5|Sg@Qh~6fpE9*|Eq2LMtS;^ zLmnJIVQzG_-qYPW(V@rP`_PgU#@}jt+ zo%7>w8u@858R0Q>ACIPP;O7X#KC|Om@wQ>HQClSw1FVYx({l||6($jn^AWr|mHuL& z(E5u~pVCeBw9Jei@)uQVU}}PRH{F)rS*2v8Io71BWMrCtq1j^n>AcF*x!?D@$aIL8 zA-BDV^ezENhkQm7g*P6kw)nw4+3WX#SR3_9g#qsQ6{iDlGH zia`#i(M@U1{Dnqvv6iNz*8bfCHG<7Z+b}%pVv?=L2!Ik-z%o#r&_M*mo-BGOB5Tnz zTO;(fc)WtG(79O3=mXxjuakypRp5BOIv>t-yG%b`Z9?**O>5g81baOKaVlQ)4nG$= z59o*n>2UP$FAdUt_y<@kPyUSW*O4BO%G%`Emer6O?p9T>b)fJOGnF;%5s#W|-Y4Gi)%Z5@_~PIF;jSOo)75IupV#zGckgKrByGUzfM?;y zh=h{e&kso}Ndy({cUylH1N6+CBWbZ^^1bstft@oCc848fHD{o-`2 z%De`qDkBg58UMd8YL>g4&VE0JTy4K(&w!|3;Qj>#XUaF5PY+^S@JpnFyiU#|lhBb) z)-irDJaQXqH3Jso$*07hA&Ao;Saxt2(p70lPM^62&D=MU3JnnPP9{d+g+MQQw0x(* zTrZ=dWrL?S+M=m@!DazIKrDb9d_inH69OwQFW&pB(kuKjl0Coj7;4=I)&m(f^!@Vr zXc((@kpfsadpBt2JFpxu{?*E~*0>TR<5!Y?m6+p$P5fQkI*S&}hTRN$hBvuy$n8Hv zT6+Vf0Ihd~tTjldnC+@_m{PMR_OCeT#A^PmL(0O31N9AwwA!`}Kc=G6+7~2V z#I6=h1gW)t`@Lkky5Wkih4gBj_34@i?ym%l&x$Fjr)zJ~d!j>YD4jx^Yl>51leP{q zr0L85@s1oKc^&{U0kZtHZ`po~Zf3OT5^|;Tms{2&buNpLvdMk-H1^ISN)B>(7h(=EqarfL5I60{X(mX_cn}uz;(xTS$2j_gmm`|Y@XXw|CJ*nbs<*kdUAbkUi*ojXARBgvL zZJv%&&n_{eM& zaHl>G;e)$S>6%OEIlZ&I%9EohipZ$+dM_J>74x~4imQNDmw(vANXff0&xr#WbvQy> zP9JyLM?WIb)Xr$jvJ4+A{Ips5l(ku>Irc5hM1~gg~f~AZQoQ5APvig1S5sE+}Xz2?^E^f&97fvR+{u1 zPG0%_y;1By$wYe)%gNoO{hRH&h6;?YeTT#gM@{y4&ZdIo$W3oM^ahxA*>_JL2GO;@ zc6%(!@1yHyFTDN8ix&@5^AULCR{A)+@3Ql!u2e>ghkdxI{>WaqW4F`6q`waw7!PnK z20^>(CoX^7mdFn1q(K*+y9gTlo6GVlJ0?2vt6D_e-xhv1(8A0;M6q!z3uRHrw@~qn z=2b`aQ@NGv3fsT=maQ+w2vZ~&m!bei0H?JRfpXMrh^Bg__u3=?|IW;lNF;I82;l2e ztp}b%<vVXmVb5&@e}BvI~jpaXT6A^nGSo9g;6q6LT6y}euD5efDGnEq;NTv0U6pl zT&=2o&`1xoJ96)FjmhbmrEq6~A{$p#Kt;1oqFF&HD{=~t<3v~zfvL?B<@Ie?8I1r7k=$re zT}@%p;`%j}`atX1VNB8A>ZID!l`!KY$YyFZod)NGijb!70=>@*8T#@L0=NDwa_XnZ z^$p*@)eSnNh`bg%0_`?i@;cd(GO){RensJY)K9s!=iV0axMF$3<1zPY=exbr6AY*H z#4~=UYMN?R6=|wIXC|Xn9{UeOUoFabjHrbv(_`q5Pjy^!z*cnZ%%;c>=}G9}RSwfP z;hu-PnaU!Dc*fmr9+GR{v(?_(3vu^xEj!z?{`<)uU8?xWe#!rKd>X$aBgC2Vx$4}4 z#^fq@6)cir1!Z}% z)S#yN&r6=fPm%)!C~4~RZ=Km*#S9q9RGfQrR z2W{5=w5(-bWw(>Ne&|a^7;4&1i+4{w?e1k`j#^bF)sykCYEf?4X7QVy)tYaXvN*(b z=z%13rM-?DRJAj@=FW%t#dA`PtN4@SsrGG{;QUjZJHuLZ#Y5oHX$)p09MAHkK4-Uu zk*1$3)Q{t#)#5J1w2%DnTnanJf~u=es>AWFo`e|XkGC;ZP9!l$dfln?4{5TNsPb4r zw0O=E`O|Hy>aN+dSH#02-~5C(+&zZGuk0aDm@`^e(~qOe*t85_?ve3>Sce&2CC-AP z_K!N)0F>(89d4TDki3E=1UB@bS*MtBnZeL-7G}q9OF&JZ z<1fc-8cF@viN>zNpbA|RMGox5@XYCDMZJS?Q*Qgj{L(uO_Av;tpRuV_f}9kom?{ zb<=UDrkJbfpn&8veyCY?K74Mg&;LI#G{H!~kdvVYS*6L1_(%N7{itl65{H>_FO6c% zUH`uFM)!uO=7)^~C#RA!Gza${laR+w^b}lAm|Lfa4Yzl?kLe)OsfTpi>!XPj2<)gS zS|pr3OuyJHPv`>OVFD@7lVGzZyTp-hWoP6@Yl~eQ3UI+j(ZssKbWq`Ne8wK9#H?^P z-<}h`2{U8oM)ByKPWJ69tQ4{s9@_OGs- z(FYUczvIKfx{KiwUvWI|89_By0?C4!N&S+RNVx< zlS57c-i)ssQJ#);(>Uzz&5UHLZ-(bq`ygAQYs~MiUE6}($N3Z2o1>WT@oE>D!xb-o zDQntMR0w4kFMrK!vLs|(04pxZXmr-eR9F3M6U_k4?AOsrFDZT}_C7@P1}>oIj+tmD ziJ2Qc2Qq`$VY*>qN4o6%)AIBe83HpA@wJn#lANF6ZY{XY>)Zg{Q?p-O|E0fmk#w>g za!tZk0k8>QRjE5|TkwfJd6lzTQuCb)EjjAR{Ovo`ze)3&D#PI~^e;Hx#+@awV zuvOa+whgB4Nj0^GS*EDP+fy3F78{`%@GW1_rJlSa8dAv*et7br_>BjUtps9(n~jGJ z;ytLc?DtEAHbnffpq9w-(fT6`BbfT{86G4nV_f zB`OI{x=$3|I|0_0I*b?Kc)@d1cR>Cm;OT@5zxF|qN1+!%RsF{Ur^KL{ItJvvIS{j#}?T*MAl*x~Z!Wi{i}&yP0#ZZN}LLA1VgRdbgRgPv`qM zQw|e!q_U|);F35{k0JdM3Ah|G`1z(q8Fz4$rw0I`^$X?H=&sm4fr6c)LDaWjD{u_5A*$HmH%a!BTM)SkZ2 zyIu%WANTjHCo@i@NIcLubfL1SJ^!zrTCCcX-u@~k@fjJbnSCN{4=K+tEwlYp$J=bm zKwV+S+jJj3B7Co@+p$y3j+-%m9?0J#`#yN#E2NZTj!#oXODbpS&B(x(EY7p~PX8a}=_!;dBaRU^;migZ#vvC}aFx z-HqX;ap5`BI4Ck)1gTYFhnuz^UU{U!f9oImaCIOs{n!+h{Z0~zC0u!XAcUG~v%4l( zsd_2oY(nV+g^M> zd22{dZNIgLWb|eo$n?7bu)=hxvKCopz=F`fUm{)(q5xP8jw_-=sgG1_)=~*x9$DHf zP4sOh&qs7gyteYBo`{MQy${p!<2txPMHG5bD;VfvQVB-8kU32d=lU1hWAnr&;QOIJ z=krtkesm)W@+Xe1UrJ3o#&VFmce@~W$??SAmEWXv!8J9)ex$JL;GZ2W%S`!nIb@_s zo)ANqTT2pW=H#Es5Il%-$*Q4+%JA1pDt{Cm(o+{%K>@&jqoxx4_fR*~pMM6T9ZW5O zO}+MqyE%@?a_%W{UC&_iez8khwZ_QOV6y3B!;h^yp)GW&Sd#E1o)LgDK{qLo1U9H9 zQ&Y4z)cQIn1o<->HjR&gBp^0!Zt0!L7J)pnW42cwvG*FeSS7EI0)_4lYB3fo?9ZI8 z4`HdWdy7H7HhR&&25jkTLG#FUhH%nMdSL1_e5kA_7wYn4MM)tM3(!v+FeVEA!EatV zIz~^0TM6s;!6!Xco_Wlh>o+dN%6Sv^kGD0sH%x8SXw+NI-~ zO`wNUE)(h=k&ExXZ#(?2)P;)c1Aa?TR2}YeX(To=8<-&d`0;;v^d+hFsP=o z@)=qj$^7w}m{GSH_EQ>Qfp5RiRi>YKe~9ERXxprEU1SbLk(f^h2?8nqIW17fzyy1p|fPqeEU_ z|Bpj(P~Lz7pSJ<7dVrW~Ql_vU zs?G(Y6m}vjXMF@T%nfz!gy{!!_DGZ`=6+@S5=Mz@O5raZw4xIkmxa*ZAGfONpRprQ z(_5NWOMU&1K-|V5fFOPkO-G4Y2-{Aob29C?4eoLOU7|m}UbETG=p6h&(yxbU#%?Qi zq^ntR?jAklNFT-iDKJb6#v49kk8D+!uBnW`KLz1}f7kC&n9n;Tp0gY5WYlfR(#mu* zhX%A6zOH%zd{ODPZk=i2Zh4CA^Vsmn@~7;83=s{|HkKAvSEdwZ0mditW}B#R+ek(= z)H-p!kllJKPY{^eKf%;hi9z2R9I4LO1WCk0HV&6Ym%7P)?5{6#R41jY=P)(B;a6ff9^8sH`=yGLVxRH88#T z6zyhPt8~*AWx|Sh{Kh!JkQ*LM$$P}UdrXZ7d^(2V>roy{Io{PXz$14Zes$6n0@)M`NJI4u6rSfFTFFM6ez+&eyTjVrhA3_}DJdBHPM~a6Doo z{nk%N?@kDRA}I&`)5@M3 zuw0SEvp z*m8NN^OMuS2Ta4USh5kS~a%R0GV5*xOWOPg4doCpI~CKnWZ4&$MujIXBz86ALgz zrKvq_y!PlWR~cy6k^#FnyMKP^Dbz|w3k@OR3Bc3!-+;+ycA|Mlk{~N`p~xivGXut;42J9aY^jn1#c$qh zn3_x!748}j(C$cvfc)Jb{3>>43^+?F?l^E0VxyfE2h!uB*IU;iceXHP^pl3cDdp}F z3C#2m#_2gs3%Kff55qaH_UUB`>E6IT)qQE94DfL)P zE;^}Hvh)k=DwWOQwW?L3^Gw?vgU-Qi3!X?J@_jX*wR~vc?wa8Dso5EmaT9eH(u+Fk z?A%V3G>U+L^VP6DlvGNHosk#q@qVoVTB>OlFEICb#%8+OYfecf-~c&tmh!v+2TOcSK2AXIk!~rkyxxb^h=C=ru|{7 zMAJ8LyI74lmTThxwc+STXvP%P^zGYCwT1kXE8iFVccpDX319pbW&bb?M?$|XRiJHy zfud0B4S~HtcM?}3Kq75xfD8{v;r7QTE4+=_%YZC5fa&XMTspU5=2U__CNl)TC>hOi z@zt+#fXLd|b&j;urGla=SACQ=dWZB+j*-)MFruR+*%k_}!`Q&9fg)M5vBS=1%}YS< z3pAn>8FwGSH|cW_mo^z9>gX$)s6CTgE$P=stG_eozoS@*zjKFNh#g1U&WOnT`bAj^ z2lzbBf=d^&yq>>#{-dP45j;&C(&hDuFP?wF{@Wm5@O}A?{hEhse-r86zdza?OHVP? zT9x&Fn0MKLQxb`2bexhLxIkoQw&P0FjRH|vXckx}+-Sg$mY80OpQq(++;AEO!=rU` z#vG|hN&ef9<_wtkj`r4aom*ZCE-b4Qc>Tk!Ge+ZcJ&|$WllhsK+l9+#GSTq*QfJC! z)n@(By>nlOo!sr+h{AR9$TrN^JiI>2SiazxB73&k#IZ68!`c*tp<2Qt!Y$kTv#LQx zsTkPZek>eHGCP*)J+U5cT2~wObM={x5Il5Z^AE=^R`%XqiGpk$Xke^u&dx5Y)v8R` z1XBvOQ|}={9dP|n)M56qyC>9DA7YM9b;DfZj2UDd#~BjkjuZzNQe`!|M}7EG!{{t; z@c9HL=LT`WZUd*VwgXoxF4|coJ0{v$&F|9~xw*Fv5f!@J5j83Svz^TM=>vtR41ZbV z2SykG^CC5JNB|`KmmYbpM3(a*%>nz0)FmKf5-lp*1nyYiWe$z#n zQtS|Hi>?bN7QHIog&ZL)lA{n%|AuziItR zFmHzX9BohJotR!axJ%+!9d~A^Xo)l1rRTmE2cW<~-@zO*rsOMA1)%tST6!uKOS)H5zXN*iEVOV7k zR#6$jD$EK9^iVgkJ%5%wZG`vC*`9+VoN9SEsYVpZ)SYC%eCo1fEy7boUtH3K{IC}6 z`g=sirP<82*q{emIOtGN6|hA9dg^~3i_i&1(2Nu`f`Q(7Qo%c=8`_Mi_}BOjFBYiL z6y=X<Wf$P9L8$Bige$pPQfK1KOS+t^y_XWLI-41l>YM9wyO(?;#NP9m`1p0Uj5 zJY|Z5*71}7fj#Pd8aLGKiygH-2M_hFu@v#O6FI*`c9dMw##L#Hyw~DrLmytP<^Q^L zX;>ce!~-R5xKr|lzc|xfrel`~?;?CmEIW%gOl-Qu9*t5Jbos*XWB))yy=>qdCOD9E zmC^ps+1E~u)^gQrf^50R$6ZzV2Zz~t>fADLV4(Cq^ubSO5||Mi@p)zJ1abZ2l^<8^ z%;}oIf|7-w_kK?5OS+>{{icB}o4W8yn-MiC31wfrd`tfhX4qCUFk=CrxHo*Wbm)SV zL=B2;U+g@xd_{EX$Y+}9MFTl|x9yp)j=i^nr%65-)*^k{8u|$!MQ|vJab43=K^+ERFw&P3dw1dr4&c6JTRd2v8{~EU2_reZ^=2|rkYnj*?udiR z3>0-vOD&a(>c>F6N>GOZZ;@xN@c2@I$c3&QLR<8}zb{#vfP2+D+^xn-%bT_#*<@|# zd*{T`CGwF3nH*_LgO0agHsalX4#EkX*$H1f6K0P@?8xG2iL59(Q-Zd4wySe98b@lr z;+*I?V64eXsPdMEcRf?~1I9cC|N; zq*8BDXM3Lr*NiRFQeC3*k7q!CfIqGu=xDnY`EL)a8-3rZ8iv^k_t3zH7BiytlFc>^HaZJ#=a}sZ4A3Y)6#R!d#T0nE}WmO<_CV-U=U30 zJGx1$cyrKn)d?%2L6x(VB^-Z9xPPFNl{_@Uz9p(}*0cf5iAe$4%th^>({=Q^tLXd?EWkF*sg1R`8%QV}DUS(5|0sQaq4yO(NbnlZRq=jPFzB_c<`| z%&$$7rKrU`xoF8`iTDNr0nAXOL`{k<-`>#9e`ygq6kvFqytqA=Ma`<~w5&a;y z`jZ9la0Q6S%gEQOKa3_0I99VryYbV{8SMI16ryhPC^vkCOVZMzF7(^vs%X3uQ+Nb>8sR+iqB=#JGsLjz8`(hIbJ{ zS}@8>x3Qj6pyz$ZXVkXeH?$&7HK~FWgBF~Aiu@UvHBKnb6kD`wnP1&Bv3yvRCzp4JQ4jJ!n5~WCAXvt~VXH#@lI=;(V+D8o? zq483wujM5zDvz}Et*4;6^35j2J+0F>rRlx`GJofUMCe)gfcigV{r2w@b6|CI_-|Xy zO?B;mKrnVlaSHelH#1&81HS4Sn6>t9xZC}l|Mnvy$~EU%IyZs+{Y_mWf-)ZL0x^>d%h+lLH>A z>XT{KMHimxNKaLo;lIX#w;^y;cHY8`b|>HG0HTaxJcPsXc_!_${I?4cZn7M2B_n12 z(viiVHqe}eQ81#Dby?yFym)C96`;n0!imWi=xzj^;%{Qw1ECr7f z%gGcgIvDvt1J{X<6mAx7`)#1kja~85pWJf>wh?1S+?O1X?`4Z1>LL;L#pg;24ONM2D+C{OOG1qG2S3;l|aVPLx zY4e8ruRvtIttlW=edb_VD$|F8KqLE)}pg5Er z_pY0#CR>Z{I_?FS^;WNAZCux5CZPs52peADTV3#73Jah5GUYJG-CtH$X)P}pHB-UF;$YrC<7Cx2x9w@s1Wff*Sp7^ zj41g(YP}dQr*DRDyj~9L(!1;;x3#`JMC5ASj0|}aUNi;`edMkFCkcA%lMdA|ubUaB z%~Iui5L0d>Bc_W4Kq1mI8$LP$8z$%O3w7>})4>0Lj}>J;(!shjtX_!LRD#(xW>`f9 z`(g)4+61l#sq*IK73^pnp%mn+OH+5*O0%1Z@!O3l_p>POQw96TvvO{m*A)WQe`bN7{U&bV4(A=&S+^=G4 zb|^_h8F`vdcnt9z#Y1~2zLR4DK(AG74%1hU)VQ(arG=$NX+-dK`s5=tjAu7Wo^_(v zm8Yk;&?apsJWCKsPRjEVB+7axff=plbVpKNH)msKyN*$S6UxlRvDgT9lF9I7G%K?7 z<9Aq~y^rVjkIW{8N^|Q4N1#9TdzHlC6BfdwZy(Q1JUDqpaw`8k3~s|NnNqpvMM=MN zuqQrT!IA#X9G&&Q2g!Oj9ynK}(>}?@V&*)(X#Fyv{Z(%J3ascqFS+Suwu6o;`2~u6 zq|lE+DAy4DN+6U+0=2h`KU&7Nzzv+MF%9F*kO|ty^qw#LYOP~##g)#|loqTI0+O*k zbKlLj2KWR-x)`_TIlS4rhs0z7=fr1xTI+ecWP7%+3Ul#4SFHbTux%DLkpqD~1;m26 z>kn7&fl;GkkvY@ERnPy`x^AI7FtyHH$MM$c8^T7!nLETRQ|imIcZHIOMrOf?O{O2C zFS?pidMw?$jInT~N1MJ(?$eL`-v#QziERpf6-`$LzT|FR)}?}uX4_$;i+A~FCvB^ z!`~TbA<9C~r2uy5fP zfo}Uunne;8l%1r!=i6F?0?Gkr`Z$Y z;)-rONDHJ#75wFC6sQGujyeI6#2a#;dJ(1hZ%s0J)^?mn@+1<|-bS4}zm_jGnT}t& zm8f@AUR^|dom)jDF6`!hTuvEVHx8F`y%1cZ3zZ3krbDA-)znF23KsBtC^5@WUU92m z23X1AzjRQ-2aRYZC&+ZH;qb2K;g8J`-VRdrl1H%=#o_aNQtwI(y=SW=?}AxdUN6|3 zkHIh)td9#eacF<^;%+N;uayXuS`M<56rewOFqq(P-VePX1G^p6x)lw^xJ+P{c*dDl zQK2Ugn)UoH9^m2T5IHW!yH*)GXCp0|Va$#& z{~1r90~pUUUe$%paw@Uo9ou5TMM~1Q?vZ=We5rIQi^tdTxv&0`C*bgg9&IE2t9z>a zTyq!6=t`{TW2CLZpjzToy3SG$aq;{u)}M&SNHe;wbI*o(uPp+=&${m&AJcorJ~_4W z+msAhWMmv4uRU(NS=Q>$2Gk+bp0MBm3d)5_RB@S_T1K<*Wa-=h{ zT#ZTX?^|1ARl$;v5I34HW~Z-!m%;Hw!lxc2mbP~HOY`2-zC%~Eg~NO^X=}Dx8oCY~ zUyl{N3-z36E$va)ejE6AC-o46`8DD_+eETcDyMAu=yOa<|ko11h>au&P$=sVcSE_DQx#9U_t7)Dfj|V_K(A z=8bb=;9F;d&y_(wl51c5^lKpjqtC(1|H(GUYlNs9-Nbl91CsJ3W}FWfI)zb!EG>?$j7FS0;2k)lr?%rxour47+V*ixQn+b{Z zJ%Y#9*{>mM{E7WP}?0%%40c|FBNe&pw@Dl-i5I+Oo!Gl?-Uhq!22v9PEI*B9HbVv}(7lq(p0v!TG$lJ?f)lJ#v6gSs{F zCd5k;g6elIA=P2lq&;r7*M~S93++bD*1LO3`vBYU#QN4JmcZ@v#|9f!E) zM)E!e?AcIlGzyp`erVBcWXGM}IA-RJPpt&Jao*`&hxpzW{j=3C&EK=a4a{U^J7i@R zrw3kHV;QCKkiBN!bATqpZr{|cKWU5oKwTRuI_ri9t2@eL=nkBPvAH|{@jP_6vo(@_ z(t7dY186JuA)VVuYv!g`K~LgASE6DXAJ zgHiA`Kj~Q#;f0iBDg!aWi}M)q!Qa5VNkRZ;RMbjR2JfE5|!TPm^}P zthfW6PkA#1A5BQ!U}f;@N8jR;l&p&k{L}m^i>ZL#lU8W}e9>*Q-YVY*In`??b+2cn zA(QR|9BR@*-8pPL7kVu**a@&ZyuQnd7+j-T zUDV}TXiB@J;dl()rGsTsZOkTJ_g;1UKJR5R8GEZaooM}!Y3gr8Av5R==zotEVDIXH zKL7ZP3>Zy1mL4gBC@3PeVt=cGfKU1Fz<2HPsdpIUz*ljwDrt`@GL-cS1z^#;j`sSa zBw<(M@mEs&%NRY2a&QvPlkia*P|)0Bp8vUGo7)~)i~V~I6v@c$?n-Nq{nQP#3}Rkp z@txB4CfsI7^++8uHdcPvq<|-y6r@DxXF^*x?9;SN-f6~G)-{SdRPLpP0^Qf7&Z!~2 zi&E^efhK8N5RFoJ>KHR0xZ>C&EXk$g5yimI@cTjxy#%nQ*+G&>0KRU`SiEKk(Gt5F zfM>cZ@)}uxJiW6%P-=b?ha4ORpR>hIGyXIlFe&IG+M0nxqkbZNnJrOuVwAmyvV2#A zv;j@p!%@3xF&=VSa^NgzZ_i4~@3JK${|C&0HLVek2s)v4V5%yk!9%s@tcq43YCjY% z`ZmCJ4As{nuo0<>5zDTbwRF?75Fb#%P~-LFkYLa#Rbk6NT-4{(oa`kb!!AQ%&}K0= z7bvJoWYEK-M>qhroB# z{>W^rp7uV?1~hA2R|`G&l^`Kh#|c9@_sqHLGy}6f!s{cWkd_?F>vc$8RgbKHn(_p# zRkQ_FhxCTZ*Wd9-s=cRuGq zlp^B5xqIi=Ht1Y7FYp=xm?}rA#JiudgTj^j)YgoJN_tLJT)F;T^s6!DBTSVu*r!6Y zvS4`by|GVk%C7EmP$0swW?i!aZjPl{iyGg%3~8$E5+L zh{Oz&0sF)jHv0%(I9<~S{ihU0nc~?yFc0-duI_d|zRs=g2qFH_E2==62RJ=x@Y)^$ zvzWAhJ3@K`aHXNV6PX=-M}4%4H;xbvq!rAo7%r>qjl_{h>Tpk44HrHjv#B zhRf1H1*SdQOPuvuyZmp;yACF#39wy#xvADmFw?XSE5oio037JN0E>Dw^%byKM$3^~ z2eUoTyM-wa?Jyrw2E)Lj8Rv&Ts$o(lT*2|946`#fRw)S^EwZU(fg?DgVoCQP%RIqbEtsiSC~D z==u6+;vpycLH=8ujC_Oo%8Vo3)qzuTp;A2AunS4p*^{3Z-MO4<=p9Dfy`(!~A^a7I zH40`(NB=2yz@7&wd`@^zFZyzb)Z;RLO9(6F8cPethkHVlGWH&P-cxo0_RpU}`(hoA zi~i(}_*5Ne_Ao{X+U&xqkf31zFc07DOm1zgjl*@Lhny>A*tM}ZeQ2>Y02TRXGE)uN zFHiCu!7!!~X>njH1%21_tX|67>fVci7~UINu5NAA_`E!P&Qq_Xm4$9KfnMBfoBHtv zHMAQTABtKDNDkf@rYF&#L&O^hcYN-ht2R&(dj~kYT*zThW5QL_!>WXMAC!bGwZc~JSTwAoAf(&Y8T^KM{+ ztWTn5LqXcKfua!zHi>tG4u#P3M_M1|jkgAfTme+W9A}Tng<{YaimuPELr(fJWx^hU z{ngFcLQ3*kDQosSow%kV`NR zMYp1>-Ru8%t(@q4N7q16YTM-c2Eq$AW=qQ7$jZp}(GYm*pl)bPib&FaEL)(<50VGe zjCx3?j9?4)M5s7mg~}*wAkeOJ^PO6%^F*YO0lwKLXpxY)v$;zAbMTlrW2W(`nD%Boov`l@u?&K2e|*aA(qmy)1QVa@jQW3_eIANXhs)0I*498 z`*78OT|WplJ*2an{; zd;d5KgN{?4JO|n@1rNe8TvbZvcJnoW&lu-3uI_u1FBlt>RR4G)gclQyfkt9XNSDXy z7!}u{YYc_QzVESFI~bS8C4oXxf1rd|@lA8f|BeY~T@)%uP8Wm`Tgrg5zAs1iFufim zk(e7ntlYh?CwLm{J*4Tn|9C$Q57V<}t4`8l=&8=k%sz!!%DntnXG&mCTCh+j%&2_X z4<_Rfk-u5Fwzerd+!&7*OSUj-{(jAVgc*?1=KbuS_qU=4(KB4Ui0jJJy_L9SZ! zCUCa$TsbtPXA7PqWkiT5nL}5sv^+>a9LpI*%wZK4r8i@5qyCC3@;y?qQ)IJ-P z(;e3zV*KHzG3ntm@7Z}}fXEw;gioAz+dRV8E{9Ge6BRQ$s2xdBXZ#r9oUD*)bu3R` zd!Ig-6MT)ovB8br%~H!3*mUFVL&$(lEo$!q>gbpA5_u3XMTd!8iC|!PdMP;+kWeiN~V)J)^aOM3CedRvw+7$^p+#K;2I zw`j1?=>>C}tf5v89#ML<1aC7^$~>&=vqN^;^!VP{jqz#J*`tLz*UQ*) z$f40DUC5fm#W@Y|i`?~UBhQeqb6Y3AZ!-n$@j}x)bghKOLXmC$z0&)1y%9~-f6w)UD;o?h9h-v#@ z2&pY@o%-*ua&DP$PNCfju_|L=L72nciVo;r8N;8r8)9uhHSIA3-qvQhCKj6XxFNkz z!qYEpIaz=7?tPD}uKJpt-NF-sS3Qh;!P_2Il=%5weJs$OMkLoz*{dzqoRWBvu8$O@A`#>I{#FN`HJ>mVU z>#zt;K{#tq5GQ+@XpF7!Tq-kV^JG&_uiQY?;>%MJUvJ;b|K_;x>Q5DvqJOJs!_qG8 zZVP7P#3=hxEqB?SrM%S7P6%e_A-!kXaFBqJlf1EctHTv32B`^u&tHynU|%|@wD-3G zM+g50<(JEvce}zK8So&EPVHRWr01CDy3%Xj2PMwo58RyVaX>i zpas3sIhrkaoff0y$@j6X-+W@d7#Zi(iBK69x$6dwDlhRXJz1Zq7*z#yUxGbMUQp4qxw&|O;&;nrW= z6HXX%4{hEHw00k#y<#>yx1%!pCBS&>A-PYLBrrBXys6Z#jjUg7?K(^I#nKE{g?5Ye za4=Dv_ff!I1Ia^=R1xA_9*ZnTy!YGWuza_Y_GI~8K?^#ZWk70%Gx*vmRoi}oyD7bq~qeJdP;1o2Tm>3SX!vxVSAPm_*(x#+Lv=* z23LoRYP#y84K{v0kz;n~*N=%v;hH&NvYN6uAfAS+GBPq#C%T+4fn1-+P<&$#i0)!H zRk{my;$8)=KeprO(0#AW1m0nX#;QShG@l0IXwZ%U8AlVE5#CGJN$u^RVy@0v>xFc< zAEy`;J&R(}_%kexw8Q$|hUus~!j2Ut>g{j;JCruVI4P#myQ(KX2pa z1KO?953G92*IR zIdHA&wVUx1(OTxNHQRq?2_TOIkh^x@aRv~;Aw|zJj?!8a}K2KRv=jUXmEovhTP~Oti(7V1Ev5Pjg;(eB)j&M-62e!ju z3K0j2Clrm$1adYxSij5d!cZ!4lsX~YC73z2 zU|lb`T9B9Cbmj$JQibd+)LqTp$1YovYj|38586p~#mk8GoWA$%rlwx?Iy;tD-}Lh4 zp3;c6IA2KNHm8}4qYqQwYfbFu@hFF)tuG$@lNOwFvY7BJm|n7*@sYjP$X=du;_Ug| zm!I*?FZCN)V@JLv%l$yTzHt@w(g(JkIGG|(bD%OUqX97Y%3##8m&O3YUPfg+(XjwR~8^Z}N&R{zQd6@XQtmhGX&nyKcAM=1b>X-o&#`EB+!= z)rlJ=Cd7+J6PRef7=3EwjgyC#%K42#HsONYURGpDd^0otA!*5J zoYY)2oOMLig3C@=?6@KlrS#>|$=(w)(xUa6WRCOX5F01p+n9PDiZA6-#{^ zWO+R+K9cm{8|l42ZFWDEV}tieY-PU&)#aE3c&BP7jC-d#v>3r@q@?gxhWlKJr_ijl zcS(8viTJ_m9p)gq!)ZqHjZqtJKRmpTFH6AZQ((VjPd>}8m+sTH)t64$R_pJ*Chc*O zr|W?*;aTM@!@z;P((7v#hw08&tf=?-zMif+PWi8n%rNs%0*<9^Q%rf*F?h7Dkucg> zcOyY{C&fA^#+uDX`Gh&lmgj_c-E5)^l?k=khqYoiy-h_LYempPxD@{oK{TgZKfq(6#*#lP>R9_!i0--R{6ebf-7jXHND!ES(?oQMVDHNr$oI zH}1dVxGnDF)U~l7?*yB8yBLa`CeqiInUB?HSn|%<@OeBkm>km%P_VjotJ-V3zJmCD zl}~-|t<~YIbTraC5MF{2_-Wgj6+EnbONo5P_&-7swl5g=SR=HI4p#ub2Z!Kl5TM^z6+X` z^w^r-%J_v5*)QFs_4SWVM#)>t9`_v5f8R(f#Je(JPJ`b6?two|c1F7Jt+P~?QQ%9} z8|Ee2nHOAyE=CBYq{jNgY^}J#FWiwYon}51CMJpIWf@gQNqsAuDA`HzhNa@|FAYDT z(+BulI$I;^v=y$MjXH3={xjc@&F((A0beUE`CVsnZ#Z}kANzA?%XD?W?t=`smXX!r z%xkN|Pol25MNQ8x2xy#$&RFv{C-ZUSlp>!yS(Yy5Vi}0Job-0##p^e^raz|klp@yb zrYhJ?77WzqQIUj&0WLK2A->EH7hY=Do`oT?A*b367Y2-3$k8#!SUoF{)&;&nyAJY< zg(mrcq3~>eYdO*mfr&$`NFo7q)gc*Ra6~RSp;wZjGn7 zaG{@O%0kuPrd7wRd`eXr@zVuxn6B;rHF`Atg}yond}s&9?|{CaaA z@Ycz=!t-CJkysCQMr)6;CY=YaFfj+)H7MV{vF2x;6Cr_#rZZ9?@TaQXs;FfRaeQy$ z=V?zVxZ|qXsjw*anLg$>Zr>r&k6!JG&?we?}F zDt5K_je*eOz`{oZRxTga6Rlr17JUhnG=spKOnD~7N0F|zAD?=v4-ezZ1Y_?ebCm}`HX3Fmb z0FkHxIEjzD&_DIl1>O`-6^ho_!LM>cLth*Sc#2Hop5wAhVU~vRykqMS_PMjm_a!_$ zF4^A3!x`=2^nE<$0VW31xTllf%Y-J*C?Lr8Ei&nkt0QVcDUcTNcYw#P@^ zwz=^7S?GP*fkOT*?NeYYwZSonQT4H^V0C!cRW~8bNR=xRws&DbHkwaR6z)!=25Wb} zITFcvCu)PR7C=D^DtaNt`lrfUFg9-^ysckh*;<0F{4;i7fg%(8xq& z%jmIgS1D!7SR4ZLdo6kET3-{KsC$w&%d`Qac|gDHn^fjuyF!5p8~#i6x?&1d6?mW2^CE( z{uW+3jy71F8b_&VjWS@wS?Uwvm~3OCDut8XMMx_7sBLu=fsU~#*`>|CnFRON2@X-c zcW=#}dKTu0UtHlu9a5GPb4in0*Opt(^UgiWJUeT=bohF(kIWoTKO%qsW9X|?VnEWD zftc)D7IBW};Q`6(!x5QDmRE&?|yuf-pXXT}I}@cPBZaGTVF)EmEQvq@MKnHVPFqBh>3iQ zY5Fb9i6}KW&g5YtzccM56@6NM@_KM3?djJM?5ZUX*dD{~L=b30FoKe=x*DASYp;;N zaXg|Vhg^Z82U)KJ*rx2-HWsp?wBddwe6eBRM#nz(oA2JCcWLC=}!OerkQ5z)YpWU=8JuNECDT?B? z2qy8PI;_!^+6s@(isj!U1*(A$X`W?+x?)jnEmydjrr zQ1|QLwOG{!a`+1iloV%zBim8>Z*q{W;cApWM4)_2OO|BIIQj{2TA=^YZhC|L_@2TI zYtdO>c%jso9lovn>NkjJD@LpheT?1yb2k9bgp-(PTd+~rM*GUAP=2u1%PA3%VzsI`lzJF!kQ){dO`P51nSlBUC7wk5!k}&6DUg3%*&$ z651zTkrQ%G_Jf0*9#hIj=H`ZryA~A$wM$ba_nbKUwz9)CH^XCWMvE+T-YhRGTx3Gj zjlw%uWqWpK8&YOHc&y$|xKHcg*ZT#~0r@8|=knqPC7d@e`5W*H+JXjdH?;5iWzgq8k(MpjYu5d2kBg!!D)_A~+CCHw2 z0Yr9TU>-%JV%-al9f$FS0*n0Id|+Cp4l* z**O(#-11HcGve^hv%bE9#Z32039FCY3|>j+xOULy)wDMKj}t6#L&FmA(?nog1}?1A zPYc`sG2p2{*yrkFj+Jyg2S-QSXWK?3D%WY_yQ=RM1MpSbpkb;HjE4i($}8 z98UPXCVlf-Y$^y4eYff!MS9||Le(|db?eNFSW&c_rG|J=s6+_u?rPV+W(~iE@{8`D zRP?HuzjoNcNdeAuDZI`=SEdVn$3}y>gv<{)`VD82;Z?P(aF#lA3~KgyYL0SCJDApv z?F|LWD&d(8P#K5IGiu|P=07aUhu$7an}QFY_O<2v_qqFy)^m1VTRxb1_LiBlNqzJS zmVb423UdpWtm01o$y)Q(eJ#_v@IaXu12!7UH$vPQS2mt`)qUR7I?z)mhbJjf7#4W+ z&-K{9M??-xav|`EbCG9J$JVgTM7_~JPJp!-9$QY5gHlc|aV$$b!k|)w`fIN($xz_B z!_&Cy-yB)dU3pJ&O)y$Rxx4Nw2HzuDMGH5@R$I1b9i|4b!Um+E4nX<`rCl6|1^>($ z@8U)vTZAATh=*|9=_?d5on6487~8!EzpF zRzFxfjvIB2V+R@K2}CjkS>L~w3vukdZe3S*R9NMa=`AiD6)gd~B#%fE8+qBCg9m|L zl{ZbpL5DIR;xIC+MG?_blvM0f<#yyzMLZsOT0e_Dt#~687g)u6`PKtgLpCczAJQ?q z{nDNxciWEbpH2$13+7Fgfh`*EIr^8;A~-HML9g(Tz&+A>V4Jb1nM}J?De0r2R;p+2 zFVT!vr=PFRj&5B_pLr1Kv;3b-G@qo`s=h`)lKQ8rTlyvw$xSPI*=g(SEJ0L^G+u~a ze#5GORTesssZj{zwW%7zZT0OSLb|cBdFM=!t71(_04P4ln5A79V4{giai$OeC zx!I|XX{Z+U z>`~6(MVtV%5*qWhB>c6?d}Jzli+4=0q$IbURaOK-bk#1G)b>r&`|sE;bTqRc%(ya< z)>$NA)>993GJ1-?(N58t{mC!g6{}yr;<#B#y8STC1aR6aVCZio6eWK%it+9_F|%6F30LbZR>Kb{SfAz;{w2B%poXq-L(*lb=E-c0bhPT(I;rEv_uAl^&i_zI4cY!Ac!!GIB=1> zOYqL-*JrqYT@d__uzJza+O2sjkATXdFdA8B(0b{28>CZh-1^9T|Rjg6s*|arg4tlUo1n=p#ac;pU_UuW_9) zc;X0}aPfn9Fv&KV;iN*rBO*PYks7W7P*|Ar2i@ zC&YS%;q@SWz$&RVFzD+XfVuJFtE^+)b>t;qm^0SKc>Li8n3G)B)blfAVwB5Jxsi_s zLYTt+R4MG8BraGu(*-iPX826W(m<&ldn0FWA}7I=41<8;PF%YFkb@>Y4bP12`d_J3;1(SPVct>bwvikQ(QjpMnxFHdBIGtMzfX&0~ z;L90MWs#&pJt)~LNCMBh`XJ1Dl+y@8c=8!%e+Th9I}33-u_;=c<0%D9`Zhb`oiV5H zfPB5t5g3fAojh#EJ2z-jPqn`qDtejw^6kNuK%Li8BD(W69m;B}N@l131pSl0v$Y2T zr(YcdPp{FQM5%3VKH&1PhIKNqA)Tb~zqc;k?KcJMo619Cp-GkG%qn4T9v0;1LM@yP zUy2b2#4A`DJK;y_Jm!3u!`}gC!=~!-b z;cXdsrb3_Q0VJWq=Yt!b2SJms!G+RCJiTnP?tL6RFgg~78U2+0rREiKCd?a%NH$g- z6%N}G6X|_U4qH4p14W{=GARaUNrp!nu&hFP&T~KCJC1t5p#dEH3CD0V42~<%O|=xTd6RV54&Vl@jd=b%1W5Y=W}AD4_qjf zx$y0!#>xD>vG}pUm4H*s@&5ayK&241GVnY4moFihwbdCzdk>SCVPdY*N)v_}k=W`3 z3e`*#bGXpgwQWqazw3)ayJ&6&xYaZq-Sdk1zUmN8bUB}v4T~^25XJcM-1htz=lNi9 z0(}!xp5Q6jsB03!=Xiz)ppT$2k%2kmP=jYFZ)|AF>bn!4}C@eL5m1JsMwB*-$E%rqE8sFDJ8TOVcU~Q|gi)NXI$CUGSl^){PVB9L* zm*F`L4vs$DTbO&i@vmW^=al(}^oRPrB21KKOvt8f*grWOd{lbf?reC@(>Szv;39fy zNc-!?q6nTY^P@;}U$nF)%@y+r&>t%7_18B7>l=#%$KAD_?4|?c&3ufd2x_yR7qyvU zK6hxk$byZNKn(yqh+%t>i(tS03nERn1Zwnyc9FlKY(@L?T04r7R&OTKU-zS8=%wb} zs6t!-A9@@DCC;B9OdbGDl`Ld;%4)45A8ztD zEJ#)VqO3Z~D*H&N7ig)hZiPv9u<2Fbev>?`^(GktHX)^*&CEKSkROs8N2e0`#hBq? zBr@+alXp5~O;W<$gH%C1;^v}Z7DcR_9@cG^9@J0T%hYYg|2F}JnKjzNg0a@&)%Ujy4)IF?7kslxbb$*R- z%z1yPHXS1V*>q}cc}Gy5E(*fktc50(T1=j}`~?Fnct;HHJfMX|7KHFURur-{drz4A zjx0NkZN`>Br?8@?lh10IQZW5Qey&3?OMEjHK;ww%?|F3T35U?c>eal=IcQcoEr-21 zGal7$XY2+uOzz+r&fv+#O@IAiVK}V?f>F0P8zQ+punOocU?wB}qU{~)Slq`=b zV^a!!Wfa)~`eKHE#mt(1~trlJaI$9H_t&&KPimZ`dIZR|99qZ8e3xvD;1o zXy30%0LD3Jwxd7>&%CDjy#}Q6iWaum;hEW~C)>GzA0Ld)i%U>-H0ZIQ!c2V*Vg#y+7Z*gZ}ZksG*#$(`I9YP(FXU+_lc4BOO)@ z83Fe*_u-(a7AAVxA7z}mwtdGOepSZpBu&_f^IHBpw`wqdT~Igv*^&71PtvQ-vF&2D zB26qbUbX|RMpwZ2g%`mp@Q0&>2a3wuC6IL90*r3b18vyhV(0VPU0Ra)uxuqBE$;kk zgRwh%Kf{CcIQCAK(OSIBX{3kIuxc%Vn9~?(e8gY zxy$ys7z$!0AZL0`88;ebnv`j^#j>nPqr1;RPNAFa#R#bW0I>!gLJLpp=Jo9lIDkms4yd*nLKDW!iSra zKV(+&+U97RmTaIf;qboc;w5fj*(E8QU=E~eP};|`&SptH1&ZB+3=boW!nEo0G?R5x zzo`>oP8Is%2r~Pne@oWIl5Z&gon=C-#PA7Jdd-TM%1p%obqiuo%m8W6sa z6%SAJXHCn(*kePp(}sVAFdGgnj_ZYy-%FI3>X^`Ex2Zbo7X#yAUw&K?;Y8Dwgkshl zo^VGAp(@*=vmzC3Hj5jJY(I*)&@qGwj1Z&%{rSn=Smgdrzu9i|>!bm`#|W!jvz^32 zi})8v0;#dkE%6)^Id?aR9JKn;^nm(?pLEV1RH5XTVwmzM+l!MOG#3^w^l>763e1b< zur#iT!p2YnjF(}Yc?L)7OJYcRoMddpjn?!K*zu+s)!^tO-qyU4dN-}Tk{hu(g@xal zzgw<5GP;a+uHAz=$UvnzO$S^W-#zjuH4I!VPoO7e4ku7K{I1UQx1W~f zmaJHhaOg@At*y;#&o%8Qes@U9N^AFc%6s_)AR3ud>lN$Ei9l~d?qikihUJp_mme#CPn`hv zt81@yJnIw??d|8C?50q2u+pKX2poXY@3M`>xP&4c(twwWiaTQk?j8f0t+zfgpypoY z+~$)Y8Fmr0gC}#aE$9OaOxIZu1cxyrjp`?^;pVnDK5m9_m~z1$E2z&oQsb@+9!ta6 zla@=(uFS?tZ#C61R~SR<4KmbPEk+!WXQr1^E&xBFiSM;-{OIS{;Rp?Hc#*{NT5E7x zZ98N2S2IkZTTEX*Ed>6NedMhxPZPi~LZ90~Y}0Mctj6M3$}qwq@;*0OE7V(!z3orF z!deliH*PU1TSIIWAzd8TX0du?x^lh!SK^)^;+w=Ae%Nkiwovvw)%ulCRp(`8DeG4% zc={0xMeDvrB!)jur0rXuk+OHmZzFn+6H9ajd;1~QZg`bOkK2JNfr5WoWjFU}MZ>hl z#P3>5t@D!pa)@L3KGHi90WHK`9(e1jYJXPrvLj~WD9$Oi6Q0-Ncq^}T%euRo(<88T z0#Nki^d6)-oMNgjz^+E=+-PR(yA%H*?il8KVwOk%K9L}HRc=rv>g;ixkF#BpZ_V9%TSb+FDz zR0n%gu&|W0FTEUC_jH#`21_uG>@V$2e*`Cr+3WdsE@mFnx2hp6E|pd>qq(*5=lgcm z@BU|{<~KC9oOIt^dnu8Myv&ebxmF#wx9TCQx$l#jPu7_Y(F;!kycBFqx@+X_L=2>~ zc{#T~__}qq-+OH%uz=~M8@6RB#)xoysm4|-rdwqa9L|`z{rqtXY%>u5@^b|zS2X)` zMS@%3oAF)XBYYNZUb%!!bq>hJ{zaAsoHmF+X65ZPC%^K^`Fp9OQ6~S~a@}G#9j6`r zwvQlK+7Wg#1$YCcwy6&9$J-8TBE0P?-dL(eam;RD$(kdt5gYswH!5>N4oZyK$nV;f z1LavxGc^u=_y@7QcO9?)?S-m(EF%wSEah^S5ovD)(aoe*3~~jIh0;*Yx9tK1mN+mQ z_NhB$T=;+9vLnK;`WAy+TE3>$f5dGBQhjBYu|Bfa7ivACZ_DtyU>739_? zakktP@*}pdxn=-j68R~s*QI2^xODMZD|`JR?e#2P^zhK`$dgAg>_~(4evFodHy>Iq zs>AwFFH2(VL4EKcX8BSM#5Nlb^7?4qCkG#x-LI}qUO_GpBVx$a39=M#$yzkJ$>*TQ$7;eYe9{zW%`R z>U#sn`FnEPYs35Iiqw$asL=UO$2ovE&W>?vU@WE=^E?iGE@m_0)Bm=nHWpK4&rIi` zZdYui3&_M6il+ zVA78r)mN{$S9t{dkR~Z1u)CpW@JWXsjB5Eb-zE0*5V#mfR3nv^V9;pRZX07^KsRwp zHL1@blI@AQMso{C+^IE3AAUkB_Sn%41{0ZM8nO5B*?$r!{m|n4D=CZAh?`-E(NcJdgGasiY}}@4{$W9m zJL_2)e5i0*SMba|BhF2jT0cxW!x`1h_L*Q!;@bT1gdZ*LWsLJ(D?OFHykg$DZJ}HH`6KzvrQ(ZvX-B!f4&xfp?c%AQi2s0(f9nq=N+)|m&0@5@~jJXwcv`tYWd-J zQ{F&1rAR;b>kmnOeYL2X)u$Bk-x5d&rsHmszROCM@O56)W$77B4rt94Ev~6GWp4ad z`VshCVNp}Ktzm2<-HM1_p5Zy*=#|Q39$+v;tY)HBVvx#smKkPy8#V^iLNdMTr=2wP zVH4y<)i6job1z14cFwNYo(Cpv6jws*+pTGf0RAC9M9`GoJ0yby_Nr5SA)Mz@sGkq! z%|YwOE=eNi);U1Spu5Nl{rWH&*RF`s9c4mKN8k<$62Trrh{5bi8}>ufRlvL&xXTTL zrErM9;tdc!8j8EEy!3X0Lsw-%aOXyyYNHcwNrGr1iyyF}Bp{dTy;QJNTBXe64g@Z`J-8*c$x#VAX@tATqJ= zxU3FK>X1pNvn|ThnS;uFiQ5^ZHCLZH*bcF(EfO==Iq=u3ewhVWemeeoOrUUmCNW6- zj^AFScdLq%_8$l@>d^f6eEsUkq}c7Y`a6F$ACsc-;LLlVAfj)^C3@Z9K9{I{rZV(w z2x6>W{gA*n7YF`@<3up)jalGD$b55_nQ}%sp*4OKqpQmY%eD(=#(zLRFrcbxJyJT! zGkB@2?;?EB#2zxG09P9~=eWQpth8rD+V{D@Os5!MAi7n*9SGw^o-K1WedM07z<~_G z>Sk+t0{4 z__%AgK#{W0j-$Uf+CQA$j8TDKEFyl_>8;8CG<*NZ~=1MbPFA z`YWtfZ{5_&?d*!L-jDZ0X&HdF)(X1!{^)>ty|E)#+$W9`Aq%|Z>o%=-76+4R{I(OZ zv`z0v|J<54Pxmh$$I>cY3foG!L_<<<-)#G%tacMxQFM>*%dux6v!Zem#rBNh(t8Ue zZhaSq9Y=imf~do8VUTIWLB%NV9Lohr1y1j%MAE$j4c)Litr!vAPDkj8tu4|~uNhaK zxjcEcz(hH`)Z&8q^NUvP{329lHXkOQA*Z(dZRX+tx}g+eIzk-;`RoVQbon#}(B0M=IDW*R<4P-cNs`J^Xf zC^bUvMHM`wh=!}JVPCz2#ZRkW5|{oxJS&4;EpOOXMKm)V8e{0l@3!>;qxFTwPvt)z z$6Ozo^nW=?21)@&>q=@jaa651b(cNbkYKz;N(xEyV2^n4ejL z?9>JZTw+0d^Jzu9QP&O_K7_e*7T4|he}7MWSWAb-pSL0Um|XzT@y>+8U9dE$o--4`_Hl93-LoR^jA z{0X3Aa(makClbB6IOQa(Evu7`8iCvr`|;?4;aVYZJy3KzrHBs={Mj||Q?L2l%3Bu# z9p9X(!G-?P8~d-(QKC)f-#<4D#dG`7S8wN-OI5p`hePfDSStY57}8I@(v9@xjSx+C z3`y-MR{Dp&FCh;rIG4E_-EE|OjX1*VQ@uB5xA|}2#Tes%@%&_3Ke3rJNtcP%i?lXw z9TPxt5-;TTyfJYjPTu1i48$fa8!QiX_MJ}KYD&vY5gtKKoSf+c&a0X&-2kFa99cVlk4b#Ivk2jAUwgU_7NH)JtjNdgOPtu36OFt~WheDqpro3xcf0A~O@>Qt3m`R{?&o+}Mi*s6bEqsr&5_B@;A z@qE2NZnYxYHOuzw$_1n8kn0f81=D|z5(JKPh+m_(7?5E=pLS3)Z zK|;0~nCaL2-Kc9K><42yn92SIjNt;aHuH|(Z3VIF<*Ydaep?MTP$YgvL9#fN%}5n9 z&Svzk9V~G;vphoD{m^U`WErc)M3p*mnQ@lG*pU_HNoQi4TxJdrCbV**kCvpt%43)X zxxEK%QMSsXwJtEx4VY+G?syg8ZVF8Zz}=?lLUb*T-qcsdq;FTg5Rg;S$y4u~$+Y){q84o)&538s{LNv+-2ND<|>cq&s5WGlRJ+}axARU$V5F-5fS z+BC7<_X5k~Y122mBRk>$H@#Uf?vk}2>V0BhZ?Mn8@!;T@BYDOPRpKergAhe;A@Xa7 z;<&4?<}Gzj4&Nw?tM1<5OEY7&&XP%8A#)v_liN^x11+P!-{!YT1b?_+s~S}|Gqe)u zxDTmQ3BF+=@ZgHu&>2}oNx!ep;#r{lpN8jA<*QFsayArzHRFf>h<=*^Xjp%FwMc$* zvHm{f8tN99|4rsP3b%4i2U0gLvBNcGACOmU--y?6NiTD&c_aKs&Ad1YD_z$n1FD?k zD&tsYkk<382WQqzoN@TvOwtZi79M^$jPFN(+yNuTd5 z1yCG=T*+;XxC~Qb18AQo*e3QMA5#*Dci{)PC81)^YP$kfFt~&R(dO$*HqyU-!Ki~K z{U%WZ+zq{zBW&@slxPi-Osl)e5o4KFb<}EV^eE7ezxd*ZNHTn>zQ(=y z_A)c{g>*ZX7V@9>%U~ZI?KGZZXR^ri+%nlZANF=jBwK^;$c+5X;5@xfGvd7y_O^-X zp3K~BS5~#3O-=M{j+!OY?>fwPE;EF~`23o;>Jq)&ZcRKa)@&_n{tLE>BeIYEvs`J7 zDLf1uUwMz5x&QZ8qhpU%*8m%tPruFMj~WQqza)N&@k24sjSE?vzy0YrU)0;EP}k;6 zIgq`X&tdAbZ8htd>a#uF@uQpYoCf?D%$~TBC3!sEg99x%22yuc%HWMMymDRJypxJf z{fR+Mf3y{oa#--#Y21)PZCeE4dOJ7M>s{Tu(Iu1N-R5O=p-_6dLVxG-M7DH+We_ft zfgUX7ps5ckhKaD$z*$TWN>fYg@N^EF$$1&gb}r<$Li@ulRpdxKGaJ~|xQljJ1xdC5 zmy(H(!S}PYCVpA9CVc{33fnY8xT|hKdHV{yHVvuG{j$~RLF~A3!slh80~mLm@y3$V zzlE2HC?7lf`pvp&^>LZ3d%-7sr1E5f5uy7xj2BRDg(MnetBp0|lY&K4cvCk`>)vKI z%Hk8N6TP&T@T*y$gO7CNmKiUc*J;EGP7juLKg7JXV;`_e%rEU`Y!X3a^lx=1vZaw# z-XZ1~oE5)Cq2629!%+@^cDcqOz4@p2J%5dRe}q-r9{hZTTlL_)y}@(Ru`Ke~a4w8q zoR;{)mr|5YHwTehRWn1Gg^>O~~ex3^S3|4HV+w4HYme3=|xrm<=$Bo=V#ieoF z$$`HP?nCk~@qgr`BG3VM_raP7piOL5eG&21hz?GCp?N6wA(mct%)pnaXEn{HSZea^ zdmfmy+xcbo@E@%MWR#O&?Do!xMTBCD(=8K2@4{CLCxagYg0R56H4vlg2Y+Q0zh<~F z!+}n?i4UvwR?`OOuKx%qms0O6Kd}M=#9Heohaa#4QMFM_lWQDvPP@q@=7Z^hj-~07 z3hd+#TA`&AJ2Vqv@Dv++Fdi(mTFCKC8j{YJSr4$jLEaj0N z_3RrnefLRyH_WtON08LmXt}RA_Yob8Db`b?g&p=j@Iob-a5fXH!DqZNUEYUU>tk3iRi89#cgwE89%l5*XTb1>Irgq)fO%PPB5%bEb zyRTs^SK4RI;h^Ry@shEc-cfoR+zh-L6fLimwtfE6*_fwS((ShrUt?VF*S6+9sFH74 z+VqvZA_Lka*K#}cG|!->Ya1y!1Mq77{ilBHvptu7pG)1CJceFnImw2Ku+aP!#Fa zMbfc1_TYC_C?eW~s^W!j6ByS)M|l?bj}RsV>{|j!!el1uJ*5hRU1{zdluTx-UimW% zaC`~g1DmH?upgW0RjkXt_;Du6@o|XloFYuV1g%^^iv(L^TkuGSv{uxlG;$aRCRM>6 z7EI*&am>W;x>z+tyyK6))J+E+!d2dB_(4^+}!cWx(G*npF`52o5y5{wb4V} z#Q2ofZ%1XOrH-Ag7xpDY)4YdwE7a%Ynq~25Yh2*gemwQmqgm*#Jd)3Ze%>8PcLmQQ zu7V05AG)OfFN!7(qa|(MY6r4;=a9xh(g6K|X|gp32LU}Ft$lE6Fz_G|nO422VD?>a zRlee6UO{zVrjKP@@he@+ui}7mXqyfK%qHEoYbS}5>!rVh;PjjXq6g|l77VU*l{ga6 z>K5)f+izWg649Sy6vyO&a%#~f^FNEx7sc`K+&6!_uq-zG`Fzg6%_$Cp{$uqUnG6VFjx1V0j2WEqyWn`oMz9y6Vpknl z$i;yk(Gu_man6k27I=@e>$A{qt00nud<)8QjerQnjYvDl44G~*WWiRPDh4PX^M|3G zazztEokSK20?0V>ZFc|WSR4?jA-+-(XBmf)3?-NWiJfgx595MB0x22t$>@mb4F(<^MWvTiJ>yqx6N z6Bay^;Lc8q6jB(Pcy+@B^OlWfZ|fn8m}MWuh<#8&X7#jAv%19|U>s@Of2&{NPRyXP z-Z+NZ{=4qRf%E4aK3q7lRWWJF_)H(lhnR6>dPKIu6`2nU3kuJ%V846BU$M7+E_ZaZ z>2jvg{C^fd&-voW^3l<=pm0p!aZ{8#55})KQ(*^TTh*m*&)084j{Bb*6SZOcp!-%* zrwwBx-F(e&sLr8yQ-J$`ID^SNe_QuE@M9O8@8kA6EXc+%!j_jTq%FV+fL|Roeu^W> zvm8N0o^j}VZL+-&-zxx>*_wO41KQu-g`b%}F}iy}fWdw^OEc50JSmGE-sh#Nanugq z4;)PNbO6D!05%#dw*<_UgLk4gTZWGk10X<7K+{=2v*Kvatbpz{;=$V3Bgg`G)c&jO zDoFepBX`Q^tLsYfD%nFClK2`T2Z6a{Fuh$DDmSOxgXA1;nQ6yok=TV(mS+hP zh6BkwnjRJ#JX3wu0XX8gas?jrGA_i+d4RcGWjErF6yP`I{K2ZxxwtmC`N7%Zkq;BA z(UQHVSZPJu@6q(RI#ainCFw7GFv?QCsN=mERAfwU@qhKk)Bmj7ZBzr9IooNy%eHfR z52hS_S!g5k_l^XKyEAg(Ns!j-Hf{=Tsu9SFK8#^Y0_9d)tbW6o{(nLw+3kpW%VNv5 z0d`NUr=goFCS*O33*$fIlCzg9DwY4ml_8Aom)R==b#2kO01nz0*q?&~2k*x&)nMob zOM_@ewG$p5_l$V;r1CL|6|R8!0%^lszVYtdXK{9Z|o*8d)!t{w)cU4N(8L! zuwP?oep&Wjy6G>Iu`7aY3dXS`N3WeKdYNUcJ=#_RMlQY}lI6Tk7}I_KNw%m&mx<9O z|F5GfafE7p!`~S@L-u`1_E2M&Yl|d%S9Z#{NXx{85QfQCDOs{cxz@^3C>g~pb;;I6 zMT*R{xJJ}WmN2&8*YErZ=R4nf-uHQ)_j%46YOJXJY4t*5u*%Ii_SRXg%hpGMFWOoY zf-`F-!Mrt!Pc1S}IvAs5A7sp#a|}nqG<4p)JPA@*>H+4JLz(B5(qFazxXWbG@VXxK zsD_K%w)&J3p9?)9H^;hJoyU#~5FZ*ZtuGhE(|HN>>cz4&Eh9p%^LKAv_Rk9vKbKs@ zY*?p%)uIx#<||`%AAySc=5e}CS2%8nu5IJTp$cN7v>zkJAx3N zMR~oEr+(xiCP6=~NmHUxx-j9IusJXL92cXCNQ-x~!pHYvO$cTP{(dGeC_l#hmTrD; zEQ6PtPQJwsK^T7*T>?Rm4K4HhoIy)M+HuX9j10S3t5U>LxUA4i;iX8xX`Bsy9A4e85F<5&R6BH9TB~74bE^i%q zt}Ad+dTdN1nA7$(`-P?$mDRQ&C!hLejHMvZEk3i<`Pz)D^anxhXN=*t4~r40o>JU# z!WzxZaNbGwB<0FdKUkLD9VgU+6Bl_t!G0~Ahi!>Ua9T1`F548&seH@M*_&$r`e8%a zUQ~-_GOA9PPW_b$O-DvfSsq^G%qttJ(Kte4BU$7p+&WhC93^6m1XnXf;?ib=2zBe* z!M&AZ9}fjHfe7=DSiZSQL8_7}vF62WBDj2cSd6H~=>?Hw?h+9B6mHmz>-`3snQ}u9 z_rHnP#yV^58|*&fPf?sAhFtt_Q+GxYi_{sh-FbqCwF%~PX5 zvRGf+wqERL9M!lYGHmBZdjOJEUcD-#*7DpglhNps!XM1(EztE(rO)JdIo(a(2lNIa z>RBNgU4MbfWVjl=cG06~7%*^FsP9Fn1mB+F&(;BatE0C_xr#(HkvXHXc3%`@%y*jL zg(S=h1cQhT7CegLOQ6^jRor~Q$x zd!r*#>2-gz{oBLd%BS_`9x8_TKvqU{-X6|%J*PdFO^a(?o~YkfyrnY#uKJ3#D5z}M zJ%2^t>EW=ySTlNCPj1vHEbPK)!w@Gx7$qxP5tTXf7fC0pIcPA4UUa)+;7B8zb$w*; zUH9Hj&Jqmibf9mtQ2j+?mXE#(77crU`x+&g=&fD3D`#mb_j~z-q4D5M*4$>VVal#x_LcM0=df~XQO=bvF33pU+&@Lae8nF?nn z1$vEWq_YP22|~Q9^!OFXjom*L&N!mCjTKfUDi~#gxbBSqBm)`+=An)O$E5@HDWwO^ zu&-(>{L|n7nkOWj@3$cEq_yy@snpr6e7CQRqas0R9d7pQHiTV(^7Cx{^}aworM6d_ z=xb0I8i;hMo@rvWs5`|`H8kVL?+W3Qse>_mcb;qQsbJPmkImGf34?5R{1F_>V!RJYL$Rl=4 zq-ogxy9&(Wl+dn&TI-Hm0e}t@)`aK&c>6w7He_yIV`N+M1B#?BgOHk6I(Udt#(elb zh9K2M0sjw!e5N|J_mw#HHmp{%C=yJ^k{eon^+w6ikB(d5{RQIChaoFwW}O<~^u0mA zD824>%L1>mo$BKdyr`i5vPsp*F%MDd7eVaRtd##^s@(KuvUBRxL5w!vTK-!9Vku;z z&?v0LKmj?&bJ{&_1|i#kSG zx$fP%bC8G8&bD^?JdL8dD{Z}WXtv;Z{OPy@vM3Q`zHU3ZdP2%ZciQap*uwDPg7v1h z2(}fYL23*?Lu(JEfT_#dQXkwrvDQC(#_Dq!W*wfxF)}g4*l6Ol8M4+Iv~`9*+?MW7 zw>h$WdtBO1GQ`AG^qrj_7vlsUBjs3HZEm;=-O`31Yfq<578?pO+*6UDT@146crcka z^8B_dI#PoAQGohMMpw>N&hG*j__523A+n3{4;(r6lGzY^xlw{me$**+OAhyRZ`Cb) zQ^R9uX(k6YBH^HqDbG*dUu9^HJ1pON(Qorn7}&H0xPkoQUMZ?|adg|2x{Bf>dKTAA z0UYUjusoPwYWkKRdyn4eF)yr1tT?Ux@)pW(UaqeocEO4^8Rql>xV+ZnK2%a%Tf*0L z#kz1IrCnWs_=Z2-TQUbN{pa#oq@~_VGkkoeEq<7S9V&ykfqn9Ma6%C% zsA4_-J)yXBM6mC@ojIR%i~;ExH)f=xymB_4E&1V1hddYKfeJTX>B*^9oLewAK87<6 zNMRUcZG07w?$Dfrf2v7=AKD1cYs3b+g5&jx3ZXXI6T*5f?7UDsKlVtEyaCuJrwDQ7 z>+5Si{%PkXEVvRl0w}-e1IGFGH+4#i;KzQYF6j1cGw`HJQ4q`KF4vg29NnZ%bn#%f z6?6MKzx95i?rlZ;EKnSKs+EVOO$@fRxBpUAq3?uZ=w*`97u(Wr_tJcs8mM zAxHIN6S`~lv>zlRFI(c8-7W3Fg#{@xII1m=ct^F%I&@= z-27zS>MDO1)X+AiN^ihLv-Ka<0#KW4^U?G>B@yX5{Tiwim#kAf5!X+{Xlzbp^2sk+ zCAbaLHK<9H5NhbQ1Gz;?XjQ@_7iQF~X?MjvQ|b7%>%bk>nB%_})(9Xz5hz@VeTyPd zOo&l~VzGaKAI*4wK>CW)Cq{9D9}mEkbh?{Nh_N!&uQzYb<3{x02NHU0}U#wesoE;Z74DbEL)}I}h8^n`$_j_a<1>Dj zF16MY8Exs3>&ri-6*?8744b#CVQ^yE}NLSl@H-(=O5qKcwbw(5%4zpgD zESeok$$WqF^nZn9sFSlj@B`qQU`>tPRz#6-wuzFXGN5U>T|eU$Vp$qt2@w+cB#|a7 zG2$!xXN^#4Pggx_AH95zkGj>)*O8BE?9YdpX)YXb;+LIau;#M?$b*0kXN`?XF81!Q z^JpG)eJoRq58@~c>s<_GE(Q@MYn<;uR=qz4`t8C2Nb9Q|G^tAdd|Wr3J5;I%y(B7p z4&Z94Uh!J00!`kt&;N~;6Snerf_4Aq?+C8R>&htx+hU}-N+n14tCrZ?A1J0uY!+J4 z1gKvH4hLfV3S9R&iaQt)og|xG@L!$JSdyfu@KU5uqGCtimoHzsFskApLuhgur8F4y zW7Zx?MGy{{pfxWnciyXcD0C_I82aT>>&b818{^F8!*k{2v6z~;dZXD#o>6tjg}Sy4 z6FVa>F?Gpm{;9iUyEmd2gE%+-SsR=VeyrU3bJeShlH<{5fl8Qf_sjLUy=pd@`e-l4 zX}NL_v1hxS;0Vv6Af?^AG9?^odVfrvX2(C|2n zcRMWKE<#~lpx1jSePo-~&rkj02A4zd=eHMNLv+Yb4UYu9j=v`{H~F2ZVBoi826c?T z;!$hkJ1DBzCT9?~y0SP#(TKEDe=eNKMk_C)d(YVIR2!x9P`j0>$D0A})sY#U$6&&M z#9<3-6Wz@4calDcE;y6L36AL}Yd;wbL2iW{l`VINpQwV}w+utE4N2l*Wqt#vg?l~0 zFjj8{1>I|OvTY%u@TX}A3 z+)u1mY1HOOtr{P-bsP`t9@SXG7;1KBJ<0kHZA~ay@u$el2>Vy86ulia+|kG?uUZ`r zSblD1E1HG(yzB@)lk1kf<;GOsJk6(~$!Z!7rpd9Sl zYP?p9a=+s}gi*9R`AgmlvwIuN`xB{ewBoL|`-&1)JR4F89PdzRGgUZMbp8GFrjZEs z5Pf!EO0@W5rIsS`t`3TGDa(dWY~(!hVj^gSC<%=~4<3Wk2^kCGdeysGFw{Xo!BtL+ z)CbRiDfrRAgC}jLXc1Y^WeN?A3w*+`CdX5gu9oUE1Kl>jkJADS3UmFDE38<>fD8i} zUVwxaVX&(M1>fq+>+xJh#FzTSd|C@4GnUcDeR(Y7;`85!pdy$9lrQw4(F_BDOw*5O z4+D9N^?Xd3xM%BslGKW94GmbDU^da5;|Dtz@tJ43g>(hlj*l)g)n)lh8RW~HVKUlD5WTA&Ur_X6EvI|R*XI+}soId1SdLV@7@|I(yc z8+^`EoD;p8kKnT_ji+Ib#jK5oIYdfiUMdn5a#8nioh-!Fqab7#Hqus*`GCr95h1t00st>~0tl%C7SqxKl0N7}&wTe>Xi^zRg6rRGxZb9(xuS4TI zIF2hy8u1g{_C3~jd>+L7DaVCX7^nhwJi#%;8FWUprI$ww!k(&*lk}-l^w1~?4NPx! z)qc6ppcLqJDsnTz5&R;z5V2o+sJQm4^CEDM(L_&A8$Ds1arP}R(7fm-U6$_QB}q{4 zt&PbGzsP&j)?)4vIqbsneV!JH2wL*F!+$Xq$hauUrz=eF%tzh<`4i4_8yok3>3YR@ z^53EV&FC~%x}81Ow{gRg*dH6K;r^opxA_su+VB627b+Tt%M5EmzXkkmnpX*Bq7P|I4(S_qX)XDEi@}TaO;jw~QOE<fhDpu*rZ-i()o@~PNn>w!t0}B+Y{n%ux#`8Ewu^bo?zsw7>pMY> z*sjcdRNVTY z(NXDHqU?d+8=~dzhEdx=!Guj?-h-n;L4DZnmo)v;1x=Qmbo{ftqRmkcy~l*-$S0wF zk$NJF>v}(zF&k)7vk6{@H{fQFWol^bBh0##`tHzMIV-)4xuwTa{C z)*U~-mdl;x9WBPOsN|5DZ0O+Bn}7G$=dG5}LM^?WeLOAXSk%W5h1jfzbgm7TGLmGt ze${3iXnycJw^Pg1T)3X?jRz%|Ee`)AQa9V}bn5Ptpb(>ibXJ^_!VR?_K6d-PR3%_` z;TG5tCWTMHS^J_(%xLC-+z}Mly0+zN^N=-h?HMixlyE@hNV_BcDH(;8r3Al`O)M)vT^SgPLPLG_VNq*b7e*zyS&^xMjiyw6opSxy@ z#PP?Q3#NhQ@jMnPcg0%7z<)1FO_NG9fjy?h-$|$-4uIuVz$3AgXYgkWs5>BAfP!*3 zYs#t_Tkgbuu$pEzzb{v|APk!mizh`kPn-$!URA+P8Nb4T$P^UF!QLZghzu+U_3Ovlp`^ zQL-V?S|T5dfQ3PQpRD=`2PXz^TS-5GI@;;Kcrow;UuYA==inD5~Khk zLb@VGx{B_g_f6Qb>69jwLwx>WKOU~XXbmU-8F)bbs}QX=iTP&qk?eWLYXx#F+#+9Pb(LTh)2T0&hk!McN1FwVW9 ze5&sLd3#$0OlYc?m9Ak;g#=!8I&Rx;bw=mJjp!r||1I}s0&BS|8o6wMmOEU_abmpZ zqHRQS@Jio4{3yI`ro`a=jEJ8PvN>Munu`;E%o|Ewe!cl|(LZDIqtq9<#%uwy_h3z0 z7r5iN0Qp$^`oo4ILf;Un^d`>-Ums+U%sWrysPR|T25+%sO}dK(Q4pVw>t8}dp~azj zCZ%-kYaeme`MADg+WSANed3L7xithHT=!f&RqFG9XOcxjPu;@C+O%2Rr7`wFxNM z#>%`gOJq)3n@%(_jBOiLhsAmHuROz@jy_z~7FutPuw&e38yqV@ydX7KDdZ!<8leUI z09!-U)}7hcHG5_9C;MM7Gzu<#);3p*NKo}HJKsUpEku?F2hQzX>?Qpvjb4xfnj{l& zgx9G&mjD)uK!xbJR}^POV4Jm@iV!on_g^udE^Rq_Y-fe;7~2w00Q-7RpI$9Qu#%`# zyAM8BPqAu!##K%a%#xZnGe)uR=KCpVXA8(L?(C=s(oi!DkmwI>`u8zf$ zb3V`SpT(5Et$0K5H=R_csXMq&sbTES zI-pnNsqb_5pkm*~v411u3hD#YH(JViqfCXUx%&@dxYwqK#7*Wu%KZ1oUuy1du3yiJ z@@JL@RlPlW-GS$LWsTpBV^k{i-IuK=Ww@&M{7u?iFFt|MrWhO4rF{k;5Wq zaOIgU^7Ii#6BM2_{|vV#sz95VAB$@tD(w0@|E$yq`q(6s(kLKZBrB|sn+Kh>nmXiL zmixjQpFyZ=@?0Rpk?JqM#R4S6Kw$r7urJStkT0pLQ>08!_pb9=kC96FE9g^?^(=uw zlV)vaMbV|p0R}`83S}W(Z)UePS0HZn}v+5>*5T3#=3(;WZg_pNA^Ku`z_# zRbL6O{X{U8gtJOw!(F5HH|MN4yFKd?_$1hVPGYwj?d*52om9=49|dh1Gi=rKI!I(P zxBkB2+RW9%`_#HvNK0daP{aYX{ZfEs*xSv;)rsUj_iv$H1(O~gC%sSpO;GFI!EeWV zRh$Il_W#NSJ3OeDloYK<($Azl0=XoCTm%quyT#tW65?syV#7nEddF8U`F=vdY+3=+ z#x}dx&QP4mWEQ6qh)`7ehc9JC)ycRNwM(+Cp|iv=GtNo0%<(L=4;LB4PmNav6hDcl+GJKOLd=H zX8}E<_8&J@*q;N{0DFs&;IROs-M43>St_;n_rO$gQ zKZJ}Bk7q=2Wnf0#+FXr>U@On8U&7`*V4Tn0rKIT`->87KdpDOA!pRjp0wnzgd6l)kSgW0lKa~zAXV5^9f zUMoesaEHp%iU7P+=bvP4%$jz%2qS(b)izL;mbzwB3nR-45~B1gxzZUM|q;t?a>ydV3nc>LZkEP2>}EcF?3E@GPJ_nCfil zz5qNU7ORW72I%=mfp2G3ZvnPZPC|A>-=p`dT$|fUV_DvMcJo_~U+27v9uPOj*$^4$ zsY(vp&O~O~TnW=fo2~l&@t17ksFUJ#@GWtSUwWFDqxQGotPq%G?CM_Aqe6t+7=oRe zRZnvh@(E}C#E0ELLFCX+Y)keAr4fkcH#EOIZ2J>&ulG7-m#4`SFt^W*~G zc2qt@&(WN1ZOXRNsuAcJhk|nX7KNIxE4d$P%;0SS`FQCi}slFth%pf_S2#*njCED*X zMy@Pab|KZvhZ5o;)8sA2EvEAXdR|MD{$U~u7!pm_eqy(cy+KTO`Gt~-G%j6MD}snc zdDhU)-m51nAIGZ=_T3|zf54TM+ZI4@lbp)bMMBniz$FYqwDs5bJ`~n?wy;WhPk}sA zzSKwgS9%QXt1bh%ch{+AE&QzzM(Ht=V}wK_Q7W!tP^y^I@uNUU+j)!{n?npCd4lwE zK`(XnKE^Q~Zl#V-d0g>|&li*l_!n^>riX9&Ri1dlu zG{*h@l{@GxYliY7!(WYNeu}7JCCjK=$rYte1m;}Zd^D7S>$Xw!>EKEq&`L!g$MpE7 zaI>jiQ0-EIaG8J#H&!utxbx+XE@1M1f?b*+p|>&QQ+4O?$ttIy>QlJSTMr$PzAD{F zKTeC!jNMD@S*)`wBgDj~(W4BD+Dmyos%W2_L3nfen$8mAKERq$@W17(+-LY-q}d?2 zZovY7Cyk)`g$*D@5Y$u>7j9#w4NzKLwpCA$1Z^+4?m@Q><-(lN> zmdh;?rj{=9_=j!&Oh*@HIxGN8p4P44?krL7pmBE`{ZLfrDz~J`55j#-wNyfy@g!Ls z;TU>JNTZ;Vz)hL6|Dtfk|CV7qF`94|#TVNw&)RVP#G)mJZnoZ++P0^rF16nLauk(5 z8nL{^Fv^NFMQ0hHhnK%tv?@3zm;0ge{*+u->U(W=}*Z{fJs;y{A^1n(nCa15a?0yFszJnMe0e3mrASCKTAQ1!ms zfW<;|R-T250MNUS_zR8?Wf z;feJD7R3Cp0mZO0Or;dz*AZV?Uu)1S5o>H0HL2^<#O&B+~4pb$ZSi z7I!dfPb|7Yq5PaP))+Y55J0Qz7l>ZC5{+`w$`F82U^`<{iy z)PE*C%WQY!{e5ZB6Sjv`bcyMa(ipUs<~1w)5sTh!Tp8KApN@0Xr3F!i*K!=GO3vF# zAMINDjlLCQh3BM{hJk||KnQQGYH6S+5>TV)P6_eBZ0WFPiT&gv+>L&_WH%@B zJaP_)6OHbBp69@*dpG!TS7LqU)4^=iWOc}h@FaXi)S1EYE2{*OiME?2=fJ2+lJ&1v z%f6G_DrSu5jaO|K!q6fA*$~=3we=c-p`4xBge2F|cbngAN+Yh8kHM{0y#iwhIm~73 zX*8S!^6IdM1D~6`0rHr*BxC#G}42c=@7w!g`3vWrq=kvfIRh zWwkQMbOi9l=mi)oycV8{Qz+v@@5@vBH#B;st7C?mqsrt>AO%dC-;qBfK53gF*u>L) zW6>@Ci~xw7hdWR~if;Z&TTbza19HcAsf~BQt(-6-Ux0;d4u6dU2{$rXvsD^AIi=1* z{y`rizwrHJ$vzw9vG=Ew_~DD4j8v;HT5ZL}gXX7m;PjQ+{5d%vv7g{?OD3;YjzGVx z=FIrKaoC>wvh^!^-uhDOu?#{y@GvyA^Rw~AEcNnh+}*M<*?pAApEaeeZWyR42Kt|P z%PVMz0+WLF0V?EODeu&#uKtur^8W(98wdBG=x8~_h{x^%UmT+(V)>){mbSF24`!85 z(z+NHc7D2CmhU96<4p&-4h$oja|(@FFQ7kPI}}#?Xzfyspof=eN^gVXsZE;~ZX(riYJY7mTk>1$|QB$&BND zcr)4tEh#n(gg>qsME>JD>IO+|waIC5s~jLsQRiKcBzMa!cS9=_LVjKx!&V&3K3$t+ zCyJq0xM|Ltg@}U!g#WYyPP&VH{{eq%;-7i;)~<9cf0JxO>~(JP)Ptj}_Ne;Aek1VV zTP@wI&UmD`pq?tI@6PNWypw>xH|1)Wh46fWG0*&Mje^$8Kh;Ah%m$|kLS6Z6%2^L0 zUcsAU6adPJZA(&k6kn7N)d(Op`e(Ir2<4VgMC35tVx10k*~K1BlR0G2S!xVr^5R;K zws)aDG23O^LML&xh+32t?z3v7DQMH!XRtq2{=8~n{?>b7QJcz#PMwrd(3j;R$G}g{ zg1~Px?$7T_Vf&e(mU;YQRb1KmQMKHN8k#!?Hp*xxM<58)sWXJ zA?_A}wP0VvnyVrCt}@p(QoA?_b(fa^`ZV6;oB$F%I4#6~0<%lD=rgXg7i~W(O$zgI zLH#RMpSRe{5U+o%>^QeMp~uxSheWRVu}RcfeTIyLZk8bSi(h}s7=}tmi1xLPQ;TPH z1%i~4ycYIMvf96yW~?lMx?M`QKoGtx)!B<&B|P;RjsiGwOx9DNN$P6qHM<|i)Y!-c zuXuON^Y`8D0Ab+Z(zOO{l~XFp?7{YB+bj4betai{^ICM{HcFjG1$&^g&Z0AE z0#iS+mAZCX3do~U0Ezg@hb}E57FER$V|_^u?8)x8VCr-)>#d^ht zx!{w@d*DZ#r_)$$gJ*3xBNaSUL}Ryx8Qp*$hGtURXI!BJ+F=_tHfmRS0DY{ty9Bwu z*Alxbu6$f2vdaB#&g5GuwXf|p22-Dm0NNagC04jcb+CJ zg<^bIjH#{7bnRX?E#?W05x2A-m7DIqm5$2C?bf@Y?P73yX@ytOB9%CWE9kc+enX5A z8M{Tlpsy?wVd1MeXK*QhT%OGvI%`lbY-Z*=`fVsxShpRuO^+_SfaSnxOajbmwb*kL zWF}&?aMz@%L2^S>(FcrKicuUS33*c7(h14EBw7TgEpV`n@K}+PA`uY;IDLY^X3OIIBYXkSWkaEQ0I7(qB{C zd3bDX5XeaP`x7LiO*a*Fdz*HWP%r6ZCU!00ng9@^)P8J8`TWv@Zl&l&36YLoShHI~ z2}YR&(Nfw>(cDXr@d)EZ$Xvt+&(-FdM<4jY7c|X?T^`6r#8^bV<+?Xs*)9Grt1%@irmXYr{)Q#0Ku75b*P>m*zIeK7-d+xZZba9a&31w-HVl1%>PPZptY{ zbrzknU(S41SgZKd6s$q737449CiFS0ieS(fkqPTmukXl0WA$*e`@WQ1){w8JoKmez zd^#U^377HmC-MI-49pWNa9a4n%lPl8*Q`^MsH$5qE>fhY-k{PF-*vv2kJkL;*{`19@EF10uoVpM(qA`lpW1v#^R?_0e7+J^GtcU)Ck*X3?# z>5W{Nl(Fc9zCVO-<@(4EM~S5A;je_UY~VgP$(YCGw=(b)usS`}%aP5GyBP4{7R#n9 z5`=Wb>;hiM8BlaDoLu;qIk9cWs&i+}kuNF+r}h;Wx1FVWpkvza(y!Dppf(rbqA-GD zsek_jy|f%qi6e|ubK;(#$1BnP0Ex#{d|~9Ufg!dh4`sB3%d(mWYPcO~xV?&`e^pGG z?$*j1dp-qeLI37c8>O9-Gtk^Eeu`PSP#`mb+n=#O+3?c$94GgQGY`yBTn|eR(fj=nRtjB3KFvoaFcFs+TlJaiZ_4( zQp^+e6{}6&Kb+DpV?5h5+byV3rME{scxu%!M55HBwGb8w4m0u^TJza&q`z~4TyAfG z(s*nE<#)t%Cd0%Ogko1}`E=ywDMCPN0QPFOP;3uJ1t?m9X7s38>-z17^#C3P>mG-gb@78MJwUl9QnjLjb(l4V5Y;6RCLCtr6 zs%E!cbb{BEUB#F^FYuF@KCW|_NZj_1U%WcZO{zQC`l)WmiNmOk z)fBp5I?Y2!T#;K<3#(fC@SK85NPag-;{rPyW<|`x-DB`if}u*S)K6~0E#6`le~H+h zd(k~p{hqw|+eblw7u3YIQ9_LP^7HNG#VscQvKIH`D2UO$jm^L@Ul*7K-z!Ayd@TR{ zh!{P80bNS+sXlf2)4r2kZF5Iq_zjT=UmE%NQu3ne)12C?3C)BlaiGR^mRcNRY|X0~MhP z<9RLJ)S@+x)y&bEsW}1bypSNJzC-<-ou64+>sBkG@lqIR^Q&Bj@zqHMNMDN7-Hut= z1zTY9^Qv&h<_PJa(+w#R8^r4(D?Xe~I4-H}HADs)o8I*rEfB$z_NrQr{@psij7QVwLBVX+>mg%H;?Seen>J z>uK%jgyuufb?bM{Hy#5p&2FMj*Io*NbznmYw!rFQvEeU$>y=YcV&$6byP)M~a0hmL zzaeF+wRu(l#V0D0vG6-T!#(`hsCTk>yy9?+$Vsw!0Q27S#uecjm%n%g3$2R3(6w77 zuNu+Jl^NcsCt;`2sm(ZC|LO+Wzw(Vp-1v*%%mYhvv7|DU7W~ac8^AZm; zE4Fy%qojTSa#NYmO6Yh6w>`OLrjfVd`9>%z6-VB!d^ebgHVG@eGLrR$Dvr4Bw(4`r z(VNz)4jEE#g59px9cRgBj@0>E<6N<-wU&wAy#X)moqCX$pGd@MbTE4Q6WZUoqG|uGAl^=(CrLX|a0(HpQb1 z(aAm4#!mfDseS@c9pgj?=Tds#2#RMI)v){}EUZ~Bv?J9?V+^WCE(_P)NJyfk&J29U zts8~D9ks(DErS{hE1nXdEpyfJ^O~E&3WqgiTz>w_Ph{e)Fd7|u?k`i@_X=(NYUprx zV9CIb=_)mQ){3M?)zW&Vv@G$Q^qtf={(!UIMkjUrBKshhB1oduK*b+9NEYRbe*Wu3 zdqm+xk3xOF9o5sAL+92rEu}YK&`Zn5{r)?iTe8J~Gv1xj8iD%j?N9HJhaF3*f6AI% zLC*Ty6pB41>{eJG&ENLIKy`wP%i91i-OKAvDF zv@N1|T=wAvzs(e&WdMfg4d=E4y7r_H{p0IxENu4|JMlL0RS^t_3)b`Kv2}q3D)eB2752 zhHvy#PcaGr`ZuV5SZ5Va2JSJY=?Z$mK++qWT9S(u2p!%HYxU|JVxC`?@AYY04i`fm zbhAhv=J zFR*ts5aKqxylQ?a|5TZJFDd!cNDj0It`hy;8xM!qxHbGx7Z#2kPcFa6E*@XXr${VE zX(e&+q-kEV3C#D?*f3CIdDKa~d>FrE_k(^IJ+@!9xRr95O=Ud7(dwgoBl^|T}n$3ugP23Zop~@#&=DtC?54UqO z!I{Urx#6^DzIS%7kMMW2tgVhd&=ym*x0#1qhhjAF{@255jMY^_P@kF1Qd8@?%ys@) z4_THpkTMrRsL)=RBzhav#+?eDU4Kxaj`!FWab)~?0SgsT`d&cw$kla_it=Pd57TGR zWww0Lg})S#qx|IuPNGq?>qGvW$Yz3qDWrHyxpXUy3wP*w1>LV)_zd^_G&(>$^(g_H z;GzqNcoO&b;O4B-4Qy)ZWZm@kPalU-f##+#Z_g5OMUco{lPvKFU(G9jc=XH^fighU zpamOd&G@TEh+oM4s^iT!tU!^Y#^ zLCoi8xQ-s;TQKR|iSlcPF|+CE6+z@qmT5uO;B*|>4_K}F9%tf# z5Kok}I4TI-c-3R?t-`Fw2N1zKnh*?0I&WALHn(j+ z*}15$wQA7p61a7Io5R@)jx2fc@be=#}~Uqdbvo@1@zkT?wzUwiPdIT+MM1Fi}9)I&X@>M^ckZk zG!H+hn}v2EVSjtANVhJ8FHHBX{|5(;C9!+IfSPTbqG`zx<{XDVjtw(NcySm0QzLsa zZPT5S?@3AXtO>a+z~;b@H(75K|HNNeNUjtndXP)uB#cqF$Shk%JwzMqs^e#b zAQP@{NSZujDg&Wg>eX8dbE`T2+R0Oa#eJ2Bj9S;7YYbzzCwVC;% z3C?XP^c-)!!fiVpwV8)U{hE0lbh1Vsw5fNU`O|Foqx6i*(BxmL-$%sLW-IUMUoG!h zT3@JyH4>no_PZ6*nnUawOY7=fV!gf9)XrK9%&>ygMB+{3AyVae6%XlF6Y#+2_uVmP zSTUBmnC6mhi6Me&NMQkg|7pTByn_NbKc$*`hET^;IRPJx4OGJQ?@QvV_$8O&k3{}s zkr4m6YLEpuItSEhKK#z|S5xvax(}edt}nAaISK`aB#K6P-ZEkccN00}PpUqfc!Vd= zn-|E<>5h!KX5Ml zc}(8r;;qh`}1D#LRJx$a7z7`(B-%ZS9 z%u8{jY&5uV^P+vAuv1U4PQRMmrhYy)SCj1)O+#Qlg41|#ARggyw7_r3!=9#uU@9L_ z8h|-d2kdJX#y~G)e8h)uab}JmXF|e<<3{Z(_$uaKzU8Z6N#k+30aBiR@qidNAs=Tr zT;#ku1(zmGk<{^P^u7)Ka5)zqfvA-`)HnbpT;Vknxy~q_u%c;P=6q31C2;I-h69yn z38EYFhuq9fokRUXc>>VZGpPeMZB|7tcVNMkAUU=DqO4z@-HjV2YvvD>eEsEWUFlc* zYC5vPuZ=-z;7nj%>|o+c`rlwJ42m11mk83cP%juST%R6J6(8<}w_bFrkxi70HN;q- z4|!}LC>dL_dzk)TirdX-YhVCNJZPn9Xg_HY!GWKT8C1s$E!n+2*&REgtFzP$ivXB3 zZmxlkoWq(;jM)4TBLoc^S2?NbVfb4y$_BvsTe!=2iC0Nq{X&Wh5f150LxC*a>}E+5?V_M?RQQh3$v^{&Pc08C`9 zI-jt|GW_D-Wq@9Cd3e|I6nlZt~PTKPFN&`oV_|pdI0^8 z0RLhHkuJ`rlabnHmdjMZX4FsCE&tg*K9Z%)QD}2I6c*#0!5$0Z``3IV^k=4gH?YoB zVjp>a;Ak3fzC-+7P(3Qrmd*6K{Gwhx{P~#TGKVDV+F91bMzL)X5AKcO1$MPZ1Ut&W zX6>(BXPF7t4+rLT0cYeAu7(8k%;r4PD0okp`=Thl{>nH|lbsphzMK~3?n3c!tQ0dZ z<6YI+le6_>!QqHJIbJ^#Fc{AbG z-vW?K6s&7pWID;MLjwJ+NTAJY02wkPP=7Jk-^37OBl&(FgrGe3qPWa56)0(w^K`y= zCM^FCEpt7)dxu3Bh#0@?F3TigaCVX`LSNt!<=%NP0K^=ftU%dE&(m)fbEBDVox&)Q zv!ug2M1D({|G&3mS+&Qg-gWJ~ap-W=hYuX5{68%sS`IIZL>aAI8^NNEoS9+WnKLL} zw%dZ1VD+Vq%bg}MUYWJg7gx343XVbe_B(GW<}OU5hmF6ogp_%5DsyP5 zHvmb84@Jb-=qDjM;aw?h`_6GuDXxcu){#d%EWEU$#jUSp%iEJY$IxWvSO)uB(!`c{ z?nDeNiGPefGh){Eiw!!)B~h@YY6wF`S+(M*xoYzPo9DKpMaP`$tE-v5r7sZGex$)- z)}rI&CmBh|=^o&WndHcZS3CT5ymS(bPYt;8ydXVB(UX#>76RcV^a#KMo}8cifBJso zxSq-D6fjC1%YG9~Zj4ocuqQ(`MPo}gwb(5cqTd3S0K^_citb&e!T-ox zUNTDL8nYrMcfx$PAZjONFX}k73L#MDx}A65X1CUz2@s4L{{eW6R_pgXnF`py->i4N zk(Z|1dU^>`R*ecLx!+=@FCvukt?%vWu(y?uGQYj}9=5Um*p(2KN#9?wVcO&*5>?}A z*smX4y-l@Re5cwLYi8kAJ4<2bk{%-?FN;0C)qGh3S}^A>9!J8QV=v#wd)M*zPrnj; z2KPaZ@=1v0vTI!h1AIlLkop4bQ=$=V*Vz>utpP+&))a~8AZg9Kt;;6^t_&amay@#D zu01YuQXDMJ!4&CG-?UDqOBIZdbbqeqJl0#;ll((#4W`DLF0LQA+i&%G3SR-KzOUyQ!z7^7VvXY?GP#cJXo^J4gB-e6qK38G^M}# z;bv_pAm!8k>xAy=u`_29+gR{S_o2BYnprx}9o8qcl{<$r?tif>3kU*t5tsU%oh#^l zGpJjN$1Z)gE*ZFC9^6;l6h5G8ioIIojG(he$KN%3VWGWU6z^sh^|YQyrH9<+@7{zX6MJV zSFNFw%)<-d<ho+oWr=~S8eKQs7b0 z*(1Njt)zaO>uxB-i7`i|X>3nQq5iCi54aTN3^t-oddf^pR?W`1blDwvN1IVw@id#Q z&6NZkc9s-gsIZ`{y(4B_>V{$9%2z&;{=wMQY-D4=8TJqME6Y>bqZc-xUl#R8)HHpM zK~T28F`oIvA8Hn?@m0(Wn}};a;j{%vhb0rlZ*#hs-*xxs$>)zwC1ko@WUt;apgi?L z;<){|I6}N#3Wov>krFa2_^DxuIDi6Xt5t~HNB$q+2^|-M({hD)`upsuA4SIr~WX5uFIZN*iv^cE*Myi9QgA+I6sR8U+^v{UkJbc zK9_6&Ns7qeB)mpV#0`l5WToqIsTBVE>x_LlmNgl*+yyJya-xX8Y%~x^ZA(tT(YB$} z=&xS-Zw}~v*BIVLW1DyMPNcNZu19lvKUe#5S_}3igAfu%)ua1>NfGrt+BYsgnhnJ5 z&_#J@KVRXE%XK=dziZs4@Q~TF=>_@Ht5ON*cxhK63s1nS1>{+~{eDYh*J+aH;)=59 zGME`Rg}}VRYg)dy3^9MKk&PwgffufG668WSnJ$N~KQMG_w^X;gsG9E2ehpqFr(|venDJ;B?s*^NN+Lr_NpIUv9vnBRn0(TG88^%_|_{Zk=_;)?eM+kwHLi=B+aDZ|HeS5B$4oPJ)XHnG@KItVC{5q_>{X z8$yb4VBq_j<`x#8TWrza2#39-j=or9^(NUwE`l~AI_)xh&K)L0*KUo#elk>fdf9}P z)W!1+>?9SNuKYDj&2qVUXqqI5f1S&h+j?GWCXT7+I0MrF#*9He5=uIR`V>&LsxQ-H zX>lKb(vOe3d-Q%!^W@d>%E+8avQO|F7IEZkzE19f9hCcj+`2Rd6^RNJk2+r7?ZTCP z#r2q?2mRaWIg%|q)D4#kO9g7Hu+V5S2MmpV88BH0<-*yd+jY&Jq0>I0GLBYW+W$-k zzhJ7|AMasUIwotpL78z9qr)8}HS9Gl{@9JtS_lX?C1fP^A}%kr>olR4w4uc=oj~mC zcwBLgJ$W*jY&7`{E)D-8<jsGdhOwrw`B1^p7jyt=aKx z)I2$N=HopW7aX|^gq+j`OE*5ofBxqr6_vHo#3V$UKFqsB3VGcdDkqxnS_S(4`;TY{ zgOwdfIFpm1d5w%|?KLe%ScmOo*-H|64#erd$^DHqlFTPm(H1=3JAKBv74YZepRl~X z^&g$8)18(#1mk5{Ya8WNMdG?3mOCpUHtsc_)vR*6NHaD3l46Pw1W8O$O0)-A{a8_v zeTK`h=6c>!eeiQ$gBtXL`lbQ4W&5^&?ko+XgeNYf){+l-{Pbe#N2llv12y*Z{EHs4KrpXOq9 zkN9x+;NnP@m)=>7oh>Z9XZEZ#+=*yrg0O%sde85Wd}@C*nHkUDtf+kUR;hMS<^1;H z;*1;4s3KUsOQppxQN{kK^UsS9?v%HllqL8%@@$%J?)c*mfoYBT1#7LmW}ZMXbs z!j4UJ9Nb~}vhBl~5N;YblX}^tHVqZ*ID2`i0Bh_!CH&RyKM)|H$^n-|qIvM&qYy9Y z+UY>82`IZgIk|@@%T$~gg9Xh3YvOx(OpD2n_2#A}Hc(ow;I}O{#Z?;{si@KZ73%|U zKC(@CSrtTtcczEm5X!tT8!Iu)J*n-cm;VRq_UBJ4uI0pZz5eDS>MtHUo^u{V zI9!wz&@AZSYXON5|Fo_ZIB)-(i6o|#zpC4}{0wmRa**Uv#p6lK&R!tWl@1RM{FFXv z5y4J5cf4|1g7omn`9>Y0@I)=Uske*B2fuit+&J*%RE>001}^ewZuSg~XKBmz<`FF` z616}6nX{}~I_d>xCbg>k-QaSaSUoPQ$qQXu&L-`~5b*Ov4i8xy5EWZ1zR%$Qi?lIy zn#eM~xL2TZ`H6?MJlAvP1O*<{!xxpmA(kegLe1d|h(-{s?k8)WW?L#0-r;;v{5x1?CgD=wY^0Ej9n zMLK<-XjQ)Tn-y4trS_$?m7aWI3@HYB$o>7Y4IPbgSx*`g0aScAtAFy24SIDOr7iux zs`sn@h=}lW*04nXKnGSRojJuFntl=3 zs!n6I<<7{tDj_N{OMRKvo=w=iTJ(mn*CAu8+TI0+BloYpk-oj@h8#-Zt>RmbgF6@S zqcgR#3NN#3M?;7CTCi@S-AzM#8-nrhV3BF4eT!!EzNfQD7#CZ}1!A0w%A}wG!161A zsW8h~1Kj~jr{J>G%1!-n02}%>V21mgX|&vQH|$`|vS&@m$yD~*viPc+IinroEf5M$e#(u>;nYq?-fiL$_+`8jk zh}w<;e_lE*y(;UE$3KU^#Gm)yj%Hb$@lLnOZeZh2Z9k2v?7W77d?F0HA$@B~f4ZqK ztp=OQw+xYR3QmJw@r0>Z@F=qPt-EM2;ox|HU?0=tr-J29jVE;t!3E%cl+TwtN$IQ@ zGpG#n>g}skFA4ZldZQ|H*8e^M&`o>aBNE+OyYibZbQVr)WNxeOpF}6oh#UDCBGL8= zogXAk>POpX;r}qrD-lg!R>sFc@)986_PqcV?7~HWuVi-`$HUkeYIqyd?dV`5!M%s(9mHGyL zw1BhIWggz*S~%ytMjIb@ym&l(m$ml%)G7PC)VO$fy71NWT9a|{Op?vK?AJ6jU-jvM z$n~q>cv50a^AIn|G(wEq*SMW!&te|j^p7bZEmkuwu}0U@wPOIYOi-n#end~E=85Fv z0-4p2QMC~YK+qZf#Y+%R`oV+s@TQKGw(mR`*?vz`hzW7GuV=*py;L5d#t5@Jb)7l# zOC~dU$Hi95poLV}%52{mAA1@(^uhQ)d3=EU1%0K54P}z4VilXV@~TsJB*cz>vu>Jm ziD0f^Y%Lrmy~gyJ8IyIYSVD6G>%OOb6RHhE)Y8=`7eW%+yicL6j{3KbH5i++G@I?oxhHR4v`yg(H+6%^YvCuH&J5j2BXarXS;Zld z#s;WpgahL~m9c6}#f{MvD}WO_YnmU*x`g4i1FZH1*{V!Gm&` zqUz@q0w2k7o1pyomQ2>E6$7TM_SOGNJgTrfmTXWnz*JNqGu9{h ze@$y9&KM-+DyB32iQ613!78zKm{x)iBTaLVPO~ywPR&1^{Bo;*4rjPO0WK|76Qf+5 z<_iFt+mn%-=;;1@J3YMa;#QT|<~;^*8~U!by^5~;y$43qYq~aqYHAb_7K$45-Ai49 zJk3Ga!j3lQb8#GgD{_PXN7S1~#r*y8<9C*(Wu}E_U!<(9v}>b92nlUcGbEwXP$_Df zsd-l@^~SqG6oqJ;A=;Z>BMH%_Rof`qHItU9X_@c!`F?-rcaFcD;~e+Sz0do6KDJkX zirW>+wU{z&b$8X$CHE%Jxf}WXGv&f9!juN#5%bzT4r>!KZuHon`b=_-!`X!1I_J;( zB|B&SRGyBZ*CkYytx-LxmUPJ1oX&sD&egSJMpctEJkq*T)+La9$tf;6kcs$eGG?22 zI_$|Uxb)02x}MP$r=tXN#4nel12{Y~RE$M3S;vJ}-??2~b^s+g*H#2giFs~oSNyww zi_dz?&K8x~oy>SooSrCdHC3nH){eeCY^VmcSB~?0+n=)h#VHK@Y;}e4NZ^}x`6JWs zQ@K-k5B1lh?UPqs&+FD4I3ArG6-S5WP1< zWeP$d8SO-eQrG*&9&YC~AMETp=-Vw*<(t_%6@D&wN13}=8pywC$GZ^76lH!~zf##e zbDJIKJ-T0=^bBA)SJ!f;Q5DT%kW5kH(E4?dNxXs>t=^8dM|d?8n8{KDpr7m!*CIL& zqcRHhfRgH*qv+9diM$Q)q z55k_^Wwf0tHCwmTG&r?JYxT3QX%y}5ko)37=lgcEtDU-q>$owcSq#o?-KW2^V(>WhXK(|jKGoH#(VZ~ynqEFXt3xAOcQ zwW8Oy&G0et4%0m?ez^P|LN|_h7ngPRulm=IS39`ZsLIkzF*cRm^N!?MXv>5EE3J@i zVJ{}fFzZY#BCzutNp<8Jy*IB(520-CQz~cLrvaISN&`2LBakWsmKP<)Y?_|ILF^Ul zoKVpl>>Xk(Vzt0?=bG0*zw8+?PgsQkCRt&TJ5TOew)$8%a93BT^P%wRv3qvn0iE3W=%wl_SvW*DA|6th4hJ%&R6 zHEAfyc`X8u-c^;98cnx>Gs3G6lWXc${O?k%XtfKJ#)8-#+WGp| z8m!vnFaG>m-gDhYtte~!nr_2tliPOrok{xw8-LyzsBPwKX{zQ{87r(Nolu4cc2<&= ze3@C{;DMP`?xj36ymii(_o?=b<^wVI@GvJ-%&jSc&&!KZ!Iv%tz=Ft`W~ z0rffv@S*a7wo<03~Bovf8X*FQ_*@HT}DSz&KX(^%S^D0dYmXoRDqU} z^W;PsOL@hI7HM}R*xxx(VwswDyoJXN2tvY;Z3nDDq@Wcv`JvRZlIC=~Y1kn~CTpUd z+97x@XzCGzW1Ej~af4~}vsgynnPn>=*g2@*buE-a3f_=A#Qmh$1`&|<6&9?#GurY0s10R{4>y+E)OuJvusne`UYIsq znRyNM_@X$Q(?z0o^xxj^>@}5O?UA{H8#qCChRwc0R1kp$x&4yt^EwL9{an8t%ebqd z(3A2{JbW4eGngy}9elb-h&HUI6&|4JHju@YPS`fw0h-h&(`a4o{sbDqEC?n(dlx0+VGmw|jWgx}IniKXEZo2YtNM_j^Cv%Q!} zCob2HIp(m03trSPv;I$0tu7WY>a^M8cjANIz>(l&UtAhv^ro!&ARK}2joaEmmy|U! zR9)G8m9~X@s-@F$;S0vVDfKvbiPC1E0hI7(JDPY9wu zPu0bts#LE$K_N5k#m%rz{pVM9K~5>2GyP>JGuYrHE*>W>%Ay8A zX*CDOwT(|O?YgLhgA?Ab>UX@y+)&M3>am4v=VS2n>Tsp!?U>P9D+Ug2qlJleI4iQY zC;*jzNZ~4Z*TY@+aK0{787RyDm`6Ma@fQ+Ep~?;ZEZ8MDJAs z%VDA7W7g2$WxfW6rW?M-s{5lkKT#etP^;oC^pxDZFdZJ&(^<+CCc#<+FL30h>CU+< zKj+DXn>TCDjvqix))SqH+gI~SG8w_AX1bsHIB=aJ9#!HzY98E{-Q-JoS&4=LNzM5n za`C&{mR|pC+jX^rp9JMa(r3Dbp2Is_1}FX_&O~NkP*D5K=`4N4E>WvKT64eLNJsK{ z?yDCvfs)a-@ubKQUYvaFGxp#PbF}w49eA?+E1Ts=SAz_`$GHIudTFxY$`dR4kWAJ3 z&?h5SbT6Po(6d;J7cu+7)a-qrkc)A_^1Tt;{m&T-)LWMa#bt!r*ufa|GBh2zIA$<9T`)Ni{ZQad$a zO5HlM<@f5xu|u^OB|=KktfX6~c%{S5bZOaJqX)%Ga6OTC)gIwAJW@YGA5%$9@vtrL zSrjfL$3un`5oFL2*WY`Efme)`*7kp*fdp8LlL{Pcu=+X~PD*KmGCDpPa}9`(W(7$q zAQl&qBm)1zyyQiT1Y>~su0x8U5+xp-e2e;YtF>-A9nXaRXyDwWoBzPYxF-98Tj%&> zY>~N3KuBW6u&Zui{)r=RtDanNX&WBA`QlmXS4jXL-ahXdDG0pT(kgRT){ZK_CsuPu z_pMK=@t?YRS=?YfRo#n{Kg4+M{vWGDel%m(DU8}!?@6M@*T_d@>bdEci)TyLmC}CN zCJ~Pj>b2{~BR8_lo4k}%fQoV;U&0Ia?mwRt_N0#=vk%@MtFdrjJvM6>4MT@-k-F$r z;uHB;hp?KO_@QPwjy8s=BL?#;*3kG+&Vot{PLbl&vb;x)DF$xoddqr7MrMoo|ZT9W^*&J$XSZqA~w z7Na5zG0a@(IGLy{o5B$0`i=;;)8g32g`Rz798}V5)=Hn_u68I6WXHB)H= zq05w{F}Nw0=f_X{7i5uryA6!w{ij{EXZzuC)swwyYQ;I^D>SDAQS!KY zP-90XA0H$oV=htgIOMRSLL>}c|rX!3tRu*Qmic+ZBl)Elca zae1N3R+g+?meZ(s`4wAAZMQb%iI?>%#1Q5VSGoD=@m=Ma8J*`MK7QCO_^ynRZK(J? z`g_wJ%vS^O!g-{K%hbVS@XHO$R5;C$0^GH; z3!S9Y>#JynE#rtKa}pIahq#zrZXi!Np(Xqxfoqel1C%L-Ai;vxCwls@JDT+N`wx&g zjk?%Fm3v#!o|;%wxf)heuo}YGvZK%!BFDxi>IMQLx!cxIe~014A#>PMJy&Fpq6BMF zzM3olMBUxw1O?_zJ{wGNQcr^S1>-M$b4|Q-Ip|)`ZMeL`^D@_+2*bwNFKc)CT%fsr zYU*)i$Uyijo+Qp>8A6@-;F?5__i5`cocbnyEv*Um>+d@0G3Xu$=SJ~;EN~)OvL66`QJ8o@kp^8>9w$G4EXe4 z=%o7a2ZPa^N51MLBC$$XFr{KY$UrY}_JwCk(--nDDu+(7TvDpHodHFTtl{+56J{c5j`L`|a-!T;@h?rs7duiSE;{%eKZ zd1d&qHMS>%J}ndVQ<-4LG*lR~^`h0)HvG2jX^^-9-ysi$s=WMloJTUGs|INUaaY{6 zpfFK{e9mA;g2R<3h3rlBmmY(ZS0J+vrKX9}`)$j|DYVF=EhjLOE9dLQXp0bXtrS4g zzaP!B4782}^o7c?vC22DI5KSbmzpFvzuI+$6~vvZvGBJW&9tMzAMf$F0=l5F_lQ97 z_p$n=za*bBKFEF6&fnZoIvOo<6lO96&KaAEzeDA_31FBKrEcY2dxAFwvu?p@#p+`7 z?O|m?Q`1g`5y@dlIiL3&HheC5C0(?k>8GEcSiHMjtA>a5F#*d~HrC;`_b9%l?2hwv z@@X@xn{Oj0z5lwZ#hIVjqWQ|Am*jVKCHiGm0Kc zmZoVBYF~pUcpoXMK+Opdgg^|*(FIqE-M_3FmVn7Ih<%x^p}CiI;SnoA6Cj-;=LwTW z;ncp=w6tq!?{w$M?T6nJx!J^xtJY5jxxeO)6_4gm@r@Za%lAHU{u%i*Y}nj+a!@(N zv~!~8>BwZv%}&!$&vP~hEDa=!&55Bnh+g0i|0=Kv86c2()Il6XQ3~WTq%dRPU#BpA= zsiXyy3B0amkn8xkek*MoRF>qRkR%a!oUPR|eZf_uUs$PG`=9xvLxJe>^*Ab1Ujmor~F-vKscdi5+xx=C1jzni}?tAgAth z)t{-e_(WHlozhE*^ANKR#Sz&uQKV?y!||MuxzG`mn?_gv@#|qvbddlwXJx&MYXkBG zLY}YKQk?E_*iP}j9Hr9i=#XF3F-u4_DpTXU7S~zJ={7=gG?2G=PK)E*jB6b(W_{*gy+Cb21n-`lKHrt#6V_P0cU+m_m6M^rq&`=3kI#`0+%&bS zGiLPg`a23?UT?kJ+MGmosW=@@=A429B;GAUkJ6k(J7%@vJt_872}w2fEqe_TEoR+w z1-GTLSy0gmt1Nm_`D9yMGRh|z)xYnb|1FcLy)8t=@v@@AdHZ8v2{#~3D0)V%*P?>3-?EUwN3N|16Gzile%&Kc;clcMCRmCkW^a`{m-zxlV}E2pR3`B}jm zkmZHQCkLFpUwTCsvhIguYCmWy`4N>M*mWsrk#bh+^v2P&+QsN1!PUwA%WAV8P6gCz zKqWtf5rvL3p0|`*et4!fsUq)4(=FA^8M=rz+XUNVLBAmrn7KzG)*)kidz`f)F6&oi zb0g=tdw$wFYT!cQf!9!ih!CP zK-#(5sD;`)S9k)r4TO^a?A?YG=gFaIZ&?~h1K^|rQU{tWTrEaN_yt*v+XO(Vf2Ds~ zH2;)v(F|vHy=JP2_~tL>)c*1=n7}u+dmUu8ybDO?EqJv??cH4XNAM?HrB1Nj7ucv@ zzqbC%e&c7R+83Qt#ObFpl=Ku5ZC00}!v<7p$rf~*_k@nSo^_RX)@pQFJhz+6e#Xu# zLc^6#{ymcOpKW!p6Dm>VTzE4lee&>yU|#ZY0xA5EhBz~CD>hvR<3&rama!aBOahi( z)r3Hu(Qk2Tl9GpkB^_gVqMUG2inmq7peWc1X+x7A2TPIO2vq<4MM5klmYIz6sRvVL# z0z)|(d(%FrHAoj$ZVlDHcRaY4I%Tb>tbxR^8oV@+@Ghze;0E4sY#gl&m*Z!>Wr@nG zA%|gLzyo^Z>I$Q&jo8t5aj#ToVs!)&yZ#yMJdpshL;!a$aH53$C8EcFN{Sh@Qj>?c-El4M{a(@0L8#=5yYiCY zCR~z?Je#41C4b)+DCy>)phEmf)5VRL zO1K~PT_bODUH6^yq^M8S!q?#JUYUZ*=6mctV%8O17>$S~!W9|V@IXvyBNX^Rwx(@2_A7CSlq-nkH3xnLtmIStYe zk;)(Wykaeia1>pk_SCqo6T&W@&l^z4lx)c;CP^Piw^BPm`1;wbaQ;{J-4dY=S1}GO zt@s<`V&4zg3l|TzKV!W(i7xQjJL-*3o$fqr5z=%|2l@)9bpiQZ`R)Ph+3mt;wrhET zy1i?y;j$9#v#v$!=bNl2>uIAo-q0W6gDV00aT*aFhL9tK zF>nOSLdmIOLSXl2lqDUVq!8r@j!l%CmPULg1IvTJM9>d$iBv8fqS$eL^S z_F^bC$3?RJB`egUj=H%jRO+`zb*H-A^JV6Zl)PbQS$?bYAPhfJl1wO8iX%ntt(To! z_hO5!m1?fBMwgF5lwv%|3u7QZ$4g^SQssTLb2*F zN=4}l5$6UHaOt|3A*hOeXtL1P;s#QVf~KcSO_~O)X{e;}MD)W4$b%06w=xnYP0Hb_ zv{Usk5xV7|H(y9VnF!D{X}=lsn>9GjgaRjU*~-|d#y{O)^*KXHC$VPN!UqdVq)ApE zUR8(x!7H*{aCYo%DCI`W(z6`?-GhENR(N-VzkiN=Sh%kC@gFD(U4DmuKj@F8UJ$9g ztIK)g7!7}xG@Z178Y*~;Zpv2in9>(!+4 zBbCMP+P1{9=NbRZ*G4IZ+RRPJdfcb($DJ*^oTR+GY5ACDz1Ig^j_COx7V&fOo92$) z1=Q^52QVNDI{o9nwY=3(KnF^HI*Lp5|9N~zua(&uvAvbepGjdZM+s0D*QpqFR-M)RC!eRpExX1y;-Da-3|<#}GEQfPBXz7Ch+#3jwI% z*{ra6*J*w$`b)(GRAjgbPJe6EfX2hp$UW481EvO^TfClZG0$#Zpgrrm(d8 zzmqRF6$chpo^#zlnYwVHk1P2j3va5>kC_&ci?yk@C9k$gePW`!j%UeCVhY^it`0Rr zLf&lKcTgb73NwfB?+}2)+n&F3x2rW`u?~61@jcJG^c)|Aa*IPv5`6j!PvWj4bJnA6Y{v<} zw2It`H8YQi15qP*M1oUvMLKo?kLnO8(QdDX5O|;NKd2ZVO?^h(3SB1bF#Pgr$hAtB zKWWf)ly|(Xz22F4;6E7P_q4o`U}C212h{qo9W&X(&bGGeVJ_xylU3bmjpTIf7N_{ z>S63??S63z$VO3Rh_U2al&tx!3;!;~umO?b96F=eg{~^F;~kc!`O@n$y8BbG=`oMk z&q6$W#C&w_)xHC2pD_RHvm|(1C3vAKR1D2g0r<<&9BQmF2F5YQy4z8_6Jos6YNSw< z2j~q%=U+zM!+BU04Ih7`g6t74+M}XQp$_+kzn`>mx~5)@a8GdfS#)31%y2Hz^Gcm* z*SX`eRJN5wCX0xb7sgp!ZxzUW%OLaR@3uRge$HNfzS-3HHzo0l@%8?>1A|9J&x*}U z&hxkJk6({GZ}qyf7Wn#yYE?92ksJ9+FixZqO_yyz+?RZyPy%HwhU#wwlgcW3m?aSW z6!`e`dCCFqx~5ZmX!3PVX6Oh>^rYg!rc-ccKcI^_MsG%4FsI#+vHUC=ffeyEF56FW zw08l;TbR$Q+M#;1KjqW|Y}eQXs;WzdGpmZ&9VDHnbgn}ZWJr|Ktyr^45EVFQRnx-7 z3qHhUuNnr_=!Y+l*VZ@Lv^^S0r}>03T!29lgPMVE>+B^y4Hnlj{nIhFbf_TO#eHwL znx9a1LHn)wna7YNkaMLfJ{Brf22SfZf2NC zra7(!6MC~osG$Y=bBzCUlo$!C33$iu8!NWF^io>{8yLU$<;{{Ff;0eDXw4sZi#rti#k z#F$eKqV<>lLsy+kkBMQo>|~-NDx^qE?U$ijjsl+8YuRmL>~F3hr43jfl{9EBm4@vw zmg9=$#9gC3WA!*;k@d13{=#oH7E5ob;qy%nkAyQ+#`vI@aP?@LwEc=eno%K`PYI=r zICc&!zA9i8)hxB!xlq5i7g-sJq90D$Oibnva?3>&YA(fmqsD^-P4~rbnJo+X-*2dg z&RQRyG`=Za0f{zpacnr1rdaa%;iml)%Ie8$T9wBpDwjO>Q0&)DsQd3ziT>4>Rku=p zfM61tmK_k^ezoNld!BRdu-J#Dymjj9gP2vhPxA1pDSocHn4Eh13I9XO9bQZVM6N1c z8lWR=upZ97zc+Y~hWQ&fvU~(0p4uSeJ-0;^lw(Scja?F6JuxwX2|Qf$2bC;n z(n5NU5=F^EL*_rMn&-1CvXGw7=axoCEdD+`062`$ZIqfV+ksg%hzdPz(e!%ONyB=k zyh`}6_tN_*8~iobmyIwB`%6j<=dwsT#b&0@VSXW7^aSc`tK%`~E^#XV)e-$gyXd{x zmy2w(^9ENqn+&>aSeWh|liufE=pT`oI`Uf7F+t8XSvamxpwMsi76hMaKqer|_P(-N`7ypwx#cmwdOU%XTJ(P6 zRiMl+5TSvKSTE9Lc+W;GsG`}onWIGWzY3f+L5e*{5L^S!TR?O(o^*TwP0KwB7>!-8 zZ4O6HcAxG;GuutkW%XijunW$O|FEc+f1s9Y^_FhNf}Y6$l$>DosWygu7UeOnjY>=Z zN10~muI94hFGfCH@3LR$8Ml5Bc6sc@UxhF79rN@;typDpVJ{~>{j&3R&%2nJSJ5#y zDRAqw^KMeNZVmIDn8tgRmSk2<+z^x)8~E zsp;Kz-|@n%{KS!(ICsKT*+43cfQsbzB!y?|8ib zMXs~*|GjPzu4F8a<%R2b8&Z{uS}-Uk6iD`adpe`4v_Suq2ro9mWeG5j0_QpC5;}?D z?UO_rN${$zr{>B6n^9?lg}pz46o12^Fk|S@xe2P8ML9vw7?=oS6uBFl*39qxk3~H_ zSN-oJe?ZRVra0`O)pU+6rM9MnE-zsHMv&>F4Oz;C`%UE{B!=+ez@H4RO?dDJ{#%x} z$BrB$Go;fR&b!iC@U980i(#)xB!LINS<$VM ze!qixE1f(8r(V)Bq9gns-?SW{Z0+Fq%FI;M=IACHQt8bffAox08uGkxQpxpqG(24S z7MCuVLXmLgb_i29{q;^{EbQdnMlJk{=j~z<3i@v)e&+=J^m#Y=cYsIfVJaJLb9OQ< z{>za@K66gc9RC1WjfnSX%cB?`eHA$Calpvl$02|r02Y+)zgWI}`dgL*Fx>L@9>GRR zS}(f#n<-eRS3?HYck>02d5g<;Gm2P3*)ymv5ViIHRo~HY!GoBM z3;ouz>nHiCU}&0ung?-4*I#3as(#P>GjeoyTT-Z>I_eh%^%d5le!`|+8$F@64*k-N z6<>YX1kY?ykE0q2Rt2>uPm2+fxq(~DckCZH{(>+SJ(53eTU$Q*-H*eGIuHPDXY5aY z95D_IDw`x&j~(z?+lz|I1|8L-VvvU(*1(fovB-ChUg>|0f1g?vBoktE+3Qcdk=l-eHoz4zb;NgCZT1#=E?UN{V8GNa0vgL)u%Kcy7rx?PE) zIqiL%qiNQtirC1^>8f*rg`=$>h$75pzO%!ATCf3)zB=>dW=*af=gTvEw+LtQzH-v) zOn__N@2Eu8vT1u1)ZlbJo918LwTk=d@0zlU*8axDo>6+$G>5Cd=NvsR)U;^ljh1(k z^Wp0&DYadv(pp?vhkxpDdk^%&h%hP2!8g^rwv{oTjDFB6xA9oX+af7fvkYTC7|XZz zLr7H*n}Nwz&m$(kWfz$1^u)RGu~|ca8wY}IX{Ek2Y2Kbu1b@vT-dc3MT*V zl_D*^p74okOU@aQ;W%0&DTXT}fy=sq)=OYZ^2NQ4pBFyn$Mgm1UE+&Sm99MXrBByB z`+B~07%Au?MUv#MUI-;06}@`?j`g+&)F5VmhSuMNwCz)W55~-d|8}flddv+>_9l4V zhlnY}U^y+epgMq?3RC#&0=Flr-SC5-*_4E)C-t!sUKD`vDFj$z|@( z6CO+=y4DfnS>APy7ZwDA7NN3&I~${mKAQ;~xPph9F13=%ddz~EC$yweir%B7q`qVm zI_g8u(do)}ecs*8{^X+blO|QJ5SX#UM=aVt{K?oi^C}sYuqR{x@0O%Cuooe|&aB9h z!9b+~!)F16KR#LkM{oN6J>qC|+ zv?9G~9mn)S$+jK0PA|MNSa_m0AH;5%_JG%cje-XJY2LUl;Uul8Zxee-0m(Zf|6Qr- z$5&Vp{C1#x@aZwS2)=`Jfi~iv3;hc_*Xv@O*|O&QXf5VCmAYkt+VIOkVw^D}S*|@y6y=ptL$}SY99VC8 zrS^-@c}nnl#AVs)h+t=t>OmclD^-1ZE~_&9e$>nE`y*InHKwWh1LMROA4M8*&B%Ee zsQ%40Da|R{-k2}>Xy|5a z{#UkX-cRoJ?;J<&bXv^qp;wLTY9S!cUi@z@$<^^4>6)p51n<6lY@Hd@vcPjti&pC0Sx^K4L6?p(eQ?c@>o# z989arDwHCTmu$s&2i9_ov79!s*-j-8Oql7lJm|5?=K!i^VdhCr_R$lH+A35J|(s}<;8J~=ipEtN-nGap!@@CH7CWB zWdxNh=WXg|WMlcBe@D_|Dx60-UsW+og9S1j>!I*PBw{_POG!r|O{0t?^BqhoS_ath zBt&>;E=mRH7TL)3@N@ zq`*%P_RWRvN}PIz+B=M?0qypLoGlGs4`pA(o+vk{qgX@vB)jo86W_by=VI<>K9#ob zU^;9QYfo*MH`R}GJaH74QEV~k;YLol6COmjdbN|l?z-C2l^WMHnHskcwqJd7MKkZ8 zf`k$yRUl6{UD11k^Ki9H zSP!a-f9h?u2R|b@Iwc(}Zd=lxu`y^%KUC%c%<|(ci0n)la6S#7Dn^>u`+3$c1iWx=Yf0Sodw@&kI{RViw+SOb!u>4JiqlqVzxwhSCGP}?b(qz9nR-Jq!?>{ zD;G#lAkMd>ih>MskMD)3JAL~n3wl=dPEe_hXNT=Kz#8fuIGW`@*PWI%1MkW%wfqKl zTmv$__}`x$rWz3`Z(;SY76(^w4NxuQBR#_0fGka`$Vu_GOF->k$lqc2Bo<v5vv@>|)5A~aUF3ciOh)S|h$(m^wxBNHkB)1ZPJ}LUz=VNf?Ajs zA8Olw8s#w&>6aGG_@ueTmuABQC3o}Hkd+S%k7@a=>emA6DZb`?&3fM({)K^xW@Z~sC`PrUn%u+lUY2Vq=wK@M8o?@(gn=NJ znzdN`c3>*{lsXL}AQh_wmRdk0SkM!+_8TyI?AubZg71=j*BP#>zLoOz5nXU3PHxD(eVPv?W~#`l=bh0jJ|(Py-8bdnC(xX- zU$4!ut)X3}|G=H*YBlgw&O;w9<@B%g(Hp7y6#A)JcH_tVow))k`~`(rb8T`ZfO^6&R}r zc^f~mVJX`s5Q%Fl=rY^}zmT#|tWnywR>smfffNN#%RRM!^l)WNVZoO20Fb!>1$W{~ z>6!N{{sfML81KXK;AU~2gaq&KTF&5_b0}terv-mp+hx9Oza-DuidH$fq)bf%3ipwB z$($EeSB~g_@L=`!#Jj@R*CS${HbdiedtxY`ji^lcfyjP(+n5su_M%nC z(FQZ?&S7}cZ&^~Le1^!vmQI*pikcdAoy(xkkD3aXZ;SGbBhiVGzc-YCWm}BS*`xQu zrC3+o)f`M$cTvP?k;z2YCLb5zKPx%Eu4O8EGudInJ@i$d!{=2erVzXCf!O=A%9n1l z&rUEqZ%Yx}=3E4A=fY1utF-mFC>4FmDV{U(BS^Ase~UUyQZq`EW>#;#!P4zgaXEjP zhhN%oB;)q$QmwF*Q$Kc+$-Cd|TDSnZP|k$F#(Y6fC}@I7W>$%gXcHKV{wl1JpBI`BwAB(+6^GqP*7 z|7OMMlLGu)nCa?g<-yqx#Nyedb+cJn+h|wQr7y$B_5DD7(^lH;;{11qs$-2hH$HC( za@5Z_HQ?)#b^Q;JO8K*}(dgbTTYR8vtE2l~`K_M}cV)|{sJbhv$*rJ$(q|!X%6oi3 zCU!;kwVGzBNKfS*lGx^^>#RE|G?a&>eB0Tlv&M0Kwfi91gJQJ-^-Qjs1U=j^!~=!Y zn;~9*`kV78R;Z}+=O6wdQ|+!V7)mvQ`&-3%h1*~1 zOB$GSFSx~c}zd{*1O^1_=S(7DW~L>EVkpzU(3KN zgDH^uWDDG~svR3iVg{F7j)v~1n=EvobrLb;(A~4s-MW!dPUZYGauwb(P<*4YH~1Giqq!?^v!8hopB2pj*TShieQy6s*PIJ-Hh}`%5S7q632gK z)J<7rU$puoM}rkJ@5>=_O15DZg*F!xYYd8)n(6>`ui6&HCX)nxn0&fcU^Mxi#R%)+aIY? zNkY-VtF>QHW@ZnDMwd&(IHNbUlw%b`JS?^du8|~pJJ8JSfOkQH<1L3YXhBHh0?i*o zOW#J@l81`NnTnb}k`acqWL^vO%0#yT zj|n_j{idBC>^>l`OoiDSz1rfutNc&$}U;jtp2L+f5NCDiK3* zp}Fo}{Fn*%NXm4>%7k!wS~%BJv058!vsxqU+`?QP63)*;NcvGxX4qU-G{3yCX0>mG zIuofMy25%Ms@%TdN#I42 zr4n~-H~|XA1?AWU#a&{LfQQwSpBqBeICx1OyStHnKl8&z(I>vN6f&*UlIDI4a9;zT z%`kCGKM*4Dxhc%OuzyPofyLVR|8J&TZCJ<-WL%aBdzf5NWMP}i zT8?^m2tx~@<~7s}Wcg5qxe}zv$@u2d{DJXVS0KzXLV7bqbFB6`r?N(_jG12LqO0aU zqL$b7TJH0yc$}gwfr1XfW%cNu)ExKGCHwM#xs`w;9o~Dm+?oZ8-LR6|gwG`ut*gje z-P55iY-plTih*WEobAQ1l{~%2V!Ex+{6`sE|t5^ z{N5|s8)X~!Pae1fX`TjP{SMWS1$eqF;9iDT&k;0<(>ftSAPIc3K_=-@U5f%|DM#Ud z+f`GxmR7HUtgg^Ckm7a_KAZOr_?$)ScxeyYmGsJRf-Pua^KSvw8G_Cx%2eUx2cs+p zMap`lWi#jfr>5DjbipAFY6$h*+%HgYI2s2soX%eNN~t=w#ftXpe5?$~0=;6h1hm8b ztkzGvw`ezvEk$Opx>W=;l;@92`=GB49GjE=&_^YqlLEDmX0AvS9IkAt6}WoGy^q$& z?>f7bHB*z+)GM#JZ}RXA30<)F&2g#Zl+T|Zxt=fGf}-X4W)lVV_H@ndecMv!GjSni zn=bFS8_y$!AA2IQV8y`yMom7t6{eA;>dX69oS*9e@?#37N=KAv((NTAUta&%VMU~s z^w*^w@eS(abWreN>OTd^UD&wYz5P;+(+xPABskN%AlmpA3We|J$%2-+H{|*?VX*2NojD~p^#s&!SDxj9; zXKkf@?a<6+m|q>zhlFX4GIc+VF0Lcad{F%vv)o#_Al7RcK_93Djn%QBp%$%+G(BaZ zITQ7}2dMLZhi%qo&LJ-MreI=#GH<$@D8d_fDKO2Zv9f2D`81!mv-$7i=7_@4 z6)BQ%9wDyU2Y+vwJ8$5!{*Y$p=+dF5tm~gw+WXDTc6HP~nw-AT_w=72`PF|wSDL4E ze8L%u>_PiT|4{6fGa~->HQ9~V=MRsN9glA;)w*hG6t%CfnJnvbOpLMb^MK3N5Z*C= zW~uCrOIGxUpT?uJiqIZV6aueh2ndb<>Kj2m8ZiC^TqgWV&k$%jL7xEdUdBTue?6@I zoCz3jXbmQ=GUK5#2-Hufi;(%4Z-POfe+l$|0$xV{!7Cb?rWu zk&OoENMun(W>@kDuIBZ={WZE$JtE=lA@nRG{C{T52ub9^>@Fv9nEE|9|I+RRZ$Mp@$hw^dv8PF;v>70vF2MSqyX`B#U$D?ya0 zyO#8J$Cxi{vaM8=Pz#vw-JzjozYfhOzsukyzvEnsFAl&ns~_`r$dXR+#%fQ{nv9Vp zH0SqDn)D@_DS$dx3682B;$#M&(D#>`*B~xpKDLB;lo|uqrLxZx#am&4N>vv>kaG9$ zt~IrxbfSG990FDUp*-q|N}Tm3$Qb>x6|H6|wUKps;5IyH{@J~sl&R6051IgnI-Q<3 ziFIq~b6m@r3gg*hqUL@UjE;+l@O&vt@9dU2pE`fA?>6- z7k)yt)Z&hhXAFy~eUza$QFLNDY&P#yzD?AeG|eZUOMN@%n7!H~oL*HIYN!-{p3;}d zeP9#bexL6g_Nz>?cLnEtk6r$n7=PNsO^y@c@x3SWjHx75P4!z$kn_$7b_+`NiRq3H9$U8|e^%6hkRLi9QA)==Qf*F4o}`0zY^JtEW(<97SFU+!Is zP8&L9+Xzsx8`uXo`qMV7xwqdSVSg+35Hm1qq~D#t@I5W4`*U|1_tjw1*}a;dtn0Ie z1Pf+czkVz^)6L4S%*)Tu%kMl9c~^7E+PV7Qv%ArDQ`OOxm8)!LDP)mU5Gdy;LSx^- zj&OWMKT3WJ=K7*=t`SNG@E%qjh=E|1l8Cd6Q^1q(y2&*%%g~9Kx90wYvfIMwP+A4$X?Fd6;Sd!+@7{P1TU%i~TPe zGuMIm!*5`io`O$1<&72;LeDwMc8`l_FJ9e|zMS-7K!;{UQKeD+d%ABelLhE-;jr{2 zv1+Q*9qoU2EiH=fB?1F7-!bdmjo!L#qm@1f<&YNQ`#^^qBG*4XpDJ4fqh49;)0`3U zYkIX_1nXxibi*q@Zs9FjQtekcg#r5yJUiu##^py8V3DVZX<+{HD1m0WO+g#2Faa$T z$Mh0j_}|-ymw2WA^7Z3p%mM**@4I+_+`7Z|xGg{}AIB5N8W@yGAa-aZK@!wr0Uy%J zyZ`T=@tWp0qk4Vhk;n`T8TDTH6kL3X;iyS+=7)i0myZ-D^8iraiXsn)Vo8tTr(;pb zi>SQ<7B5VkvwI*NFNnsEHh@4s=bQ6Hq1zUam1z~dIo<01nDqmnje_CIl$)X*o{}7y zRm;+SU!nA0q4TC;pd|T-E(~F%GE{Z0|Fm8JQ}Y9pgs3gKH*NeuY9W7eRa4-8-2 z0BImdXA;NxZdn#rKonUF z4XRqhmc~++til_BStdC782c#Og~YDo#vkgVDW67Pm}?yeWU?E=?jSQvf@pgQ1%S;& z3OBLu6mUCl0BR|CG#IBWmw}@GdlXDH&IpasLq9+_-R3KZ%au*-3aTS;7;C}I6(F~P z$guQ24e+cck%{ydZoW!@d+xOXFE$)KeU!w}2+;&icA$41n%?`qq{VJ}FCT7&;Ol0K zY=LZMYcLr-`;DulNdb{1WayzQGF?mNi$nYgKYLn2gq!2h#&u1<9Y$27P5-vX`d?sw z@B6M+Ci&OZ9Oj~HB+dd4U2pa}vrb>K3Rt)9vS`#iC{s1H-~23%9iArt6V0NSAqw?fn>#~kq_XQw)sCj)Q_9K@zpJ)=s})1)8M}MY(gCq0{pFA0M*U4R@F%`<{~O^ZaT!>2 zOLC!V;d;}&{*b4oiZE2AFLDJKk-tDwk}x{IASDD~DRG;e2{?QZ!|&b$LZvQhkQhm%XeSA53jsUYO=NH3#!D^&IUQuM2F6Ps^!o{sXs{Ad zM2-8q8NmyR;QUW>!m~?*3mrMF4zp1FztAJ^%%38$&LHwsW@~le!qjOpExqNU_l<96 zi34Xzm_lTK@y7MDJ^fDX5=1Q=jL^2vUKW8a4j zr?@6tW;|rerh556!h`4d_amlxJwp#7o^GCv?seMC4EFX21`ZDOfs9n|NQcJL&F1d3 z*$0$o1mJL-H8xTsC=VXjluP33jQ(&ybRnY?rcxvuwD4t`_{kt-k-?#xm0vt$8| zzb53=m|fUzxnM~{BCXv|IUrrs*aswR@0e{#8+Rt9fDpNhIGct1&x(f;wheHn8M>X> z!~35VRgosA+hXw;7=8))A%jX_@QohI4+)Ti=eZaKfOCcyA6_OlFD^%Mo)OsvL~2D{ zOEMEIKlz+KvJNn3FKjH`5;w9Hw8FaScFj5xSQwu2n%zX?Bm&xX{^Adjo0!ADExm@h6wVF(x zyHFh}fkC>^q7`r4h3)r^=7$?&w-hfNX*cg$cYku6J^RaE^Kqc0zLe$-d)+Hag%B$^ z9^(v|HF;Sld`y@+1w<(?1oxNd4?ieCXK@8=VFFGQFTVF(H=bC((}t{F;-7+_ua|!Y zIKOrY{TQwm#5UE+u_aK8tP_mIa2H@EvGMYKL0IPqNdduNdhF=~h-o`Am`7xs6Tm;! z3sFMI*ik-giz+&!$Bp}!(9oGPqoHvSUH{LPt^~S9iY{D|5sVmaS$_XNr#wiA#8VMy z%4ILY?DtG~=+$g)&NC$O-*e)u01@jjLaUX~xnFL9PCd`Lpq^_&{t;jMS8+@O5`|_& zKw*;kTf6v^x4ux&>=upIr7}SCoF~sOev<630=MKKP1P-8cCv{kB>*jrHid*4I%3-QkNuwwD}X7qp(D42fdIX$WbrtH zOA_M(em}Xl?YFf~C_5D__xz|Cf!xg`VC}u%Zua`IUx8Z~lDXpjz8_hyOFQ5 z1?SO;gO2+=w8s@YpFAf}z3l$n=`Vk)zBc+|#3oMSHWG)Ao8eAQfoLl|oTvs|Q|OD} z=kU|BU_fV<^K~DPgPxcS*;2zJ02P`$pv;R~{9jZI1NuU3eArJxj93LGI|=L^(2gWd z$v9|IOW+BiVEu7>#ITrKU{V5v1PfxqPl^#n#9APv2F5?YUc^ES3viOg5;lUx_P4y) z!9^&XbbR3^i)FSn)WrpPfk?ioQYS^U=7Xd-ss`5zaG~`JwjgpRV3&X6@>}#C1H;xZ zPeF^#$ajfFuZ=Tr;mn+B0eE6#{HJ#_9e!w|U~~Mi%k)y0^f6dLmM+FVBQTQM+}56y zsh(Q1W#(82t2}|)QX55n`O*F6={(P82NNGH7MBzZ07Spqz|#ME4@D2FZ+bN9Z31d1sG9(w;l971J~_M z`SanM3$A7nX3xb>eOfu$F%q?HYD5RDFe|1M%iq435$ilXET8ba+ld%$gpRD#p5O?K zPAtHyO7mS>-(OuK7zQa`Ul-E;K6<*FW@xa6mVfW%zIEOvbxOv$%ILEaWvPs@w)?AZ zn#Ew$uFw#r)MplFxFDKu7ol4{jueb;`o}x-X*=F@?ZjfZ8u& zIG{Ot1LnHmY0kAPAoi6Z=`Dd%NTxXgnl5_^<-$K61`!`%jy9J95tqR5A9;XNf4+cC zav(BzHlXjG4!Ac42EDnlhj)M}oe-(Xk6(Gfqk^_3Pg{L|VQ{QzHfnw>v@sRLAAeF8 z&p+R@=FfXi1X5eouC$MB5=w9dCFjADdFNsCr=aNw9MTaYr4h;tHwpB_OtxT22Jm?a z$n(Y^;m75QDfyn2;>ysrA({i`Esak)wcF0$44antb1tKCWj3lPVY%I?P&>}`>kUKn zXhJrD@ob496>?0Deg7B!eCL4>Q>^YqE3K10dgchBus5%9|CUFK!d*Y@T(@>y0kk=$ z<<=DYr)ePbh3x%U`(Ap4VCFmbci{(vVAc)hpK zf_coggcc|z(Q7gM8r)F}GASV>?4cqx*fb>32!+j{4Y?Y~odJ{TLwIL7S!F)M>OzUKD; z+P{8Vn9NDZX9kmSesy$ZHb8PEADNw68z;%roY|7lB>r{5&cNJnT5Ehu?-0#)q%`T{ z;8Ha$3e?yJ$zW0{4OzSL)*d}3hku@MpgeiDX!cPikC&a8345;Ai#yX~pI%oEFlKKw zzOp9`&Ez*NQ+gCW5ia<=I`^0RNi!8NAe7{C;AJ^KIrL2UK^cs;QQDXg>AIN|R8cO1 ziK(Ms!a(w=h;YE_`Lv!JmfqzqJCNC{M4F=|G!>LZ3(K>%><4l;$*XVruAnK&fP&u@ z62)TPUm~z<3vTk`Lz|JoHxRQ~Ep=A?Q59{JjgvyT9fABJKo&pN6-Ob+kLK2qLP|j| zq!s3X_=hjx-OiqFPigD`!ZJh}mMs8-wNm0Z&mFb2n?$P;?yCQnG}oYyO1|}&Tc>LN z0SLZ3wR|k<6o9LbOWoqXC?M3;Mz9K*TsEZ0#SXoDE5ML^(;PC&Kd~g+W3DsVzqpwG zWwB`GchH^A^#v@y`>B;-_B%@&VTktYk|!o?I}oUw*{*W(<0l~-@`0n(Ks6?ZZ-Uc5 z@yEFAVN#$v=!|_X+AuRF{4aIL?5k>Y|7SY~jQn zQ44?3r;oOYnZ_pq)2P{jz&Id3E%}05u=t29W|MrT?JP1|hTx}oaJd%poBx?ppBrC> zM!NzAj}q7+5-9|hKVvhxRCh=mYi#&mqS@-pk9nT}rbh^dtAZ(L)`za6OoU-E0_c_6 zVBp1!X9z309B^b_*0EntQTCl{VRnr8`y}wMg?s9mo9Yv?fT@nWG3xOBTvkh`SVKLC zOuO6qAnsIzJc4%ruq#=lfQ=v6}`uH_cuzTB$Q{O}25U_jCX4s-jWL+*FunKnl$vu|ga#pRSD*bp0wTW36WcXzAm&fO1n= zh|X8tMWBkmXfVB?%f-q_&U{R1P(@D|SduuWNwj>WcfgDfn6)8Ab=-F^mkR-=3>mHt ze)_Tefm>fdxs*D>*}4M=xe?i&WCm=g6Ci2^%OIGA8jZklvKug5B|ejv!!5z*+!Rj%0^${Owlo?Oh3X+hI^iua9NvE=uK;N-_@xUO)`{AOn8} z!T48%C-~cI3Hkxrzom15_F^` zqWEmJ<7+SZdqTQ@guh%VDo*+3E7fX`HW8lvw%*s6qE(thqPZOK{-@O4CXMNRNH%hR zpBSfSBf3*6v3_HnwI{1su-SIhH;nq+Pt8SwVy1n${3xiiFnCDPut{68eHW5E$AfQD zM}MAdSNbLVWBBV15GhVIJ$b8yC!ILULx}uL^V#mHsL79U3jm?*AR>VVLdGaJ#r;w} z4|3rlVp!t}TniN;fejI`8{G(XdQ1Xs{01UhdGQb~d|3qk!%`CJaMX5UX=#2t8v>Eb zS4fP>fvfl~VXI=?FcI&_Xbd0ThtKNNM3ODD?Hp-I?c2{04 z*^<#0VqNcf8^&zYugg)9SXD005kai48wasPz;w4fR`F5TO9~;Y;!Ko!N|XRz^u-BR#pq3Q$}XTm5(H>MO(N06}dNGZ2kSkB@tMRhC+CB z`x$%}Fk6c_&h{TVlmks8*-MN{IV|@`^$S_2^ost*5_~3QCE3hyFM#_ShN>2 zxpjF7lIi2T6;V)?j9N&0Qb0OS==BoTpU$1|;vwjQVz9D|pBQ zdT$-5q@d@-P_=JF>ho;tGi?HZ`nj*9Z6W=d5YFU9hyLWtwZa!aRYzvH8KDc%6&oRc zAVd(ua82}e!5hGtgheR{^}Ix4tj2;dkgPeeMB5K0BhG`!X*V9cZj{YA8~SP8szr4P zhWpNOmgjD~dpqn8;yVZ&M|gw+oFApB({1Ou1CWOoe$PI0Pq_UA9I5hsJo~JBE_Rko zfXC&2O^1W!wY<1Fds--Ak8FYnW}Z0rNU;o7q~{$@`>5TYpMJiO(efBXJSIUt#J<8Wis-`Z|^>by}a#MXYdnK%AfTYQog0jRD`}_Sk;G1>v@0N zl}N0&@3b#&D+qa^;BLh1)d*tfQ`4goI}_`nq!nn3GNW`=xLK4j;US7X>bBI#L<|o= zT=LJ!_WL~eOLa6T3<##s37kjeN@60|XlWUAktJeQHH>|ir~vUI5gVK z|ApG%mmuT@7e4eC6gh7u;zLgg@}W*41Nx{Mg15i|VKo>e2x3EPz!lP+Fks+qv;KXS z`|J|~Wwdo{;yc_LcXoK>o-#UeVc{>pZzHK77D9(wbi+LTbvtUvmCErseAMwM#4>6= z&pe1TU9*OlKK1@lu;t3Mmjy6)&jYH{?Te2pX4EWB{FRe2oqfHP(};;F~=xvntkiD_L59v}St=gip^wfnyN7nh~CL(TiCW>;Jp9ADoLx*U^nMJD__b{fv!B|3L{&7ElVT)Dz!+<E!uPy+{gISSFN4`A{ZGWcE(^<0BCI)bT<=Pn-s*ks599WZrM2!Erx zIw4{N!3OL*-+MAc(j1wA74HsYaN#tfIgeUG+fvci&2zUrmv)x_ojA*byD7|nyMfW2 zM&6F3s?kZD+kkdv!xprLp9(OS^zfA*NyVt7(^4F3X1%@~^$JAwNu-Dm!Y}b9m%uRaOzM0+|@C>0mh!!OeZvk9Q!=tfeLONeJpqJ&b)Kz<7J^ z!@}iP7tWeMnEr)8`AmVIY+UOn*ge@7Ys{xlyh@)}{krbC=sk6^0X+5nPK57U?UrYg zu4#lr6>Xebj@R^{lqT=CP@_1MoQ(Diu$-;!57VgQq^XUWyl~Z9LU^G5ZN*Gcp8B$u2S&Hy;pV-siSMA|D-8 zlU+wP0QhbJJRZJxP1K>TY*b+Yz`>jpxVHgBsDP8CBV?@cgB(BB2q6?v5VFQa2zy+* zr!15Y@399$u$O&|41Tczvs>eUkf|L=umrOzBwD{D_%UcRk`3Y;4VMY%7vGf-ozX*F zemd3e{N;c}!O~Lbt`_Tm8@Tp^S^!HkJD|;)eWp?p{}{*)+5~RBJX!}}q3~^L%LcGm zVeW$>)61lpmQyY90JdMH9tzX*m%eO1kI^q(?{W%vx&$3MMPu_c!GzU`V(c=Iab%;kw1*9e6NIiFM`J4q~a zZkMfkk%<*5hej{*j2UWM8nIPUkw_x~wcC~t;~={M^$D5dLE?DvqA$)VU*}chLLXkz zaTT)$rI**z>Qsw#5lS*%UqPb#Qe=Ub$BqfAR~Xk%#PlE-*c7=ku=NvhBh=FI(r5HC z!A7}PQeZ*N6p6&hj38cg;Tv%GOBXwO&!002zn$#|rk)ev|A<|s0A_?Ci1*=PX+SlC z>mztMOmQ24qe9hdaPmXur`LB|Ex?Q`VfK=kwgPIg2&YXi<)h9cvp1w#=ZghC1(9)e z1V7J%2M{m?kWMT-LF-#;xJOe3nY_7Pi$_#;ZQQo}XO4=(K$JM_OW@@2;wM(X{*IB& zLb!ZKbDjCZyux(L6nCFP0i0tAV!r9bBfB?;!!2{Gp`ff217eo5OCF`xdqNrQ-_;18r z=ai_N55BY?oV?qqCD9^sw^b7aU)U(bi?z=1Ad9~`;dEY;5S=iuZZO3?{h%%Qi{XlF zAOD|p)MsE}Ij3BbTqg5GK4B%Wp|CDKo4@1)tAWI@9_V`PvYCB}Hv6^zn$3vjxun4P zG#SgaaVj;LE!7J$mo<0`+U{z6Rb=OUHgZ?LeD9`%6Rp6~cMM$Fm6elC~K@7J3 zor1rlVAX$s*-htqKJt_rjK}l{o=G+GTj<;Wg^ryvnB{9Qc^i?H@{-3CvvLA<5+mQ% z0j%)|oLho>dPF>56hy$PjmC}du6V9Z9r0WLyLeU_H1kulm`Fu0KHvXUSavPk?5Q@9tT$R2Ch{=+Er4K`Go0zn-I>gqiDod9EIWNz{60i6VU z&~v@m<3Ql8@0&?ogwsxcbVOn*p7crjzI3tjz4^hvR7N&+M~tZ2ug&F|u1_k=nMmhA@e-&PHa6Q!{@0#*!1{XE!FNN^Ha{TfOu zgu{(cPrY$xFg3pwX@dAeHJRZc1}2ZHBa9#;lzRt=IN3qbBr#ytBc50t&y#S=&A{t@ zM;4$y>UH_J9Q92p)X@qg1ii0|4`To2c~S~v45S8~;|0Caprp{rJ}ZZ04;UF}4~gF0 zu_z!f^Jvh<7^Hu8<3)cZ?*aqf%F8~6%kf>v>`N}x{Oi|+XOCyX;Lw1NAvs=ZesBJd zt#8D?CCQz>|7E;_UYp5fUKzkTYLIjIOU8hGbV|v_@%iq4v7bi+LUMO5K2K{1L#KCK zw0RrWekfl%PGzr6_1C=9A8R$f-t8J&e_TbS1V3nJzs(43bIVmTB)~a~zvE|j2T>zU z&}#)sHJ(+5Q*MUr$97GeZ<4T^5%t#+-K+%v!VxjOb`n#_?}z9DH|H9hGn2{khHng4 zQyy^>KOWDuYUXC%)jmyVFOmI{47pHZYA~1#|COiU`KoXQEQEJ#Hi5}KU@~bpkh?}; z9PwvB1=W+!1sz;4#;_{1k%6SprjKM~ajiie`RD7J(1wLCQ_+CPY_-{p{hCb&8^6=( zDz>hq+Y|JsT=d<9F=J%Fw#;j|i%h@az3bn|{wW0yE3hy+)nSSzj3BesB@nEbF<+}) ziZq9qeJA%V^zz^hAKy!HvllwGKQ3MxoxGp$(!o~%uZvG5vZ-swi`L(u@0!T9y+}m0 z`tlt&$9?a*QT>aXA(n8R^K##}35rn2+)FF>~6=xI)6O`<_vwwfXD z82gh;{b@CKU|4$!!5kDt`9B%j>#Fy5YZgJ<7BR&3K?a3S?F)yi!P&yt1M0vxm1$r` zS|xqQ@`2bgKJ4K~VbfPMNVZE6{HLa0S)vQh9RxGhAOenH-34&SR?|8f$v;Fz*D(1x zOOQCX>bT%P$K8y`Ivc{K7(zZ!PVpN|ZiWL#ZppO?jYmKVrGP6R${ z^0U?^)CQQ$yoiuOTfe|un0q;i;Yyr!+?SZEyi0m56yVJ3eJu@`UqfV>IIlw` z*PxbvL-p3Ry@NAxs7zRtBMel$b=qDhUm4nT(t3J1T^^ro{Zy1bSd}^`@aOf7x_J0T zeFx4SxpN%3VH`bv>*3_z551qqlS|i{b6Rg`*AQ5PvdqMNH5GYV?CuFx81DcfJQZ{ncmANdU9Mm5lYE z#-Ci!`BAR$nAo5!8sm|XAb~N}SNjVSdocI`b{gWS34|V^KY`)B+?du50$U}M#IRBM zFFb^;QX}OcOU(>$ghAwwRA6|PnF*5dXFRyU+GyXlg)cn#TZQ>F@FTPJkNnbbWU;6+ zFWq!`A9x}z7<(pAvFr;M8U@~XiK1M_?Gp#i%T%_8m|)?VjRKzz@N;xJUG6ppTgPL#`-+ z4TDD8I2i1Q{qp~rcs>uX|I{O0nXP=-+B_hqhYYs;$DgbeL>K7ze!bJ*%nFR;pbUKR zGg$0joh}wdbHQ#->Gn#?L$Ek0tBIP=H**m&JKmgw3VMoVn^bHMkfx=%=m`3g^n5=B zBLMC70ES`HWnEzMGo#h~QOCqZ?GlqMIy2n8J)`|^g)SR78ZO-I8=jG*`MMJ)mvt!< zHaP(>FU>2c@1 zB&sE`KCa4n?G9?oN#Dktn~56FikSj#{VMv4B*(OgqqmidT}tR3Fc$X%veoo_mGE-~ z{Dku5ZYDnqcu`MrP6s4Woj6$KW zrB?rXNX)Yn!ydYBydA)J2;{yitrihy;GCQX-)RB)X>EK^7jnlPgd78tODJgi4x7LN z0emO28kI8&02wv82tB$2Oloj()`3V(E(p+nd=Gjg6z8UELW!uF2o@^Q;rm~JW|zVH zk&Pi{`}$^vlFr4qQay;KE)_|;Y_?Xb*amG-EV~8<2rPc={W{NgpQ!9DMPO-K9&Vd>B`} zV)UV}8kIe%ERQq!qvU(45v5wi(gT^w|3=)FO_L8_OmE25+jqUcjx^R?HK@OC4|Vt?e5nLXtIgCm|8H*k?cV39|*i~TmesWEREilLv1MkMdUyj zkr8?i4z*)(MQwkP!OLK9?ldT(&BBS#OaL*GC5>%SN54+F6WN{ww&a8-5qtbyo4~$i zy-hyOYPFk#*L$CE1PJgP#TN(>R3k-qg-g=3PIq*gP~Ca^FL-fV+LjgR5?Q!HQbdG| zD@ku~_NXV~F8Ot~aU0)7`sB3G8;#Prr{uDkpm?6HkN<08^+w4UY5k{9q#a3ET54#G%?CU8@tl>$qhzph zW}CVCa}(+tfLW9D_+dck=j!K6 z=j}Zh>i_Ooh(xOk#n?0QQ3dJkoZq0C?%{Ahr>~uv{TG$`m-0WHmD~L!FxU8l?t$aM z3!0hRYfBp61hzn0Wc=|3&o6=f_W5~NE0QeL9kZ?XfkFeUJ53*OP z!5~y`7VH>_2Jz2VD+o>t1SlJ{x$#U0@Dzec984aP!`k9tZQ?G5F`wee$en~zOQr}Ia0SQtvy$uBW3RWp3U|zJ*YG}fC#u$p%&Uv6c|JjGNar{c#k+XFI>dU@*%E3IA~ZI zHMx$MdU0dTk0a;*3FaWzBw)SQA%ifwJ{2-RJTbHN{NO@5Y~8rYG4m~xs{L<~fz=`W zd%(DgnDy9a*&|-2>+=7o*aqux8FSG#K2t>1LHZYSG1O}D^8+%=eA(DQt*?MMP#TH0 zNMk!UelLBc@QP;adAI3RJ}ld0_dh5Ie@nQdS$I+j?W?Hi56-<>eCMu|NTiy(!5Vin+>V?qkL#CI=36a3jhYfvuc zcH&g+<)Twd(jFsT6sO1i&}TCPECQW(UbEG#$t#aMz9tmjz3zQGp(1|ARs`!1N6QOO z5vjr19ASt>Y_lzMsNsc1;FczG+J-Sa5Gf*ZSY*aIz(^6mPaOvLpvYoIgNxz087+l4 zyERy(XG3^Qc6qiE0sG6BtvdK` zMxanVttAXvc83jU-88CQ8dNbW_0?oWh6`;CCC=_4aZ+zH+tynUxEVJ|hfau=YP)h< z@~p-Q((`U%G|zggi9!Y+wr!!#bIAM2LJ*n$#pqP^&wRi!vKf)#q1O#skQ-BGZ)_d$ z+&*%2Yn|knVqEjC^?>^HRO0X+PVMI2)FIpJ#R5kgc6jOZespIvU&!dD&+qsVDw061 z>gNOF*Ybax)A9|JVK5%VyzFL@G*UC{OqGm}sT?IF-&f(?(q_$MIps>QMeD zjyXwzkb)7*aPXGQs;;|4!hS+|kVqVCl^I~B639t_H^!PLAe~O$5h53msT7L^PY=l& z<~*?|n9*@;(){eE5c6BhfCrBlY+4rVH+XQar57wp9uR=@mPxu{!&Zgdkj3K)Z`*|Z zS+zU|FKjisB!nee(j3aVxahpU8e~Yc+nA5aoJOHVZ(H}DyLF6K2D3?nK{%PSuXSGK z&W(h=k$0KX&6e=6OwZx#!KV=SgC!^K9v2<&s_gNQI{y6erD($bsn;c+(xL$Q{i2*m3tV-^W@^Tt}$Ua znn>TCnf_e3DNr>`^XQYU_Stq{mFl~8O}yJI(cu^9+#a*zm7>%QO31f=qH-OsWD?88 zLIafUL@24UN-2iuxdPx`s80oX zGMSBOp$Aej@Ar-lc2eSy__%*Fjwd_~ZhL)~5(zzITk)d2a=(X#JY&%S=i ziks`Xo0j@7zw+#aO->1ZLxzCqP&?0_dDOmL(4%V|Xxfn~%fBHzz)m@g25c1cnv^&a zkUq5r#99+(ZxdM8t#U5p*5~e;5#3qUd|CvvaRH_J>8EVYwDI7hpDmsfsax8lz`4C} z>{L_s`j-Jeefe~CM|_L~MqC3zv=K&c0Fm7s13x(_#!%Bv1l^_|RHzk=FSpXl?YXsJWL^OG-)Pwus28d@~5o&u+UgOwn*-{o+}N&!f|m6*XRqKgerXa+o8e3t4~FJXE*Q=GXDd zu`L?8y{R1grzKj?Uhj1_34WF*C3E3<#bIx4wbAu4HH9%D)QD2;m85qnI+nTxb~4%d z_exZExVq+#t+0<+=@m2UhF_*l^u1)Mh`%_m zjkalc>SQuy64%CUMgwHIi8TI7uM?%dLH*9#dg&`|2Df#)K7fD8cttqjigSCcwjWf5 zMK(Pspdp-N`w0>=y|U0@r9u8<3J+fL0LX3RX2b|$Yr8>YDI^5QVcBS-A#)}?Os3x@ zt!?bT0wx6(Fnqu>1*f1NG>}0^vnVFAWs-@J@YvK0``GkPi}^QzgpOXlv2-L2tn&T2}i2Y6FUru|(P zHJ{8Q$cty4+KfzAP}|y6pq{mX57Pm`0e(gU32t}SgLGY1-*Sxp?G<}a7d2HEE*~}b z`bxO`M_%{zQX(_d=DWzDx^V_IR6RCY^SZ}>$kT1xUe0fc?&d+j z95ZjyP;HdE8}Xz!M^i(LuD;(x<)S7+zjmf2dP=mw-y`jyc1nJHCBK1zv$^x^de>Oh zm+_T~Vc|(5AsX{IE zgzA3SLB_8fSwmb{m#HHyKyNG%KHc{aCJWfT3$=Nj&f81Bc0hUM6&Kl!z>dsVSjz&8 zh|18I>2>NrC=g_@-@OefMMo9bi<<>#b7Kz%I9123Wd|}6D|;E(^xAZ z>*C&4Ev%=_lI;VN{-t%+Isbg^-7+r#GT&=l_$Qm>rf|r)VD{U=XUZ-1S8HC`88mi3 zZXEO6vEy-$;TDNaH(c+lc4qDW`RLU_g{Pun2c5T%RFx#JOKG`uV0);#(R9+KwhZwl zTSxx5r6OabBk;L~tE>$>X*|lEnran-ciZ}!l3ZlD&5^nQxqQCL4DiHMlM8owME7`x z!TV>avbS<+TpVS%TbG+7B8a=x7jUv}T7?0*Q8he3AGHbGc)K-eqg=88A@X(#wJ2|^ z2AG<{P3S9KUpiQym!-gwG!_;8a1A z*%kw(Qzy9mzDiTSelVv1Ge}XS%^s{0?EH{05(tuiY7d&XZn6aNOWtIBs<(XcoA#g~ zSm6pLlqi6p!&Hf#pIyq}oKd&W;2E~h1>}p!wj*7NhGFDNegUbh%Go)%5C5&t(UHDS zU()aCe)_T}CaGq`!8!7T)Ol5%BfryJz2~<1=IN+ASN-_0p*rRAosE`9y03K%B`5zH za6NEn$D6-l9ujT=Kg*;YXjCqbZGzqH>Qn2Drd4$cFJ#LyjZllTW4;POL+jA{Qg$G6 zEs*_wDoVD)UwGSxW3uUAZfu_r?#L!N_Xl|-h#XbkCRxgKdT=kWKUEot&De?UdPWD- zXx?7gaksvD;Z#`aK~NvyI)ZqB5ooa0lzjfeiE@)0=R7?sjxB6PjhK+r8LH0BSb&N( zGcG(cx7tY^tQ6S#3emgqOdh;hUL1wldlC+;BUI3tFJN#jawHtMePs>uhhSt5o5YF{ z2|D2(Nr*o#dP{9BI&$&%`;;G(uIT<qYxl)Xmtb1jj*ytjrWkALV+X=ksA#TaT>oRNU;EWoa%Pc5qtB&PtEx)@j-Kon6)2wWe=O*gV*}WNXkP#g!!Y5K3MY z+#65zUY2qH;)gH`JXBTAjk+5;MY&63$1iL@n3q!Jz$>{EFguO22N&KS<|;|cqij6? zoAOr_PO7hQ;UfNUnY4}zq4kC0xada)y zGg_LwYWCA@g130l(zHL2NZ$Wh50bv@I)e;b!%l`%=i2dsbqts9E~YjuJivRW(2Oc<0u3UqQON#<1Ue z4g2Cf+2PMnKPUp$rG;&hPA+= zFTkAkBZDGH(>+=2irBReWQL~-3Lk^XWdc7kxCR-NbAmraYpq1zy~a{y2qTOK)9ad@ zfquBVjS?y($9(pcML>Vees{t?&Mth52=d{c+l$~+-M@copD8`nf?&F*!>kFB%j_^P zs!&+HRU2-gP}G!Y(qFi9?~xru^LAZ80ajYvZ*oC-%Pb+1)MTa8W#`=IR5*hPtjdtXF&YSy}y2C{iQS z^`|eTPf-)7mN&=lw%3QTz4Ey();`6B_o#2Wd^~KTQS!9nzUSrIe&+pTkDTomegwLo z^@GC~vuh1A`E@guZ0noE)DIlXlA%(6j2arE0TL-Zm0kyck85h5+E?K&4XH;<4Lp?@ zNwz07SnE|Zxj1$N4o~oYYI3zJiSxo3{OhDg@DHs=KOP$NmRt=ijandLJ($q|H5%?I zm5{|KL*)2y;esa?ldeG+mVlE5+fKEdC9vTM<)|@aaLfi!%_QJRt)##x|w$5ciWyuPpW6C13 z;rwfLSzTf@D~96+ZcfulU`cU3gAXvk0TEdrLh}xOx@cLnQO41&`-sGT@^Sg2$vn#g zEiAE#&O2@f^{%ezrBgh=j$2LS**86ZGe3V-VC}7P-5Z7d*T?k@a;Q@m^m50{Xo4N2AK20 z7YDJf4DnGzT=s|gPc01tI1GFMA#R;aOIKZ%W~TcyS_jf3@m1!Np}S%@&%=wtr*b)} zXY(k(moI$rJL`6v;KXsoS!C7uaR=TGnozL0&Vc!I$mDlEwg2=s6CnQy+!c3UJOF2|x{cH5r@p3cXx9lp4ubh2Xj9T0s9dj$VJv-OFro=c(`?lP#J`IJY zoc9_xOw-iebc2Yh6E{j8p9uY$Kck=FGb!=MPnP(girLDs{5bO{bhq2>$9f(f9{E@5 z!~+j)&d;&zjI|fQO&s~P#`+{fLw4yfk6J(2*lpW$?)LRATMTd5kQwlS7#WjYy*o$h zkb3Q@DCsInWl`F(K7~xB)nV5^ibRqve~Yj>MR}VHcw#8nlz7FuJ>Ztuv!rdMSA5!; zmqpnGOo@aup|)ZNsM$5)KYympgZDN8cDTP7A&}N50`D_T*ANALH`{oZnTl3}S;NRh!CDF<)y)QiVqn&CWdpPFjsk-WV3lmX+H;_Xj{MKbP0 z>IwG=a^|7jwq(*V*-v~IZy8ci4_Up>euqHm*7=?Q@v*O(Fk|v!9b%xNL5Vf)VO?A_gnfgA4XMUyfez>PYH_9t znxI9b&vpLO=ffwV!cPmTg@Op|vqW|}!iI8SD=Fpz|4Crh#{;|Cci-rcn0^^hj)m}H zj~$A*osH+?mA%Xwqk`r)6X296erd>KwcaTJ866{!SLV&nF+hOuv=<*ekO2!F&-ItJ zxjB4DBq4xxnvibAC?gIGnQL2f)6THEcm(y}Odddx&z;OuHh62goBT))(ou*-yB zsoS>Z%gxFVTm`aQi6*e0qDEkY8IS(3E(=F{Ke9LudJlsJ!wD72Lwmk#NO$DHY_x#< zM{w8kRDil4iSzNi2o_+iLA#@yB?g%(wjl@{QOh#Zk2_r8=8fUqufvQngGu-jFs%eX zCSdh*ON=I*He&8Z7%*F&SMR&#cbH(f+k$^y|3B*X2XQn{>{>60A#+w>mA`gh*qE9H zFs0Yv$!3oG6#bRYUid>u4AbQ+z>NIj%MhH~l`lMfRyTa?k2G!8+iNevwPFRNvXdEcEBI7t1x9DRx?%Qvao7rNT$gE-%Rf{ScA|2G)Jgxk8 zM2P+WIJ(k!D8DxR%wonc#=fs(i!9j<$-ZwzVNeXRr81UEBE#7CohT97kRe4S#vUny zNF`1A3oVRNWU2Rfzxd4upU!#Cy~HEj52}P;x!7o5V680l>e@&urBS-I5*z&0m)6DOji_zQgZ+nVv*~?wB{bNhU z_5)+*-&NN<20ZYOC5_q>7;$B)w%7iEQ~890zq+glq7F4e!>yyYRf_{lLR&i|#E_m> z_D&fGj(fGAXkTohqNcM|kR+NF3M7aeLzcdqlSvd#!&-Y-rY z_*CsFG<0mVk0XM?lUkz3XAfN;fyYRQfQB*%zKL~%+d$Gcw-+y=q1h4G>@N{0wR_x=i;Mzj<{LhFE+!CmX~Ci(8_DSiIP00n?SF@X1;aNxFp!d@ z?0MIiDCKsaon3o9Stgkvoba`|S5W5|{)Lnq9$?}k=8wp(29yBY0tbS%$IfE1D@)v< z_P|*|aON4&9#|S_k`g^&qSI`TX8r1iWk0fgN$GFh7qA({wf0k?z)1(AZ3q5RV ze}f~#E&Hv;y1OH3s^j*Tp0ritxSB|@k7pknozHA))N+{gIFsV!x+5MV`ktVP1Yx=^v{%2Mg6$z_c_{Kb(AE0jNPZTs(AfkaRv3nLJOE^QKDum*TmoF` zKj`cj)X^Yf^fy-rPO1wRgPpMYCf0C7AwSXEVtNs5rPrXVp?jZdq?JaGUfA#(icH7yQR46~+?pDYFZzQ7c62T(Jb(afh@ zu$g$JnfuM}g20442qjmgyi*LJwcPi5&&&=*SeqsE-rj5;e)PqV&vRFIf%F|QPyr}|9JXXW7 zY-NcysMHKdSZZMy0V3;|IhvNuBvR&A?~vLv^q%$UR=}e)84OApi5n5x1bAskN)!$;CiW79@)cR~e)#G*I z$XODJHE|QA!BI12rK0gDF&IE+Ktkcd=ku2;b-^?`U|Ix4 znyUlEComf!`_HgR{m3Jrm=XWyBgeBdTdW}?K3tChs5n{GfF=$UV?y+JFL+aU4Hs~@ zTm1^`A}$G1-T}0X6Ium@s6~Q_;a@;a`m&Fc*(E@40;X9&KGLBLAWM(yA^64#zl*z3 zwUDvtkgrJ~WNgeAOH-hL!I-fa%rP`7KVA-sbA@JZn&Ga^x$eva;QQY+%?%& z$;y;kM2xZ_#f9yRCHXj#YrnosQxMj6Y0tf=my*0v%jn{{zprmzyg~S$=ciyrPL7;z z*>e*DJ~iJA_@f_0Z9MAyayRalxAQ0A_eQa6XD??aeC=+mc=G6ajb-T+O|fCq!r>tG zLWhK5`i#*$qxj&wK?2aDKO?zd;uI&!z*b@!%hM8)difCk z9H@@Om{r+4kcRDA$a^8Oo0sqZ__BWc!NR4`u7pf668yve-56 zm|Bwiv8vOs&SFb)qa{X1U#8~Df3rcaO!{bBa<5Fn2Y;u$+rJ}PGUg!{e`V7^B0+8K z{wp7=7g1u-f;wZKQ*PA9`-jG#a6cz{CrFe?(~qUs|2bTqeq%nt%ctm9BU0nG(i^|GSip2AeJhr1d3HBGq!af0v=z83%{ z^J+T!axWU+L@@UAdVzx{iIk4pvO@rO^-ckPMo4C@BE>=lAjJ5~JG!v!YqrmrAJ-t} z8aSKNLiDHKcuphAAHY>W25r~pASHWnFb~1#%Mr!*TLtLfFG8z!mlx&{GhHcq|4*iX z_5p~;3_rF%Zq4FuW<)mTr(Z6vNp;iod0@cqaUb-S}96wfLRV8~`+EPV{Za8KGL<%%D9OAMS zE`ce3x!w*kr+|rX|Cf~8aVS*L=9Trw=f}fkA7!=%t1NMhS9+Wnzo>uUZtU91e17@m zi)Z~Dg~zYFrv=lRhTlH=8RuLyAUOWIL)LJlW=*|fxW*+XaHOWD(#*;t{BB6dg!xgO zXdSr|`~z6|WL%K^ZN+G;^DLc>x>zDk=#S8VCdEXq*%rz28h-X0CWMe>0h<|^C=zfd z(t)Yje0YsE^gFTmian`{J)W=11XS!mVCYUtU=ITFl2jpzo0@A6Q_3Gm|5h5|WbdEQ ziuRH>8<=AZuf2v?Qf$og5cvtjsKfvp_yqv$#2SG z_+mdIk~9JeOq>~mojDGXvMX!m4?vs83@F@q%D(^9bW(dtVKen_UI0)G>thcyN`!m@ zHHk*-Ta9ca>7EuP3Hslb2ZF8ycDit>7OzCZVjFB(HO!O)NG1~UCFplxnDsHoo$Re( z#U0G>n5^bF`mnLrb&5{la_SK%|B$^^uU_vzix?@v5fTH>bVg*7OCuPn++nUr*Q#m_RlpMy!-!H2pM=Gw zi)7mo!775DpNkNhB{J^u5H8JVqO)cLz)WI4?U;%MwSlTXmG)(>Z$Bq@4=!Rmw!oQlK@T6ZFK%Ks z>mZFF(wbswIs6PLQYzVakz7@_j)_8$wRj*IdcvM-buE!iw(&XB>=UX^H`Fu}M+!B4 z+oAMMm`>?0yv|F{*c4qK+yBRNde`-f{LvGd>p>^S45r)&KisqK`W!=lxa9AXSt}y( z&uu66r_%8|W3KBZ6^+~rH(HYwlpB+CdP(>+Yu#yuYlnxSIIFFKlRE3x*{O3iXH%o@ zR+^O;+{+gYwYpL;eN{A+cVBrydXH@Gd|diGAuqI8=kFn{dPo(a94OJ2H(yRP5=AI4 z4qyl~`6uN*j`C(wjs5iaZisg@@(~}x^O7|hKeh4}K};0bh#8#)D@tL6;uCotOHqo6=jC8=^6;5I zeUr`- zmnb!L+}>~7;CgQA=@(_JYOLGlK+(*%f%!(m|zr)uC{TclLZZpg%Q<0IxTq{btx< zIQ_&EU7*PDo+m;pO>nYrSnvpmpKhMEu=Gyb^3NESz7WP#y6kM9FR=Fx!dXa zY-ZP;qLkwKj_AmwNQ`_kSdb%>4#OO!_~LPpW3BS?*ZuZ@BTcWeqCTI z7~c(FyU*}B@ia7~`Q8WT6p!=MQ%=55DqT)I;%ZQ%#fm74FD`$(_ZrFC9W5JQtxZUX z*Oe3=yb!{F^}mxY&E!XlDz+_HU3Wg`Kde^VEv&2R&6GLkHb$kO7m&jQTHo-JpUX~$ zx`4zp>8A-1La1qcm!sbimKQhyiaP^+>c7&i*YZx113B-+l(M~~%G z=}ax?|5#a%0R0$7)gD9Tr~o#%$4H?N_c3_P3`9N*6vl0LRlq?qOF@134p3KtISd9= zHNdG1P9Me-Cfe00-g5E4Y*Qqk(#1jV%wnL(Gk?GElc&_$YQrx)OaWr^D$2GpBFs{Y zuzns0gxn7}_HrB~N&ge_-HPEnBn5NCZ5dI9smb@^ru%v1#UTqPo#B`5j=<8Ra5^FE*bBQx?fT3F|}Y$eeh5ZRz^zsondf zzV-Fpp{zQe-MNkcJ?!Q5=F9c0k%;!wwP}GfoFjd zd2UcOS8(JLyE{`PbwRYTmqsh}djUoy{vM3|IX^~wG2(Q5j_aVAHiSmKORp*mV~5;Bg9)QK(uB{@>#NlL1Q>c7k4x3H?0*>M>LWcDC4 zM$}38O~uqA&9q2^|Bm=$r$sej`;;Y)lHgUox6FU=P#+{JOY|Z;A9S>;DKLb`k)YHs zt3?{d=HIjC<`d0-xPu{%G$;Kv0IvbAaw;U^m-qvZxb5xyhuy8~`om8j|D4S^xq3;v zd*kVe){UkIpW;Q+!TZ`AQ@-9xg@Xvm#mSJM$Tx6$S^D0rFa)629pOmmjsidJf(zZ=gGxKGft z6dHniCI*TKeW6V&PN?Gi$raWZtnnFmjNbPEx=hHI0NdQ|_0X=ne4EH?JP>{R4&Nr! zfIMGgO8Kz1Zz;}qzA0jIdG2CdD)YaH_ z#x+lFw%_!4KQce)j4zNrH2mruF#WHYDjX-9j;SQAKC)LB*Uc& z+-%vIng}``@wF|2-8cxgNkFjdU|>?h;e_Q><*abSJE;doDy3jRKXa{~-1uCi@fETW ztW`;@S74OYBe(7@k!A|{LQ4N-bEqnGb1ZuthpYYPp|u5=37t`ltm_M3gx}j7ywI`p z<~ne<@4*tKY+YFNZ?yblqo>AKJAHcch=? z`qPU21+RzR8@|g_DHU)~IQr#yh|4ICB~e!R?J_NiUzwvOg+G+)o#?{;wAI<2nRRg= zUr@woFIk0U6cj=9BdT+M%`UKhgbgj;cTS=$Si_-qePc{DXW~l$CD=Sv&JV_%tPN72 zEm1rY>fhxu7O{H+|yom-ls_hJIBzJxZh)}1#PnwTUMDotjoc7NKBb)&HwqhWuV zv(uKNmk?FZlGsqBJxb^FE~U;V+!;)tA?p=6emJITW9ghY>368&d}2k?$)#*Kcm0=ppG#_gtLj z-t`?k5p{REFIrhL!0_y?q{d6q5BXbH*swOrLPrDM$9}HB55yva5JWdrF9;J}|CtB?QT21^mk9=;MHl1>fZp#S~Tp zs^<@+_=%oN#?pt@ceMx1^7yDl_M|r)ajKWVR|y4OvxU)3eakrj!)X`OaSAqCSpcU# z7Xl1SmLeTlP30}LDwec^~bu-6L!HkzpdP#K^vV)%a9 zxW6|Co?;rCN01s`voYL!l1Ub#8t=`I#*Oy0s+;dQE7;X$z?!RJ^rAEd6;OwcZ&LDp zh%_FRML9qsar7cX)K_dBdDN17LjGd@=VWwf(8nD|e>jSJqLU?a=AcvPX?&+hwsa~o zR;^UV4CSt5X3kb>^4DiJ<3~eQ{y)Hfe&?~$|2_Pb37|$)A2>?N_%CN>Qzf#w>VBKY zS^TMQ@zP6E&9mEj4?is2dWWtLkW3OM^4;g*-svY->h)NDqVc6#ki{5gks-zY3O&RD zwB$9%P`j36s`anTRq$=kQ-an9jsv3IWX69>oKV+E&%^`lDzr#hwX>Ttxj#ciN+FFE z3ee*On_Ysa>|cwO0@(eCS~xFY+CBQII%{k}lhg2>?UJZtPV&~KLk44o&I2_)Gz^~^T|N`E9&HfPRHxw6~-O(<5iigJ-74aMSxF?qke%yub$ zq;Aedn(F7l^$-U&FwnFa10wya!pZ_PyqHbRpQdQVVPo6tb){TLk!iQC%faosBx}UI ze@Q0MTCnXje9kAEZz&6(Rv4SFUW6126Va&bJK6tFee|-4HXYKRD&cYt)f&f3__teQ>HQ|FmWbHoGJlygHu#(%E55E#>J+`%JgE{jP_4_LmkK6wLbS*B-EKDdx{eX1uQD zF+3;RM^yb-Pg#q{e*1f6$P5fu^k5PyiH9f_(&WwrT#BvS{0+Vs(AoV4ZaJ?)*!E_# zB9teRl!GHebmX4b>t5ZY7q2TG0+!A=U?>O00ce3?`Zhos%JA=vw@tw(e+=H=e^IXX>6XT$ z%d7I2d>?E*sC%if{XXyHqNl;{vXbu^11;tCA;bO(ybRu0u|i7jrB_}elLlv*iUgH` z$9LdsUc`EU)=;dsNb|9JsjLMt)rnm}$(8>-_p*X&nVqg?f*_mU=zxf=t22pKs;Qgu2bWcb4;>=-(a>HHkZ zkbO($8YQ0JBHy$!5KH5#&}^+f%n1z%+)-B3HRmYQ?`r5s@HE{DfvU6}NsZ`&{y4?wJKYNiqTo zil@6P04Ml#K>px8$HsN|nK2i$WfoqZW`2Q}sse(N=&&UHE%<>*RE+;}x5SyUT?LHk zE{^2DX-*$fq1i_cAP;mXID>^5fc=&Rw#ThBb23*Vp~^5Y@Vbd9$Mpmh^jHLl(bt3w zi(&hqm+p983ilN#sGR{q5-gw{pCSRMGesi(W-i5=Df8JHu>10j3))9jn1~=dVi-Q1 z3Z2%0QI&LN@^7GrJqb6si5K&az@H{bV#}1_ASONh1f0jK^)(P*h007-{m&A z5$lWjmQZ8NaqEM}+4R6W7NfaBl}s8pE^>*?{`r(@p?`#~5PUQA@A6`%^1zRlVwQdk z>_3KC<^u(b8c_;WAj_bD>DF&pa8Jy+Zid6ropg$=)LGufHNI&8n zwf{chCW7iF6wTu&8i+MxyH>0@ij=0Q2e6=^KlCm-w0nhTQ_mTyczMtKz z4Sx-`71UaNOO)a!icpxjqh#*~2iNf&MG0mMJaeK0YI>*{~_Blf3Chi&*i%_ zb+L|cNvN|=o}vE;X}F(8>B-pnGI7pj_tHh1FV_do7M?Ip`!AFrVc_&i& zhrJUQiv>ZHvE&ni#hghBj_8oVl@0h=xv0Mdl6KOQY`g~XA)XD`8RKV`5Wlg;(RXo_ zH-c@eve^(|VqqyjaWoXU0k#O*++DqX>9)`?wOXCB4a|__C>wz8IjKaspo}uXKz&o^ zfe2g^3<F8rT zI)s4LbAV;ylmS*2L{!HFaEls4cyq6bdG*m=0=Rp6I`4h~e535Co z`czPa@ZYH0u-%4Ym-<*h)eO>q+H>gGQ5XuZ> zIbC@fL2YO;*9v^)_x_b@Sh?J1Mlb_Kms!*mT?VzKY|8* zC}N}4_kEFvI8m!%DEjsYG#d^P43O>m2xh@cpVICE7#VbSJh^VDxbzVUnhy$)rrkCN zNcKEr910dJ0NN~Im}LEydK?#2 z&*^nZ!C(Kzk2lw-RvGZ7%U62Z&5xCwKL39Cw;#3W1U6XEn1Aa^_|$tZ71?X ziM)kDRe)>bj7z#Z^P0`^Okm6lKKSOj!&=HNnGfu+I9JtW%gAO4_hF`wN0=G=cl{ny z-_MqrW)h9X8gQal;&_Iorvy(w?|lN1uXHrYnzuAq<8W`JCxdfeC|Y$ya z4C~3GnA(4gNf2vz2CbUgJrp3#3VBu|4{Thz5cBMMLxU-S7&EG5ui#-)1Qc;$eM?gDWG|72V=|E|98H6i#*8~G8!(g}v}y&VZ_VRU{*Ic?9{_5{GQ@?j&E{oK?x|HCmTjxuNp94;f_kp)8}v+8Qm9B)vq*^=?sD=4ee4;5^f_ zhLkwkQiWHZF0ss9I7f8JRFG>~DdZo<)MORZFj@Bt-&$D}@D)8I~7`S1TkAvAe;H>&(R z3V194OVUf(+rbr20rasSy49wJCTm{Pqk#3xb1x3l)wWDbp^ihj80M_l%w)S5{Rhvt zzlJ}ZKnYCcr2|LVi#+JP7@1cG<+|Ax^fYpdK&qgGmBhD|b&LmMjZs;!@?#7-NeU^s zO*uq4C!lbX?8w1SCLo(r_sgf>h_1>EMKMFM)r*SEpC>2iT1=)HXoWH`Af>xv)`PMs zI4Sufq(6(QWv0Gea(qhsf2I_ay9?Kf4m<2d75lztsfuldLW2IB% zZ-Dy1a8(^5jnwt)YS_1AcCRZX-!vVO87OqF6L)3*UPo+jVLyQ#*C!OnQraI05`<*I z?m9+3zcL%mp*C5*acTyQ)xHCb)+z~Wc{1+*(MrA3#-*&Ic~$v4NFLy8zOx;C_avFS zot;?_fnhG0aX{w}J3qExhf<~LsDMH0+6ApJ9@ye|04L%QJmxxvSqdz)zPhdprZIQc zz@+U$AnbS~yB^e;HwclhKTgtnO+RA`N-m>9C`KN}g29+Q)JPbxRhCZ#Y(rqgPCe#o zqjZ>lBijr?Y{!Gj;wLdhr>9nlmp+Rey`glGPY40#`{jz_h3hf{T1-JDgrfKa+Ygx( zS@Q+6PkbRY2{>Ks!BJ|zTy^+QIH@_|Gv5*o!mSmRS?$QbHZh^Tw@K{M@Bb~F;-PO4 z|KRtRfx0l*?=JXL@^7a)x8=bN!Q*SCAAe7!jcqI2XwBJ*!$Wmxf1>4K&fab`ZZ-L*=xxCY4=mijGTj5cizN_ zQl%TXFeZ$$XphZo?$R;20l9smLq z9g#cVYgCrjXO>^nQGgAc#s3YsKJ=kjU6IfQeGK!i_mZCB-&Qf^gf6YS>zN+xr!LD( zEW1a{^+Yn6GoAn!Ia?DieNGqjl`JwJQtfQb5S7c0&Fr}hF82Pg7HYJn7+ebz;oMsN z07HOgZjnb>@{PIxMRx)=9QfxHeREO7s_blTApK>kd=~p_QOXtM+gqkKe+2ETfz#Yt zatSZPDADyUbx(+^m^o5YOO@YYdsCK>8utNmPT@+(ua zY^ZRJO^P-YBvnU5NjTBHCy?1`Oa?VMjj5D~g0%k#7MT`3{&kZj6M<>7tp?({b=gvomwZhFlhjaJkC zhVQ_4D>WkA&s(TANcvwX+|1)UXQzq(D)jo~qd*P2ma4oSVtau4kgh-32xej*pnRY} zsKT!0VRL^h^TqSyoK49LGP@#v{oHLU4)c)fcA_Z&Pv+VBG$Dp&mA1hh_VG;!U$ymN zcLD?orf2$%;|4iJiheEp0LKCViCRFqnS>3JlEMutArZ>q#cc|VzRzD8G>78?bc81) z{dt|sRdwU|g3YzrJs|hvm+i%~cddSu-|k3Ihmj8}Q=WX^4u<>pj+_7*V}q?yL`OA9 z=ka-H=EKK8;k0M(1Lh)EyhDQio#CO!qbL9}G(o17F?n9P@Y7!nX|OFz90Hku5O{|GA63ODUaE(#W%ycId07rERl%-}!2uf6FM|D5>x=zQ2pKkRuOYL6Kwc{5XppN=GrttaQ=Ivd znsV}-41Qe@1TIF1 z96+grAWQKHO%&7rq-dX6qZ~HHHtn0CIgZKbH{BRJHcUBVyAC=2UzOqdn+G(8_X&QrMzET+a5N9b&8=zM(ZSKPRcsuUGQd8|3 zt`ZqL%=!sw?`H}OZgs0aB@-qlFSgJHU9UaY#+~&p%H7y_$me7Ay+paQ@S>RLY>@EN zv7zUSx2`9sNp7n@_CJ8PhmV*uL6-nrCG{w+C91coR{(qa`MpOqr&(A8j_|IK%})+XQ9n(dn62n()8q?BeRW}oU$qNjgB9A4%xP*n%P&6rLl*Yw3nloUjhup_aom@`M+-~*8^Z0 z6B~CWO_ZPHiNuFneH09B_Hk_UIAHbNO~7YhY8CNxg=_n*)~BxN+1np%H zR5db!6Te=;W3CN_;n&&x*npz}5i@F!sTCx!gRMPbnwT(D5lxn2$Ii9t#KxS2mLKrH{=Y(LeBjkZR);&?3ja6i9BHsP*iO;zCsikm^f~PZlRzHBGBA!2Uu6Sw?t)6F^i%P zi*;~WKjd*=rll%S9H!~D?|&d?pTj^luu!IK-^oi9AObi0WvkO}c+gE9=+*kl4s zP^l*aj|s~SG@Govh%aJ011c6*zETv(DpXh>I-bivU?F@7HQw1=X^@lI)Ivl@Tzdm-bF5$BE;9=vT^|6|{#V+T$^gtW#M`+PXstxo z(+PHoRtr@9@}10jUwnLc&l``h=495FdsiOS9P{}0!=U|1POJ*o``6cBj>_rt4Vqsm zdB-EJ;&+m!blP^(z~^x-_>=z#+{mvufN+V|6YB=;U4g`@*+zNVibM|CH>-$x?r0C! z;5YwipZc}25Ntkja~~!fG@U%+Tu0ssbgr}Y#gL+9U4(2{u%kj~SWM&_`(7{F4W$zz z(=L~Ha*UawBT2^cBO-9Brzq9rZ>v_S=9649(0AS<-`<-e`Ca}u3f3aRVklq$0+E|< zTbZLgKA8OU>D_`>_`y4v<^)zEb7epbYcqT4p-qYW*SCw!-&O{x$@ykDm3%8yaz11y zvziZs^-i{3Gw9xG8pZy!JbBNpzUs~5(|bF#;Pc$K-Q2$3dlut3$UF*d#vP)p?Nfnm z@?8T90;lQ18C`CWIv8ce-xo3;BC)aDhHJhJi!_GI1(C1A%fGPKb70a)>X!Da0ZryV z;^}>ebvvfK>QS597b8R2_2TIps+6=pe=nXK3IHfrX;Y@_d=xb>ziT z1wXY@eD0Y&6;uHnOXko+DfxTmZ%v_Ev~oE`jiMsYKs&>qx|W(sTfhV3I%;?9`IYQ0 zKd7wt4g8^U>uK-z12w|!-P6CamYQat2YtEQ`*>sbmdUdG`bfgM_s8f)zdKva59@Iz zmiY_%J*zG`R!OR}$XbD~g7z&qlkcJG(Po(gh5$r9V|s`s7U-%);ip=qSw%=}U%@?x zHXpIECKbL~#&)gsyK5PpcdpwvW4kG<%cn&V9_KI$-Jhs{akx*A$Ale=qk9dSN>8~8 zER5!hCrpMKajZC<5}(LNu#(jRL;|)3qr&8+6OPI#Ac#rTS@HB^HcH%sSbBR*)%dNj z*f~9^PKY_O9elCe2HJRlWmd&P*Z&=c#XX4ow{sYZ8=QO%Cunu>(KCA3pz952R=q5x zq(@ki@-Eh^BPCZn2~PRxy)-DSeq+_`w7&)fIu&;2Nw#}va`(dv0~_}m%p>FJazE^z z0iYrf-W6I%yTP&L<1iYJ zie8wR#FANsuZ~pRt>^brYwY1p^Ub!^9;Wc8cO~gA-Euz~PTXjI)*J)dfx&6Ut#Ho& zJdPc-Z4qyLI-zj;%yH9?f@x0X*Q-BlR!DxA4p&jn=khd}x5Iw^M?4brsEKS?V%{{* z-5u-sRc4(tMI6sKZ&acv_*aF+%p^=98WLGqw`_u=?ar2%K{r%ixo|YUKcL5zShF zPQ;vsH6CQ1v;c4$jNUE?2Jlss6XJYO2Lr8|*El%;bsc)RUJr_iHhZypct?>UQxWQN z*M%)^j2Xe&1+{5kAl2J^z)yOzU5LKO74OFtr+{WDK&%oi%2!3^;F^gjM9|tSM6e#X z!y4Dm;F!-FlLq6C! zVA<^q#e~}5LT{m&QrL6x1w~EboLynW+Y3)-(T*MrIBB?MG?f%$VQ)ceMs}${FI5ub zg>-=9Td+$p7pmym2SvX_Qfn^7V*R{L^po%^5ZP=n^s!201QE)DH@vdy@N397O)N38 zJ#e9OZvs>5lK8-xZ|Qg<8@~89y%%Z(UnGp!0lEK~x{SZr7oHIRZ4k2;*QPG{qE8Hb zH#x{ApD-eKkSu*#uO~d3e+O~8=ZzS_Z6d9ay8o<{oo9b`my zr3}ugmjhV4t5~@h7p@7nRtKlfZZ;S*?UVy3`|FB(HCLWf0Q6s~Ijgh|6Nk77TlVrwPyWy%3VC}8*KMfR>3uhwug}<~$v8JhbA-3m8dU1*7Y#9br;Qc{nWreiVEIVS+&-`TF0}x7@ z^>Y;6DR0cYa)Z0PAz#X*L^1VTLz44h(_R z!im6X4>@4O2v{5)M|$~TruI|qOnm>321H%6e0XPg{C4F)82w&5`Q6p#OX7s1LaiIxv4P%b)21Wc+i)C+=wvPTc8>9lA&i z&tX@2ZypW;SUneTPnz2&*yfac`LDT(XqCFSG_3`1h1c1n)Z(6RQcmy;6`~@lxyuKA zAL1i;hRP*udov;ReSW%K7L_s~BS}?VS@Q?1T_T0r(B%0|EfSJ^5_lLwn?7K;J+L<;#~ipt4HJdmbYa?Ar)sQmsvh$Va^-NdY_Dj7ZS&+j6h$Nf#%BOXyeG zPMngDlZmH$O84nx(W2R%g)R&CYf4O<=L5C0$}$Z!*)P#XcZ`|!qv%GxI-8&OI6|Eo z@~di)k0XvGP7xBj82vQ#{*WW245XpXq$ivEJPq#P&7K4QddP$4)Zf9}|H38s;zPF^ zIGN37VR0uPb}OErKR5OJb>roKO6u{4C@=1ny&PWbUW&`u_xHoF2iKn+Vc0u21Zs#ZKr+)u9?QLoD_y`VAivaNR^LdBG;((wewS~U(sPKN zSsD2ccq0bF;+mrWjRK=_=G-YnA%YB8UO}+Yc)B2TubiR+NmvpKDn&u^7oz`_-g?7m z|047lBHf3&%5x{$QS`-(u4_hrPu)BZ91?DX-@$ZXndcpQwe|`E933o_bd_eQeL!D5 zTLYt~81{-2F-EGZmpm}4o{Wb)%3G8)olIA#(WSVrB3aO+0c;=%kfJMMv#5kYR~|IH zJf7Z|^iWTJ9TvQIaUm97ckY?X@@r@V)?gUF#ambrGS*Ij7>2G$d{DD72Am`XiSmhO zuXZGR0DygT5&^26X--1~PU${);M zAE1h-MH%SGc-0e4T94qml2U!MmS`bd*@lgMg}AVPeGjMnc&W8Ghd$c*{?v7`V+@;o z_NJ%FE^IHbr82qw%mqm$%eNqjqA2>+JfS&93Bdg)o0~B1K_x`*I6;?BQ3*O2m5JBj z#t!r^KX0)EaS!LgFwQI#{nn5V0JhuJPCU_Gi2G=}5fLn<1v~Q_W&;HXx&}&<_epUx zD{=J1o~ssjxEH^yl|i!~VaFr(ggaM1Z;T1i&5{NGxM4^=AC_TpH`$-TDll@K=i>+ny4(H9;kf#tS`-6TI&-;r~)poPo7(n5Kp zpG+d0#=CO#wT2c8T%#J3THpbE?kw<>bGQi{H91_$5b-(XBKynJwr1>4Y5s1EMpZX9 z_k7c_O2yRgw+E`3j+hoGISp>*jJedb;Sz27p$l8Qz^VxjpA-4vcC|;8VB0U)0dHy6jR*Kc z_x0*f)bZ5y|JWF1R6=prH-zGrv92-6=_5r3$HuBP%8XRfoY|x(XHK}`?{E!!;3I_E z)DS^ixnx}ZBd{-;n}NhaU0{I`n4UR+<+B#PF!FrjtRZ+7Ku`_3Q6w`<4Ymp7YDrwn zabb|L2PzEFkZiTmpdGO*-9=09ipn%a!0=VJ4b4(>IyGQkS1CkqkHb$KQ^r-) zM(JR~N{eV3>2k|75xO1Qi_`)1q!;R{h{PG&ED$?pqIq4VHD>aIgxfOwaFI&XrB_HZ z^i~pwAw$@W@w_exXD)68(a3d#bS4q*@KfJ5(MrF*8Mp>7hBM$I4?JQu zReFjZZ>gP4I76>{^GnZnLulzz;jVUx#^-JY@uYL2-}HK5eR{=xjfu(y^G_NR!Aq$p z7IaxjPTRclJ0mJ7v`W#Ibbq{<@6Rk#O%8&J*i|&jCzY=6Lv>dhqg>5y>9TIL;19Lv z)eX(1uJfI?_2V}>lSD{DWBh5a&_;=75}K&6i|7KJGNucoi6=P;PFNvXQ|^!>CsXIIPegaueu#?b7*>l0 zUUnE@X5qB{G&O>OqZ5!DDwKEu1$X$-H|fZT8SCD6C^}<^R7g85-3PA7Fff9|gU;!e z=*MH7Wk=0<(1;j3yB!0atyeebr=0m4*1!=v@GhU00ZXd(OjhvxbI^rN&5R-2`xY(O z2Fz{cQ{*yf9N=nPNZ;3RG1vbyVNfi8`+7p!6!FD|7azzU#qV8!xp&`*t|9Gkl|3E! ze!6QVes%ikN?gvZ%%MO29bZ;UR6=S8w|L>g-W*A$;oaTHg$+ao^Vm1!X%tzE zlvTkVq$?5~n^uGK^7S+Flo&U+;ddz7yw7z)S#KypBDLF|)>-Fe$R(twXtSl)f9{|J zfB=b3U&VMeHgIqN zm|z7WL@j+`@O>FZf|IDGUo{m1y@L63S0iVOpO&+;3P+&|4_VJokE1ysazz&oU}6^N z21Qi*XjSZ1IxTte8Vg8sFL(vW7Q$$-vI=-6a7R%WP4`YC)+da|xcObrIS*67TgU#a zzeJ}oO&(k}69z>ye!bp5N?w`A4i?-o;jTidkkZ~Bc9LYuo*Pi5pN&DKAm1Qs`#mbjue>Q#`n6U zfiStZViFxhOM|u=S7`W4(Tv?Xr^m>$gFq~Xia>r*E5IF6w|epP$0if*&8kx2DvGxQs)UJNwii z1+I5IS+>%CyOss0Z!l3k0bO*e(d#%*NPt%`b4!VZJr>71d)Rdr;i4Sn>^_|+|)UE6ax_CuV8a0c1 zyYwHXlP|Y12N|WH!eOQXVsulsOjgma*EXO2OC8sm+@29zb7#Bj)z?eszZVvxTSca$-EK3C`yI@KZ{={bq_Bi9l}q*Hm zh$yoDf*_1Ea7k`t3-lCF_D87jN_^twZ5cJjjO{CUvxq?xy{c6&l!Bmd)Y&a%)?QTK z0o+i-4$%uy`)j;RowZbMBk6B$i&*q-B)Mn(n}iT|!-ZCVR0U7ZV&U{>41n4E`LG8g z3Fjl=4%v^&cJOMwgqy}-B=v~>hvjmi)}2WHRUF@=Bc0+AA;IvU%HK_2`4dqWJf4E! z6G!fwq}`IwzLC*+lbX<#!J`^*)p5z5=Zy|R3abU1K$;4Npad@;;(m&~YteC!!W1|0 znbah>C({~5G)vjmxIvxrs$ko9i#?y#F;)?Z}|J&#@z40Uhn33>)L%zeBVJ?b6(kaLc$d0JGK>hWX|Pg(I451 z%`bE&KIL&XW@SVcr?soQXX%@aqh2AJucXt|iy$!2s84Y&>4rq!{p(rgKMBnjq?X0|El=JYapzbgo(>(_TKv;badvk-(HO(dAGV%-Z#Mo8 zm1%{=@`>p`em(_7zew)-rHicb>6dpSpri{J=oFzvUNuB5)kXnC8YM=J##-s#Aj`-o z?ruq2>P--pI{jAwlyn6P65s_-nSxd2o#1@?0ksyPT9#<`(ieb;%i<=OTb}5L5)={Q z8*UO5xaT^!kR;Z*e`Cjj?*r-S70ft>^&m>`#-U1+G2KTy@}9tx#|L1&0pGZKK+fI$=(O> zt68GB1(hOa$(gFkm_`TTUDLi3m@G#j(sKn|&{jCU(69qqakK5xy`qH=(NmsxcG{On zGvq$Z`(1rHPpaFkv@$yV*4eZhQnXBW%~aFbv;)=Q@{5_2HF|krc8y?LMIGY!dbB)g zgeN0$V7;hr7f7U?x;nE(tito;$y@m92e`ZPCgbK?+29pm6XhJlR;SePx2OugBSz=? zZ1qlcw6hs%!tiv~7f({DLi*WT4r@>0*mXt^gQ?ymyEDi>TT8C0^RPU^Vs!%iLg^yU zSu^>+In!hk1{w{cO?Z;VHZ@`Raf`KE#<3V5c`lDn1@(S=4nlSof%Mc0#9XCT>hoVy z$d-F(Ssqi6(Y~T%>-=Sby4ef(tA9zh1x`Jw;anvd>X9^qYOxL&olI)JKE%jBMCAgYcDcF%K}0F zh(D!Fn8bq&oMxSSfIqpUtD@e&I?TCWdv5?+S+E`B&6b)T(@P7WHoe=T*%+OO87McB z95zwmENo1>5yfOR33#EO+MXejs$Mm`W6x8++NH?Ib1(JQpSH5QrrOlh(#ZLFvEI%> zpYkX9>#ta!&zFX9leJBrAC6aWiSK10s#k2Fu)0Jjqc{V;~QV z+-c+}=R=(SUfCf|<;MC9H+Rtu7m!aN@(G??RfwBx)+SE1v&Vjuk+pVJ<{1NcaHP9^4Z1^tUxnU!pi2HR~~4ap_{)!s@< z7{86;gVH4xT+G#~V<6pg|8aDX7_QH+mPZUF2m*)JdzuQZS|0qqzRk))SaGtgUV#+` za&iB&5)8`8$(|$TPW~QF!0t)a>i?;Qn!ASJ%QZ_qhWkpIrO8PkG}U}o8`08-qA!3s z9s`<=2mFx=Z+_N_eDI&u2(bVp6z9KY};IU2GmlhB^yd zVYj1>X-S%O)?L1-^SE9 z+h?==qxbnttl!h=!HSUF?rO#++hQSo(ZEJGIgOR~RNOglWG{|s=YaQc1&|ZB`PP2>vb6U- zp>>@e<|1=ci!x#;&}K;uva6c@1Hmig1qamz5OX01q0qylvFxl8OOByTZjGRtGqY=x zIq+TZzbg*;5xA?-D1ifz_XI#KS!5f^7*wjmF;ShrZmZXbZVi;Y=FF5>BH3`Es+?o#hZT&mi^m_4h+ zdv7xC>d(F)ANk}}0RYA5}g{N?DK}VQo0koy~~Hc>9_) zbowfl0uymYyOapbtOqd3kjZ#pReA*E%$W5%4)RzHlm+{=+y5pP?L&DKjKM~*NqM)IAaLFeYcr3#>>&#EKZ6SpafMW(LlLJW-FG%p7t1a0t zK;7H>B;1gRVAcIdD*QnO4nl>b%4wu_+kjaPI}Nhteg}Ske-$Zd)a?o$cjWN{HkCnZ zFJ-tz;-9DyHjxCeY52*T5$q^!eb>7ORBFlX#yMg3zXbXOQv`U06X5cVk?E|l@#Q$w zSsr+7>*RFK3+nDEy!@}g`Z#KvbaLx{;04jATDw=BYx_qfPw!GS<6+N#e3S7D5~U%4 zS?ZW(Q{43b0H@uJ|(svfcsQq8nfwCS%;5;7Fs( z=NhqB`HJp8bTj3y>NUj*$%?bT888L?TNd%Ai+^mbDeC6d;wuCIYpKH9Rrz5*sx(vudy%z>=G23^!)C9Ia@NdUl8 zv!zFIKgK4j2;s$+)}+5l)iK#iPQS?T@MVKp$V6hhA?*f+D2|EIS;U)*{z6X5Ke)Sf(4@h>V?o?AUKp!GIx@!SVzivgo-R$okdN&CgK zZ|&}2OLO+p(<5<<-iJ7`t#d3up>2+ozgsZ?U+%O=XwXs%iySl2vKVuHaABTy!E3~G zv^x@w!G*Jhtt$Xn$g6@&`8?a}08fZ2x2^e4e-O7gG%tu-Jfro&3ZU9L$5Gy}BGB{$ z={qDVPP6eRrst7X+F2eaB>WSglY1Y@xmJaM3)@u%e)NDq78X8(g(r-IAd9>WZlQ_* z3;5I<8X3M9n%l+7Som}fpe&y2=56-ORPAL@2~g>g>=il*)IVlBB+_n zU%+ldag9(|ohB6DBVsEwY=&ZC056}cW${@smHFvF%2Y(Is2mdmMgkz$m*_mmGQ9XO zJekD9pEW_ScKELoSwAcg)hb)mZhi8XS)Q>!+mBA06KIub=dsWi6j&C(=?uU}w~zQ0 z=~Yd8otawvXPHeM{%)ql9fe&s@7Vh)z3b9bbc>Tgz>f)KMl!2N6ETmAz9tEqNu7)52jd6g9hr4LKxN!Rn2V7 zz3p4rLive83r>vNDru&53H_064el=m`Yy?R9LbXN5vBP|g^VB3p1*C7IbGjoPWrK? zScfo~8MDj6Wbd%6+aVDr13l{)40o($ke-4oJv-NGB$f-d+zpAuP23 znHW>xq>DmAj7qm}c-sHZxsb7k#F9-D|`ODkn5|k=WeU1d;omtxXzjbP07I?f7u{ zUTph*(dnm>FOSC;atj%GS44d;o*mX+8IxXJr(;DQfCX<)4On&=~j$eEaYQQgCqo;z1?Vp?6Db&K$2Eo6W^RLmPGy;23~ue+th# zFGfoC@CPHIp%gVRqaj#f7P)Pw%b^xPyLQJbJyg|R{wW|V`V_@y++2pgB;je0!Z?|3 zl2$E05fO>(+30kDnQ`bz_gk)PP@WF*<;Ia{AGVZI zISy6us|;F45pr^{`tfjqhU9c;@`m}#b)^%g4WWYlhiW$d+Yj<&)js7!3Q;q(pnlfj@_j*_5fC@q3=7Th7o_~Yaso`hA)+}mh`ynasZ}|t~5}3$P zz3X9bwuSAvjN`gLH@bk&5lIi4h?d{}0FNRGjv}wjAUfwNM8IJG72!$j{ggb4+6X;u z(cX*T8)qFjFYVfb;_@U>NKKK69zC@-Uk5oy{>P$hVb3L9G<3va{^Clf>Qz+cjy3Xv zRmOs2LG)C8N`nm;sIe!Vp>xKl7V`_S@`9(gM-iXsNn@4OQ;`NTG9z^}PIee4Tcp`H zj+cOz?p6=z$n$CsnF;iBpDDjwU}}<SX?GI*JpVtT3u&Wz|79c~Ny2`4DXaJISG<}? zolUz0Fykx=`rf_+Mv+Ha+?isuOc}^Ym)Rc2g9`mCwsAGMzY9gNckSf3x#zryVue)B zuaceYb4CKW(bzNnAA_IBQhT32bfj}n{?Z&^MqjBaY|l+SqwsN)eO}OB4r+C#PNDMv z?33jh06w;H33)@-caw36ZFMmyx%%)jgV%`G7~mxuZcuxVxVROIZL498?@`0aGtC0n zb%Zj15Dw_S*SQE_jcMS$)3XT`lnq#OC?rpfTd;sSb-2_z>3 z>4ZLj5m;FGz!b>umKUU6M)8A9!TAP-IH3FHa$H3>nx*zj1LXF5@pL!_&s9sW|FK>5 z(NtzsyqB=)jgzUsPjM4g)_TX6@F=qQsJ;Z0HeRlZ{mT*SBRVU|aI-=mWX#?(cDqnX zwmf8z`&B3Pq<-$#xYCUTHscflmW#&ZDFZ!eXJ_}E;Pk~@@Q{E&m_bCv%YvJ5W|Mq4 z>CSHFpmy!?URdiE`v zy!maB3AB55S6rPm0$dqcCnS2gMHy0uSbdUbhIFIo5TFLEuWGuOPPVN% zdQE5DHm&Jv2#XTLDxU~jz3Nzs(;!`JxSd1;5A;@*E=xU#yr%g1%B+55LI;-p0n*Hc zXv%z5_#R&XQmT`W0t@r>XCE`vSXN!5?jyun2-1XSns;2OG8Z&_IcF|7R{mzaGpN?) zpIX?1nf?n**Tm7Q;d~9jQ=lCgK+Wx`T?Nghqa=C(fylWUse z*9m^3Ny)%nXZL1zktkf10XCJH;BN}JG_D26p54voS(I3c!sH4&6xSYYVBpS-u)GvE zm2Uj?^5RxUVB{_UZ=E4}`nm0<)8`+L@Ey6t5p8u}MW<8p6El7RY{SO-mjyHeeDh?r zIK9-qqpF1sWd)Dh{Y9Kl2)k<3;ftYlag&is1E&L-X*4C;CqZ|LvR##ut9Dya?t}ve zI=Hm46dUxri+89YWr)f~fUU=T`?V2i2hK>B<>)7f}-l zwX}(x2G{c%k}+N~KD20q=tkj_C&4Q+OUCc0sc^uh3MHIrJzt1#5U0PfG}()tR`zFK zeVRs0ERA*p^daf2pSthp;GR)kZW64JEC1jkzbkm}sg4;v1by6-&Db!UwVfPJ6&QN5 zrEgVzpLZ2dmB=|r&&vfsrumh?DFUzJj2Sx+2CZWVA{@Y#qY2*wN`#T$*BO<9irh8} zw4D|x@(bN75ARtgP(Bz1nK|==F@nF^S1^R8h@=1zl48hx-gk+#5^A|ahV9WmLF7%4 z#(X6Y-xCDQA9P69SI>YTsb`4VkWWB4HM(a!NPBUe+#)@b!4?VB^BThz+=Yn~X+Rq3FIWqvPNtlv5S#APs!7IE^?+qM_s5(3^GvRsaMRW7+u? zGl7V;ACDENz(03TDN?(`O0NJrq~I`7MtGUmW=vK?td#)}&ZToMDxTvp{O0n)9uWBO z2LpvRBB%dC0{rgRTmw}4N2(@xsx5e(kIc>Xcjni`nhWHdB@f`s^z>uv1plH*PU8kp zrX!b;eyfPx6B>CnAT_0|z0rDTC|~3jKiF%LkTp_800*r_cbwNnGjg8rYybp? z?A>u&=mTOAkF8cq=sZs-Qw6LlUz(|cIBBZ~qG{EOkY!1*dlts0=J8R)G%!pWy8E9y zMs1?<8te4Tz!%w`8b2=aQyPdkgZDfFlyo#u78$xJh)6`rzVtAiP$9Xfd5-;W& zKIbru1*H7%a((G0U&7rXR)*PLfA;#-wt4|veXO5)|9mCHI;2Dq_+!>xaO48(n8sUS z)`;uP zPV@QCRDg7UTi=I#xf!lQOxMy7L$4X|=jqD;F-L%?t(O}foN@aX%Jl6(3XV;==}_cm zS3?SO8=VG;4AV8S`L8^%FM73|E$X(CftkBzs~WVTLlRNgZcLEtlx*}+%V?@_TnSV4$!6|C!@J=927Heym#T8hxd>G;W(5e2KuBVDNf-7s@}|RKYqY1l zuq}1KN@gWMB~K95&b^7z@P?u%8lYB1pXW2D5lQt}I1mA=3RU4fKn-UF6jrAXLKTF$ zqzVjw{y{ln&Q}%wm-MAoRv|cuJq9(qYgD(M`0Wp}DV#o`HUe?4`jpA@+qKU8w!_Tt zDnV%nA!n^l@8`W$Q0uz0{#M{h3}eLKK3V<*6rT%vBVsfM7!h$@7UH87-827i(zG0L zhQ0|yV4404N(*(;pEglp782(P^;LFbt{88paSd=?;iLXmas8Ek$j+ZBK9qZYo6fIgb^hO6MOztnm2(E~TMqh6IA{~Agl=Zc$Zp?@ zJZo#f^$hjsxHg;X2=qI7?H5jZ&4u?ffx&5;QL-n0h=Om0Hryr_ zNV|VR4}qpZ9h+p&^csy+FgsMm4xm3lm903Xip_UcWfkZ5mT zc+pGWB1dvw{((cG3q~VLhUQY8Ruw9iZtGc9uA7?TrA4kp{2@O9;^vRU3&6b;%5 z$xQ_>MO;1Dbl+VEVBFmfui0=VTAAPw?h~k2K&I3=$kxXYH~m`rPZNL7{x_N9^J{F) zo%EDddP^!k$+S%+cvEkfk_leI$=ku$t6=KNiAG|fsT$M0Ti7_IfZORb!Yr?7Lt6oc z4^1~r)0_w(4{i)=qu5OE*vrCC$&MC?6ijmY1;&c>J_k6nM?m!$|Y z!;hm58l57R(~}IJR@Z3iVW)S<$>`|MIe2%ZxiRDCYH0Y#4$+2TyzFEvp1T*>`e5_6 z=b1Gibx1B*LvSn#N;1Ba>hl2!>dES25C3_jJY7qIG4ngW2TDH-F4;kht5r_}pt-vY z=izc4mc5{}kk~_`1J&GV4=9t+64*x{d8X6ixtYuj=jS6N^}1aF++@FqMtI9{y(~|{ zCMk||#*KlCF;Oj22iW#Owf8X(I@O+;<XKi84$Wrqn|Q%ec*8 z(&J8FLnh=wi(4SEk6yOWfNCAiwtI4b;uPzwh3a8XVa!b%s!rD`B)mQ@3HaY?y|QMC zdwy{!JS9Om?(QmAku~BEF^U_7bZjTgDKw)%`o+1)s=*E<;6%>J{%K5mOm0!@Irk?; zD-RtfP!M=}7jK00pOamisYZ3 zNK7>FvXypANMV=;uL9!GhprHcf6aL+^Mh64+8H~Yde`M)g8!Ci&z+^N+)jv6SbCYocrWs=T z_JC6BX`_ec2+47YHLxPnJAPeennmtPXn=k=aL;vAGtHV&SB$uG6)T!%wr#M}Xahf& z#g|8?Z|-<70Q);|FYlgnj&_@n%L1oqVU9#inZH$Z1IHAf(d&4%DqC_m7at|>0=8TP zh^R;}UHEXHTe6{nsHP_!w9%}&1sv*G4+JW0iI)k$)rA*ye%KrRuuP!7r>mE{?&j#K zI{ry*!5+OVU&P5Z#V*6Ri^K_^k8I-Rk`tPGmz_S|ds{B}SEzzuXhyxp!YPX-R+$FS zMSG{!c!FSXtzd$eq6)g4(97K3oy`cKU#N`*@25bhY<$p4kZLt+j+#6DjSL4?AUQpu zaWCe8 zQ8U$d!a=7^R1N%?voZ2Dj}VJe2-uK|vP#0^%;=`m)=VZcl>cn;vX`*tNbd6TyFOml#dE2F6c8Zgn@gUo}#ZgbgXQH&TQiTN9oh`78q z&=@pzQnbY?IffiA=1CPjNMOdummhjqPTx;jAb?nRif{qM{;jCi0JB{49MN7Yl>q-B z-d>O5x1DSQxWyJIbYI&}K+9sAU4~WMwi9G0<0)NiXyqI*yd8W6Ocd80v3z5UYjHvYWa< zT;M)E6~iLLv;}aaZ<*+20&VSTsY~__7CnZxW*9h+XGfBc#&G5 z%P1~#kjjH) zuTQ;Y$d&@fz?(pwYFwne7rZS)q^YNw`ao#?z?kth=Elrpsvk>D%XAO&rcQAj-gfpq z-K=&MhCQr=y+aot^X&w2YU~rFC&vm#uHQEkd}DZ=HBFpe+U{(WtjY(=rX|7gD?mLi zAo&sjHPQBZ5Y3D{Fm>j)yru|fc3sur9t=YmoEKxL@eADY{z1plC^ zDOcaYdg)e^+SmD#D$_yVOlaHVMp*ig3yI^T*yUYQLith08h2vOw%{zXcx+8tI2a_d zjB_d1SzmH%S>#jQmTPC|F>bf02}x>=F#GKTpBmRmm-8Mn)j>D6WYRkqrh0#6w(w06 zYrL*+@O=81^~19FcRre=`D1dKV*iv4&&e!hUd$S$f%Z-0&Rts5N>@$(%`8r5xrl1} zp16gQMmAsq9+S%^f`gzszbI#4!=gdNihiTdIh8^|ufBiiE$f508~ zRXgUfP@b^XZ4%s6XQ*0yYs7WjM8;2TS9M>nw^A!v6QpUU42-;emK++aU@p+XdiI8@ zqdy})?W6ZxGvInIJ@%>6Cho!?rq5AV26{Y!^z*hwn!QUBM#s~A| zxDA~q$d~zTD_rH0FB4dZ7DDnU8#?!NS+s;QP6NI(fPq3g;M8Aq6Z%SQ&x)9+_D>Gss5kAtA^AUp9O6n9Ay1!EW^K}!Uaw>vtgs;GCCtnVnOHwB3C?6 zi@d}wjx`*Y^v_jnlR8{O?KkKMI>Hotzd^_egv3{4Td;)LhS`;g7uiw=8T(cF3j^#F zJJC$DCIbWwK?bOP@#QL=3|-ZNv%83!Mmyho!KJNlg^?4U#*6}_yd|eBEn`h_JZ4>7 zCx-2((0}PF0*LZ|z6Tu(noiJ9*_^4f#mP2^yORCUIIoSwy~5l34Kl!#-g%`0p)e1Z z$@LxP(iQX}69ijhgM!tdc(|&*Q2C_jp@-LKeXo4XHH5YeHr%>5lB(0#}?iGL;Jr6MK zj7(Q(=T2qnEL%mUrxDPIk2LWFn9RrsC$S(}S>jRUw}M9%>;M?8M3-Q z^y)3j+~XiqrrDRUy#^g1G8Y}kr<4K-b{SL0!wZ&n$y7M|aUqnQ|9%oE?;8E_(?RPM zdeXcJz_JaOdYqt9^4yspmW#i>TrhS?3_AjM$$r`r0L`DE6flIy!AId-IKkIYSfv5` z9LYfC^2owWi=f7%r_WxlnjiwTac=Cft;l;fv~`L*xKr$)GdCcRnr&4ka7X?Yc*E8R zLu`c#ITrcEN)ln7Yz!8MQ2mbKv3kjoZ$m0idw;B8W3oJe%eDP={+c<>0PgK+@#H=- zn1(+oVpsGGZ`*{Q{rqTR5>fdP-+4+)6)X!=fC@1gj{;ZD%`TpX z7IP4MePJ+UVb#*0375NXCjb%Uxp0fSuuJHEXD7(hC_ZTzpbE5yqj z$zg9w>2XPm!W`X|)26vbsnlxjh$8QInl}mHt)>UAJRr|?y>Z<${@p<)ragchf}uch zT1NXhpmRQVX&HXyO&?R_6%v3gExWxyME!Cu$^{56MYY}}G#6|o9=2C|oCG)Q0+Trf z!=AeTbL|i97)N)L@t0j7dDvzplQi`;&jp`RU{d9*3<#7@4DjOr`f(pUCb)ekajYDL@Y3iC&6%P`oagVtnXv*j;MFd zfHakaWqL$epx~`61QR3BIUJ(#;)u8$iS0>Xfz6YkZ!4mIZ#!tzykY}JUbE)V2X=Ym zjP~Dz1mAUT+cMD0Ph2p{ugM5YSp0kQTMOtS-OMcwD86d1=C*@4Qq$xcxO#-Fu=Q>> z5A-Jd>nd88fB_kk#jO^IP1qyA-tq%+hw$=QGZp%|Ew^o=(hx!kO?!v`kq?oVeFMs_ zVHFtWUe;af2TgCr0!hnxPyjmND*K)R{@5(hLe1@T@ywH{!L+> z*$?sGxEYadE-!J=aXo0vw`0Noj2oIeoc+(-BYs|k_XV#HKMEdhY$m!hVrUpObFKh*=(hwioCJlmbY8qGfe_zs+N)YNw1133=fJ(gSCxHzuR*K7V(njoM%)8bnHPMN*z3lJ)~Aug2Z+5}G=<^5Re!Y`i28fD+o1~W zak{{NoUK-TL5VTHAKdEFLmnjDqI#qtj@snAfu88d+n zFmaGb0Z?cRk$VN58B_yAk`egB03KX>zJxTdQ@Gab+{XGqDaDNtSzL)<7lt&Bp$G6$ zn_JBCrd=!oxLDApuz5XoIf817CJn%|*PS~Z3IqPlp7pA9Q`a~21*}!RNE+AN4AkWA zS+$YH;`9Nh8ZS|I2~2tRabDpW|o*pkRaJonHjb>isX8P$?KW z?kSN$v9OhkicwB@M+R zLXguSVKoP8{f8p>O>VhoEa;q{XChlt@IRm{Tz)=k`aKOw!kDU-wPxs)K>$Qn6*zbI z#-RDl2%uYkr#vliPZZ{i7y26Z(*vz`L#>mLn8#tb0l{WN2?-Cx5o6vGdzDew|B_s3 zz29&O-PujWV%TpNCdDj3c3R(%QeX9vU^pt4!*pcKK8#;&>vh-v15OkDD;0iU$~)8dpyzx zksof%(5>u9v#nX15q7_q>piIGalGA1r&zfR*{I6du0TNml&MB7^Vq$!t*U}!InWO< zlz(ZhHy6DIE;Ln=4XL!13I!12pSq&?wg7{$Qw8g`Mkoh%(DW)G0&|~@LCVgN1Xr8T zvTvI3o|4wbP|}0bhJlE=T^NCJjxeu(1<+k$`G#$)I|{8bqwzPPFY%4QCf@f&fcwHT z)*-d~x}~3Sn|R)F#?6-e%E0L$y_D2$OPc(0T%q%}UFn`U2~iCp-p<(ETi2ewEfTX6 z&{=z(6Pa<+f$Z7nm^|0If$W+%=~HWRqC$rBC?kHKUa|E-qAFPo@NaZhDivkHAZgf3+;U)@$UZF&-cLRET2pjXgE?L%Ev`CVHw-c3|o zt9s5oNL7vQ2}M{uZ$`pj($0aBg?)>_G`5eo_?ZQQ7@GG4N*kd$@N)5bt2KX%0?#!A zH`2veW$4^>WxkEz&RW6W^7Rj`%Gh`+8=W}O0Dg&=fAHQgO^27nMA z2Jat>i*!;64~BJFuP6PF&oeMtIJH zHm@IZ*_#+-DNr{ovmZFAoDG53*GHEk>xV1QvTo`XG?`?e?)z{jN5{|?Ijv4}(mJT7 ze_Zn8&2@5vujs~+Sq!2wdpQOow&rBo0Gz7g!tup^@?$OO8#>44^(Wz?SDl+Y3}<*- zEPdWi+XMy@dZid{LJc^|bdADT@67Uque8Z+DDn=G)}_^9SF`a^-Pw|XTzrlnfVTc` zESI3!u@pgdHe#)tsf?ZIzNXklQ_mK$8c@5ReOc!bkv`)<69!6IYNxD4TOuquM?g%O zb3LR9){|%h$N%wSn%zq}42`Yq@Ii5{w5f=s5}%}gkTCO4F9b48#^nsSH;~Hsm5C4- z&gIT$?4MX#qwf@q4PF*jdMHD70#Hx$4;ubJhd(SiLxJ+`XI!B@&dcXqIFK)HxoG0hvVs9PtmC&1gHSLA#-o z{6U-i3ejeQi8B)XT;D&51iS`~7pd$F7%r!6(v?}hLLdQhN8SSgEd$!)hmKx2prn&n zuro+``dU3tTUnA=@Dlw9GEgYG$X68fD#6!nQJ%XbUdzi>Bie#YHVh%g*GzHhamFF+ zz*+61%96-k0;Ur^)el=*7i&+HZNr8@{8WejK>8zS%nC@K-UGV)@-hJaBys*GQWm<1 z0C_Y-ndf6e**W?DJL@Xbs1v}}`5m&gf&HB={-g|c@<6MDx!`K~ilXs~c@R8IfbFcH zPQ~cxu|rU1kly)KL1}OAIfi_6@z~D|e84s2R%|pT9p-U#6#6oGHoy;`X`|T_da8Ry z0C_b_{eUne=CKcvZxq7snzzduP+aE zcZucut6j4)m|~U8?#FB6#TgW4GUr*5B<@ot3faDoNc?Mj=ju9*F z8$>K4j$Et60~E9V(0XOT5e`xwy2$MK-m8cPV>xyC#q>GyyY^8?oe+0{!3bg3T z{Lu?590iYkS!T(~f*5RR7dIRT!7TFIF3dH#KRve-Et%2oKJ~mgE-?ps;%rm`rt)D$ zU^!Fqi3+IlxRfH$S7=ZbR8z}FS$7vMp}Eylx73sZlz=X5_V<5MI|S=b z@H%1K;$tXeH(y_{N`_AAhUN}n1oFb)=%I6~=k}duoR8h)h;}vws753vQ$qrk1*c8% z)buS9=*v|d6t@ZG>O=A&V6hO79A!EPiG1h2q=g^b844$H@95az)gie!)cN9?V2}6OIyw6I4=V~vHOUU=| zlelpS-~_#a>?H3zzMI=$-moE*_?mn5%EDlE1^Y?^;luxY>T5-@~Y304I{bJtMQB>{*K z)3$3+s}XdiI(Dr-bPRiLCQy3%n-0gj>jMKo4bw-Rha;T%Z_pufvL8uEAJUia(3kNW zOtUMx@y-^rlv0SHDvmXCzuk;gN|e!zWLk z74eLPJLt5oxcj)X{?hV3U7wo0n7jz!)|9gH9ud8|;k}rY?FX2RY(rp5y*Vc5qo?FF z^|xYTo1VzAn6+0|^ag;f;}Rb$kaq#_x_#bRR9a;VcECc+--eN|;656WvBsYQ?XSz! zi`(InX3UGv$$wr07qlF=D0C|=YdfSXSa0y_->Lr0ns8DLJYPcP4DTTJYF@4~#(ILZ zX^;ou;C}Umfr-Qo8AIiSU>A{8&PL=t9A#YNF$`SveV$c-SNC7*Rs)YT+o>q6^xmh$ zD-#(0gT4y^ZmCA;R7W9`1x_@3L3?JrVNUxsKvan1<-BJz=;GioAw>WH)_ntt9LTXk)E!R)9(qN57^gT#cH~S9`e0Z|P?HcD>w4 zjX%-;>iKeWFHopFs7~@ODW1$SOLOEBW=)GXtOr8K5x@uK*^t&QUB(eqIPcg@g0+fL z>v2Lc7n!on8j(dv@PdFs&^klNfD6)Wc0*padY;1tZ9LBc7Rpq{_=)F`y~cy4u$~q^Ss#ttqh{Pbi(+Yh_auhk(is= zQtn2zT~LLu6FK7wN@CzNi6fY*YI2#g<{qN6R-~KT8HMczIl3vIc4*QN^eoU~VF3D= z${xF+Wya?EAvDNPCq4wFEZB2HIkHo(THVl*VW}Vo1i@LZ*-~+5zX#S(v&eK7*%Fj|b%x5nm>-AmqJlb zA%s#{MzSO!vQ)~H6sZtJvivUJ^E;>W{8gRjbi1zWv%KH0H`uh8E!w|1e?Tm{V^6d{ z>K_m13^q?sX(u436KJkPSbZ2{nvN+&si2PpnkYzum)l+iZrduxMr-!M#ba`2Q~q~c z)SAqFPkBSp!`ohZq}q#)!nzAoc3R7obBD$F%qKsaW3(3zdF=~$h!14|5kc?ELnk@b%f3iz?cU4EUd0LxQ>hDf$Q-spdp%XbPt&cw6ZC-r&>cy|h z^WJ}*571hI-+3Sl`WYUN2wVuIn^pkBIGLr9w|IK(ooEO77LH_^D4|(6x6iI~`!Fg} z*#pA@4Yy3@YY{)uQ^H!0;`eq##m}GH=?V%fyU!+abP#=)6=xWbU zjh?d3jq-NXdCK!$z1HU!Pwx>U7QOeT2|?dXCWGywAoJ;jCXtP?63%@UTdO4fJvBih zJ{K}+cb)*;uz*(Ij<9KJf&L#nBfxZ$$S|1< zaT7L6pcvNU0x;h6XCR(AcR9N?FQ;`UqnFtqQ5K}HMUsvg8T@jNVSs~52$?m( z6BtA#4!-UMp45kO8AFs+sV|=Ir;hmcbQIQKpf26aIu4W1 zjXQL>La+n!+6(tp@DD&*5iM9cN(A;wdR20m+GoM$=@n!{S0UPKKkb`0X+2^VXRSEqvTv6y}@-W^zgZbU zDq=MQnJ2TY;hNo=E3SWnaVL*%p_gf%@EdNH9Io={VZz*jvQN1I??vZwDr;4o(I<1? z{*JdK^{e-y4kw*`3N{&zRq6W035}P0fnBgzRfiscOGAF85$O%YQTfg79b}hq4c2e< zNxzBql1aD9?A9CX#Z6?d1~6V?dmoebSNlDLcNxR4rAb&j)!3#)%b#g z37C3pp*tcy;JXIGWuiK}_0w$NGN7mDi;Ib4eoEl+J{h|qDj|FhAB~l*miX8_l zTkGkp3)7=;$G#u}C6>sx3tA3;ULSb;0aeG~jKqqtrmp!!f5_;N>+ ztvvMCbRK8UxoLg6$kt(boYA0`^2SP8!iue$SlIayv4giC)R|AH2aBDN=bmeC24TuO zM20Oi{wXyHCL&cnvLV=HzB|E94)VP=hvYh@Zi`*sqgVA6$7BhSwvbv*KK9D=kP`jM zGe@aqsO_tHp|b2hYTEYE&Zee=-Jh9l{kIq7k20z{-d<8^iN(;YKd%auQ;q-UO6Te2 zEvHIc}s42>Kq~9fP>Jc`fmg-HH7;RuDjTWmKuy>O*n80FIc|)u4RdY>&7~Edl1T+ zQ^ko7;-e&Np3z**tw4X5#|LEU(5t~bH^R$R4%fjLa)g?y&dneX(V>TAREn@>+Rr?_ zu1O4>-qbBV1w_{#=!TLU>K7jZW{DCcgP9d!S5x3`jTu2EAofN9&1@etgw0i74ny1m z`fQK~Bv?nN)MuO6@O2;LpiSC_89J-+Uu3iVjyp{%BlGKVl-m*iT!1r;BJ0^tIzD`; zy;wI+F66+@+^%5d|3t&qM4F;XZi`WveW*(e(wl{zC*s_ERb_tE z3A$Zmb0%;?o-I=w9ycGAW&NIVSt*TOAu!L6p8=tEwz06!3L%d^Q6!Jf!+x4Kb|%LbFB;k3^`0G+_^~kJ z+Y?*2bWxQU&hR6cg^{^H*2@+iw&S?-kKLb=Vx9!)f%86zgT5?3NdgUEoV$HR@gkc5 zqmU4;gstT)w-b7`o2VqV@LeBp`zdI21smLw8t)2D*{_I>a2kjo6CARIH(}Q4=k!3P z$XRJJ3h@(r2`bgZrMn$(1ywW>T|E>~Ar{8zeKsIM%5-MXw#P3H#}sC7xoJ964u1=% z=kjNjuG7f+^;-y`yJ7Rnscl_x|5?>VKvaHR=JAa??NpV)hv(8oZL@C3SH3YG&2Cq2 zyMdRLY14b~O9?ClNw%#Ce0KFjlu0uRZ8t!b;hRl%R5yyWq#SqZqjs3;%0$O#^=ofB;{8njyZu8kAVRL(T7~jgQD$wK^LwU$L!Mf z>S3^ho$v%coOk#tmAzdiSb11QxvZtFlFG+poDkZ#y}#hiM|CU>`n!V}$`R1*fuTd- zP!U^GM`{~`X*G#snkOlOl0DEh%`vq{wFxlK=x*yTp-^Srn2oXJHS>aKw89NF66;OQ z#MUlwPa@iX+mk4sp7@N!N5M38AYr8hCIgDf_u>7O=(z-OE{x8c+;{7!>}mI>p4ApZ z<}(LdqH|4bgxDb)@V-g!zkD|#aC%B-=X+6SUct`ba&xZ!PpD2B3qsM&9I|LQkKGd` z;wLh}*aPbU|4ba?F@ArDFt4d4m^V>?G;~+1q{b?@8M9GSFZpTFzVf4Eb~Y@vr=#Vv zLcW^B4c_hem9yg+nX-AQPpB5CHO_N>34O=%Xk zX)%{d`YUjj^4$}sA)4_ZoYjmX83pqg*M|@&^vFNZ<9I1(Ur6@fO-4V+kifGd%BfqFh*&&T&fhCJ_M2bsG2<}*jU zc-RfoqOxbNaF3sGG!?WoFiP|C)kvPAWKxB@RV9QC?178+Lf?|2_5%Mhsoz)SYOHBZ zqKLIw+2Qn4M?}tzr#$OqxDZ-oO=l=Li8{eGP5pSTH_q? z`=)8c?;q%ASC0$-{>AYr7+Y?rlWUXMvPnow8fm8bE@8$@@ecpSnO~9>{CPr89ON*1 zA{jSuYiyW&Lo1re(|=zH%v}Wt`3!Jy+DAVDaxt`2X6e7LQaH+_u@}Kx5ZPc@nn34F z8QjGlh}Ia&8>0|;&`VFB!#)UF&}2>d=)4S{9;vl>2%9_!e_2po*tC-Ym$YX%-a|&{-0OHJ9Q`(? zshYqH>?;q|hrLz}E5%ujf(B?W7_!vXSR4nF(4m$zb%of!R4d89wzrFxm!NsZvR=oB zz&I?{y}_39?5R%Lg)38G?C%)^SK9Y(Jt71$yQbJ)T7AL`0`0D39P_NEOx#!6Dev*< z12f`UGIdlq>Hk|*C1Zn#qsoWTg9=1EWkr5xd zv#uh|Pfg)pBuF0pr;_^2h7TggqynOy69lx{JzDsa;k>qUEwh|zIUmW4;GYv|=AS#n z5?&N^>Sasl9i~FD;AXKR*y{Y>=lS8By8ex|r^XJ9RvLi013yc$))gr_-%5<>nCVNo z9;&ErY)G5{6+@e)QNVtZZ>C3!30uQViA+q%A-1cUl76@Z4E0xuAI4pfbpbnMoW&+A zt#kb`A&obcng0UxA=Jb8(Q9yw6a$~5pANcfx7In|wKJr$O(qexvgT<$VLNsWh;6@v z&rc#4q8+%)m4F%8C^fyTg6Q1dqb?j@NrWiT7z|bPiaabM?_acw3+;XfMb5E)edNnVZZKip+ga&mgFK-=jKS5U~ zMs5~eePkY%^Puf+%ddAHEDQg3{2f^d&oSKcM zEG^7shBkhkm2H{NBf4QT%+sC^(v_4>nK-g8sOg|WFSuwD?W!e~aLc3`byZqtryr&Q zLp`LUwiciDD$lW$wE@R=O1L5J0JuER$b$!Y{wN#6XWbj-4DHfq;E0;gP#SQtZ=;@- z5(+#*K;V-!4rcOC!N=a9#E=E`B;11v6=L{6Aumh{Ik|mu1h?4(UqOEYbGP?G&hAA? zNT`AAB1fc7zqZv|^E3zQJC$!p6wH68g+-1}0ighRAz|_3jcEJn0xQXxAG98>2V2 zb><1)NL3N@{N0Wrr>d;`{Br?#X5q-`p_2l`x{40#-Iy2-8>J^JXO~|-Xk&-tiTFs% zY>$nL0DJ*eHNt3TnU4%4UJUxk- zpELg~vsE5Dw?8*(WcB(rxdTQD<|ezO8p`&(rbwd4IL$EhNC9;CP=8um0d}=eG_ny- zo#o)8W9XOFgl3Aq5#UF;fvx>k(vfIF9@f4Vy64@Fa3$pEaXGMh`ZwZWZtz^TfC(?ZiCv$3#}c#SJP)fZUuza_5z~27$gv}pEiehdSZnjie}BGh zq<7q3@5Rxc?>W#q{C($t82@A;=#V?+LbC?BAS_F|)bF3D$0DF5p}Vb0E3jdRp72m! zGt4FsCx&jVQ@?LAAOC9KVecRwWihoUn*1h)jDSqllC`fAD!qe z0`K=>LB?TRXsERJvbcjdaW&4}U-&b7p=0SW)(*qT_Kf{|kS3*VpG+Tf92Rv&@z5K} zvW;}dpl5s4mZ2Gu#w)lKuFLNjr99i0D7J!dz_nqUl!aIO<37}*^5 z`(^$2N$(o^erWq9gz-?0_W7}c?i|(Ni&YhN)U=Yv4Qc)@|LQ#FC_}oF{Ws&Eds1VO zBaV*nh13Lo9p_^o*G-ZLC8>!Md0jncT@;mk5a-K^Gyo$gxwNRcON|KhPv#5 zUR=sAr9#wo*tJXKkEAyjQ*H*}v5s`m&4mvI4p-U2bds5pE3fhwB`XH*>@(?RspTj; zeR-TignGSI%+zlN?hI`_j&uMyD*;W$`DTR7UG^EOh6b2_9*T=7b6Slh!Iw#R2BJC4 z6b8N$p`#6KgZHK1Vty5-w*|zvo=oMugJGO}@5gbwu$`T`v;{?AGl<>$7i*Ytw$%`L ztV}dLFB#zuslu``)oX|G>7AqEM~KQougq@c(Ir`Htz%vAd89HChJ132ankOLkhOEU z31`PXdm3IfP)?l^&eKWTMPgS0JF|{6{a6;T$bw8Tww`CL4ntKVA5tL|Wl|G<+xch8 zl9Uu&t9kT5zHsw^n=i5;m0;SIYo**@?gVOV)vpeeulG1sIoQk874y#>aIE_xE3WrEZkwz;#BQ1cTbpHM4ps^tB=qLyVYxy6`ws}DnUf7*KVNNFhE-K5 zzC7>f-k$AF*3xzYnE(`Z;c3@J6I?f+X!~M5ruIG|%>X<10Ko90z#Sl&dwh5dG-YGn z&yf^V&?mF`(3(q8A3sldHe7Abh;L2(dRH8tsWJS0F4!BrW<8Bp(cioXY(*CSiZMjO z2Odc^JzsqRj3gEy*)V_$N`{K)Fmh07iw#xBdz=BgRfQuwT%T^MAe0b0c^a1Hv!IEk zRpYd_^E6M#Gcl+aSqeKYh~++eCi_w439H*mt*#&yzOJ>GtycBv0t&ChHq%s|APRqEezem|92E*fTQR+jf444f>3iIQ;R zTP_>W-{lW`*ZP8N<<1-SbR6X@_Ke}euH56{E+FCNvITjx{oTBzDG zicl`gNxQS&s;9Re%Fo;l?YZbA)0RY1U(e&zXWm%9tBN}WMul=c!gD>8;RXWh4`WJ1 zs~FPY5N3L@kb_|(LY*sYt9wS8>C6eQVc38`JBAjfkkd*Y<3_Ynh`MeqXLZWN4bMtn zmXt#O-bA>VaR=uB7xXgmiXn`f^3gHCpo%Q^Fs_}1sE`M>;;=h1?ASxwawQSei;XnA z(n{X@>9!yk9|4oIz1@?cI}WiMQ}o5cJ8q5)KfKm836rWWzd@SbzY-D_+lCSRl0cfG z;fBI{%?E7Gwh@>meBllpF#5s;T&~-}ct(3(jsrsRw7>D*?3v8!K~3Ox!D+90_>;!$ z!E;z4cw3qYw8Z|p)$LZEsm%XY*3?WXhNJv6W&Eq>`_?=bN3MYh@!uDyE0W1mM%prq zOVXXeeP&|a@KU2G(XWXLhfh^+};~z|yHqNwswz2&1Yx2WtJ77fC{^@;QW49Wg>EQ=PT{lND?>ul6rP}80 z0Kmx*j5ifL!S&{eDz~|%1NZ6_bpL$G?Y&#gDm!J_;g7ESAR#RQ!_@r-uI~efSju)} z$d98=Az+{qyV{=R$=ANPYGiJbjMc%@44)Cw-ep9|?G^JR{NWwk_6&OCMb}I@u?ANt zEN(U#zJzm{L?`U!+e)|hq_$PC)Z(FZ*+bNK*V-SCb}4uU)u^z70GB^tn<|r9znXKr zN1c`yA8LXUXmE$$iX9l)c3-Kz8&p=%8gTT`M0PuW`@t79GY@^}3Rx-M3H9c79$2P7 zq>aOMq={50w2gMWQ&qy>1N5nJwsCn=KJ<{hw+b57o~6ZYYXKcfGSyMK$uYlb;R<7^ zR{o1*nwR@09UNn7$kr-YY%hl%8C-YXHDnjKk0iB>=?sRP=;E_jQE`{6$6F@6RF;+Q z$bUXCW5yK+Q`&lOVaE3zZ<(^|ZnG_#Mzz0jkoA+ZH`x%*Um> z@bG-W^%9szqoB*SAw}}_QukDPtMAxReK)vF@|iW0r-!8>{i~wsl1n;Ot#&z0eazS?RRoK z6>3goNR2O(9=pl1my4Yto=Y6m4&yv+R`w?G8E92MUBw8M<@WEJ_OwuUluDZ-KMT(I zjX?~a7i16D<7hsVs;H3^S*ZG6kT1&QXK*OT;?;+ga*zM07j$zINz>tXQzHv7{P>z- z-`c>27awg+e+J73$ygt87hA_F8JW(f`=yem2D1j=#kRt@Nx}Q=b074G>M>iS5dn$3 zh>CZUGH*7M*1uINNvxlvJ!tcA#=P97`;WtrR90F5jMSQTeOJYJdxAv}qZ43ruK15La*m7B6?PRs&QOA{oQ+)<2`0|;(rmPf8dY>FH+r-0f zLxu+RY@_-@lLBv=+~1s=LEmV#%hNo)-$=5z=ELE($u`3dQ*j63x^3ctq3okehF9Ro zNK+dbeJ>+^gkZ>_jGn~^;yu2FeEJG;)~HG~~{%MR_WqGDu$UK)b|2$VZokmn6xIEVvk&a<3Pwe& zkt)-fU6mLbTO3{+lI~uo#1>@pFT5xlwB8=8`tq@>xXm=$akK=gktbQj2V3)w*9qzc zL<=x{_%5%v2#`npCvcGzN9DwB8`*QSVv?^;CAMB~|H-X7_rX|onSI*z@!HF2*V)P4 z_ade>BG`QXK{VYb77F}0d6-(QM_9O=FGGEK5p&80oo6vZn$=+70&pC z85ha0im@9;x~)6}-DGBmaoyrLN)a0L zeo2I?&BI_~`)Bmu&f8{4vb-H!ad&2o36PQnx5aC32jxahD-pa2tu6@jHRLcu)nmOA4{8RoDfAOVHB;F$2HN79d`r0uO^>e)KY5 zd~9H+4bZ|OO~{_Qyl%U1JW5j9gAZ)>W?{7QC908Gf0`+EP}HcVW#TbQCa@RDOYjC_ zOSL~!X!6q?3kM~#?0OHUJ(C78qN|BbQI_Onnd__1?j%j+^J`NkO?PR|%8YRyrO4Eo zo(+DHpE=aQ-v}}M80JNl<-4cK(#Ia83hMn3e`ua0@Of|_N6SsHe>+iGS(pQ7W1VDi zO8NA%x`mnYi(cfY)eB6p%kEdbLM=I0l^R98jh~C+Ag1xr=6`ONau6NG+Rv`L+WG>D z(Ru)z(Q|s;Rgn=lf&0mgCB2@S6PSLPQc>Ve!VZn{;cCZ>Yl2xm+W44UME-c-DY|Hh zg92Leob`mpY>6$e7?E}s5(%WDr_w0-#!rb%GPJcYgSnw>Md13b+|~{rBzzKfWgSU+ z==?b;RG0AB8Ju?pTw~GU&BL4ih=kiPr3-C}0-E*5wr#PkkE$4Q_`co{F`11gMQW-SeCct@7*jR2- z)ckJ+w62gYEb<*gZWMVAbW~T{Ir-uRe$@s(GN|ebzCe}F3UQIH`)MYYa0Z*6B$^*m zCYOetV60~h9htFFCmFA%z;i?Nk@ch`aNHFvG%d>;Wm~Sef?Uq;`17Q#y`cjx4oZTwIZ(W$Z+9dh}L9n>ROi`88f~Os&-+RCyQ9H zL+d+4GhB8`qgjPgABX&EHSu!7)rzK3Q+2%tCn-bx3*IDR7@Oa2VI&+W(p1BMVK&rp6;avV*X6NEIQAu`Ha?l#w%b zwAdXwWE#}ssmtBzcz?&7;aAfVI%PB=z}ZU#49n~M&HQk=FZQ*1EDyQ$Hx(Yi|7r%uZg~W+ z%O;k1ZSc0ZW0xYxKo=&yb|X9<+`{0sB-zkc=rTX2Rb}B85ii>lnadWI zxTFmjqlf`J7cGfdx}K^lidyiB!31Ff7Z+oQkOpX?h&|XHd*I9einJ*>;mJlWySfns z7~?Ur>8-`B80PK(jMg&evDgjxAS|pFokCwg_e<9<^HhA^$caAdV9K@eGUQl9OJDB%R*dXSKVa&VtJeOM-OfGoa z;OHb4{-82LGyt+lgqv{8!9*vpK;vb|^A{op@dwYS;ZByp-I`6JSh2OP3W&E-j$l6^ z3%B3IWYKZC5OZUaY>2^_IoFVBrD#5}z1X?{tPkdAHWbp+URpU^52}-*zO*`!X8vdp zh5=Y}!6e@znxfCR2I&7hIIne{6CFl$mv;pc1P|}o6O$@kc>G4itwF^bsgiRqSzn*H zqm!Juep3F`FL3WTT`t_X_u3f)38!zTO>1PA3UXT&oAs*tTcjs>*=kzXR-bnaJX(Du zY-~LpqaWnT%P819j5J?lE)NV;Z5D6{Q{ks6?}nX@5O$~|8ky~EI183G>c=DN*-ep! z&wPo@QesuG8sfi+M^?*NVOflze>X*p=e2(tC|H=JpIjEV7l(Eue$xUs!X-Plp^R!t zsMm>G6cXtJ=eVCQjDNQLuLR;zM~8(#ia=~NLhbh8DhnkV37~s6w_qa*)2q55n{8lJ zwMktZOB-MYcF-=dgj>)0i%dunp@cN0{hO`2DP$%691@2(I2Bgfm5M4Q{OA#1_BgGQ zq=@I`&ECTBHe;>G8;mt|P(!8Q&PGglonmqPeU5>0Px)&|bYQ8?mZ=j-T(>IjDFZI* zLo#Qvhven{X1a{?5Z!z=asInQGtAV{W4o8@h1h9{6|%-dJCJPP--kr6hbxv$h$+Z{# zzaD$1rEpj2fRPM3dFtl~qEvEWmg6ZDg}oB`JCeA1p>qHFdf-cF0lB*PVkJcV6)anS z4`jA_{`+SzX1u3?;0@J{gQFt+K;0olPXx?(R- zPExh3KbVE)ttMT9h5p$(kw6-dKF^)j%mW&K;P!$mbb^e?a5%Au9Q$}0o^lho;S zcoVC!tEP8x_ptPb0-nd(oLFhDHiSKwtK@OowdAz^v((v88&!IGz?Z8o@gJTX)?Ub< z=y*GZ$aREo4@*-{5O=;XD`RD0@K~`GWJ{&Vz^~P>MxHO+zU@?Xo|kE6#=K{Y@)$_{ zh~*yP=}Q!2XUfWjD?~stnGB|OMdsxl32R^nPmmKA^go`|T}Gb6@zKFYONG6ePj&a# zWh*4OyMjY%(=Ox!$LP90X|1gnj{&;Df$U{LzMGJYqYlCP)3?O~|79tFbF3lP@Yuf&Ai9k@JxIVNkz$ zA(InoZM*(`j1vS(sL;c#%?s|&1`tL8VqH_}ArBm6P|+ZtlUp#RE_OUp^yGae*m*q+ zhN7+50T-}v3`-M2H3Rq*J?RFcg{IZuR8+YQ-f-IbnGL1AlqNHHXObBAM4nTlQbot1^6pE0OYF6wUgndi z&UgK$zIQDirxU*%o#E|f8e|M%sKN%b>g0J(`RSC@XBRbO3$ne~ng1|Mx?|p|fpE0w zFoBV6fIh?eXj zM)#?)*=VR1=0DrdJ^8Q2xiR77{M|D@N0y(AZdU5Ef4HP;d~QU&IqODwdgNhy7Zuc4 z2o!q=Y&q?!zRN?^WLenbXMXl~UMN?5WZHlCE`R%6@+6m*|3vH5gTkp^dac+^7@B}b6Hw<*=g zM#gXmJ8pK_{xv-70-9^BH)06PlcpX?P*2qB{T?NQxj6gMqZ%wksfdvF>NdFYtZu9C z7&o2K6Yg94*Yp}Oa0UxJ$aqbgWYo_)2)*rg&_f6-f>Q`2OcGm5_VP{OiidGAxvgxD z5p4I$YYgM=9f7OCEtt?Kt-R805EI!n%#O}Sa-jd(L>Sa$CpMC}iVNxUlkVoT z>5NX<=|yk>FYGCCA+-{Thw5ZAV~R4L5>W0kG3)(hdpWLs9(?l6@~x@y&~;3HIaM~H zl`90Iw~o`V9%s?a#ptBwm~HhX&3I6G?cY#^?si?}xtcKg+)(NDYyi+gB#!-{A!c-mW4Z4wPi#5=6&R0nj_CX|iB$j}>H(bY zVHSpLjV}BA3+kCHC8UY)p^aP{F@R=Mdh`KXw(U-aR+J+`gd2$>uK2@8_RdI`#fT$LSJr>t9_H zsv`FT`IT33=Or{jG0|$#)zE)S4lZjkVb>H1&g&^(2Yk1}_lh$H7@ML?+FJIT@pxL@ zh7eK(Rb;jHrDC^ny1$tRvf*{fWA9{1o*b$Zu}f^0vwKLy#rY`F%?i!zx~`7(8vm8a|ZZD(cR(eZL2 z=}M!T+1UMMW!DZM&Do!Hdf-j@AVQXfvI-|g)~THl<+guh;197zD5Ued0Dp?$i?Vbz z-Q`4#&Yikuv9)4>X3pYT>9rMYK}PBGwWS>vukJoyJISNE;rRMQ!4uDG1LY%%$f|Kc zGFyeS_l2cPBhRsefX1R;l;;?;&m01@yB$ulWlx~x+l#>g4sc!B+{CyrEccZ*GA@5W9^cJwdWca9t}6nlffhqE zTX(bQX(5-u$|Z>4THzm?#Gra)Qi|R|GLFX3;F&vTi z0rSD9hga3%MJW(48k;kVgGm>{kO9Nvpadk(JK|e)-h>CIGwlmS=x(^oKY2O<3NZBhc<|-NiOJ zf#!jaqL)5|o6pUs!3kj6U(qAVZLn(e2f3*wjP;eKqb@1)Urb#!iQa(DeEjFDUI-fTnqh(BNJGat(}72(0rrW zqZxM+q>aSl8R1Php}TCuU#SSOnh1Bs3Jok2HQ_1-JWtA5Ax|xizqC@GPEyk`;2OOw zn=2oJlZcZKu`;X$!o+rtt37+Q+yBuBg2q=d)O9O=cq|$t%FoPMKAsRXql~B@g`eP^ z>o?1b=jk`L+bIciSRU@rYd$xly0=4(ry}ut#|xD)&=jy2Bj#xeSUvvL+M57 zchXTd=D;KiZB4OI^^Uz|>0@>ukJgoN|0Q`g#$t)`-Abk4jjId27@gjl&nrd4Zj0(i z(mzN@q7H!y>u(ZE=H6RA`C8N!{tSGGuy6arvcfBxu><)0+rtm$_qe=`oc(j&XhZ@k zj)Q_Xrz^)%)#~3v$oqL2X*RRUtsV* z9f}FOzp9Ww%Q=T;6oK~j77;k7FvK(diku8%a)duQvsU<%bwg;Ns!O0dqn1S8Vkvb_|wBg(U(tP30FlcAgjOp(6# z3|-Vqz5*^JobII&?agA_IcxGfRj^6RO`ND z-uJ>LD;eKB(w=DfIqnIc%>1T^rS}%$Mw~GeLX9#yDZe(9d_n$crQ7!VV?L?4sQxJZ z9{fHBFP(i51tMm@w-K4CH@$yI7|{OBZytZO`S1Aok8wXF%7331{iQ9;SP~uFd_nvI zl+&0Q>nEv^^#tFv5+_!=*FG^+7hh@a!9lZ+y0vOuT2qa{+#UPhPXtYG1l_^v*l*>F zDZzi|ud_v1xXz2gGv4c>)lfIP>fXjNxd3i0eZ3Cz6Gnf(1g#t5AdnBZ?rt}hL?6YM zVHn|hZ}6ALfUxjsU_i*i!Z^nDOA{5q1rK?H6g_2;z+$aVMmRfdl9PA`R%icNgurP+ zLbz(oKsi77XJ^A_Ti|vG$JirF^0%2_h$T*Yk;A3C@XSb7H8ksijx;>q%m1F6NP= z=*)Q--HnBZBz0tvxp%Nlz zn@WJ|kB3skt>5RhFEcyg)O_?03!oDjjw`&=K~)tcPy7gs!d{Ys?$%*-7-vC^j0N#L zy`Cp(Z<%=f#i)nH&r@rYZn0W#Ep|>dT zJaAbv@_ncQGsyh8nEHxOPuWarurp7sos$Yz0!LpmC7>wjFbt=6Ol*hN+b_S5!)HYQ zuAiO8H_zyqRX%7f(4n6lK?veHIF`Kc1}0 zu=WGWnN&XLMoI(`kEQQW3w!ng_lNM@iJWU57tNoUnh_maM^ zTfy(0p8YrT-0SqvmhI9h!&l=r+lLUDYmyy_KJSjTapgpf=)}B^FD4!LBsD$GiY#OokOQr7s~9ZyHKOHO6=NY!Omk~nz0E{;lNdQIJV9L2`S=xM)0?dNH}8&5lu_Lo-w4;ZKC@u7nR>y34I=nN%(~+Z=sC%QVxLgs+LU!@9GIwPMeyzImEm z5?#^nei*ml!G?QJjX$l!+`=8@_*V07%qm`H*P~FWiGNrB*dUjG zTf4iz4KGS8nf~#jb0D?s^GSsM+BgV~6!?(7pE5ELTx(yw4#6L7_jh~7BlA4`R`-!3 zV}7(9;XxY_gc{8DMWSJray6n+E#TRJLew9&?B>lvP*sa_;Fm7tSWdO2@0;A^xYzer z2`|G82U&BFwGg&9qLbu%G^lT_QXEQ5cUM5(R>eGR$Ww|}Ib7oNoLCTpam@y-K(qdh zAnoc~Fc$9p5dLU4Gm;-U`UsaWzq$X3U1qzL$4{?Xs5jNJ9CV6<2|Lxx_QTHj+FAV1 z{ndtgtL|M_z;I&OGXiWd`S2->J)f(aR*z zt~@(Mln*(LN`=`1Vxrh7!u2upv}3ph=?1=5sxi)NfmeusXWqKi?V}`R(28D+mrc-u z&?{hRp<&#<6gm?o@*Pp$ZZx^Bw7P&@nl6vI`^{fj3#HmpPTgj|!_M>!6_^a^H;wR}C^!ersyllf(*K*~BhOJ*8 z&v;?4p8;AMG4~PwwH(aq9X!om8tp_*^C{>?3}N!eJXWfNcNV>v5!I$mqR+&M9rqBw z9b=Ok;XO3A=r62Zyo_b@5gwcJnouAL&Myuhc}Tu7&olUti*a5x))7p6M2=1nxAT?6 zjYNU=%^Elvb(rigEMk&S|6JN(7ny zqlgGU8?fGLP6kFMD+etX5QK(`C2KRUeceJbOP4g){Kd-Ua2Vjm$*jk#Q3O|L$8dFx| zCl$-7Q;F;xgj#c` z03YL_BJmtE4==+Gr9Uzjx(x_j_zt@ftL}0ILN9ipS=*edQbT8rblll)Dy+HT4okF# zP(wM;tsG!UvSf2$Nx>+ir-6YKP7%Pc{LSWM2V6~Aw= zW2qE?O-EUL6qF&LWq4ua`%E%jMh8cs#-rpFgh)>=>chh84mVTHK%kGle%QSxW>3%woFykrF{>uxbwBiuOK zNwy+(NyR;N?wLJxas%SSFBeRaW;o1?XT}J@{hAq$Vqq2|;TN9pM1;UlE%=qQJzHZf zkL$V^?|N7-^t3Mpq%92x%O^yH!x|&6{e-pJO1lT8LT&8Cv2YVF63+RSCn=H@wOz_% zr5{?`TzA;;S^Xg7JrFkg?-qf1UhK)DV1ujJMQ_meR;g~Mru+Ji#ih+e-x|PBj`;Ar zbKu|e@X)lMGGM`aEwoy2!t$*#;m_no=;p+#@E%FDb5pdVW0nU=*$s5DPO+@@ zl8E4e1Fe4ZT%kTQ;WF#d@_ETsv~E+u3kK9Fq4WH378lURjbo;?v#g!F&C!GfX!?NJWe^Iqh(D{5+DUZ2C=d!9i#P%vM{$6D zH<8%(3rc3Iev65NsTbtIJw+deoehri%<<_!v-M}IOsapnW~SL$YMeP2s1@XgxjC~w zgRpSUJRT(ld(T}=SS!>^%pTpay2Q@>uL}dZ;rHlv4w<>)$-xX2Q68G0S>Hf?p?dkh zI(|m^^BZVd(f=PEj~InD@rGRmeahF`e1%J@!8r5JN$YG4wMtP!XRShdCEazJXD8Q*LHgU`P7lHjL)Z9uer~N=?uOI+4Gg ztlc~XR@hL{K{9B1k6nGB*0i~Bcn4c0_`dKqm;-^n7Fru_3$^IL9T23uh^Lso`VtS2L>S5&a`feduG(5k^KVeyv^Yf-;n;UdipO^TN_>VALQ@nA$|83-S z_p_N2Rp7sWxaJlKU0UZ{FBsX}`;w9LcVGz`F8d;{zu<$WuB&YM@3z}dv&kx4;!IH^ zk5L8}Q`KRTHDcqpD1<3+kAl^mK<74o2!aH|JAbd76F^_g1+kzUbI=#08~&1{EW}v% z{+7qwiKBPg*Fs;V@te8v5ez#2LLFuGR?ae#fb)}(rX5_Roc1j_mpYL z7-|5m-;Dp2)1EqU56WtmmT&%7kbPoAqT8U#YBDhtcg@@J8%fNdokyq?a0SwkTC2Ld ze7cSbtpBw68E^MPN$~%bbnfv?|6d$`?_$JUl3Q+FHBfa*K!%%B572O7@W?RC6g5wW%;EMiVCd-aUT%Z~yF%&u8z;d7amJzFP3dBy0}b zc87j*_=K{R*WK@CD-Ttg`|6)|+OgknWRm%jQ^1fM4P_F^#B#Aij% zf5L;?GZagm*Zcr~-;rx+HrJ)T>ErT3Kc|(l#ha_QGT0R(^VX049`gL4c;4k)99OFR zsXXut9r^uHak5cb)VO_^B<89k(j5K--PYgo;GX8R(snZB&njD(&P#EZ9GP z)AiHnJXpoNv0r_suN{(vHvjcQ~qq03O zr0Dj;lZLDp`3c7NWLzOznS~YuH?knZN~~t1rTQI+3%GjpSSrN~pQ^&jw9nUfs?^x&u4R}!>aTfQ zLD7`Op~c4RPU1crKRrm58~gGYcHdrc1u_%aQ0(mOIG+I2g`D!-g=AFK+p{71pB*H5 z!ya;tC~(LPaMrVwH!;6mXybOyk)^p3^J?kwih=8;5Y^u+GR^6j0p<0q&vqqKD&+Bd zaj)@;y?)6obKxUx$0^UgagcvqC3sPT`1)Q27_8L1_1E(=S(qflLo>uD)-m!>|He?e zhfbQYQqFUE_IaL9aT-?(G7Ee#TgH*S*9U`qB`vFuBt>NlodEYTb6Q7hX zg_jUXDMd*?-)XzK?#BjC(r0FmtG4AuwvXbGVtSxR6E~!YnG;&~c(ichD(E<%JH9d) zy0M<=$1BZtsn(~tw=lkghIq%qwp-8T!M%p*i4wrO5kyDj|71Uu;3c`#F6*;Kdkb#P zIQHCg4->&(yN{!;1`BiKjBRajVt;qtx){+r{N+r(H-<{s-aQlbq7$+!sxkEg-LsQ$ z#$^u1lqWPU27o9_pv)h4Ey}B6|512KpUdY%>a+G)D9r@YQospg(C>%Yf@8|EoSbUH z15Ciggt19ZUTJHrX3h~Rmd3p~sciuIjhZkIP(g1U?MmIxnZ)QtVof4R23VYJHf1-? zq{XeV29}{YQX0*uwTk1pXv+7_u5YhpH9S&lZ-IioU_L@6==tECc9pKn`RnLUh5~_; zo;abH)0Vy=BKRoz=@F;&_M-Xw@md%87?dDa@x6Zk<`5AVqtiF6sp=G{7%%+m9aQM-~e=v#PHI@FBaxD-s^LohNQp>W)~Eo zaSM|Tn3_k+@6IgF-g&ev&vFrcs937E_9g#fXUHI`wjroXzoaCnZ*iLnhTs3`3=?PLfx*o;AQ;ftZbl%kU~@;AqN2 zO=P+LmoY0(W2Z9kkr)oPkgTdpeIuO@1`qS&JPvePot^BEV32ULHjy((nGzv1fahqi zM3r94QX?gR)6Ww}6uc_ol_6|(7>2MCsms}JL4A8G-;3qLw||`ky;Xm(1C;iIc^4o3 zd8rdY(-Svp8Yo*A-3Fq!qYUm)7Q)E#wr)oi5TZ)^{c3PX*{s)slD^@YpR{4zy>KKe z^AdSY#6IDLi^XFbbCkApP!9xV-Rd%}oF18dNorCv$(ivy5#OC~qh7Lkc=_>ExnPpO zERtv3;LW>IN`sZZVgOe|Gq7}(0&dKSpD?&NI;VLPm{UG!SfD9g*}XflefqVfiq7x2D2 zL}YL9I-_;A(vW;$f3!b}{^CqkU#4rW2|aSem)u&FylbB@L;(U0PygU^jffw*n8}+( zTTK2M{x;+*igq>q&I?!E8dO%YAujt(P?oh6i_;mE*d8>c@jRumL~?u|8cJmkXZZAH zl;zX3{spy{97*c*lIDY1=<*PWd+h!D^Mys#f@8A4|C!- zjCwE!WnZN@R4LxH{H1X7sO_Y)E*{zkR;4EHb^`y>4kvLiLgnG=wpn@ovng+j@ot){yvT$&M`h8k=UAhE}}}G z^{61hfZY0JRf9|Rty47{j&Iu*d4e1pgIwg>wM}?9r31@U6N-J;YwAk-LJ5{x=|=sB zcWnxNF)XgqDk9roM*Blh$Yr-ncMm)l&K{lPw6}OHEzQ2-RdUly!@q4|*TfQU89P{K zj98gztYDP<_)*ecu!_Zrm;XpQs974v-O26aZ;8$O^6Yc^Ot5#ggR&3(7D(lne&HUR zT(p)6GTg~+R#rk%D%F?NVSQ*mq-H#NX)!9acO+bnRY(?PjfC$M-7OOm%O)SB6o!Q% z-;@yZ<<-DhXtuHw&nq`VUkCYSYXgKy@*C{9WG>2Cs4=U7JgEFGY}p?SXhAa6o8h{) zoXH_VZF#r~hL<{tr76}0-w)g4hoxCVML(aE1L&jPP}!%J-kZC+5j-9S=KB0eIEGg* zk6gaLM&TzeTRR#tt(TxWwy17|T>_u5U8<^6Q`N9KsyT%dd?#URzDESFKd-ajhybru za!yY+T8Dx#J1Yf*x5C`1Ms}Fu4n_-j+J-A+cE4Aw+mKX1ox(b8uI)bqolSY2ot@Eo zy8m9qh2kb9=erxIH5ZFzBaU`IQOQ8F$Qh+i`B5l?$0X8mx@Z^d60CqrJkzdIouh(Qa??5zuZf7{wxr8-8;Nadv>QIQi22XTXj zPYytwyE61%CIp8r+&OJxY_oavYsvok%g2vznO)LM__thyoFmKjfZcz?Vn_|}MhD6k zJ&aiv&Y~<3-P`J_&m#QIMO95@q?kjuQk`+l+-lTT^YTwbtibV0)81R*p+HBZM3iWK z@#?D#RGP0ghHO3wyhU{~ywkE&%+)%mCY!^m!|KclG2}Dq+G^IxckbvpcNB61g&3Ol zN3P6%g;D8Hk!Rddqv#|>_`_;_Pg^D)hJAf)1A|Fwv^s2*7Hi?*-H@I=!Qc{J#_UjY z@tE(J)4bYx_KTlwmZaT&80wyz>ZgEtFRbx5 zGmX%e;oD-}iecF@7V0fAjv6cstlh?awds#KC2lt`m;IHh4krp_C~D~?;Y2V|y|vzu zP;)Fb5e|5CUjsf%%XrpgtqgAg&s%^^7dX#0Yp2u-FSVI6*59GV4BNw~!GM3EYMAKv z#}VtIIH_@1CO%RRxxLp#uQ0l=eQguP)3n)OryWdR4i0{ZN?XCY&~&|qlN zi0zd_ieFvCwYo^WIs!7*i?re5f#*f^nZk#Tw6UDH&C~+HU>8v zhdXLk#O%s#Li0|@@=^mqUEr<13SO|5P`9DOZg7uu{z!s3_F4KpNAA!LQa4XxWCv^* zZ)(9q09~4ia%?xCtX9W*>SRZ_orOBoeibJxaS-S#roI0MLFn$ba}`Tjnl-A3+~0F5 z3Dxk!kleY-;E8&xws(z$Pgj;dPxRhQBRLea?Te)$fwx0_`wCRI>1`(7n*rkae^RZI#*?`7(sF zHf|5FnQ7EAjtk^=$t4Oq%2y*A5o^n ziFJ7xmx}tz{mcU6G2Qo6kdvymR>SagU<`fLZC$q<^9B{2zW(N#khzoV&`*63la2d> zx9N9U!2CLtNvHB=)_hUlH}D4L?m^XlGxP3KU=Aj3V`={_F75){-=NVKLis4!2?w7o zonB>{*JQoE$P&`y}?*P4Ka`k(j4__#{#2MyE?nl65BGbTr?{IBL@r!&E=IM64ljK8T?7nOt-a`< zg%bM16%r%1y2E2Z@TTFk!nwVvqv;*@tD7h~nMbcd=t{Pa3>qR_Eo0A!A^uW?ygtuSOe$55bF|@yDLDPmSsiGx zqXY%2%*T7@4SsSPl{wL-)U3b)*FI-3Nua6gnmE}`^JWyN9htKv% z@XCqPcFJS$=|+bPj@sIu7iqb`Ze?01s#&Yr_6W{S{4C1kfLu0zi#C`zxgSHlgVGV5 zBk&7h_1)2B;XE|<_Fp>8Y3N?nxr?VbT{)o)Rre(AdIIa295R!*XlvU3`0>|E@oE5m N$o6}7-rYex^FL5}`gZ^T literal 0 HcmV?d00001 diff --git a/jevdual/results/agent-visual-bench-20261011/source-freeze.json b/jevdual/results/agent-visual-bench-20261011/source-freeze.json new file mode 100644 index 0000000..d2ca778 --- /dev/null +++ b/jevdual/results/agent-visual-bench-20261011/source-freeze.json @@ -0,0 +1,16 @@ +{ + "commit": "9a5d2f8bfac8088b13c63052887e0c0c2e9d5c7e", + "files": { + "tools/camera-capture-experiment/capture.py": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "tools/physical-workcell/agent_bench.py": "e120dbfc9a96ca07fedb15226f27282265203755866210b86d5f856f6e3f5e07", + "tools/physical-workcell/bench.py": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "tools/physical-workcell/episode_cases.py": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "tools/physical-workcell/image_guided.py": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961", + "tools/physical-workcell/measurement.py": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "tools/physical-workcell/order_protocol.py": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "tools/physical-workcell/qualify_bench.py": "524c537c1b310a0f0ae493acee99a069966a5e7c4b0a783daadf347094db58ef", + "tools/physical-workcell/scene.xml": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "tools/physical-workcell/score_agent_bench.py": "8a0eeb0885efaa5360a94cd3e187b460c34610c06a973f37dcd3b7d287fac521", + "tools/physical-workcell/workcell.py": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2" + } +} From d539f2b6862abaa1881a8464576c43225d81c696 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 15:12:46 -0400 Subject: [PATCH 098/216] Preserve image recovery proof and register bounded installer supervision extension --- .../notebook/2026-10-11-u2-vm-provision.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md index 5b5df11..fe8afbe 100644 --- a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md +++ b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md @@ -44,3 +44,27 @@ Test: resume incomplete segments with Range beginning at their recorded absolute Predicts: retained segments remain unchanged, each range reaches its exact expected length, the complete image matches Apple SHA256885503b7f4b06609e9a512f2befd40f59730640a3f1233e3892d60affdd51c95, and only then the committed Tart provisioning test starts. Against: the CDN ignores/rejects offsets, repeated partial transport prevents completion, existing bytes are altered, or final image hash differs. Refs: output/u2-vm-provision-20261011/apple-ipsw-headers.txt; output/u2-vm-provision-20261011/download_apple_ranges.py + +## VMU4 · update · 2026-10-11 14:41 +Resolves: VM4 = held +Observed: five bounded continuation requests returned HTTP206 with exact absolute Content-Range; all missing bytes were retained in separate attempt files before append. Original completed ranges were not downloaded again. Single streamed assembly/fsync produced 19,772,231,540 bytes and Apple SHA256885503b7f4b06609e9a512f2befd40f59730640a3f1233e3892d60affdd51c95. The image is read-only with recorded file identity and private non-symlink parent; Tart creation started only after those guards passed. A redundant preliminary prefix-hash scan was stopped before network requests, preserving its script/context; no image was certified from that attempt. +Next: supervise Tart installation and hand its actual native viewer to root; VM2 and VM3 guest observations remain open. +Refs: output/u2-vm-provision-20261011/apple-ipsw-provenance.json; output/u2-vm-provision-20261011/provision-state.json; output/u2-vm-provision-20261011/tart-create.log + +## VMU5 · update · 2026-10-11 14:41 +Resolves: VM1 = inconclusive +Observed: pinned Lume integrity/signature/configuration checks passed, but native clipboard source behavior and absence of a supported VNC bind option caused its controller to stop before any guest creation. Actual provisioning now uses independently verified Tart2.40.1 with its supported disabled-clipboard route; the Lume guest hypothesis was not executed to completion. +Next: retain Lume findings as the launcher selection rationale; do not call them a Lume installation or first-use failure. +Refs: output/u2-vm-provision-20261011/launcher-provenance.json; output/u2-vm-provision-20261011/tart-launcher-provenance.json + +## VM5 · prediction · 2026-10-11 15:11 +Hypothesis: pausing only the Python controller before its create timeout while Tart continues verified disk work, then resuming after the create child exits, preserves the actual child exit status and allows existing configuration/viewer steps without restarting installation. +Test: inspect the active controller's Python/POSIX subprocess wait semantics and exact process relationships, pause only that controller if creation remains active near15:18, supervise the same child PID and scoped disk activity for at most15additionalminutes, then resume the controller after the child exits or becomes a zombie; preserve any timeout/failure without resetting the partial guest. +Predicts: Tart1958 continues writing while its supervisor alone is stopped, the completed child is reaped before timeout rejection in the resumed wait, and the same fresh guest reaches the queued native viewer with the selected isolation flags. +Against: pausing affects the child/process group, the resumed controller loses true exit status or times out despite completion, installation fails/stalls, or the15minute extension expires without a justified handoff. +Refs: output/u2-vm-provision-20261011/provision_tart_after_download.py; output/u2-vm-provision-20261011/python-popen-wait-source.txt; output/u2-vm-provision-20261011/installer-liveness-current.json + +## VMU6 · update · 2026-10-11 15:12 +Observed: VM5 was written at15:12EDT (clock19:12:02UTC), while its heading used15:11; the heading minute is approximate and git commit order remains the preregistration boundary. POSIX _wait polls waitpid before testing the elapsed deadline on each iteration, but a stop between that poll and deadline calculation would still permit a timeout on resume; the prediction does not assume away that narrow race. +Next: commit VM5 before any pause, prefer observing the controller sleeping in its wait loop, and report any resumed timeout honestly rather than inferring successful child status from a percentage. +Refs: output/u2-vm-provision-20261011/python-popen-wait-source.txt From ab374a682f798c39b1f9ad248d859b03bf8a8817 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 15:23:00 -0400 Subject: [PATCH 099/216] Preserve verified clean Mac provisioning at human setup boundary --- .../notebook/2026-10-11-u2-vm-provision.md | 20 ++++ .../u2-vm-provision-20261011/report.md | 31 +++++ .../u2-vm-provision-20261011/summary.json | 111 ++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 jevdual/results/u2-vm-provision-20261011/report.md create mode 100644 jevdual/results/u2-vm-provision-20261011/summary.json diff --git a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md index fe8afbe..493c6e9 100644 --- a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md +++ b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md @@ -68,3 +68,23 @@ Refs: output/u2-vm-provision-20261011/provision_tart_after_download.py; output/u Observed: VM5 was written at15:12EDT (clock19:12:02UTC), while its heading used15:11; the heading minute is approximate and git commit order remains the preregistration boundary. POSIX _wait polls waitpid before testing the elapsed deadline on each iteration, but a stop between that poll and deadline calculation would still permit a timeout on resume; the prediction does not assume away that narrow race. Next: commit VM5 before any pause, prefer observing the controller sleeping in its wait loop, and report any resumed timeout honestly rather than inferring successful child status from a percentage. Refs: output/u2-vm-provision-20261011/python-popen-wait-source.txt + + +## VMU7 · update · 2026-10-11 15:20 +Resolves: VM2 = held +Observed: Tart creation returned success at15:14EDT before its timeout; get/list report the same owned guest running with4CPUs,8192MB RAM and64GB logical disk. Actual argv disables clipboard/audio/USB passthrough, captures system keys and attaches the verified ISO read-only. Root bound exactPID25080/window footwork-u2-20261011 and observed fresh welcome then actual Setup Assistant Language page/English/license-use notice in native CUA tool images. Root owns all GUI input; human license approval is pending. +Inferred: provisioning reached a visible pristine setup boundary; this does not establish guest SIP, initial TCC denial, ISO guest readback or the U2 permission journey. +Next: retain the running guest for human setup and root's independent onboarding qualification; VM3 remains open. +Refs: output/u2-vm-provision-20261011/delivery-record/summary.json; output/u2-vm-provision-20261011/provision-state.json; root native CUA tool images in this chat + +## VMU8 · update · 2026-10-11 15:20 +Resolves: VM5 = inconclusive +Observed: installer completed normally before the planned15:18pause boundary, so no controller pause, resume, swap or extended timeout was executed. +Next: preserve the proposed recovery and narrow wait-race caveat as untested; do not call VM5 held. +Refs: output/u2-vm-provision-20261011/tart-create.log; output/u2-vm-provision-20261011/provision-state.json + +## VMS1 · summary · 2026-10-11 15:20 +Established: pinned launchers/artifact provenance, safe supported Tart flags/storage, bounded authenticated Apple image recovery, exact ISO inventory/payload verification, successful fresh guest creation/configuration and root-observed visible Setup Assistant. No global launcher, host permission change, guest account/SSH/TCC grant or SIP change was performed. +Uncertain: guest SIP runtime status, denied Accessibility baseline, actual ISO guest read-only/hash readback and the complete installed U2 effect/restart/report/cleanup journey. Tart Gatekeeper diagnostics reported Unnotarized Developer ID even though normal CLI/create/run succeeded without policy overrides. +Decision: hand the running guest and all GUI ownership to root at the explicit human setup/license boundary; keep VM3 and UO2 open. +Refs: output/u2-vm-provision-20261011/delivery-record/report.md; output/u2-vm-provision-20261011/delivery-record/summary.json diff --git a/jevdual/results/u2-vm-provision-20261011/report.md b/jevdual/results/u2-vm-provision-20261011/report.md new file mode 100644 index 0000000..1b67bc4 --- /dev/null +++ b/jevdual/results/u2-vm-provision-20261011/report.md @@ -0,0 +1,31 @@ +# U2 disposable Mac provisioning handoff + +Recorded 2026-10-11 19:20 UTC. The fresh disposable guest `footwork-u2-20261011` was installed from an authenticated Apple restore image and is running at the human Setup Assistant boundary. This closes provisioning only. The independent permission journey remains unexecuted. + +Root bound the native Tart app to exact PID `25080` and window `footwork-u2-20261011`, observed the fresh welcome page, then the Language page with English selected and Apple's license-use notice. Evidence is the native CUA tool images in this chat; no screenshot file path is invented. Root has requested human license approval. The worker performed no guest GUI input, account setup, SSH enablement, TCC grant or SIP change. Root owns further GUI actions. + +Tart's runtime configuration reports 4 CPUs, 8192 MB memory, a 64 GB logical disk and 1280x800px display. Actual launch arguments disable clipboard, audio and USB passthrough, capture system keys, and attach only the validated asset ISO read-only. There are no host directory shares; a scoped check found no TCP listener on the Tart PID. Guest SIP and initial Accessibility status have not been measured. + +## Provenance and launcher choice + +Local Cua reference commit: `5458c77b04a6e5e7a099929e0c4d4366e83dd403`. Lume 0.6.1 release source: `3350f504014c85416009a90fcb339fe556ce02fc`. The notarized Lume asset passed official digest/signature checks, but release source confirms automatic host clipboard reads in native mode and its CLI supplies no VNC bind-address control. No Lume guest was created. These source findings were also checked against the exact release, not just the local checkout. + +Tart 2.40.1 source: `05edeac562bae804ea4f88592cfbc98cc6791b5d`. The [official asset](https://github.com/openai/tart/releases/tag/2.40.1) matches SHA256 `363e2701154a8155cbc1bb6d845430c9b42697d2a186bc49574471ca2877db46`. Strict/deep code-signature verification passed for Cirrus Labs, Inc., Team `9M2P8L4D89`. **Gatekeeper diagnostics rejected both bundle and inner CLI as Unnotarized Developer ID; no ticket is stapled.** Normal CLI, create and run nevertheless succeeded under unchanged OS policy. No quarantine/security override was performed. The launcher is distributed under FSL-1.1-ALv2. It is local qualification infrastructure and is not bundled in the MIT Footwork packet. + +Launcher, cache, temporary state, images and guest storage reside under `/Volumes/External SSD/footwork-u2-20261011`. No global installer or LaunchAgent was used. `TART_HOME` isolates runtime storage, and inherited trace export is disabled for this invocation. + +## Image and delivery integrity + +Apple Virtualization supplied macOS 26.6.2/build 25G83's restore URL. The downloaded image contains exactly 19,772,231,540 bytes and matches Apple's advertised SHA256 `885503b7f4b06609e9a512f2befd40f59730640a3f1233e3892d60affdd51c95`. Original parallel transfer failed with curl exit 18; its context remains. Five exact HTTP206 continuations recovered only missing bytes after Content-Range validation. Streamed assembly combined writes with hashing and fsync; the resulting file is 0444 with recorded device/inode/size/mtime and a private non-symlink parent before create. + +The qualification ISO SHA256 is `89f082fcdc943449f1994d70cd4bd30b08b88ecf6abceec7d42c33c206049f6d`. A standard-library Joliet parser independently verified its exact six-member inventory and every payload byte against the staged files. It contains only packet v3, Python 3.14.7 installer, uv 0.12.5 archive, Google Chrome DMG and two provenance/checksum files. It was built without mounting a host volume. **Guest volume/read-only/hash readback remains pending.** + +Packet v3 SHA256: `769c08c89061731368db33d78b180e7c8c96d531190f43bee44263642a76fd0f`. Python and uv match official hashes; Python's installer is signed/notarized by the Python Software Foundation. Chrome DMG checksum passes, but host read-only attach was denied; its inner app signature/version must still be checked in the guest. No prerequisite was installed on the host. + +## Evidence and remaining gates + +Structured values and source/runtime references are in `summary.json`. Ignored raw evidence remains in the sibling output directory: launcher/release provenance, original and resumed transfer headers/logs, image proof, ISO proof, installer log, final configuration/list, process state and runtime log. Do not commit raw logs or downloaded binaries. + +VM1 is inconclusive because Lume creation was never run. VM2 is held for provisioning to actual visible Setup Assistant only. VM4 is held for authenticated range recovery. VM5 is inconclusive: installation finished normally before the planned controller pause, so that extension was not executed. VM3 remains open; UO2 remains unexecuted. + +Next: the human completes the license/account boundary without sharing credentials. From interactive guest Terminal, root verifies OS/SIP and the attached volume/hashes, installs the reviewed prerequisites and wheel, then records the denied Accessibility baseline before any grant. The explicit grant/restart/readback transition and installed append/restart/report/cleanup oracle follow. The denial probe requires installed dependencies; installation does not grant Accessibility. Existing host grants, successful installation and a visible setup page do not qualify that journey. diff --git a/jevdual/results/u2-vm-provision-20261011/summary.json b/jevdual/results/u2-vm-provision-20261011/summary.json new file mode 100644 index 0000000..5720ebb --- /dev/null +++ b/jevdual/results/u2-vm-provision-20261011/summary.json @@ -0,0 +1,111 @@ +{ + "status": "provisioned_running_at_human_setup_gate", + "recorded_utc": "2026-10-11T19:20:22.512174+00:00", + "vm_name": "footwork-u2-20261011", + "runtime_pid": 25080, + "bundle_id": "com.github.cirruslabs.tart", + "window_title": "footwork-u2-20261011", + "runtime_configuration": { + "Size": "22.720", + "Memory": 8192, + "Running": true, + "State": "running", + "Disk": 64, + "DiskFormat": "raw", + "OS": "darwin", + "Display": "1280x800px", + "CPU": 4 + }, + "source_refs": { + "local_cua_commit": "5458c77b04a6e5e7a099929e0c4d4366e83dd403", + "lume_release_commit": "3350f504014c85416009a90fcb339fe556ce02fc", + "tart_version": "2.40.1", + "tart_commit": "05edeac562bae804ea4f88592cfbc98cc6791b5d" + }, + "artifacts": { + "apple_ipsw": { + "version": "26.6.2", + "build": "25G83", + "bytes": 19772231540, + "url": "https://updates.cdn-apple.com/2026SummerFCS/fullrestores/140-75212/A2A24B94-1FC1-45A3-93F7-C51B02AF1F4D/UniversalMac_26.6.2_25G83_Restore.ipsw", + "sha256": "885503b7f4b06609e9a512f2befd40f59730640a3f1233e3892d60affdd51c95", + "sha256_matches_apple_metadata": true, + "fsynced": true, + "read_only_mode": "0444", + "file_identity": { + "device": 16777240, + "inode": 39044176, + "bytes": 19772231540, + "mtime_ns": 1791744046377973440, + "mode": 33060 + } + }, + "tart_archive_sha256": "363e2701154a8155cbc1bb6d845430c9b42697d2a186bc49574471ca2877db46", + "packet_v3_sha256": "769c08c89061731368db33d78b180e7c8c96d531190f43bee44263642a76fd0f", + "iso_sha256": "89f082fcdc943449f1994d70cd4bd30b08b88ecf6abceec7d42c33c206049f6d" + }, + "launcher_integrity": { + "codesign_strict_deep": "valid, Cirrus Labs Inc Team9M2P8L4D89", + "spctl_bundle_and_inner_cli": "rejected, Unnotarized Developer ID", + "stapled_ticket": false, + "normal_cli_and_vm_create_run": "succeeded under unchanged OS policy", + "security_policy_or_quarantine_override": false + }, + "isolation": { + "flags": [ + "--no-clipboard", + "--no-audio", + "--no-usb-accessories", + "--capture-system-keys", + "--disk", + "/Volumes/External SSD/footwork-u2-20261011/qualification-assets.iso:ro" + ], + "host_folder_shares": [], + "no_global_launcher_install": true, + "no_host_tcc_change": true, + "no_guest_accounts_created": true, + "no_guest_ssh_enabled_by_workflow": true, + "no_guest_permission_grants": true, + "no_sip_change": true, + "tart_pid_tcp_listeners_observed": [] + }, + "gui_observation": { + "observer": "root agent through native CUA tool", + "evidence": "observed tool images in this chat; no screenshot file was generated by documented APIs", + "reported_stage": "fresh welcome then Setup Assistant Language page, English selected, Apple license-use notice", + "reported_time_approx_edt": "2026-10-11 15:16", + "license_approval": "requested from human, pending", + "worker_gui_actions": [] + }, + "qualification": { + "VM1": "inconclusive; Lume never created a guest", + "VM2": "held for provisioning to visible Setup Assistant only", + "VM3": "open; ISO source inventory and payload hashes verified, guest read-only volume/hash readback pending", + "VM4": "held; exact HTTP206 continuation and final Apple SHA passed", + "VM5": "inconclusive; timeout extension was not executed", + "UO2": "unexecuted; independent permission journey remains unqualified", + "guest_sip_runtime_status": "not verified", + "guest_accessibility_baseline": "not measured" + }, + "evidence_refs": [ + "launcher-provenance.json", + "tart-launcher-provenance.json", + "tart-tag-ref.json", + "prerequisite-provenance.json", + "iso-verification.json", + "apple-ipsw-provenance.json", + "tart-create.log", + "tart-set.log", + "tart-guest-config.json", + "tart-guest-list.json", + "provision-state.json", + "tart-guest-run.log", + "installer-liveness-current.json" + ], + "next": [ + "Human approves the actual Apple license step and enters a new local-account password personally.", + "From interactive guest Terminal, verify OS/SIP and ISO read-only volume/hashes; verify and install prerequisites, then cold-install the approved wheel.", + "Record strict doctor and fixture denial before any Accessibility grant; verify no fixture resources were created.", + "Human grants the exact responsible host; record restart/readback, then run installed append/restart/report and independent cleanup checks." + ] +} From fccf7abcd3b1b9cde88f26fa18bee545f784922b Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 15:26:31 -0400 Subject: [PATCH 100/216] Preregister unattended visual bench operator and product qualification --- .../docs/experiments/SIM8-bench-operator.md | 31 +++++++++++++++++++ .../notebook/2026-10-11-bench-operator.md | 8 +++++ 2 files changed, 39 insertions(+) create mode 100644 jevdual/docs/experiments/SIM8-bench-operator.md create mode 100644 jevdual/docs/notebook/2026-10-11-bench-operator.md diff --git a/jevdual/docs/experiments/SIM8-bench-operator.md b/jevdual/docs/experiments/SIM8-bench-operator.md new file mode 100644 index 0000000..db52e1b --- /dev/null +++ b/jevdual/docs/experiments/SIM8-bench-operator.md @@ -0,0 +1,31 @@ +# SIM8: unattended visual control and a usable bench operator + +## Question and hypothesis + +Can a local bench-operator product run two successive image-guided jobs using the installed, authenticated Codex CLI for decisions, retain the existing simulation guards, recover from an injected displacement, and expose truthful progress, measurement results and pause controls in the browser? + +The hypothesis is that the external AI handoff can be driven by an independently running model process, with deterministic scheduling, call budgets and result verification. The browser can provide task creation and supervision without creating another physical-authority path. + +## Predictions + +If true, two queued jobs complete on one retained bench, each with one saved measurement and contact reset. A disturbance after a saved second-job measurement decision refuses that stale action; a subsequent image-based model decision recovers. Browser reload preserves job/result state. A pause request during model inference prevents the returned decision from dispatching; resume obtains fresh evidence. Neither the browser nor a model-generated completion flag can bypass the bench. + +Against: chat supervision or a deterministic coordinate planner is needed to complete jobs; stale images dispatch; stopped model replies execute; interrupted effects replay; the UI reports completion without verified reset and saved measurement; native guard source must be weakened. + +## Design + +Add an isolated product beside existing physical-workcell tools: a bounded Codex CLI visual-policy adapter, a durable serialized job runtime, a loopback-only HTTP app and a responsive browser operator. Reuse the current agent and bench APIs unchanged. The model receives the exact PNG, task/calibration and a bounded history of chosen actions/outcomes. Strip detector coordinates and native poses. Codex runs ephemerally with user configuration/hooks, shell/action tools and web access disabled; saved CLI authentication is used, without opening or provisioning keys. Validate structured model output before proposing an action. + +Persist call reservation and dispatch intent before each boundary. Count unavailable/cancelled model calls against the budget; never retry a possibly dispatched physical effect. One active job, at most 32 model calls per job, bounded call timeout, and pause at action boundaries. Pause does not promise mid-motion hardware cancellation. Unknown physical/handoff outcomes block resume; unavailable model output pauses for operator attention. Source drift and restarts do not implicitly replay unfinished work. + +Use stdlib Python and plain HTML/CSS/JavaScript with the existing MuJoCo environment. No new dependencies, cloud deployment, hardware or API-key writes. Operator jobs request an image-footprint measurement with a target region. Preserve all attempts and model logs privately; commit derived reports rather than raw model traces. + +## Qualification and primary metric + +After development conformance, freeze measured source before live model calls. Drive the actual browser to enqueue an ordinary job (region x=[0.035,0.105]) and a disturbance job (x=[0.045,0.115]), both y=[-0.025,0.025]. Inject one bounded native force between the second job's saved first measurement decision and dispatch. Score native measurement/reset states and read-only SQLite after the run, separately from the model. Record every model call, proposal, refusal and cleanup outcome. + +Primary metric: completed queued job cycles, required 2/2 on the first frozen qualification attempt. Stale refusal and fresh-image recovery are required, as are truthful browser readback and pause semantics. Conformance can use an explicitly labelled fake policy to deterministically test failures; that is not model-control evidence. A failed frozen run is retained and reported; any repair needs a new preregistered version rather than a hidden retry. + +## Decision and limits + +Adopt only as a local simulated bench-operator prototype if the complete flow and guards pass. Record model/CLI identity, call count, token usage when reported and elapsed time; subscription usage does not supply an independently verified monetary price. This does not establish hardware transfer, broad model repeatability, production security, physical power-loss recovery, billing accuracy or demand. diff --git a/jevdual/docs/notebook/2026-10-11-bench-operator.md b/jevdual/docs/notebook/2026-10-11-bench-operator.md new file mode 100644 index 0000000..cb55630 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-11-bench-operator.md @@ -0,0 +1,8 @@ +# Unattended visual AI and the bench operator product + +## SIM8-P1 · prediction · 2026-10-11 15:24 +Hypothesis: a bounded independent Codex vision process can drive the existing proposal API across two queued prepare-measure-reset jobs, while a local browser product truthfully exposes progress and pause behavior without widening effect authority. +Test: build the policy/runtime/browser boundaries, run labelled deterministic conformance, freeze source before live model requests, enqueue two jobs through the actual browser including a saved-decision disturbance, then separately score physics, SQLite and UI reload readback. +Predicts: two verified cycles, one measurement per job, continuous bench state, stale refusal and fresh-image recovery, pause preventing late model-result dispatch, unchanged native guards and preserved evidence for all calls and outcomes. +Against: chat-directed targets or an automatic coordinate planner are required, stale or paused decisions dispatch, unknown effects replay, the UI invents completion, or native guards need weakening. +Refs: docs/experiments/SIM8-bench-operator.md; tools/physical-workcell/AGENT_BENCH.md; results/bench-operator-20261011/ From 3e6475e6082f2795e4b285ba727f888c5a9afede Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 15:33:41 -0400 Subject: [PATCH 101/216] Add bounded unattended Codex visual policy and preregister its transport probe --- .../notebook/2026-10-11-bench-operator.md | 7 + .../codex-action.schema.json | 11 ++ tools/physical-workcell/codex-policy.md | 11 ++ tools/physical-workcell/codex_policy.py | 166 ++++++++++++++++++ tools/physical-workcell/test_codex_policy.py | 69 ++++++++ 5 files changed, 264 insertions(+) create mode 100644 tools/physical-workcell/codex-action.schema.json create mode 100644 tools/physical-workcell/codex-policy.md create mode 100644 tools/physical-workcell/codex_policy.py create mode 100644 tools/physical-workcell/test_codex_policy.py diff --git a/jevdual/docs/notebook/2026-10-11-bench-operator.md b/jevdual/docs/notebook/2026-10-11-bench-operator.md index cb55630..7d04366 100644 --- a/jevdual/docs/notebook/2026-10-11-bench-operator.md +++ b/jevdual/docs/notebook/2026-10-11-bench-operator.md @@ -6,3 +6,10 @@ Test: build the policy/runtime/browser boundaries, run labelled deterministic co Predicts: two verified cycles, one measurement per job, continuous bench state, stale refusal and fresh-image recovery, pause preventing late model-result dispatch, unchanged native guards and preserved evidence for all calls and outcomes. Against: chat-directed targets or an automatic coordinate planner are required, stale or paused decisions dispatch, unknown effects replay, the UI invents completion, or native guards need weakening. Refs: docs/experiments/SIM8-bench-operator.md; tools/physical-workcell/AGENT_BENCH.md; results/bench-operator-20261011/ + +## SIM8-CLI · prediction · 2026-10-11 15:33 +Hypothesis: the installed authenticated Codex CLI can return one schema-valid image-based action with action tools disabled, using the current bounded policy adapter without key provisioning. +Test: commit the policy source, render a fresh native preparation image, invoke one CLI decision with no physical dispatch, and retain exit/schema/usage evidence separately from the primary product qualification. +Predicts: a bounded completed model process returns a valid typed action and reported usage, with no tool events and no native state change. +Against: configuration or authentication fails, tools are invoked, the model cannot accept the image/schema, output is invalid, or the probe dispatches a bench action. +Refs: tools/physical-workcell/codex_policy.py; tools/physical-workcell/output/sim8-policy-smoke1/ diff --git a/tools/physical-workcell/codex-action.schema.json b/tools/physical-workcell/codex-action.schema.json new file mode 100644 index 0000000..a242e24 --- /dev/null +++ b/tools/physical-workcell/codex-action.schema.json @@ -0,0 +1,11 @@ +{ + "type": "object", + "properties": { + "action": {"type": "string", "enum": ["move", "measure", "begin_reset", "finish_reset", "stop"]}, + "target_x": {"type": ["number", "null"]}, + "target_y": {"type": ["number", "null"]}, + "intent": {"type": "string"} + }, + "required": ["action", "target_x", "target_y", "intent"], + "additionalProperties": false +} diff --git a/tools/physical-workcell/codex-policy.md b/tools/physical-workcell/codex-policy.md new file mode 100644 index 0000000..8982224 --- /dev/null +++ b/tools/physical-workcell/codex-policy.md @@ -0,0 +1,11 @@ +You are the visual policy for a simulated experiment bench. Choose exactly one next action from the attached current image and task metadata. Return only the requested JSON shape. You have no tools and must not request tools, inspect files, run code, or claim success without controller verification. + +The orange object is a free block. The blue object is an XY pusher; move targets position the pusher, not the block. The green rectangle is the measurement region. Dark shapes are shadows. The camera is orthographic, 640 by 360 pixels, with its world origin at pixel (320,180). Use the supplied calibration: increasing image x is increasing world x, increasing image y is decreasing world y. Infer current object positions from the image yourself. The block footprint is approximately 0.07 by 0.07 meters; the pusher is 0.04 by 0.14 meters. Native contact moves the block; you cannot pick it up or teleport it. + +During prepare, put the block CENTER inside the supplied target zone. Its entire footprint need not fit. Push from its left to move it right, or from its right to move it left. Clear the pusher away from contact before measuring. When the fresh image shows the center in the region and the pusher clear, choose measure. A rejected stale decision is feedback: inspect the new image and choose the necessary correction; do not blindly retry measurement. + +After a verified measurement, choose begin_reset. During resetting, move the block CENTER into the home zone and return the pusher to world (-0.30,0). To push the block left, approach from the right. When crossing from one side of the block to the other, first enter a clear lateral lane, cross horizontally, then return to y=0. Avoid diagonal paths through the block. Clearance depends on both footprints; y around +0.135 meters is a usable bypass lane for a block near y=0. Keep all pusher targets within the supplied bounds. When releasing right-side contact after a leftward push, retreat slightly right before entering the bypass lane so you do not drag the block. + +In resetting, when the current image shows both bodies home, choose finish_reset and let the controller verify it. Never use finish_reset or measure to manufacture success. If the situation cannot be resolved within the task or lacks usable evidence, choose stop and briefly explain why. + +For move, provide finite target_x and target_y in meters. For all other actions, both targets must be null. Intent must be one short sentence describing the next action's purpose. Every call is bounded; use purposeful moves rather than many tiny increments. History describes earlier actions, not current placement. The current attached image is the basis for your next decision. diff --git a/tools/physical-workcell/codex_policy.py b/tools/physical-workcell/codex_policy.py new file mode 100644 index 0000000..431374a --- /dev/null +++ b/tools/physical-workcell/codex_policy.py @@ -0,0 +1,166 @@ +"""Bounded image-only Codex CLI policy; it never dispatches bench actions.""" + +import contextlib +import hashlib +import json +import os +import shutil +import signal +import subprocess +import time +from pathlib import Path + +import agent_bench +import order_protocol as protocol + +BASE = Path(__file__).resolve().parent +TIMEOUT_S = 100 +MAX_TRACE_BYTES = 1024 * 1024 +MAX_RESULT_BYTES = 8192 +EXPECTED_CLI = "codex-cli 0.147.0" + + +class PolicyUnavailable(RuntimeError): + """Safe failure code; provider output and credentials stay private.""" + + +class PolicyCancelled(PolicyUnavailable): + pass + + +def preflight(): + executable = shutil.which("codex") + if not executable: + return {"available": False, "reason": "Codex CLI is not installed", "provider": "codex_cli"} + try: + version = subprocess.run([executable, "--version"], capture_output=True, text=True, timeout=5, check=False) + auth = subprocess.run([executable, "login", "status"], capture_output=True, text=True, timeout=5, check=False) + cli_version = version.stdout.strip() + available = version.returncode == auth.returncode == 0 and cli_version == EXPECTED_CLI + return {"available": available, "provider": "codex_cli", "cli_version": cli_version, + "auth_mode": "saved_cli_authentication", "reason": None if available else "CLI version or sign-in is unavailable"} + except (OSError, subprocess.TimeoutExpired): + return {"available": False, "reason": "Codex CLI readiness could not be checked", "provider": "codex_cli"} + + +def validate_action(value): + protocol.fields(value, ("action", "target_x", "target_y", "intent"), "model action") + action = value["action"] + if action not in agent_bench.ACTIONS | {"stop"} or not isinstance(value["intent"], str) or not 1 <= len(value["intent"].strip()) <= 500: + raise PolicyUnavailable("model_action_schema") + if action == "move": + x, y = protocol.finite(value["target_x"]), protocol.finite(value["target_y"]) + if not -.32 <= x <= .18 or not -.15 <= y <= .15: + raise PolicyUnavailable("model_target_outside_bounds") + elif value["target_x"] is not None or value["target_y"] is not None: + raise PolicyUnavailable("nonmotion_targets_must_be_null") + return value + + +def terminate(process): + if process.poll() is not None: + return + with contextlib.suppress(ProcessLookupError): + os.killpg(process.pid, signal.SIGTERM) + try: + process.wait(timeout=3) + except subprocess.TimeoutExpired: + with contextlib.suppress(ProcessLookupError): + os.killpg(process.pid, signal.SIGKILL) + process.wait(timeout=3) + + +def usage_from_events(content): + reported = None + for line in content.decode("utf-8", errors="replace").splitlines(): + try: + event = json.loads(line) + except (ValueError, TypeError): + continue + if not isinstance(event, dict): + continue + item = event.get("item", {}) + if isinstance(item, dict) and item.get("type") not in {None, "agent_message", "reasoning"}: + raise PolicyUnavailable("unexpected_model_tool_use") + if event.get("type") == "turn.completed": + data = event.get("usage", {}) + if isinstance(data, dict) and all(type(data.get(k)) is int and 0 <= data[k] <= 1000000 for k in ("input_tokens", "output_tokens")): + reported = {k: data[k] for k in ("input_tokens", "output_tokens", "cached_input_tokens") if type(data.get(k)) is int} + return reported + + +def decide(challenge, history, call_dir, cancel_event): + root = protocol.directory(call_dir, create=True) + if any(path.name != "reservation.json" for path in root.iterdir()): + raise PolicyUnavailable("model_call_directory_already_used") + packet = challenge["observation"] + image = protocol.read_bytes(Path(challenge["image_path"]), maximum=1024 * 1024) + if protocol.sha(image) != packet["image_sha256"]: + raise PolicyUnavailable("model_image_digest_changed") + readiness = preflight() + if not readiness["available"]: + raise PolicyUnavailable("codex_cli_unavailable") + if cancel_event.is_set(): + raise PolicyCancelled("operator_pause_requested") + data = agent_bench.public_response({"current": {"job_id": packet["job_id"], "phase": packet["phase"], + "generation": packet["generation"], "calibration": packet["calibration"], "task": challenge["task"]}, + "recent_actions": history[-12:]}) + prompt = "Choose one next action from this current attached image and task data.\n" + protocol.encoded(data).decode() + instructions = protocol.read_bytes(BASE / "codex-policy.md") + schema = protocol.read_bytes(BASE / "codex-action.schema.json") + for name, content in (("input.png", image), ("instructions.md", instructions), ("schema.json", schema), ("prompt.txt", prompt.encode())): + agent_bench.bench.body.create_file(root / name, content) + request_sha = hashlib.sha256(prompt.encode() + image + instructions + schema).hexdigest() + flags = ["--ignore-user-config", "--ignore-rules", "--ephemeral", "--skip-git-repo-check", "--sandbox", "read-only", + "--disable", "shell_tool", "--disable", "unified_exec", "--disable", "hooks", "--disable", "multi_agent", + "--disable", "apps", "--disable", "image_generation", "--disable", "view_image", "--disable", "code_mode_host", + "-c", "tools.view_image=false", "-c", 'web_search="disabled"', "-c", "project_doc_max_bytes=0", + "-c", "approval_policy=\"never\"", "-c", 'model_reasoning_effort="low"', + "-c", "model_instructions_file=" + json.dumps(str(root / "instructions.md")), + "--cd", str(root), "--image", str(root / "input.png"), "--output-schema", str(root / "schema.json"), + "--output-last-message", str(root / "result.json"), "--json", "-"] + executable = shutil.which("codex") + environment = {k: v for k, v in os.environ.items() if not any(word in k.upper() for word in ("API_KEY", "TOKEN", "SECRET", "PASSWORD"))} + metadata = {"provider": "codex_cli", "cli_version": readiness["cli_version"], "request_sha256": request_sha, + "image_sha256": packet["image_sha256"], "started_at": time.time(), "usage": None} + agent_bench.bench.body.create_file(root / "request.json", protocol.encoded({**metadata, "flags": flags, "tools_enabled": False})) + started = time.monotonic() + with (root / "events.jsonl").open("xb") as stdout, (root / "stderr.log").open("xb") as stderr: + try: + process = subprocess.Popen([executable, "exec", *flags], stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, + env=environment, start_new_session=True) + except OSError as exc: + raise PolicyUnavailable("codex_cli_launch_failed") from exc + metadata["pid"] = process.pid + try: + process.stdin.write(prompt.encode()) + process.stdin.close() + while process.poll() is None: + if cancel_event.wait(.15): + raise PolicyCancelled("operator_pause_requested") + if time.monotonic() - started > TIMEOUT_S: + raise PolicyUnavailable("model_call_timeout") + if max((root / "events.jsonl").stat().st_size, (root / "stderr.log").stat().st_size) > MAX_TRACE_BYTES: + raise PolicyUnavailable("model_trace_exceeds_bound") + if cancel_event.is_set(): + raise PolicyCancelled("operator_pause_requested") + if process.returncode != 0: + raise PolicyUnavailable("codex_cli_exit_" + str(process.returncode)) + content = protocol.read_bytes(root / "result.json", maximum=MAX_RESULT_BYTES) + value = validate_action(protocol.decode(content)) + metadata["usage"] = usage_from_events(protocol.read_bytes(root / "events.jsonl", maximum=MAX_TRACE_BYTES)) + except (PolicyUnavailable, OSError, ValueError, TypeError, KeyError) as exc: + terminate(process) + metadata.update(outcome="cancelled" if isinstance(exc, PolicyCancelled) else "unavailable", + reason=str(exc) if isinstance(exc, PolicyUnavailable) else "invalid_or_unavailable_model_result") + if isinstance(exc, PolicyUnavailable): + raise + raise PolicyUnavailable("invalid_or_unavailable_model_result") from exc + finally: + terminate(process) + metadata.update(elapsed_s=time.monotonic() - started, process_exit_observed=process.poll() is not None, + exit_code=process.poll()) + protocol.persist(root / "outcome.json", metadata) + metadata["outcome"] = "decision" + protocol.persist(root / "outcome.json", metadata) + return value, metadata diff --git a/tools/physical-workcell/test_codex_policy.py b/tools/physical-workcell/test_codex_policy.py new file mode 100644 index 0000000..302b501 --- /dev/null +++ b/tools/physical-workcell/test_codex_policy.py @@ -0,0 +1,69 @@ +"""Policy conformance uses a labelled fake CLI; it is not live model evidence.""" + +import json +import sys +import tempfile +import threading +import unittest +from pathlib import Path +from unittest.mock import patch + +import codex_policy as policy +import operator_runtime + + +class PolicyTests(unittest.TestCase): + def test_closed_action_schema_finite_targets_and_no_success_flag(self): + valid = {"action": "move", "target_x": .01, "target_y": 0, "intent": "Push into the task region."} + self.assertEqual(policy.validate_action(valid), valid) + for changed in ({**valid, "target_x": True}, {**valid, "target_x": float("nan")}, + {**valid, "target_x": .5}, {**valid, "success": True}, + {**valid, "action": "measure"}, {**valid, "intent": ""}): + with self.subTest(changed=changed), self.assertRaises((policy.PolicyUnavailable, ValueError)): + policy.validate_action(changed) + + def test_usage_optional_and_any_tool_event_refuses(self): + self.assertIsNone(policy.usage_from_events(b'{}\nnull\n')) + usage = {"input_tokens": 20, "output_tokens": 10, "cached_input_tokens": 2} + self.assertEqual(policy.usage_from_events(json.dumps({"type": "turn.completed", "usage": usage}).encode()), usage) + for kind in ("command_execution", "file_change", "mcp_tool_call", "web_search", "tool_call", "plan", "image_view"): + with self.subTest(kind=kind), self.assertRaises(policy.PolicyUnavailable): + policy.usage_from_events(json.dumps({"type": "item.completed", "item": {"type": kind}}).encode()) + + def test_fake_cli_bound_image_schema_tool_isolation_and_reservation(self): + with tempfile.TemporaryDirectory(prefix="policy-test-", dir=policy.protocol.OUTPUT) as temp: + root = Path(temp) + operator_runtime.initialize(root / "operator") + target = policy.agent_bench.AgentBench(root / "operator/agent") + challenge = target.observe() + fake = root / "fake-cli" + fake.write_text("#!" + sys.executable + "\n" + '''import json,sys +from pathlib import Path +args=sys.argv[1:] +assert '--ignore-user-config' in args and '--ephemeral' in args +assert args[args.index('--sandbox')+1]=='read-only' +assert 'shell_tool' in args and 'tools.view_image=false' in args +assert 'web_search="disabled"' in args +png=Path(args[args.index('--image')+1]).read_bytes() +assert png.startswith(b'\\x89PNG') +prompt=sys.stdin.read() +assert 'block_center_xy' not in prompt and 'block_xyz' not in prompt +out=Path(args[args.index('--output-last-message')+1]) +out.write_text(json.dumps({'action':'stop','target_x':None,'target_y':None,'intent':'Labelled fake policy.'})) +print(json.dumps({'type':'turn.completed','usage':{'input_tokens':20,'output_tokens':10}})) +''') + fake.chmod(0o700) + call = root / "call" + call.mkdir(mode=0o700) + (call / "reservation.json").write_text("{}") + with patch.object(policy, "preflight", return_value={"available": True, "cli_version": policy.EXPECTED_CLI}), patch.object(policy.shutil, "which", return_value=str(fake)): + action, metadata = policy.decide(challenge, [{"block_center_xy": [1, 2], "block_xyz": [3, 4, 5]}], call, threading.Event()) + self.assertEqual(action["action"], "stop") + self.assertTrue(metadata["process_exit_observed"]) + self.assertEqual(metadata["usage"]["input_tokens"], 20) + with self.assertRaises(policy.PolicyUnavailable): + policy.decide(challenge, [], call, threading.Event()) + + +if __name__ == "__main__": + unittest.main() From 7867d963bf446c0bc9f0dca2afce0e46d32aa280 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 15:37:28 -0400 Subject: [PATCH 102/216] Distinguish known CLI diagnostics from policy tool execution --- .../docs/notebook/2026-10-11-bench-operator.md | 15 +++++++++++++++ tools/physical-workcell/codex_policy.py | 8 +++++++- tools/physical-workcell/test_codex_policy.py | 5 +++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/jevdual/docs/notebook/2026-10-11-bench-operator.md b/jevdual/docs/notebook/2026-10-11-bench-operator.md index 7d04366..98a0555 100644 --- a/jevdual/docs/notebook/2026-10-11-bench-operator.md +++ b/jevdual/docs/notebook/2026-10-11-bench-operator.md @@ -13,3 +13,18 @@ Test: commit the policy source, render a fresh native preparation image, invoke Predicts: a bounded completed model process returns a valid typed action and reported usage, with no tool events and no native state change. Against: configuration or authentication fails, tools are invoked, the model cannot accept the image/schema, output is invalid, or the probe dispatches a bench action. Refs: tools/physical-workcell/codex_policy.py; tools/physical-workcell/output/sim8-policy-smoke1/ + +## SIM8-CLI-U1 · update · 2026-10-11 15:36 +Resolves: SIM8-CLI = failed +Observed: the first committed-source probe exited 0 with a valid movement action but the adapter refused it as unexpected tool use. The emitted error items were two nonfatal startup diagnostics: disabled code-mode host and shortened skill descriptions. No tool call or native dispatch occurred; all raw output remains retained. +Inferred: the event classifier confused startup diagnostics with tool execution. This does not establish the complete accepted policy transport. +Next: retain this failure, allow only those exact diagnostic prefixes, keep arbitrary errors and actual tool items refused, rerun focused checks, commit the revised prediction and policy, then probe a fresh call before product qualification. +Refs: 3e6475e; tools/physical-workcell/output/sim8-policy-smoke1/model-call/outcome.json; tools/physical-workcell/test_codex_policy.py + +## SIM8-CLI-R · prediction · 2026-10-11 15:36 +Revises: SIM8-CLI +Hypothesis: separating the two known nonfatal startup diagnostics from tool events permits a valid bounded model action without admitting actual tool use or arbitrary provider errors. +Test: commit the corrected classifier and invoke one fresh no-dispatch decision, then check schema, usage, process exit and unchanged native generation. +Predicts: valid typed action accepted with reported usage, no actual tool items, process reaped and native generation zero; focused unknown-error/tool tests still refuse. +Against: actual tools or arbitrary errors are accepted, a normal action still fails, or the bench moves during the transport probe. +Refs: tools/physical-workcell/output/sim8-policy-smoke1/model-call-v2/; tools/physical-workcell/test_codex_policy.py diff --git a/tools/physical-workcell/codex_policy.py b/tools/physical-workcell/codex_policy.py index 431374a..16b268c 100644 --- a/tools/physical-workcell/codex_policy.py +++ b/tools/physical-workcell/codex_policy.py @@ -80,7 +80,13 @@ def usage_from_events(content): if not isinstance(event, dict): continue item = event.get("item", {}) - if isinstance(item, dict) and item.get("type") not in {None, "agent_message", "reasoning"}: + if isinstance(item, dict) and item.get("type") == "error": + message = item.get("message", "") + known = ("Code Mode is unavailable because code-mode host is disabled.", + "Skill descriptions were shortened to fit the skills context budget.") + if not isinstance(message, str) or not message.startswith(known): + raise PolicyUnavailable("codex_reported_error") + elif isinstance(item, dict) and item.get("type") not in {None, "agent_message", "reasoning"}: raise PolicyUnavailable("unexpected_model_tool_use") if event.get("type") == "turn.completed": data = event.get("usage", {}) diff --git a/tools/physical-workcell/test_codex_policy.py b/tools/physical-workcell/test_codex_policy.py index 302b501..c12a22d 100644 --- a/tools/physical-workcell/test_codex_policy.py +++ b/tools/physical-workcell/test_codex_policy.py @@ -26,6 +26,11 @@ def test_usage_optional_and_any_tool_event_refuses(self): self.assertIsNone(policy.usage_from_events(b'{}\nnull\n')) usage = {"input_tokens": 20, "output_tokens": 10, "cached_input_tokens": 2} self.assertEqual(policy.usage_from_events(json.dumps({"type": "turn.completed", "usage": usage}).encode()), usage) + for message in ("Code Mode is unavailable because code-mode host is disabled.", + "Skill descriptions were shortened to fit the skills context budget."): + self.assertIsNone(policy.usage_from_events(json.dumps({"type": "item.completed", "item": {"type": "error", "message": message}}).encode())) + with self.assertRaises(policy.PolicyUnavailable): + policy.usage_from_events(b'{"item":{"type":"error","message":"unknown failure"}}') for kind in ("command_execution", "file_change", "mcp_tool_call", "web_search", "tool_call", "plan", "image_view"): with self.subTest(kind=kind), self.assertRaises(policy.PolicyUnavailable): policy.usage_from_events(json.dumps({"type": "item.completed", "item": {"type": kind}}).encode()) From e7b716a8221db6b69c876dde030235f59d643460 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 15:45:34 -0400 Subject: [PATCH 103/216] Build local Footwork Bench product with bounded unattended visual AI --- .../notebook/2026-10-11-bench-operator.md | 13 + tools/physical-workcell/OPERATOR.md | 34 ++ tools/physical-workcell/README.md | 5 + tools/physical-workcell/bench_operator.html | 190 +++++++++ tools/physical-workcell/bench_operator.py | 148 +++++++ tools/physical-workcell/operator_runtime.py | 382 ++++++++++++++++++ tools/physical-workcell/score_operator.py | 120 ++++++ .../test_operator_runtime.py | 288 +++++++++++++ 8 files changed, 1180 insertions(+) create mode 100644 tools/physical-workcell/OPERATOR.md create mode 100644 tools/physical-workcell/bench_operator.html create mode 100644 tools/physical-workcell/bench_operator.py create mode 100644 tools/physical-workcell/operator_runtime.py create mode 100644 tools/physical-workcell/score_operator.py create mode 100644 tools/physical-workcell/test_operator_runtime.py diff --git a/jevdual/docs/notebook/2026-10-11-bench-operator.md b/jevdual/docs/notebook/2026-10-11-bench-operator.md index 98a0555..05f3624 100644 --- a/jevdual/docs/notebook/2026-10-11-bench-operator.md +++ b/jevdual/docs/notebook/2026-10-11-bench-operator.md @@ -28,3 +28,16 @@ Test: commit the corrected classifier and invoke one fresh no-dispatch decision, Predicts: valid typed action accepted with reported usage, no actual tool items, process reaped and native generation zero; focused unknown-error/tool tests still refuse. Against: actual tools or arbitrary errors are accepted, a normal action still fails, or the bench moves during the transport probe. Refs: tools/physical-workcell/output/sim8-policy-smoke1/model-call-v2/; tools/physical-workcell/test_codex_policy.py + +## SIM8-CLI-U2 · update · 2026-10-11 15:42 +Resolves: SIM8-CLI-R = held +Observed: the revised committed-source probe accepted a schema-valid movement decision from the exact PNG, reported token usage, and reaped the CLI process after 7.46 seconds. Native generation remained zero with no dispatch. Focused conformance still refuses unknown errors and tool items. +Inferred: the installed authenticated CLI supports the bounded decision transport; full unattended job completion remains untested. +Next: freeze the complete operator product after conformance and browser preview, then run the primary two-job qualification through its UI. +Refs: 7867d96; tools/physical-workcell/output/sim8-policy-smoke1/probe-v2.json; tools/physical-workcell/test_codex_policy.py + +## SIM8-CONFORMANCE · summary · 2026-10-11 15:44 +Established: 19 deterministic operator checks, 3 policy checks, 15 agent checks and 14 bench checks passed. The browser preview showed the idle camera, new-job form and pause/resume. Review corrected the pause/resume control version, source/image identity, completion readback and incomplete token reporting. Existing native guard source is unchanged. +Uncertain: fake policy conformance establishes no live AI job completion. The first complete frozen model/product attempt remains open. +Decision: commit the product and separate post-trial scorer, freeze their exact bytes, and drive the two-job qualification through the browser without chat-directed motion. +Refs: tools/physical-workcell/output/sim8-final-runtime-tests.log; tools/physical-workcell/output/sim8-final-policy-tests.log; tools/physical-workcell/output/sim8-final-agent-tests.log; tools/physical-workcell/output/sim8-final-bench-tests.log; tools/physical-workcell/output/sim8-empty-preview/ diff --git a/tools/physical-workcell/OPERATOR.md b/tools/physical-workcell/OPERATOR.md new file mode 100644 index 0000000..043fcd9 --- /dev/null +++ b/tools/physical-workcell/OPERATOR.md @@ -0,0 +1,34 @@ +# Footwork Bench + +Queue an inspection, watch the AI prepare the block from camera images, and get a saved optical measurement after placement is verified. The AI then returns the block and pusher home by contact so the next job can use the same bench. + +This is a local simulated product. The camera is a MuJoCo render and the actuator is a bounded XY pusher. Real cameras and robots are future adapters. + +## Start + +Run from the Footwork repository root with the existing pinned workcell environment and Codex CLI 0.147.0 signed in. Each new operator needs an empty private directory. No API key is provisioned. The policy uses saved CLI authentication as described in the [Codex non-interactive documentation](https://learn.chatgpt.com/docs/non-interactive-mode). + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/bench_operator.py init \ + --root tools/physical-workcell/output/my-bench +tools/physical-workcell/.venv/bin/python tools/physical-workcell/bench_operator.py serve \ + --root tools/physical-workcell/output/my-bench --port 8765 +``` + +Open the printed loopback URL. Select **New job**, name the inspection, choose a region and add it to the queue. **Test recovery** uses the far region and applies a bounded external force after the AI's first measurement decision is saved. The stale decision must be refused before the AI receives another image. + +The operator shows the most recent captured image, planning state, last intent, queued jobs, measurement and retained activity. The optical area is the orange image footprint multiplied by calibration; it is not a claim about the block's true surface area. Job completion requires the separately saved SQLite measurement and verified native contact reset. Reloading preserves jobs and results. + +**Pause** cancels a pending model process and withholds its reply. An already running native action may finish before the next boundary. **Resume** requires a known bench state. An uncertain physical outcome blocks further work. Stop the server with Ctrl-C; restart on its retained port and explicitly resume after inspecting unfinished state. + +The current limit is six jobs per operator, 32 model requests per job and 96 requests per operator lifetime. Reservations count even when a model call fails or is cancelled. Token totals include only reported usage and show when reporting is incomplete. Monetary cost is not measured. + +## Boundaries + +`bench_operator.html` provides the browser interface. `bench_operator.py` serves loopback HTTP. `operator_runtime.py` serializes queue ownership, model reservations and dispatch. `codex_policy.py` sends the exact PNG and bounded task history to an ephemeral Codex process with action tools disabled, then validates its structured response. Existing `agent_bench.py` and `bench.py` own image freshness, source identity, movement bounds, measurements, replay refusal and native verification. + +The model chooses each action. No coordinate planner runs beside it. Detector locations and native poses stay out of its input. Source changes invalidate the retained operator; create a new operator for changed source. Private call directories retain failures, model output and process outcomes, while committed reports contain derived evidence. + +This package lives beside the existing workcell experiments in Footwork. Python and browser JavaScript are sufficient here; native MuJoCo already performs the integration. A Rust hot path needs a measured bottleneck and a pure-Python equivalence test before adoption. + +The prototype does not establish hardware transfer, unattended physical safety, broad model reliability or customer demand. Preregistered qualification: [SIM8](../../jevdual/docs/experiments/SIM8-bench-operator.md). diff --git a/tools/physical-workcell/README.md b/tools/physical-workcell/README.md index 6369d85..8cd6475 100644 --- a/tools/physical-workcell/README.md +++ b/tools/physical-workcell/README.md @@ -31,6 +31,11 @@ The [reusable bench](BENCH.md) keeps one simulated body across successive jobs: preparation, a separately executed computer measurement, contact-driven reset, and recovery from a bounded unexpected block displacement. +The [Footwork Bench operator](OPERATOR.md) adds a local browser product: queue jobs, +watch an independently running visual AI prepare and reset the bench, inspect saved +measurements, and pause at action boundaries. It uses the installed authenticated Codex +CLI for decisions and preserves the existing simulated effect guards. + ## One work order The package uses pinned `mujoco==3.15.0` in its own ignored `.venv`. The existing Footwork diff --git a/tools/physical-workcell/bench_operator.html b/tools/physical-workcell/bench_operator.html new file mode 100644 index 0000000..77e93dc --- /dev/null +++ b/tools/physical-workcell/bench_operator.html @@ -0,0 +1,190 @@ + + + + + +Footwork · Bench + + + +

+

New inspection

Place the part, measure its footprint, then reset the bench.

Measurement area

Move the block unexpectedly before measurement. The agent must observe it again and correct its placement.

+ + + diff --git a/tools/physical-workcell/bench_operator.py b/tools/physical-workcell/bench_operator.py new file mode 100644 index 0000000..71aa8d5 --- /dev/null +++ b/tools/physical-workcell/bench_operator.py @@ -0,0 +1,148 @@ +"""Loopback browser product for the guarded simulated bench operator.""" +import argparse +import json +import signal +import threading +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from pathlib import Path +from urllib.parse import urlsplit + +import operator_runtime as runtime +import order_protocol as protocol + +BASE = Path(__file__).resolve().parent + + +class Server(ThreadingHTTPServer): + daemon_threads = True + allow_reuse_address = True + + def __init__(self, address, operator): + super().__init__(address, Handler) + self.operator = operator + self.origin = f"http://127.0.0.1:{self.server_address[1]}" + self.host = f"127.0.0.1:{self.server_address[1]}" + + +class Handler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + + def log_message(self, *_): + pass + + def reply(self, code, body, content_type="application/json"): + if isinstance(body, dict): + body = json.dumps(body, allow_nan=False).encode() + self.send_response(code) + self.send_header("Content-Type", content_type) + self.send_header("Content-Length", str(len(body))) + self.send_header("Cache-Control", "no-store") + self.send_header("X-Content-Type-Options", "nosniff") + self.send_header("Referrer-Policy", "no-referrer") + self.send_header("Connection", "close") + self.end_headers() + self.wfile.write(body) + self.close_connection = True + + def exact_header(self, name, value): + return self.headers.get_all(name) == [value] + + def do_GET(self): + try: + if not self.exact_header("Host", self.server.host): + raise protocol.Refusal("exact loopback Host is required") + parsed = urlsplit(self.path) + if parsed.path == "/" and not parsed.query: + self.server.operator._identity() + self.reply(200, protocol.read_bytes(BASE / "bench_operator.html"), "text/html; charset=utf-8") + elif parsed.path == "/api/state" and not parsed.query: + self.reply(200, self.server.operator.state()) + elif parsed.path == "/api/frame": + self.reply(200, self.server.operator.frame(self.path), "image/png") + else: + self.reply(404, {"error": "Unknown operator route"}) + except (protocol.Refusal, OSError, ValueError) as exc: + self.reply(409, {"error": str(exc)}) + + def do_POST(self): + try: + app_id = self.server.operator.m["app_id"] + if (not self.exact_header("Host", self.server.host) or + not self.exact_header("Origin", self.server.origin) or + not self.exact_header("X-Footwork-App-ID", app_id)): + raise protocol.Refusal("exact loopback origin and application identity are required before mutation") + lengths = self.headers.get_all("Content-Length") + if (lengths is None or len(lengths) != 1 or not lengths[0].isascii() or + not lengths[0].isdigit() or not 1 <= int(lengths[0]) <= 4096 or + self.headers.get_all("Transfer-Encoding") is not None or + not self.exact_header("Content-Type", "application/json")): + raise protocol.Refusal("request requires one bounded JSON body with an exact content length") + self.connection.settimeout(5) + content = self.rfile.read(int(lengths[0])) + if len(content) != int(lengths[0]): + raise protocol.Refusal("JSON body is incomplete") + request = protocol.decode(content) + if self.path == "/api/jobs": + result = self.server.operator.enqueue(request) + elif self.path in ("/api/pause", "/api/resume"): + protocol.fields(request, (), "operator control") + result = getattr(self.server.operator, self.path.rsplit("/", 1)[1])() + else: + raise protocol.Refusal("unknown operator mutation route") + self.reply(200, result) + except (protocol.Refusal, OSError, TypeError, ValueError) as exc: + self.reply(409, {"error": str(exc)}) + + +def serve(root, port, policy): + root = protocol.directory(root) + operator = runtime.Operator(root, policy) + server = None + try: + server = Server(("127.0.0.1", port), operator) + readiness = root / "readiness.json" + if readiness.exists(): + previous = protocol.decode(protocol.read_bytes(readiness)) + if previous["app_id"] != operator.m["app_id"] or previous["origin"] != server.origin: + raise protocol.Refusal("retained application origin changed; restart on its exact port") + protocol.persist(readiness, {"app_id": operator.m["app_id"], "origin": server.origin, + "port": server.server_address[1], "simulation": True}) + print(json.dumps(protocol.decode(protocol.read_bytes(readiness))), flush=True) + def stop(*_): + operator.cancel.set() + threading.Thread(target=server.shutdown, daemon=True).start() + signal.signal(signal.SIGTERM, stop) + signal.signal(signal.SIGINT, stop) + server.serve_forever(poll_interval=.2) + finally: + if server: + server.server_close() + operator.close() + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + commands = parser.add_subparsers(dest="command", required=True) + init = commands.add_parser("init") + init.add_argument("--root", type=Path, required=True) + run = commands.add_parser("serve") + run.add_argument("--root", type=Path, required=True) + run.add_argument("--port", type=int, default=0) + run.add_argument("--backend", choices=("codex",), default="codex") + args = parser.parse_args() + try: + if args.command == "init": + print(json.dumps({"app_id": runtime.initialize(args.root), "simulation": True})) + else: + if not 0 <= args.port <= 65535: + raise protocol.Refusal("port must be in the TCP range") + from codex_policy import decide + serve(args.root, args.port, decide) + return 0 + except (protocol.Refusal, OSError, ValueError) as exc: + print(json.dumps({"error": str(exc)})) + return 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/physical-workcell/operator_runtime.py b/tools/physical-workcell/operator_runtime.py new file mode 100644 index 0000000..295ed6e --- /dev/null +++ b/tools/physical-workcell/operator_runtime.py @@ -0,0 +1,382 @@ +"""Serialized, durable model host for a local simulated bench operator.""" +import copy +import threading +import time +import uuid +from pathlib import Path + +import agent_bench as agent +import bench +import measurement +import order_protocol as protocol + +BASE = Path(__file__).resolve().parent +MAX_CALLS = 32 +MAX_TOTAL_CALLS = 96 +ZONES = {"A": {"x_min": .035, "x_max": .105, "y_min": -.025, "y_max": .025}, + "B": {"x_min": .045, "x_max": .115, "y_min": -.025, "y_max": .025}} + + +def sources(): + return {**agent.sources(), **{name: protocol.sha(protocol.read_bytes(BASE / name)) + for name in ("operator_runtime.py", "bench_operator.py", "codex_policy.py", "bench_operator.html", + "codex-policy.md", "codex-action.schema.json")}} + + +def initialize(root): + root = protocol.directory(root, create=True) + with protocol.locked(root): + if any(p.name != "app.lock" for p in root.iterdir()): + raise protocol.Refusal("operator initialization requires a new empty directory") + source = sources() + status = bench.initialize(root / "bench", diagnostic_enabled=True) + agent.initialize(root / "agent", root / "bench") + (root / "calls").mkdir(mode=0o700) + manifest = {"version": 1, "app_id": uuid.uuid4().hex, "bench_id": status["bench_id"], + "source_fingerprints": source, "opened": False, "runner_status": "running", + "active_job_id": None, "jobs": [], "activity": [], "sequence": 0, + "frame": None, "usage": {"calls": 0, "input_tokens": 0, "output_tokens": 0, "reported_calls": 0}, + "reason": "Ready for a simulated job"} + protocol.create_file(root / "identity.json", protocol.encoded( + {"app_id": manifest["app_id"], "bench_id": manifest["bench_id"], "source_fingerprints": source})) + protocol.persist(root / "operator.json", manifest) + return manifest["app_id"] + + +def validate_job(value): + protocol.fields(value, ("job_id", "label", "target", "disturbance_test"), "job") + protocol.identity(value["job_id"]) + if (not isinstance(value["label"], str) or not 1 <= len(value["label"].strip()) <= 120 or + value["target"] not in ZONES or type(value["disturbance_test"]) is not bool): + raise protocol.Refusal("job needs a short label, target A or B, and a boolean disturbance flag") + if value["disturbance_test"] and value["target"] != "B": + raise protocol.Refusal("the disturbance trial is limited to target B") + + +class Operator: + def __init__(self, root, policy, *, start_worker=True): + self.root = protocol.directory(root) + self.lock = threading.RLock() + self.wake = threading.Event() + self.cancel = threading.Event() + self.closing = False + self.in_model = False + self.control_epoch = 0 + self.saved_digest = None + self.policy = policy + self.owner = protocol.locked(self.root) + self.owner.__enter__() + try: + self.m = protocol.decode(protocol.read_bytes(self.root / "operator.json")) + self._identity() + self.body = bench.Bench(self.root / "bench") + self.agent = agent.AgentBench(self.root / "agent") + health_error = None + try: + self._healthy() + except Exception as exc: # noqa: BLE001 - preserve unknown startup evidence. + health_error = str(exc) + if self.m["opened"]: + self.m["runner_status"] = "paused" + self.m["reason"] = "Restarted; inspect retained state and explicitly resume" + for job in self.m["jobs"]: + if job["status"] == "running": + job["status"] = "paused" + job["error"] = "Restarted during an unfinished job; no action replayed" + if health_error: + self.m.update(runner_status="blocked", reason=health_error) + for job in self.m["jobs"]: + if job["id"] == self.m["active_job_id"]: + job.update(status="unknown", error=health_error) + self.m["opened"] = True + if self.m["frame"] is None and not health_error: + self._cache(self.agent.observe()) + self._save() + self.worker = threading.Thread(target=self._loop, name="bench-operator", daemon=True) + if start_worker: + self.worker.start() + self.wake.set() + except Exception: + self.owner.__exit__(None, None, None) + raise + + def _identity(self): + if self.saved_digest and protocol.sha(protocol.read_bytes(self.root / "operator.json")) != self.saved_digest: + raise protocol.Refusal("retained operator state changed outside its owner") + identity = protocol.decode(protocol.read_bytes(self.root / "identity.json")) + if identity != {key: self.m[key] for key in ("app_id", "bench_id", "source_fingerprints")}: + raise protocol.Refusal("persistent operator identity changed") + protocol.fields(self.m, ("version", "app_id", "bench_id", "source_fingerprints", "opened", + "runner_status", "active_job_id", "jobs", "activity", "sequence", "frame", "usage", "reason"), "operator manifest") + if (type(self.m["version"]) is not int or self.m["version"] != 1 or + not isinstance(self.m["app_id"], str) or not protocol.UUID.fullmatch(self.m["app_id"]) or + self.m["source_fingerprints"] != sources()): + raise protocol.Refusal("operator identity or measured source changed") + if not isinstance(self.m["jobs"], list) or len(self.m["jobs"]) > 6: + raise protocol.Refusal("operator job budget exceeded") + + def _healthy(self, allow_completed=False): + self._identity() + state = self.agent.status() + if state["bench_id"] != self.m["bench_id"] or state["bench"]["state"] != "ready" or state["unresolved_proposals"]: + raise protocol.Refusal("native or agent outcome is unknown; operator intervention required") + active = state["bench"]["active_job"] + expected = self.m["active_job_id"] + if ((active is not None and active["job_id"] != expected) or + (expected is not None and active is None and + (not allow_completed or expected not in state["bench"]["jobs"]))): + raise protocol.Refusal("active physical job differs from the operator job") + for job in self.m["jobs"]: + if job["status"] == "completed": + completed = state["bench"]["jobs"].get(job["id"]) + if (not completed or completed["phase"] != "completed" or + completed["reset_receipt"].get("block_home_verified") is not True or + completed["reset_receipt"].get("pusher_home_verified") is not True or + job["measurement"] != agent.public_response(completed["measurement_receipt"]["measurement"])): + raise protocol.Refusal("displayed completion lacks retained native and computer proof") + return state["bench"] + + def _save(self): + protocol.persist(self.root / "operator.json", self.m) + self.saved_digest = protocol.sha(protocol.encoded(self.m)) + + def _event(self, kind, intent="", outcome=""): + self.m["sequence"] += 1 + value = {"seq": self.m["sequence"], "time": time.time(), "kind": kind, + "intent": str(intent)[:2000], "outcome": str(outcome)[:1000]} + protocol.create_file(self.root / "calls" / f"event-{value['seq']:06d}.json", protocol.encoded(value)) + self.m["activity"] = (self.m["activity"] + [value])[-24:] + self._save() + + def _cache(self, challenge): + packet = challenge["observation"] + path = Path(challenge["image_path"]) + if path.parent != self.root / "bench" / "images": + raise protocol.Refusal("camera frame is not bench-owned") + if protocol.sha(protocol.read_bytes(path, maximum=8 * 1024 * 1024)) != packet["image_sha256"]: + raise protocol.Refusal("camera frame bytes changed") + self.m["frame"] = {"path": str(path), "sha256": packet["image_sha256"], "generation": packet["generation"]} + + def state(self): + with self.lock: + self._identity() + try: + self._healthy() + except Exception as exc: # noqa: BLE001 - report changed native evidence as blocked. + if self.m["runner_status"] != "blocked": + self._halt(str(exc), "blocked") + frame = self.m["frame"] + jobs = [{("job_id" if key == "id" else key): value for key, value in job.items() + if key not in {"history", "disturbed"}} for job in self.m["jobs"]] + return copy.deepcopy({"app_id": self.m["app_id"], "simulation": True, + "runner_status": self.m["runner_status"], "jobs": jobs, + "model_request_pending": self.in_model, + "active_job_id": self.m["active_job_id"], "activity": self.m["activity"], + "usage": {**self.m["usage"], "token_usage_complete": self.m["usage"]["reported_calls"] == self.m["usage"]["calls"]}, "readiness": {"ready": self.m["runner_status"] == "running", "reason": self.m["reason"]}, + "current_frame": {"generation": frame["generation"] if frame else None, + "image_url": f"/api/frame?generation={frame['generation']}&sha256={frame['sha256']}" if frame else None, + "available": frame is not None}}) + + def frame(self, requested_url=None): + with self.lock: + self._identity() + frame = self.m["frame"] + if not frame or Path(frame["path"]).parent != self.root / "bench" / "images": + raise protocol.Refusal("no owned camera frame") + expected_url = f"/api/frame?generation={frame['generation']}&sha256={frame['sha256']}" + if requested_url is not None and requested_url != expected_url: + raise protocol.Refusal("requested capture is no longer the current cached image") + data = protocol.read_bytes(Path(frame["path"]), maximum=8 * 1024 * 1024) + if protocol.sha(data) != frame["sha256"]: + raise protocol.Refusal("cached camera frame changed") + return data + + def enqueue(self, request): + validate_job(request) + with self.lock: + self._identity() + if self.closing or len(self.m["jobs"]) >= 6 or any(j["id"] == request["job_id"] for j in self.m["jobs"]): + raise protocol.Refusal("job identity reused or operator queue budget exhausted") + self.m["jobs"].append({"id": request["job_id"], "label": request["label"].strip(), + "target": request["target"], "disturbance_test": request["disturbance_test"], + "disturbed": False, "status": "queued", "phase": None, "call_count": 0, + "last_intent": "", "measurement": None, "error": None, "history": []}) + self._event("queued", request["label"], request["job_id"]) + self.wake.set() + return self.state() + + def pause(self): + # Set immediately, even if a native action currently owns the action-boundary lock. + self.cancel.set() + with self.lock: + self.control_epoch += 1 + if self.m["runner_status"] != "blocked": + self.m["runner_status"] = "pausing" if self.in_model else "paused" + self.m["reason"] = "Paused; an in-flight native action may finish before the next boundary" + for job in self.m["jobs"]: + if job["id"] == self.m["active_job_id"] and job["status"] == "running": + job["status"] = "paused" + self._event("pause", outcome=self.m["reason"]) + return self.state() + + def resume(self): + with self.lock: + if self.closing or self.cancel.is_set() and self.in_model: + raise protocol.Refusal("wait for the cancelled model call to exit before resuming") + try: + self._healthy() + except Exception as exc: + self.m.update(runner_status="blocked", reason=str(exc)) + self._save() + raise + self.cancel.clear() + self.m.update(runner_status="running", reason="Ready for the next action boundary") + self._event("resume") + self.wake.set() + return self.state() + + def close(self): + self.cancel.set() + with self.lock: + self.control_epoch += 1 + self.closing = True + self.m.update(runner_status="pausing", reason="Stopping; waiting for the owned worker to exit") + self._save() + self.wake.set() + if self.worker.is_alive(): + self.worker.join(timeout=35) + if self.worker.is_alive(): + raise protocol.Refusal("owned worker has not exited; ownership lock retained") + with self.lock: + self.m.update(runner_status="stopped", reason="Operator stopped; retained bench has not been reset") + self._save() + self.owner.__exit__(None, None, None) + + def _loop(self): + while not self.closing: + self.wake.wait(.5) + self.wake.clear() + while not self.closing: + with self.lock: + if self.m["runner_status"] != "running" or self.cancel.is_set(): + break + try: + if not self._step(): + break + except Exception as exc: # noqa: BLE001 - retain model and native failures. + with self.lock: + if self.closing: + self._event("shutdown_model_exit", outcome=str(exc)) + break + try: + self._healthy() + state = "paused" + except Exception: # noqa: BLE001 - uncertainty cannot authorize resume. + state = "blocked" + self._halt(str(exc), state) + + def _halt(self, reason, state="paused"): + self.m.update(runner_status=state, reason=str(reason)) + job = next((j for j in self.m["jobs"] if j["id"] == self.m["active_job_id"]), None) + if state == "blocked": + for previous in self.m["jobs"]: + if previous["status"] == "completed": + previous.update(status="unknown", error="Retained completion evidence could not be validated") + if job: + job.update(status="unknown" if state == "blocked" else "paused", error=str(reason)) + self._event("halt", outcome=reason) + + def _step(self): + with self.lock: + self._healthy() + if self.m["usage"]["calls"] >= MAX_TOTAL_CALLS: + self._halt("Operator lifetime model-call budget exhausted") + return False + job = next((j for j in self.m["jobs"] if j["id"] == self.m["active_job_id"]), None) + if job is None: + job = next((j for j in self.m["jobs"] if j["status"] == "queued"), None) + if job is None: + return False + # Durable start intention precedes changing the native bench. + self.m["active_job_id"] = job["id"] + job["status"] = "running" + self._event("start_intent", job["label"], job["id"]) + self.body.start_job(job["id"], ZONES[job["target"]]) + if job["call_count"] >= MAX_CALLS: + self._halt("Model call budget exhausted") + return False + challenge = agent.public_response(self.agent.observe()) + self._cache(challenge) + job.update(status="running", phase=challenge["observation"]["phase"], error=None) + job["call_count"] += 1 + self.m["usage"]["calls"] += 1 + call_dir = self.root / "calls" / f"{job['id']}-{job['call_count']:02d}" + call_dir.mkdir(mode=0o700) + protocol.create_file(call_dir / "reservation.json", protocol.encoded({"job_id": job["id"], + "call": job["call_count"], "challenge": challenge, "history": job["history"][-6:]})) + self._event("inference", job["label"], f"Model call {job['call_count']} reserved") + self.in_model = True + call_epoch = self.control_epoch + try: + action, metadata = self.policy(challenge, copy.deepcopy(job["history"][-6:]), call_dir, self.cancel) + protocol.create_file(call_dir / "decision.json", protocol.encoded({"action": action, "metadata": metadata})) + finally: + with self.lock: + self.in_model = False + with self.lock: + usage = metadata.get("usage") + if isinstance(usage, dict) and all(type(usage.get(key)) is int and usage[key] >= 0 for key in ("input_tokens", "output_tokens")): + self.m["usage"]["reported_calls"] += 1 + for key in ("input_tokens", "output_tokens"): + tokens = (metadata.get("usage") or {}).get(key, 0) + if type(tokens) is int and tokens >= 0: + self.m["usage"][key] += tokens + if (call_epoch != self.control_epoch or self.cancel.is_set() or + self.m["runner_status"] != "running" or self.closing): + if self.m["runner_status"] == "pausing": + self.m["runner_status"] = "paused" + self._event("decision_withheld", outcome="Paused model reply was not dispatched") + return False + self._healthy() + protocol.fields(action, ("action", "target_x", "target_y", "intent"), "model action") + job["last_intent"] = action["intent"] + if action["action"] == "stop": + self._halt(action["intent"]) + return False + proposal = self.agent.propose(challenge["challenge_id"], action["action"], action["intent"], + action["target_x"], action["target_y"]) + protocol.create_file(call_dir / "proposal.json", protocol.encoded(proposal)) + if job["disturbance_test"] and not job["disturbed"] and action["action"] == "measure": + job["disturbed"] = True + self._event("disturbance_intent", outcome="Bounded external-force test before saved proposal dispatch") + self.body.disturb("disturb-" + uuid.uuid4().hex, -1.5, 80) + result = agent.public_response(self.agent.dispatch(proposal["proposal_id"])) + protocol.create_file(call_dir / "dispatch.json", protocol.encoded(result)) + job["history"].append({"action": action, "outcome": result["outcome"], "reason": result.get("reason", "")}) + job["history"] = job["history"][-6:] + self._event("dispatch", action["intent"], result["outcome"] + ": " + result.get("reason", action["action"])) + if result["outcome"] == "unknown" or result.get("next_observation") is None: + self._halt(result.get("reason", "Unknown outcome or observation unavailable"), "blocked") + return False + self._cache(result["next_observation"]) + status = self._healthy(allow_completed=action["action"] == "finish_reset" and result["outcome"] == "executed") + active = status["active_job"] + if active: + job["phase"] = active["phase"] + if "measurement_receipt" in active: + job["measurement"] = agent.public_response(active["measurement_receipt"]["measurement"]) + if action["action"] == "finish_reset" and result["outcome"] == "executed": + completed = status["jobs"].get(job["id"]) + receipt = result.get("receipt", {}) + if (not completed or completed["phase"] != "completed" or active is not None or + receipt != completed["reset_receipt"] or receipt.get("job_id") != job["id"] or + receipt.get("block_home_verified") is not True or receipt.get("pusher_home_verified") is not True): + raise protocol.Refusal("completion is missing independent bench reset evidence") + saved = measurement.read_result(self.root / "bench", completed["measurement_operation_id"]) + if saved != completed["measurement_receipt"]: + raise protocol.Refusal("completion is missing the durable computer measurement") + job.update(status="completed", phase="completed", measurement=agent.public_response(saved["measurement"]), error=None) + self.m["active_job_id"] = None + self._event("completed", job["label"], "Saved measurement and contact reset verified") + self._save() + return True diff --git a/tools/physical-workcell/score_operator.py b/tools/physical-workcell/score_operator.py new file mode 100644 index 0000000..95b4f58 --- /dev/null +++ b/tools/physical-workcell/score_operator.py @@ -0,0 +1,120 @@ +"""Post-trial native, SQLite and model-boundary scorer; never guides the policy.""" +import argparse +import json +import subprocess +from pathlib import Path + +import agent_bench +import bench +import operator_runtime as runtime +import order_protocol as protocol +import qualify_bench + +BASE = Path(__file__).resolve().parent +REPO = BASE.parents[1] +NAMES = ("bench_operator.py", "bench_operator.html", "operator_runtime.py", "codex_policy.py", + "codex-policy.md", "codex-action.schema.json", "agent_bench.py", "bench.py", "measurement.py", + "workcell.py", "image_guided.py", "episode_cases.py", "order_protocol.py", "scene.xml", + "qualify_bench.py", "score_operator.py") + + +def freeze(root, commit): + if subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=REPO, text=True).strip() != commit: + raise protocol.Refusal("qualification must start at the named source commit") + files = {} + for path in [*(BASE / name for name in NAMES), BASE.parent / "camera-capture-experiment" / "capture.py"]: + relative = str(path.relative_to(REPO)) + content = protocol.read_bytes(path) + if subprocess.check_output(["git", "show", f"{commit}:{relative}"], cwd=REPO) != content: + raise protocol.Refusal("measured source differs from its frozen commit") + files[relative] = protocol.sha(content) + runtime.initialize(root) + root = protocol.directory(root) + protocol.create_file(root / "source-freeze.json", protocol.encoded({"commit": commit, "files": files})) + protocol.create_file(root / "initial.json", protocol.encoded(bench.Bench(root / "bench").status())) + return {"source_commit": commit, "root": str(root)} + + +def private_fields(value): + if isinstance(value, dict): + return bool(agent_bench.DERIVED_LOCATION_FIELDS.intersection(value)) or any(private_fields(v) for v in value.values()) + return isinstance(value, list) and any(private_fields(v) for v in value) + + +def score(root): + root = protocol.directory(root) + read = lambda path: protocol.decode(protocol.read_bytes(path)) + frozen, initial = read(root / "source-freeze.json"), read(root / "initial.json") + unchanged = all(protocol.sha(protocol.read_bytes(REPO / name)) == digest for name, digest in frozen["files"].items()) + operator = read(root / "operator.json") + status = bench.Bench(root / "bench").status() + database = qualify_bench.sqlite_score(root / "bench") + scores, calls = [], [] + previous_generation, previous_time = initial["generation"], initial["native_time_s"] + for item in operator["jobs"]: + job = status["jobs"].get(item["id"]) + if not job or job["phase"] != "completed": + scores.append({"job_id": item["id"], "passed": False, "reason": "cycle not completed"}) + continue + measurement, reset = job["measurement_receipt"], job["reset_receipt"] + stage = qualify_bench.native_score(root / "bench", measurement["generation"], measurement["state_sha256"], job["target_zone"]) + home = qualify_bench.native_score(root / "bench", reset["generation"], reset["state_sha256"], bench.HOME_ZONE) + rows = [row for row in database["rows"] if row["job_id"] == item["id"]] + passed = bool(item["status"] == "completed" and len(rows) == 1 and rows[0]["receipt"] == measurement and + item["measurement"] == agent_bench.public_response(measurement["measurement"]) and + stage["block_center_in_zone"] and home["block_center_in_zone"] and home["pusher_home"] and + stage["external_force_cleared"] and home["external_force_cleared"] and + reset["reset_contact_samples"] > 0 and reset["reset_native_steps"] > 0 and + reset["bench_id"] == measurement["bench_id"] == initial["bench_id"] == status["bench_id"] and + job["started_generation"] == previous_generation and job["started_native_time_s"] == previous_time) + scores.append({"job_id": item["id"], "label": item["label"], "passed": passed, + "measurement_state": stage, "reset_state": home, "measurement": measurement, + "reset": reset, "motion_count": job["moves"], "model_calls": item["call_count"]}) + previous_generation, previous_time = job["completed_generation"], job["completed_native_time_s"] + for directory in sorted(p for p in (root / "calls").iterdir() if p.is_dir()): + reservation = read(directory / "reservation.json") + record = {"job_id": reservation["job_id"], "call": reservation["call"], "call_dir": str(directory), + "image_sha256": reservation["challenge"]["observation"]["image_sha256"], + "input_has_no_private_pose": not private_fields(reservation)} + if (directory / "outcome.json").exists(): + record["process"] = read(directory / "outcome.json") + if (directory / "input.png").exists(): + record["exact_image"] = protocol.sha(protocol.read_bytes(directory / "input.png")) == record["image_sha256"] + prompt = protocol.read_bytes(directory / "prompt.txt").decode().split("\n", 1)[1] + record["input_has_no_private_pose"] &= not private_fields(json.loads(prompt)) + if (directory / "decision.json").exists(): + record["decision"] = read(directory / "decision.json")["action"] + if (directory / "dispatch.json").exists(): + dispatch = read(directory / "dispatch.json") + record.update(outcome=dispatch["outcome"], reason=dispatch.get("reason", "")) + calls.append(record) + disturbance_job = next((j["id"] for j in operator["jobs"] if j["disturbance_test"]), None) + stale = next((c for c in calls if c["job_id"] == disturbance_job and c.get("outcome") == "refused" and + c.get("decision", {}).get("action") == "measure"), None) + recovery = bool(stale and any(c["job_id"] == disturbance_job and c["call"] > stale["call"] and + c.get("outcome") == "executed" and c.get("decision", {}).get("action") == "move" for c in calls)) + model_boundaries = bool(calls and all(c.get("exact_image") and c["input_has_no_private_pose"] and + c.get("process", {}).get("process_exit_observed") for c in calls)) + passed = bool(unchanged and len(scores) == database["count"] == 2 and all(s["passed"] for s in scores) and + status["state"] == "ready" and status["active_job"] is None and recovery and model_boundaries) + result = {"version": 1, "attempt": 1, "passed": passed, "source_commit": frozen["commit"], + "source_unchanged": unchanged, "bench_id": status["bench_id"], "completed_cycles": sum(s["passed"] for s in scores), + "stale_measure_refused": stale is not None, "fresh_model_move_after_refusal": recovery, + "model_boundaries_passed": model_boundaries, "scores": scores, "sqlite": database, "calls": calls, + "usage": operator["usage"], "current_status": status, + "scope": "separate post-trial native/SQLite and retained model-boundary scoring; browser evidence recorded separately"} + protocol.create_file(root / "qualification-score.json", protocol.encoded(result)) + return {k: result[k] for k in ("passed", "completed_cycles", "source_unchanged", "stale_measure_refused", "fresh_model_move_after_refusal")} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("command", choices=("freeze", "score")) + parser.add_argument("--root", type=Path, required=True) + parser.add_argument("--source-commit") + args = parser.parse_args() + print(json.dumps(freeze(args.root, args.source_commit) if args.command == "freeze" else score(args.root), sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/test_operator_runtime.py b/tools/physical-workcell/test_operator_runtime.py new file mode 100644 index 0000000..4c7fa91 --- /dev/null +++ b/tools/physical-workcell/test_operator_runtime.py @@ -0,0 +1,288 @@ +"""Labelled deterministic conformance; fake decisions are not AI-control evidence.""" +import json +import threading +import time +import unittest +import uuid +from http.client import HTTPConnection +from unittest import mock + +import bench_operator +import operator_runtime as runtime +import order_protocol as protocol + + +def action(name="stop", x=None, y=None): + return {"action": name, "target_x": x, "target_y": y, "intent": "Deterministic conformance fixture"} + + +class OperatorTests(unittest.TestCase): + def setUp(self): + self.root = runtime.BASE / "output" / ("operator-test-" + uuid.uuid4().hex[:10]) + self.patcher = mock.patch.object(runtime, "sources", return_value={"diagnostic_source": "frozen"}) + self.patcher.start() + runtime.initialize(self.root) + self.operator = None + self.server = None + self.thread = None + + def tearDown(self): + if self.server: + self.server.shutdown() + self.server.server_close() + self.thread.join(5) + if self.operator: + self.operator.close() + result = self._outcome.result + failed = any(test is self for test, _ in (*result.failures, *result.errors)) + protocol.create_file(self.root / "conformance.json", protocol.encoded( + {"test_id": self.id(), "passed": not failed, "policy": "explicitly_fake_diagnostic", + "state": protocol.decode(protocol.read_bytes(self.root / "operator.json"))})) + self.patcher.stop() + + def open(self, policy=None, worker=False): + self.operator = runtime.Operator(self.root, policy or (lambda *_: (action(), {})), start_worker=worker) + return self.operator + + def job(self, name="one", **changes): + return {"job_id": name, "label": "Diagnostic job", "target": "A", "disturbance_test": False, **changes} + + def wait(self, predicate): + until = time.monotonic() + 15 + while not predicate() and time.monotonic() < until: + time.sleep(.02) + self.assertTrue(predicate()) + + def test_new_identity_bound_to_separate_persistent_bench(self): + op = self.open() + self.assertNotEqual(op.m["app_id"], op.body.status()["bench_id"]) + self.assertEqual(op.state()["current_frame"]["generation"], 0) + self.assertEqual(op.body.status()["generation"], 0) + self.assertTrue(op.frame().startswith(b"\x89PNG")) + + def test_get_state_and_frame_do_not_capture_or_call_model(self): + op = self.open(lambda *_: self.fail("GET invoked model")) + before = op.agent.status()["sequence"] + for _ in range(3): + op.state() + op.frame() + self.assertEqual(op.agent.status()["sequence"], before) + + def test_queue_validation_duplicate_and_path_schema(self): + op = self.open() + for value in (self.job("../bad"), self.job(target="C"), self.job(disturbance_test=1), + self.job(command="rm"), self.job(label=""), self.job(disturbance_test=True)): + with self.assertRaises((protocol.Refusal, TypeError)): + op.enqueue(value) + op.enqueue(self.job()) + with self.assertRaises(protocol.Refusal): + op.enqueue(self.job()) + self.assertEqual(len(op.state()["jobs"]), 1) + + def test_stop_decision_pauses_without_completion(self): + op = self.open(worker=True) + op.enqueue(self.job()) + self.wait(lambda: op.state()["runner_status"] == "paused") + self.assertEqual(op.state()["jobs"][0]["status"], "paused") + self.assertEqual(op.body.status()["generation"], 0) + self.assertFalse((self.root / "bench" / "measurements.sqlite").exists()) + + def test_pause_during_model_prevents_late_reply_dispatch(self): + entered, release = threading.Event(), threading.Event() + def policy(*_): + entered.set() + release.wait(5) + return action("move", -.25, 0), {"usage": {"input_tokens": 7, "output_tokens": 3}} + op = self.open(policy, worker=True) + op.enqueue(self.job()) + self.assertTrue(entered.wait(10)) + op.pause() + with self.assertRaises(protocol.Refusal): + op.resume() + release.set() + self.wait(lambda: not op.in_model) + self.wait(lambda: any(e["kind"] == "decision_withheld" for e in op.m["activity"])) + self.assertEqual(op.body.status()["generation"], 0) + self.assertEqual(op.state()["usage"]["calls"], 1) + self.assertEqual(op.state()["usage"]["input_tokens"], 7) + self.assertEqual(len(list((self.root / "agent" / "proposals").glob("*.json"))), 0) + + def test_cancelled_reply_stays_withheld_after_event_clears(self): + # Simulate the narrow interval after owned process exit but before old reply dispatch. + op = self.open() + def policy(*_): + op.pause() + op.in_model = False + op.resume() + return action("move", -.25, 0), {} + op.policy = policy + op.enqueue(self.job()) + self.assertFalse(op._step()) + self.assertEqual(op.body.status()["generation"], 0) + self.assertEqual(len(list((self.root / "agent" / "proposals").glob("*.json"))), 0) + self.assertTrue(any(e["kind"] == "decision_withheld" for e in op.state()["activity"])) + + def test_model_unavailable_pauses_counts_attempt_and_never_completes(self): + def policy(*_): + raise RuntimeError("Diagnostic model unavailable") + op = self.open(policy, worker=True) + op.enqueue(self.job()) + self.wait(lambda: op.state()["runner_status"] == "paused") + self.assertEqual(op.state()["jobs"][0]["call_count"], 1) + self.assertEqual(op.body.status()["generation"], 0) + + def test_model_cannot_claim_completion_or_bypass_guard(self): + op = self.open(lambda *_: (dict(action("finish_reset"), completed=True), {})) + op.enqueue(self.job()) + with self.assertRaises(protocol.Refusal): + op._step() + self.assertEqual(op.body.status()["active_job"]["phase"], "prepare") + self.assertNotEqual(op.state()["jobs"][0]["status"], "completed") + + def test_invalid_finish_reset_refuses_native_guard(self): + op = self.open(lambda *_: (action("finish_reset"), {})) + op.enqueue(self.job()) + op._step() + self.assertEqual(op.m["jobs"][0]["history"][-1]["outcome"], "refused") + self.assertEqual(op.body.status()["active_job"]["phase"], "prepare") + + def test_restart_retains_body_and_queue_without_replay(self): + op = self.open() + op.enqueue(self.job()) + op.close() + self.operator = None + op = self.open(lambda *_: self.fail("restart invoked model"), worker=True) + time.sleep(.1) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(op.state()["jobs"][0]["status"], "queued") + self.assertEqual(op.body.status()["generation"], 0) + self.assertEqual(op.state()["usage"]["calls"], 0) + + def test_unknown_native_blocks_resume_and_no_reset(self): + op = self.open() + manifest = protocol.decode(protocol.read_bytes(self.root / "bench" / "bench.json")) + manifest["busy"] = {"operation_id": "interrupted", "kind": "move"} + protocol.persist(self.root / "bench" / "bench.json", manifest) + with self.assertRaises(protocol.Refusal): + op.resume() + self.assertEqual(op.state()["runner_status"], "blocked") + self.assertEqual(op.body.status()["state"], "unknown") + + def test_source_change_refuses_mutation(self): + op = self.open() + with (mock.patch.object(runtime, "sources", return_value={"diagnostic_source": "changed"}), + self.assertRaises(protocol.Refusal)): + op.enqueue(self.job()) + self.assertEqual(len(op.state()["jobs"]), 0) + + def test_two_jobs_replay_public_action_fixture_and_disturbance_guard(self): + # Replay a declared previous development trajectory, not a model qualification. + audit = runtime.BASE.parent.parent / "jevdual/results/agent-visual-bench-20261011/AI-action-audit.json" + proposals = iter(json.loads(audit.read_text())["actions"]) + def policy(*_): + recorded = next(proposals)["proposal"] + return {key: recorded[key] for key in ("action", "target_x", "target_y", "intent")}, {} + op = self.open(policy) + op.enqueue(self.job()) + op.enqueue(self.job("two", target="B", disturbance_test=True)) + for _ in range(40): + if not op._step(): + break + self.assertEqual([j["status"] for j in op.state()["jobs"]], ["completed", "completed"]) + self.assertEqual(len(op.body.status()["jobs"]), 2) + self.assertIsNone(op.body.status()["active_job"]) + events = [protocol.decode(protocol.read_bytes(p)) for p in (self.root / "calls").glob("event-*.json")] + self.assertTrue(any("stale" in e["outcome"] for e in events)) + self.assertEqual(op.state()["usage"]["calls"], 29) + self.assertTrue(all(j["measurement"]["orange_pixel_count"] > 0 for j in op.state()["jobs"])) + + def test_frame_identity_changes_when_zone_repaint_keeps_generation(self): + op = self.open() + first_url = op.state()["current_frame"]["image_url"] + op.enqueue(self.job()) + op._step() + second_url = op.state()["current_frame"]["image_url"] + self.assertNotEqual(first_url, second_url) + self.assertEqual(op.state()["current_frame"]["generation"], 0) + with self.assertRaises(protocol.Refusal): + op.frame(first_url) + self.assertTrue(op.frame(second_url).startswith(b"\x89PNG")) + + def test_interrupted_start_intent_blocks_restart_without_replay(self): + op = self.open() + op.enqueue(self.job()) + op.m["active_job_id"] = "one" + op.m["jobs"][0]["status"] = "running" + op._save() + op.close() + self.operator = None + op = self.open(lambda *_: self.fail("replayed interrupted start"), worker=True) + self.assertEqual(op.state()["runner_status"], "blocked") + with self.assertRaises(protocol.Refusal): + op.resume() + self.assertIsNone(op.body.status()["active_job"]) + self.assertEqual(op.body.status()["generation"], 0) + + def test_mutated_operator_manifest_and_fabricated_completion_refuse(self): + op = self.open() + op.enqueue(self.job()) + op.m["jobs"][0]["status"] = "completed" + op._save() + self.assertEqual(op.state()["runner_status"], "blocked") + self.assertEqual(op.state()["jobs"][0]["status"], "unknown") + retained = protocol.decode(protocol.read_bytes(self.root / "operator.json")) + retained["reason"] = "Changed externally" + protocol.persist(self.root / "operator.json", retained) + with self.assertRaises(protocol.Refusal): + op.enqueue(self.job("two")) + + def test_global_reserved_call_budget_blocks_starting_another_job(self): + op = self.open(lambda *_: self.fail("budget-exhausted model request")) + op.enqueue(self.job()) + op.m["usage"]["calls"] = runtime.MAX_TOTAL_CALLS + op._save() + self.assertFalse(op._step()) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertIsNone(op.body.status()["active_job"]) + self.assertFalse(op.state()["usage"]["token_usage_complete"]) + + def test_shutdown_cancelled_model_exit_persists_stopped_after_worker_exits(self): + entered = threading.Event() + def policy(challenge, history, directory, cancel): + entered.set() + cancel.wait(5) + raise RuntimeError("Diagnostic owned process cancellation") + op = self.open(policy, worker=True) + op.enqueue(self.job()) + self.assertTrue(entered.wait(10)) + op.close() + self.operator = None + retained = protocol.decode(protocol.read_bytes(self.root / "operator.json")) + self.assertFalse(op.worker.is_alive()) + self.assertEqual(retained["runner_status"], "stopped") + self.assertEqual(op.body.status()["generation"], 0) + + def test_http_origin_identity_duplicate_keys_and_body_schema(self): + op = self.open() + self.server = bench_operator.Server(("127.0.0.1", 0), op) + self.thread = threading.Thread(target=self.server.serve_forever, daemon=True) + self.thread.start() + headers = {"Origin": self.server.origin, "X-Footwork-App-ID": op.m["app_id"], "Content-Type": "application/json"} + def post(content, override=None): + connection = HTTPConnection(*self.server.server_address, timeout=5) + connection.request("POST", "/api/jobs", content, headers | (override or {})) + response = connection.getresponse() + response.read() + connection.close() + return response.status + self.assertEqual(post(json.dumps(self.job()), {"Origin": "http://foreign.invalid"}), 409) + self.assertEqual(post(json.dumps(self.job()), {"X-Footwork-App-ID": "foreign"}), 409) + self.assertEqual(post('{"job_id":"one","job_id":"two"}'), 409) + self.assertEqual(post(json.dumps(self.job(command="override"))), 409) + self.assertEqual(len(op.state()["jobs"]), 0) + self.assertEqual(post(json.dumps(self.job())), 200) + self.assertEqual(len(op.state()["jobs"]), 1) + + +if __name__ == "__main__": + unittest.main() From d9723c325643135fa67a65088a00cf92a7a0e6f6 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 15:53:00 -0400 Subject: [PATCH 104/216] Preserve inconclusive operator qualification and preregister admission and scoring repair --- jevdual/docs/experiments/SIM8-bench-operator.md | 4 ++++ .../docs/notebook/2026-10-11-bench-operator.md | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/jevdual/docs/experiments/SIM8-bench-operator.md b/jevdual/docs/experiments/SIM8-bench-operator.md index db52e1b..e5d72f6 100644 --- a/jevdual/docs/experiments/SIM8-bench-operator.md +++ b/jevdual/docs/experiments/SIM8-bench-operator.md @@ -26,6 +26,10 @@ After development conformance, freeze measured source before live model calls. D Primary metric: completed queued job cycles, required 2/2 on the first frozen qualification attempt. Stale refusal and fresh-image recovery are required, as are truthful browser readback and pause semantics. Conformance can use an explicitly labelled fake policy to deterministically test failures; that is not model-control evidence. A failed frozen run is retained and reported; any repair needs a new preregistered version rather than a hidden retry. +## Amendment · 2026-10-11 · version 2 + +Version 1's actual AI/browser workflow completed both cycles, but independent scoring refused its PNG byte size and did not produce a complete score. Preserve that qualification as inconclusive. A read-only review also found a paused queued-job admission race, with cancelled-motion dispatch still guarded. Version 2 repairs the admission check and scorer, explicitly verifies the diagnostic force, more than 2 cm native displacement and exact saved-proposal stale-refusal chain, then repeats the same two-job qualification on fresh committed source. Stop the owned browser/server before scoring to avoid contention. The primary requirement remains 2/2 on the first version 2 qualification attempt; retain all prior calls and failures. + ## Decision and limits Adopt only as a local simulated bench-operator prototype if the complete flow and guards pass. Record model/CLI identity, call count, token usage when reported and elapsed time; subscription usage does not supply an independently verified monetary price. This does not establish hardware transfer, broad model repeatability, production security, physical power-loss recovery, billing accuracy or demand. diff --git a/jevdual/docs/notebook/2026-10-11-bench-operator.md b/jevdual/docs/notebook/2026-10-11-bench-operator.md index 05f3624..ede166c 100644 --- a/jevdual/docs/notebook/2026-10-11-bench-operator.md +++ b/jevdual/docs/notebook/2026-10-11-bench-operator.md @@ -41,3 +41,18 @@ Established: 19 deterministic operator checks, 3 policy checks, 15 agent checks Uncertain: fake policy conformance establishes no live AI job completion. The first complete frozen model/product attempt remains open. Decision: commit the product and separate post-trial scorer, freeze their exact bytes, and drive the two-job qualification through the browser without chat-directed motion. Refs: tools/physical-workcell/output/sim8-final-runtime-tests.log; tools/physical-workcell/output/sim8-final-policy-tests.log; tools/physical-workcell/output/sim8-final-agent-tests.log; tools/physical-workcell/output/sim8-final-bench-tests.log; tools/physical-workcell/output/sim8-empty-preview/ + +## SIM8-U1 · update · 2026-10-11 15:53 +Resolves: SIM8-P1 = inconclusive +Observed: both queued AI jobs completed with measurements and resets; actual inference cancellation dispatched nothing; browser reload retained both results. Independent scoring first collided with the live ownership lock, then refused the PNG because the scorer used the smaller protocol-data byte bound. Review also found a queued-job admission race after a pause acknowledgement and a disturbance-scoring predicate that did not independently establish the force/displacement chain. +Inferred: the observed model/product workflow completed, but this frozen qualification lacks its required complete independent score. Cancelled-motion authority remained guarded; queue admission and scoring need repair before product handoff. +Next: retain version 1 unchanged as an inconclusive qualification, reproduce the admission race, repair the scorer with explicit media bounds and a native force chain, then freeze a second complete product qualification. +Refs: e7b716a; tools/physical-workcell/output/sim8-qualified-20261011-v1/; tools/physical-workcell/score_operator.py; tools/physical-workcell/operator_runtime.py + +## SIM8-P2 · prediction · 2026-10-11 15:53 +Revises: SIM8-P1 +Hypothesis: checking pause admission inside the step lock prevents a queued job start after pause; an explicit PNG bound and exact independent force/displacement chain permit complete scoring of the already bounded visual workcell workflow. +Test: demonstrate the paused-step fixture fails on version 1 and passes after the admission fix; repair scoring, run focused conformance, commit all measured source, and drive two new UI-queued model jobs with the same regions and saved-measurement disturbance. Stop the owned UI/server before post-trial scoring. +Predicts: no post-pause job start or call reservation; two verified cycles on one new persistent bench; a native displacement greater than 2 cm after a saved proposal, an exact stale refusal without measurement effects, fresh-model recovery, measurements and contact resets, truthful browser reload and owned process cleanup. +Against: the admission fixture still starts work, native/SQLite/model-boundary scoring fails, displacement or exact stale binding is absent, recovery needs chat guidance, or completion/readback cannot be substantiated. +Refs: tools/physical-workcell/output/sim8-qualified-20261011-v2/; tools/physical-workcell/test_operator_runtime.py; tools/physical-workcell/score_operator.py From 1415f594ccc91dbc6f7856ba9b2ab0252d45cfdb Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 15:55:57 -0400 Subject: [PATCH 105/216] Guard paused job admission and independently verify the disturbance chain --- .../notebook/2026-10-11-bench-operator.md | 6 ++ tools/physical-workcell/operator_runtime.py | 2 + tools/physical-workcell/score_operator.py | 70 +++++++++++++++++-- .../test_operator_runtime.py | 18 +++++ .../physical-workcell/test_score_operator.py | 39 +++++++++++ 5 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 tools/physical-workcell/test_score_operator.py diff --git a/jevdual/docs/notebook/2026-10-11-bench-operator.md b/jevdual/docs/notebook/2026-10-11-bench-operator.md index ede166c..972ba37 100644 --- a/jevdual/docs/notebook/2026-10-11-bench-operator.md +++ b/jevdual/docs/notebook/2026-10-11-bench-operator.md @@ -56,3 +56,9 @@ Test: demonstrate the paused-step fixture fails on version 1 and passes after th Predicts: no post-pause job start or call reservation; two verified cycles on one new persistent bench; a native displacement greater than 2 cm after a saved proposal, an exact stale refusal without measurement effects, fresh-model recovery, measurements and contact resets, truthful browser reload and owned process cleanup. Against: the admission fixture still starts work, native/SQLite/model-boundary scoring fails, displacement or exact stale binding is absent, recovery needs chat guidance, or completion/readback cannot be substantiated. Refs: tools/physical-workcell/output/sim8-qualified-20261011-v2/; tools/physical-workcell/test_operator_runtime.py; tools/physical-workcell/score_operator.py + +## SIM8-REPAIR · update · 2026-10-11 15:56 +Observed: the admission fixture failed on version 1 by starting a paused job and reserving one call. It passes after the in-lock check; 20 runtime checks pass. Two adversarial scorer checks reject a refusal/move sequence without native force and an unrelated out-of-zone refusal. Repaired retrospective scoring of version 1 verifies both native/SQLite cycles and a 3.98 cm force displacement with exact immutable stale-proposal binding and no measurement effect. Its overall source-unchanged flag remains false after the repairs, so it is not promoted to a passed frozen qualification. +Inferred: the admission fix and stronger post-trial scorer address the identified failures; version 2 still needs a fresh full qualification. +Next: freeze repaired source and enqueue two new actual model jobs through the browser, then stop the owned UI/server before independent scoring. +Refs: tools/physical-workcell/output/sim8-pause-admission-before-fix.log; tools/physical-workcell/output/sim8-pause-admission-after-fix-runtime.log; tools/physical-workcell/output/sim8-score-repair-tests.log; tools/physical-workcell/output/sim8-qualified-20261011-v1/qualification-score.json diff --git a/tools/physical-workcell/operator_runtime.py b/tools/physical-workcell/operator_runtime.py index 295ed6e..3545c44 100644 --- a/tools/physical-workcell/operator_runtime.py +++ b/tools/physical-workcell/operator_runtime.py @@ -288,6 +288,8 @@ def _halt(self, reason, state="paused"): def _step(self): with self.lock: + if self.closing or self.m["runner_status"] != "running" or self.cancel.is_set(): + return False self._healthy() if self.m["usage"]["calls"] >= MAX_TOTAL_CALLS: self._halt("Operator lifetime model-call budget exhausted") diff --git a/tools/physical-workcell/score_operator.py b/tools/physical-workcell/score_operator.py index 95b4f58..631bad4 100644 --- a/tools/physical-workcell/score_operator.py +++ b/tools/physical-workcell/score_operator.py @@ -1,6 +1,7 @@ """Post-trial native, SQLite and model-boundary scorer; never guides the policy.""" import argparse import json +import math import subprocess from pathlib import Path @@ -30,7 +31,7 @@ def freeze(root, commit): files[relative] = protocol.sha(content) runtime.initialize(root) root = protocol.directory(root) - protocol.create_file(root / "source-freeze.json", protocol.encoded({"commit": commit, "files": files})) + protocol.create_file(root / "source-freeze.json", protocol.encoded({"commit": commit, "files": files, "qualification_version": 2})) protocol.create_file(root / "initial.json", protocol.encoded(bench.Bench(root / "bench").status())) return {"source_commit": commit, "root": str(root)} @@ -41,6 +42,65 @@ def private_fields(value): return isinstance(value, list) and any(private_fields(v) for v in value) +def fault_score(root, calls): + read = lambda path: protocol.decode(protocol.read_bytes(path)) + native, agent = read(root / "bench/bench.json"), read(root / "agent/agent.json") + forces = [] + for path in (root / "bench/operations").glob("*.json"): + content = protocol.read_bytes(path) + value = protocol.decode(content) + if value["request"].get("kind") == "disturb": + receipt = value["receipt"] + if native["operations"].get(receipt["operation_id"]) != protocol.sha(content): + raise protocol.Refusal("force receipt differs from retained native operation") + forces.append(value) + if len(forces) != 1: + return {"passed": False, "reason": "expected exactly one native force intervention"} + force = forces[0] + receipt = force["receipt"] + stale = next((c for c in calls if c["job_id"] == receipt["job_id"] and c.get("outcome") == "refused" and + c.get("decision", {}).get("action") == "measure" and + c.get("reason") == "observation is stale or foreign; no requested effect dispatched"), None) + if stale is None: + return {"passed": False, "reason": "exact stale measurement refusal absent"} + directory = Path(stale["call_dir"]) + proposal, dispatch = read(directory / "proposal.json"), read(directory / "dispatch.json") + challenge = read(directory / "reservation.json")["challenge"] + after = dispatch["next_observation"]["observation"] + before = challenge["observation"] + bound = proposal["challenge_id"] == challenge["challenge_id"] and proposal["observation_sha256"] == challenge["observation_sha256"] + for kind, token, value in (("proposals", proposal["proposal_id"], proposal), + ("challenges", challenge["challenge_id"], challenge), + ("results", proposal["proposal_id"], dispatch)): + content = protocol.read_bytes(root / "agent" / kind / (token + ".json")) + bound &= agent[kind].get(token) == protocol.sha(content) and agent_bench.public_response(protocol.decode(content)) == value + zone = challenge["task"]["zone"] + before_state = qualify_bench.native_score(root / "bench", before["generation"], before["state_sha256"], zone) + after_state = qualify_bench.native_score(root / "bench", receipt["generation"], receipt["state_sha256"], zone) + displacement = math.dist(before_state["block_xyz"], after_state["block_xyz"]) + no_measurement_effect = proposal["operation_id"] not in native["operations"] and not ( + root / "bench/operations" / (protocol.sha(proposal["operation_id"].encode()) + ".json")).exists() + fresh_move = next((c for c in calls if c["job_id"] == receipt["job_id"] and c["call"] > stale["call"] and + c.get("outcome") == "executed" and c.get("decision", {}).get("action") == "move"), None) + fresh_binding = False + if fresh_move: + fresh = read(Path(fresh_move["call_dir"]) / "reservation.json")["challenge"]["observation"] + fresh_binding = fresh == after and fresh_move["image_sha256"] == after["image_sha256"] + passed = bool(bound and no_measurement_effect and fresh_binding and displacement > .02 and + before_state["block_center_in_zone"] and not after_state["block_center_in_zone"] and + receipt["generation"] == before["generation"] + 1 == after["generation"] and + receipt["state_sha256"] == after["state_sha256"] and + receipt["bench_id"] == before["bench_id"] == after["bench_id"] == native["bench_id"] and + receipt["job_id"] == before["job_id"] == after["job_id"] and + force["request"] == {"kind": "disturb", "force_x_n": -1.5, "steps": 80} and + receipt["force_x_n"] == -1.5 and receipt["forced_steps"] == 80 and receipt["native_steps"] == 580 and + after_state["external_force_cleared"] and after_state["native_time_s"] > before_state["native_time_s"]) + return {"passed": passed, "force": force, "displacement_m": displacement, + "before": before_state, "after": after_state, "saved_proposal_id": proposal["proposal_id"], + "immutable_chain_bound": bool(bound), "no_measurement_effect": no_measurement_effect, + "fresh_model_move_bound_to_force_image": bool(fresh_binding), "stale_call": stale["call"]} + + def score(root): root = protocol.directory(root) read = lambda path: protocol.decode(protocol.read_bytes(path)) @@ -79,7 +139,7 @@ def score(root): if (directory / "outcome.json").exists(): record["process"] = read(directory / "outcome.json") if (directory / "input.png").exists(): - record["exact_image"] = protocol.sha(protocol.read_bytes(directory / "input.png")) == record["image_sha256"] + record["exact_image"] = protocol.sha(protocol.read_bytes(directory / "input.png", maximum=1024 * 1024)) == record["image_sha256"] prompt = protocol.read_bytes(directory / "prompt.txt").decode().split("\n", 1)[1] record["input_has_no_private_pose"] &= not private_fields(json.loads(prompt)) if (directory / "decision.json").exists(): @@ -95,11 +155,13 @@ def score(root): c.get("outcome") == "executed" and c.get("decision", {}).get("action") == "move" for c in calls)) model_boundaries = bool(calls and all(c.get("exact_image") and c["input_has_no_private_pose"] and c.get("process", {}).get("process_exit_observed") for c in calls)) + fault = fault_score(root, calls) passed = bool(unchanged and len(scores) == database["count"] == 2 and all(s["passed"] for s in scores) and - status["state"] == "ready" and status["active_job"] is None and recovery and model_boundaries) + status["state"] == "ready" and status["active_job"] is None and recovery and model_boundaries and fault["passed"]) result = {"version": 1, "attempt": 1, "passed": passed, "source_commit": frozen["commit"], "source_unchanged": unchanged, "bench_id": status["bench_id"], "completed_cycles": sum(s["passed"] for s in scores), - "stale_measure_refused": stale is not None, "fresh_model_move_after_refusal": recovery, + "qualification_version": frozen.get("qualification_version", 1), + "stale_measure_refused": stale is not None, "fresh_model_move_after_refusal": recovery, "fault_chain": fault, "model_boundaries_passed": model_boundaries, "scores": scores, "sqlite": database, "calls": calls, "usage": operator["usage"], "current_status": status, "scope": "separate post-trial native/SQLite and retained model-boundary scoring; browser evidence recorded separately"} diff --git a/tools/physical-workcell/test_operator_runtime.py b/tools/physical-workcell/test_operator_runtime.py index 4c7fa91..5bcbbe6 100644 --- a/tools/physical-workcell/test_operator_runtime.py +++ b/tools/physical-workcell/test_operator_runtime.py @@ -60,6 +60,24 @@ def test_new_identity_bound_to_separate_persistent_bench(self): self.assertEqual(op.body.status()["generation"], 0) self.assertTrue(op.frame().startswith(b"\x89PNG")) + def test_pause_between_outer_loop_check_and_step_admission_starts_nothing(self): + policy_calls = [] + def policy(*args): + policy_calls.append(args) + return action(), {} + op = self.open(policy) + op.enqueue(self.job()) + # The outer loop's running check already passed; Pause now wins the admission lock. + op.pause() + self.assertFalse(op._step()) + self.assertIsNone(op.body.status()["active_job"]) + self.assertIsNone(op.state()["active_job_id"]) + self.assertEqual(op.state()["jobs"][0]["status"], "queued") + self.assertEqual(op.state()["jobs"][0]["call_count"], 0) + self.assertEqual(op.state()["usage"]["calls"], 0) + self.assertEqual(list((self.root / "calls").glob("*/reservation.json")), []) + self.assertEqual(policy_calls, []) + def test_get_state_and_frame_do_not_capture_or_call_model(self): op = self.open(lambda *_: self.fail("GET invoked model")) before = op.agent.status()["sequence"] diff --git a/tools/physical-workcell/test_score_operator.py b/tools/physical-workcell/test_score_operator.py new file mode 100644 index 0000000..e71f9ac --- /dev/null +++ b/tools/physical-workcell/test_score_operator.py @@ -0,0 +1,39 @@ +"""Adversarial scorer conformance; these fixtures are not model-run evidence.""" +import unittest +import uuid + +import order_protocol as protocol +import score_operator + + +class ScorerTests(unittest.TestCase): + def setUp(self): + self.root = protocol.directory(score_operator.BASE / "output" / ("scorer-test-" + uuid.uuid4().hex[:10]), create=True) + (self.root / "bench").mkdir(mode=0o700) + (self.root / "agent").mkdir(mode=0o700) + (self.root / "bench/operations").mkdir(mode=0o700) + protocol.persist(self.root / "bench/bench.json", {"operations": {}}) + protocol.persist(self.root / "agent/agent.json", {}) + + def calls(self, reason): + return [{"job_id": "diagnostic", "call": 1, "outcome": "refused", "reason": reason, + "decision": {"action": "measure"}}, + {"job_id": "diagnostic", "call": 2, "outcome": "executed", "decision": {"action": "move"}}] + + def test_refused_measure_and_later_move_do_not_prove_any_force(self): + result = score_operator.fault_score(self.root, self.calls("observation is stale or foreign; no requested effect dispatched")) + self.assertFalse(result["passed"]) + self.assertIn("native force", result["reason"]) + + def test_out_of_zone_refusal_does_not_count_as_stale_even_with_force(self): + receipt = {"operation_id": "force", "job_id": "diagnostic"} + content = protocol.encoded({"receipt": receipt, "request": {"kind": "disturb"}}) + protocol.create_file(self.root / "bench/operations/force.json", content) + protocol.persist(self.root / "bench/bench.json", {"operations": {"force": protocol.sha(content)}}) + result = score_operator.fault_score(self.root, self.calls("block is outside the target region")) + self.assertFalse(result["passed"]) + self.assertIn("exact stale", result["reason"]) + + +if __name__ == "__main__": + unittest.main() From e1b4e7b18bbe57e2a9e6da6736a5f118b600abbc Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:05:50 -0400 Subject: [PATCH 106/216] Record qualified Footwork Bench product and retained earlier failures --- .../docs/experiments/SIM8-bench-operator.md | 8 + .../notebook/2026-10-11-bench-operator.md | 13 + .../attempt-ledger.json | 12 + .../completed-reload.png | Bin 0 -> 70790 bytes .../conformance-summary.json | 105 ++ .../bench-operator-20261011/final-checks.json | 249 +++ .../bench-operator-20261011/initial.json | 25 + .../bench-operator-20261011/pause-check.json | 93 + .../bench-operator-20261011/paused.png | Bin 0 -> 63506 bytes .../bench-operator-20261011/product-ready.png | Bin 0 -> 66013 bytes .../qualification-score.json | 1516 +++++++++++++++++ .../bench-operator-20261011/recovery.png | Bin 0 -> 67110 bytes .../results/bench-operator-20261011/report.md | 48 + .../restart-check.json | 231 +++ .../source-freeze.json | 23 + .../v1/completed-reload.png | Bin 0 -> 69488 bytes .../v1/conformance-summary.json | 93 + .../bench-operator-20261011/v1/initial.json | 25 + .../v1/pause-check.json | 93 + .../v1/qualification-score.json | 1483 ++++++++++++++++ .../v1/score-attempt1.json | 1 + .../v1/score-attempt2.json | 1 + .../v1/source-freeze.json | 22 + tools/physical-workcell/README.md | 7 +- 24 files changed, 4045 insertions(+), 3 deletions(-) create mode 100644 jevdual/results/bench-operator-20261011/attempt-ledger.json create mode 100644 jevdual/results/bench-operator-20261011/completed-reload.png create mode 100644 jevdual/results/bench-operator-20261011/conformance-summary.json create mode 100644 jevdual/results/bench-operator-20261011/final-checks.json create mode 100644 jevdual/results/bench-operator-20261011/initial.json create mode 100644 jevdual/results/bench-operator-20261011/pause-check.json create mode 100644 jevdual/results/bench-operator-20261011/paused.png create mode 100644 jevdual/results/bench-operator-20261011/product-ready.png create mode 100644 jevdual/results/bench-operator-20261011/qualification-score.json create mode 100644 jevdual/results/bench-operator-20261011/recovery.png create mode 100644 jevdual/results/bench-operator-20261011/report.md create mode 100644 jevdual/results/bench-operator-20261011/restart-check.json create mode 100644 jevdual/results/bench-operator-20261011/source-freeze.json create mode 100644 jevdual/results/bench-operator-20261011/v1/completed-reload.png create mode 100644 jevdual/results/bench-operator-20261011/v1/conformance-summary.json create mode 100644 jevdual/results/bench-operator-20261011/v1/initial.json create mode 100644 jevdual/results/bench-operator-20261011/v1/pause-check.json create mode 100644 jevdual/results/bench-operator-20261011/v1/qualification-score.json create mode 100644 jevdual/results/bench-operator-20261011/v1/score-attempt1.json create mode 100644 jevdual/results/bench-operator-20261011/v1/score-attempt2.json create mode 100644 jevdual/results/bench-operator-20261011/v1/source-freeze.json diff --git a/jevdual/docs/experiments/SIM8-bench-operator.md b/jevdual/docs/experiments/SIM8-bench-operator.md index e5d72f6..de1a46a 100644 --- a/jevdual/docs/experiments/SIM8-bench-operator.md +++ b/jevdual/docs/experiments/SIM8-bench-operator.md @@ -33,3 +33,11 @@ Version 1's actual AI/browser workflow completed both cycles, but independent sc ## Decision and limits Adopt only as a local simulated bench-operator prototype if the complete flow and guards pass. Record model/CLI identity, call count, token usage when reported and elapsed time; subscription usage does not supply an independently verified monetary price. This does not establish hardware transfer, broad model repeatability, production security, physical power-loss recovery, billing accuracy or demand. + +## Result + +Version 1 completed both actual AI/browser cycles but its independent scoring failed on live ownership contention and PNG byte size; retain the frozen qualification as inconclusive. The pause admission regression failed before repair, with motion dispatch still guarded. A preregistered version 2 repaired admission and independently checked force/displacement/stale binding. + +Version 2 attempt 1 passed 2/2 on source freeze `1415f594ccc91dbc6f7856ba9b2ab0252d45cfdb`. Native/SQLite scoring verified measurements and contact resets on one body, and the exact immutable chain established a 5.61 cm native displacement, refusal of a saved stale measurement without effect, and fresh-image AI recovery. Actual inference cancellation dispatched nothing; browser reload and server restart retained results without replay. Thirty-one reserved CLI calls produced 30 typed decisions, 29 executed decisions, one stale refusal and one cancelled call. All model processes were reaped. Fifty-four focused checks passed; native guard source is unchanged. + +Adopt as a local simulated product prototype. Evidence, all-attempt ledger and limits: [bench-operator results](../../results/bench-operator-20261011/report.md). Raw model logs and native run directories remain private; hardware and demand remain unqualified. diff --git a/jevdual/docs/notebook/2026-10-11-bench-operator.md b/jevdual/docs/notebook/2026-10-11-bench-operator.md index 972ba37..f5d7a4e 100644 --- a/jevdual/docs/notebook/2026-10-11-bench-operator.md +++ b/jevdual/docs/notebook/2026-10-11-bench-operator.md @@ -62,3 +62,16 @@ Observed: the admission fixture failed on version 1 by starting a paused job and Inferred: the admission fix and stronger post-trial scorer address the identified failures; version 2 still needs a fresh full qualification. Next: freeze repaired source and enqueue two new actual model jobs through the browser, then stop the owned UI/server before independent scoring. Refs: tools/physical-workcell/output/sim8-pause-admission-before-fix.log; tools/physical-workcell/output/sim8-pause-admission-after-fix-runtime.log; tools/physical-workcell/output/sim8-score-repair-tests.log; tools/physical-workcell/output/sim8-qualified-20261011-v1/qualification-score.json + +## SIM8-U2 · update · 2026-10-11 16:04 +Resolves: SIM8-P2 = held +Observed: version 2 attempt 1 completed both UI-queued actual AI cycles on one retained body with unchanged frozen source. Separate native/SQLite scoring passed placement, measurements, contact resets and continuous generation/time. Exact immutable binding and native force states show a 5.61 cm displacement, stale measurement refusal without effect, and a fresh-image model move followed by recovery. Actual inference cancellation left generation zero without a proposal/dispatch. Browser reload and same-origin server restart retained both results without replay. All 31 model processes exited and were reaped; 54 focused conformance checks pass. +Inferred: the repaired local product supports the bounded unattended image/action/computer loop on these recorded attempts. This establishes neither hardware transfer nor broad model repeatability. +Next: preserve derived evidence and prior failures, leave the user-facing server running idle, and require separate network/body-adapter qualification before hardware authority. +Refs: 1415f59; results/bench-operator-20261011/qualification-score.json; results/bench-operator-20261011/final-checks.json; results/bench-operator-20261011/conformance-summary.json; results/bench-operator-20261011/attempt-ledger.json + +## SIM8-S · summary · 2026-10-11 16:04 +Established: Footwork Bench provides UI job creation, persistent camera/queue/result state, autonomous visual decisions, separately saved optical measurement, contact reset, bounded pause/resume, source/freshness guards and independent evidence. The final first-attempt version 2 qualification passed 2/2; all earlier probe, scorer and conformance failures are retained. Native guard files remain unchanged. Model usage is reported with missing cancelled-call accounting explicit. +Uncertain: hardware, general manipulation, physical power-loss recovery, network fault tolerance, production security, customer demand and monetary pricing remain unqualified. +Decision: adopt as a local simulated prototype in the existing Footwork workcell package. Keep the current server intentionally open with no queued/pending model work. Next physical boundary is a qualified persistent body adapter; do not infer hardware readiness from these simulation runs. +Refs: results/bench-operator-20261011/report.md; tools/physical-workcell/OPERATOR.md; results/bench-operator-20261011/final-checks.json diff --git a/jevdual/results/bench-operator-20261011/attempt-ledger.json b/jevdual/results/bench-operator-20261011/attempt-ledger.json new file mode 100644 index 0000000..7a58f4d --- /dev/null +++ b/jevdual/results/bench-operator-20261011/attempt-ledger.json @@ -0,0 +1,12 @@ +{ + "transport_probes": 2, + "trial_v1_reserved_calls": 30, + "trial_v2_reserved_calls": 31, + "total_reserved_cli_requests": 63, + "usage_scope": "reported token totals only; no monetary price or complete billing evidence", + "v1_qualification": "inconclusive, retained; retrospective repaired score has changed-source flag", + "v2_qualification": "passed first version-2 attempt", + "cli_version": "codex-cli 0.147.0", + "model": "CLI default; exact model name not reported", + "reasoning_effort": "low" +} \ No newline at end of file diff --git a/jevdual/results/bench-operator-20261011/completed-reload.png b/jevdual/results/bench-operator-20261011/completed-reload.png new file mode 100644 index 0000000000000000000000000000000000000000..b78b46136a4d99adceb9eaa6c9ba126594f07350 GIT binary patch literal 70790 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 literal 0 HcmV?d00001 diff --git a/jevdual/results/bench-operator-20261011/conformance-summary.json b/jevdual/results/bench-operator-20261011/conformance-summary.json new file mode 100644 index 0000000..7fb5e74 --- /dev/null +++ b/jevdual/results/bench-operator-20261011/conformance-summary.json @@ -0,0 +1,105 @@ +{ + "suites": [ + { + "suite": "runtime", + "passed": true, + "tests": 20, + "elapsed_s": 14.404, + "cases": [ + "test_cancelled_reply_stays_withheld_after_event_clears (test_operator_runtime.OperatorTests.test_cancelled_reply_stays_withheld_after_event_clears)", + "test_frame_identity_changes_when_zone_repaint_keeps_generation (test_operator_runtime.OperatorTests.test_frame_identity_changes_when_zone_repaint_keeps_generation)", + "test_get_state_and_frame_do_not_capture_or_call_model (test_operator_runtime.OperatorTests.test_get_state_and_frame_do_not_capture_or_call_model)", + "test_global_reserved_call_budget_blocks_starting_another_job (test_operator_runtime.OperatorTests.test_global_reserved_call_budget_blocks_starting_another_job)", + "test_http_origin_identity_duplicate_keys_and_body_schema (test_operator_runtime.OperatorTests.test_http_origin_identity_duplicate_keys_and_body_schema)", + "test_interrupted_start_intent_blocks_restart_without_replay (test_operator_runtime.OperatorTests.test_interrupted_start_intent_blocks_restart_without_replay)", + "test_invalid_finish_reset_refuses_native_guard (test_operator_runtime.OperatorTests.test_invalid_finish_reset_refuses_native_guard)", + "test_model_cannot_claim_completion_or_bypass_guard (test_operator_runtime.OperatorTests.test_model_cannot_claim_completion_or_bypass_guard)", + "test_model_unavailable_pauses_counts_attempt_and_never_completes (test_operator_runtime.OperatorTests.test_model_unavailable_pauses_counts_attempt_and_never_completes)", + "test_mutated_operator_manifest_and_fabricated_completion_refuse (test_operator_runtime.OperatorTests.test_mutated_operator_manifest_and_fabricated_completion_refuse)", + "test_new_identity_bound_to_separate_persistent_bench (test_operator_runtime.OperatorTests.test_new_identity_bound_to_separate_persistent_bench)", + "test_pause_between_outer_loop_check_and_step_admission_starts_nothing (test_operator_runtime.OperatorTests.test_pause_between_outer_loop_check_and_step_admission_starts_nothing)", + "test_pause_during_model_prevents_late_reply_dispatch (test_operator_runtime.OperatorTests.test_pause_during_model_prevents_late_reply_dispatch)", + "test_queue_validation_duplicate_and_path_schema (test_operator_runtime.OperatorTests.test_queue_validation_duplicate_and_path_schema)", + "test_restart_retains_body_and_queue_without_replay (test_operator_runtime.OperatorTests.test_restart_retains_body_and_queue_without_replay)", + "test_shutdown_cancelled_model_exit_persists_stopped_after_worker_exits (test_operator_runtime.OperatorTests.test_shutdown_cancelled_model_exit_persists_stopped_after_worker_exits)", + "test_source_change_refuses_mutation (test_operator_runtime.OperatorTests.test_source_change_refuses_mutation)", + "test_stop_decision_pauses_without_completion (test_operator_runtime.OperatorTests.test_stop_decision_pauses_without_completion)", + "test_two_jobs_replay_public_action_fixture_and_disturbance_guard (test_operator_runtime.OperatorTests.test_two_jobs_replay_public_action_fixture_and_disturbance_guard)", + "test_unknown_native_blocks_resume_and_no_reset (test_operator_runtime.OperatorTests.test_unknown_native_blocks_resume_and_no_reset)" + ], + "private_log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-pause-admission-after-fix-runtime.log" + }, + { + "suite": "policy", + "passed": true, + "tests": 3, + "elapsed_s": 0.559, + "cases": [ + "test_closed_action_schema_finite_targets_and_no_success_flag (test_codex_policy.PolicyTests.test_closed_action_schema_finite_targets_and_no_success_flag)", + "test_fake_cli_bound_image_schema_tool_isolation_and_reservation (test_codex_policy.PolicyTests.test_fake_cli_bound_image_schema_tool_isolation_and_reservation)", + "test_usage_optional_and_any_tool_event_refuses (test_codex_policy.PolicyTests.test_usage_optional_and_any_tool_event_refuses)" + ], + "private_log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-final-policy-tests.log" + }, + { + "suite": "agent", + "passed": true, + "tests": 15, + "elapsed_s": 3.689, + "cases": [ + "test_challenge_has_only_images_task_and_public_observation (test_agent_bench.AgentBenchTests.test_challenge_has_only_images_task_and_public_observation)", + "test_changed_challenge_image_refuses (test_agent_bench.AgentBenchTests.test_changed_challenge_image_refuses)", + "test_changed_proposal_refuses_before_dispatch (test_agent_bench.AgentBenchTests.test_changed_proposal_refuses_before_dispatch)", + "test_error_after_real_move_stays_unknown_even_if_bench_ready (test_agent_bench.AgentBenchTests.test_error_after_real_move_stays_unknown_even_if_bench_ready)", + "test_foreign_challenge_and_unsafe_identity_refuse (test_agent_bench.AgentBenchTests.test_foreign_challenge_and_unsafe_identity_refuse)", + "test_measurement_placement_refusal_does_not_create_sqlite (test_agent_bench.AgentBenchTests.test_measurement_placement_refusal_does_not_create_sqlite)", + "test_measurement_worker_failure_retains_unknown_and_blocks_replay (test_agent_bench.AgentBenchTests.test_measurement_worker_failure_retains_unknown_and_blocks_replay)", + "test_move_executes_once_duplicate_returns_exact_result (test_agent_bench.AgentBenchTests.test_move_executes_once_duplicate_returns_exact_result)", + "test_nonfinite_and_conflicting_arguments_never_create_proposal (test_agent_bench.AgentBenchTests.test_nonfinite_and_conflicting_arguments_never_create_proposal)", + "test_proposal_persists_intent_without_effect (test_agent_bench.AgentBenchTests.test_proposal_persists_intent_without_effect)", + "test_public_cli_measurement_reset_and_status_strip_detector_locations (test_agent_bench.AgentBenchTests.test_public_cli_measurement_reset_and_status_strip_detector_locations)", + "test_source_change_and_foreign_bench_identity_block_dispatch (test_agent_bench.AgentBenchTests.test_source_change_and_foreign_bench_identity_block_dispatch)", + "test_stale_move_refuses_and_returns_fresh_image (test_agent_bench.AgentBenchTests.test_stale_move_refuses_and_returns_fresh_image)", + "test_unresolved_intent_blocks_same_and_new_proposal (test_agent_bench.AgentBenchTests.test_unresolved_intent_blocks_same_and_new_proposal)", + "test_wrong_reset_phase_preserves_bench (test_agent_bench.AgentBenchTests.test_wrong_reset_phase_preserves_bench)" + ], + "private_log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-final-agent-tests.log" + }, + { + "suite": "bench", + "passed": true, + "tests": 14, + "elapsed_s": 5.049, + "cases": [ + "test_corrupted_image_refuses_measurement_and_does_not_create_a_database (test_bench.BenchBehaviorTests.test_corrupted_image_refuses_measurement_and_does_not_create_a_database)", + "test_corrupted_native_state_never_causes_an_implicit_reset (test_bench.BenchBehaviorTests.test_corrupted_native_state_never_causes_an_implicit_reset)", + "test_corrupted_retained_model_refuses_without_recreating_the_body (test_bench.BenchBehaviorTests.test_corrupted_retained_model_refuses_without_recreating_the_body)", + "test_corrupted_source_binding_refuses_without_a_new_generation (test_bench.BenchBehaviorTests.test_corrupted_source_binding_refuses_without_a_new_generation)", + "test_diagnostic_force_needs_explicit_enablement_and_finite_bounds (test_bench.BenchBehaviorTests.test_diagnostic_force_needs_explicit_enablement_and_finite_bounds)", + "test_exact_motion_replay_retains_one_native_effect_and_conflicts_refuse (test_bench.BenchBehaviorTests.test_exact_motion_replay_retains_one_native_effect_and_conflicts_refuse)", + "test_external_force_invalidates_stale_motion_and_measurement_before_dispatch (test_bench.BenchBehaviorTests.test_external_force_invalidates_stale_motion_and_measurement_before_dispatch)", + "test_foreign_or_modified_observation_cannot_authorize_a_motion (test_bench.BenchBehaviorTests.test_foreign_or_modified_observation_cannot_authorize_a_motion)", + "test_measurement_column_corruption_is_not_hidden_by_an_unchanged_receipt (test_bench.BenchBehaviorTests.test_measurement_column_corruption_is_not_hidden_by_an_unchanged_receipt)", + "test_measurement_is_a_separate_process_with_exact_persisted_image_binding (test_bench.BenchBehaviorTests.test_measurement_is_a_separate_process_with_exact_persisted_image_binding)", + "test_measurement_receipt_corruption_refuses_historical_replay (test_bench.BenchBehaviorTests.test_measurement_receipt_corruption_refuses_historical_replay)", + "test_measurement_replay_is_historical_and_does_not_run_another_worker (test_bench.BenchBehaviorTests.test_measurement_replay_is_historical_and_does_not_run_another_worker)", + "test_retained_interrupted_intent_blocks_all_new_dispatch (test_bench.BenchBehaviorTests.test_retained_interrupted_intent_blocks_all_new_dispatch)", + "test_successive_job_gate_requires_measurement_and_verified_reset (test_bench.BenchBehaviorTests.test_successive_job_gate_requires_measurement_and_verified_reset)" + ], + "private_log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-final-bench-tests.log" + }, + { + "suite": "scorer", + "passed": true, + "tests": 2, + "elapsed_s": 0.004, + "cases": [ + "test_out_of_zone_refusal_does_not_count_as_stale_even_with_force (test_score_operator.ScorerTests.test_out_of_zone_refusal_does_not_count_as_stale_even_with_force)", + "test_refused_measure_and_later_move_do_not_prove_any_force (test_score_operator.ScorerTests.test_refused_measure_and_later_move_do_not_prove_any_force)" + ], + "private_log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-score-repair-tests.log" + } + ], + "total_tests": 54, + "scope": "labelled conformance; fake policies are not actual AI completion evidence" +} \ No newline at end of file diff --git a/jevdual/results/bench-operator-20261011/final-checks.json b/jevdual/results/bench-operator-20261011/final-checks.json new file mode 100644 index 0000000..151c5e0 --- /dev/null +++ b/jevdual/results/bench-operator-20261011/final-checks.json @@ -0,0 +1,249 @@ +{ + "passed": true, + "qualification_version": 2, + "attempt": 1, + "native_sqlite": true, + "browser_reload_completed_jobs": 2, + "browser_results_match_measurements": true, + "live_pause_no_effect": true, + "restart_no_replay": true, + "unchanged_core_guards": true, + "model_processes_reaped": 31, + "owned_model_pids_still_alive": [], + "product_server_retained_intentionally": { + "pid": 79998, + "origin": "http://127.0.0.1:64370", + "purpose": "user-facing product left running idle after verified trial", + "started_at": 1791748917.8438258 + }, + "final_state": { + "app_id": "dfc891dc85774b2497cd8b306844a96e", + "simulation": true, + "runner_status": "running", + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "9bd00615-a89f-4c60-99ff-4b3dd5110b4b", + "label": "Baseline inspection", + "last_intent": "Finish reset now that the block center and pusher are both in their home positions.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "status": "completed", + "target": "A" + }, + { + "call_count": 17, + "disturbance_test": true, + "error": null, + "job_id": "9a905ec1-093b-47b6-ba1f-558b736da542", + "label": "Recovery inspection", + "last_intent": "Finish reset now that the block is centered in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "active_job_id": null, + "activity": [ + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 7 reserved", + "seq": 49, + "time": 1791748757.249968 + }, + { + "intent": "Measure with the block centered in the target region and the pusher clear of contact.", + "kind": "dispatch", + "outcome": "executed: measure", + "seq": 50, + "time": 1791748763.792654 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 8 reserved", + "seq": 51, + "time": 1791748764.077049 + }, + { + "intent": "Begin the reset sequence after the verified measurement.", + "kind": "dispatch", + "outcome": "executed: begin_reset", + "seq": 52, + "time": 1791748768.943161 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 9 reserved", + "seq": 53, + "time": 1791748769.218656 + }, + { + "intent": "Enter the upper bypass lane before crossing to the block's right side.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 54, + "time": 1791748776.686862 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 10 reserved", + "seq": 55, + "time": 1791748776.915343 + }, + { + "intent": "Cross the upper bypass lane to position the pusher safely right of the block.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 56, + "time": 1791748784.087341 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 11 reserved", + "seq": 57, + "time": 1791748784.352294 + }, + { + "intent": "Return from the bypass lane to align on the block's right side for a leftward push.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 58, + "time": 1791748791.344933 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 12 reserved", + "seq": 59, + "time": 1791748791.558492 + }, + { + "intent": "Push the block left from its right side until its center reaches the home zone.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 60, + "time": 1791748799.1835608 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 13 reserved", + "seq": 61, + "time": 1791748799.412058 + }, + { + "intent": "Retreat right to clear contact with the home-positioned block before entering the bypass lane.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 62, + "time": 1791748809.6114829 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 14 reserved", + "seq": 63, + "time": 1791748809.81729 + }, + { + "intent": "Enter the upper bypass lane before crossing left toward the pusher home position.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 64, + "time": 1791748817.115353 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 15 reserved", + "seq": 65, + "time": 1791748817.392006 + }, + { + "intent": "Cross the upper bypass lane to align above the pusher home position.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 66, + "time": 1791748824.084478 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 16 reserved", + "seq": 67, + "time": 1791748824.3450701 + }, + { + "intent": "Lower the safely bypassed pusher to its home position while leaving the block centered in the home zone.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 68, + "time": 1791748831.661006 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 17 reserved", + "seq": 69, + "time": 1791748831.861367 + }, + { + "intent": "Finish reset now that the block is centered in the home zone and the pusher is at its home position.", + "kind": "dispatch", + "outcome": "executed: finish_reset", + "seq": 70, + "time": 1791748838.118604 + }, + { + "intent": "Recovery inspection", + "kind": "completed", + "outcome": "Saved measurement and contact reset verified", + "seq": 71, + "time": 1791748838.1658392 + }, + { + "seq": 72, + "time": 1791748926.575486, + "kind": "resume", + "intent": "", + "outcome": "" + } + ], + "usage": { + "calls": 31, + "input_tokens": 388482, + "output_tokens": 4804, + "reported_calls": 30, + "token_usage_complete": false + }, + "readiness": { + "ready": true, + "reason": "Ready for the next action boundary" + }, + "current_frame": { + "generation": 24, + "image_url": "/api/frame?generation=24&sha256=010748ac551827d5579da25ccf5ef0a1618f26a60826a7c5d5c452904d1eb68b", + "available": true + } + }, + "remaining_queue_slots": 4, + "native_hardware_qualified": false, + "scope": "local simulated prototype; no hardware or demand qualification" +} \ No newline at end of file diff --git a/jevdual/results/bench-operator-20261011/initial.json b/jevdual/results/bench-operator-20261011/initial.json new file mode 100644 index 0000000..e0ce58f --- /dev/null +++ b/jevdual/results/bench-operator-20261011/initial.json @@ -0,0 +1,25 @@ +{ + "active_job": null, + "bench_id": "3e46ab9264d148db8f026373a79f0078", + "diagnostic_enabled": true, + "generation": 0, + "jobs": {}, + "native_time_s": 1.0000000000000007, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 +} diff --git a/jevdual/results/bench-operator-20261011/pause-check.json b/jevdual/results/bench-operator-20261011/pause-check.json new file mode 100644 index 0000000..b8113fc --- /dev/null +++ b/jevdual/results/bench-operator-20261011/pause-check.json @@ -0,0 +1,93 @@ +{ + "state": { + "app_id": "dfc891dc85774b2497cd8b306844a96e", + "simulation": true, + "runner_status": "paused", + "jobs": [ + { + "job_id": "9bd00615-a89f-4c60-99ff-4b3dd5110b4b", + "label": "Baseline inspection", + "target": "A", + "disturbance_test": false, + "status": "paused", + "phase": "prepare", + "call_count": 1, + "last_intent": "", + "measurement": null, + "error": "operator_pause_requested" + } + ], + "model_request_pending": false, + "active_job_id": "9bd00615-a89f-4c60-99ff-4b3dd5110b4b", + "activity": [ + { + "seq": 1, + "time": 1791748595.4540858, + "kind": "queued", + "intent": "Baseline inspection", + "outcome": "9bd00615-a89f-4c60-99ff-4b3dd5110b4b" + }, + { + "seq": 2, + "time": 1791748595.4656131, + "kind": "start_intent", + "intent": "Baseline inspection", + "outcome": "9bd00615-a89f-4c60-99ff-4b3dd5110b4b" + }, + { + "seq": 3, + "time": 1791748595.552342, + "kind": "inference", + "intent": "Baseline inspection", + "outcome": "Model call 1 reserved" + }, + { + "seq": 4, + "time": 1791748598.720981, + "kind": "pause", + "intent": "", + "outcome": "Paused; an in-flight native action may finish before the next boundary" + }, + { + "seq": 5, + "time": 1791748598.737185, + "kind": "halt", + "intent": "", + "outcome": "operator_pause_requested" + } + ], + "usage": { + "calls": 1, + "input_tokens": 0, + "output_tokens": 0, + "reported_calls": 0, + "token_usage_complete": false + }, + "readiness": { + "ready": false, + "reason": "operator_pause_requested" + }, + "current_frame": { + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "available": true + } + }, + "outcome": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 2.8941972500178963, + "exit_code": 0, + "image_sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "outcome": "cancelled", + "pid": 60738, + "process_exit_observed": true, + "provider": "codex_cli", + "reason": "operator_pause_requested", + "request_sha256": "a0f2b3e1bf07e9e33875d1eb4709ef4377bee4cb2c0863310c95f6d4e405c053", + "started_at": 1791748595.837315, + "usage": null + }, + "proposal_exists": false, + "dispatch_exists": false, + "native_generation": 0 +} \ No newline at end of file diff --git a/jevdual/results/bench-operator-20261011/paused.png b/jevdual/results/bench-operator-20261011/paused.png new file mode 100644 index 0000000000000000000000000000000000000000..7543d0ae8c3ceed254b86a396a48b40f94e35a36 GIT binary patch literal 63506 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
odFI&8KzK62&z3*C6i<-Inse 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�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 literal 0 HcmV?d00001 diff --git a/jevdual/results/bench-operator-20261011/report.md b/jevdual/results/bench-operator-20261011/report.md new file mode 100644 index 0000000..38df955 --- /dev/null +++ b/jevdual/results/bench-operator-20261011/report.md @@ -0,0 +1,48 @@ +# Footwork Bench: unattended visual workcell and local product + +The final source-frozen qualification passed two queued image-guided inspection cycles on one persistent simulated bench. A real independently running Codex policy chose each move, measurement and reset action. Native state and read-only SQLite verified both cycles separately; the browser retained their results after reload and a server restart. + +## What the product does + +Open the local bench, add a named inspection and select a region. The AI observes the camera image, moves the pusher, corrects placement, triggers a separately executed optical measurement and returns both bodies home by contact. The browser exposes the queue, most recent camera capture, model planning, intent, measurement, activity and pause/resume. Repeat creates a new job. Simulation remains explicit throughout. + +Runbook: [OPERATOR.md](../../../tools/physical-workcell/OPERATOR.md). Implementation stays in Footwork's existing physical-workcell package: stdlib Python, plain browser HTML/CSS/JavaScript and pinned MuJoCo 3.15.0. Existing native guard files are unchanged. + +## Final qualification + +Source freeze: `1415f594ccc91dbc6f7856ba9b2ab0252d45cfdb`. Version 2, attempt 1. Private run: `tools/physical-workcell/output/sim8-qualified-20261011-v2/`. + +Bench identity: `3e46ab9264d148db8f026373a79f0078`. Native generations continued 0 → 10 → 24; simulation time continued 1.000 → 21.414 → 47.084 seconds. No body reinitialization or pose assignment reset occurred. + +| Job | Reserved model calls | Native moves | Measurement generation | Reset generation | Apparent area, mm² | +|---|---:|---:|---:|---:|---:| +| Baseline inspection | 14 | 10 | 2 | 10 | 4794.4 | +| Recovery inspection | 17 | 13 | 16 | 24 | 4802.8 | + +The disturbance moved the block **5.61 cm** out of its target region after the first measurement proposal was saved. The immutable proposal/challenge/result chain and native force receipt bind that decision to the older generation. The stale measurement was refused without a native measurement operation; the next executed model move used the exact post-force image. The AI recovered and later measured successfully. The scorer independently checks force, displacement, freshness, SQLite rows, native placement, contact reset and continuous body/time identity. + +There were 31 reserved CLI requests: 30 typed decisions and one cancelled request. Twenty-nine decisions executed, one stale measurement was refused, and no outcome was unknown. Every launched model process exited and was reaped. Inputs contained exact matching PNG bytes and bounded task/history metadata; detector locations and native poses were absent. + +Pause during actual inference left generation zero and created no proposal or dispatch. Resume obtained fresh evidence. Server restart retained both completed jobs and the same origin/body, paused without replay, and required an explicit resume. The user-facing server is intentionally left running idle at http://127.0.0.1:64370 with no pending model request. Its owned PID is recorded in `final-checks.json`; four queue slots remain. The product limit is six jobs, 32 calls per job and 96 calls per operator lifetime. Stop this instance with `kill -TERM 79998`; restart on the retained port as documented. + +Reported final-trial usage: 388,482 input and 4,804 output tokens across 30 of 31 requests. Cancelled-call usage is unavailable. The CLI is 0.147.0, uses saved authentication and its default model with low reasoning; an exact model name is not reported. No API key was opened or provisioned. Monetary price is unmeasured. + +## Checks and preserved failures + +**54 focused conformance checks passed**: 20 runtime, 3 policy, 15 agent, 14 bench and 2 scorer. Fake policies are labelled diagnostic and supply no model-control evidence. Ruff, JavaScript syntax, whitespace and notebook validation passed. + +The first no-dispatch policy probe returned a valid action but was classified as unexpected tool use because two nonfatal CLI startup diagnostics were misread. It is retained privately; the committed classifier repair accepted a second fresh probe while unknown errors and actual tool items still refuse. + +Version 1's actual AI/browser workflow completed both cycles, but the original scorer first encountered a live ownership lock and then applied a 64 KiB protocol-data bound to a larger PNG. Its frozen qualification is **inconclusive**. Retrospective repaired scoring verifies its native cycles and 3.98 cm disturbance, while retaining a false source-unchanged flag; it is not promoted to a passed frozen run. The initial run and scorer failures are retained under `v1/` and its private run directory. + +Read-only review then found a pause admission race between the outer loop check and step lock. The regression started a queued job/reserved a call after pause before the fix; an in-lock check now prevents both. Cancelled-motion dispatch was already guarded. The scorer was also tightened so an unrelated measurement refusal followed by a move cannot count as disturbance recovery. Both repairs were preregistered and committed before the fresh version 2 model run. + +## Evidence and limits + +- [Independent score](qualification-score.json), [force chain](qualification-score.json), [source freeze](source-freeze.json), [final readback and process checks](final-checks.json). +- [Conformance cases](conformance-summary.json), [all-attempt ledger](attempt-ledger.json), [version 1 retrospective record](v1/qualification-score.json). +- [Product ready](product-ready.png), [paused request](paused.png), [recovery in progress](recovery.png), [completed browser reload](completed-reload.png). + +Adopt as a local simulated product prototype. The result establishes this bounded image-to-action-to-computer loop on the recorded scene and attempts. It does not establish hardware transfer, general manipulation, broad model repeatability, power-loss recovery, production security or customer demand. Optical area is an apparent calibrated image footprint, not the block's true surface area. Python remains adequate; the native integration already runs in MuJoCo. No measured Rust hot path has been identified. + +The next hardware boundary is a persistent body adapter with the same observation/proposal/receipt semantics, qualified first under network delay, disconnects, duplicates and cancellation. The browser product can remain the workcell supervisor while the simulated body is exchanged for a qualified device. diff --git a/jevdual/results/bench-operator-20261011/restart-check.json b/jevdual/results/bench-operator-20261011/restart-check.json new file mode 100644 index 0000000..5a22d08 --- /dev/null +++ b/jevdual/results/bench-operator-20261011/restart-check.json @@ -0,0 +1,231 @@ +{ + "passed": true, + "state": { + "app_id": "dfc891dc85774b2497cd8b306844a96e", + "simulation": true, + "runner_status": "paused", + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "9bd00615-a89f-4c60-99ff-4b3dd5110b4b", + "label": "Baseline inspection", + "last_intent": "Finish reset now that the block center and pusher are both in their home positions.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "status": "completed", + "target": "A" + }, + { + "call_count": 17, + "disturbance_test": true, + "error": null, + "job_id": "9a905ec1-093b-47b6-ba1f-558b736da542", + "label": "Recovery inspection", + "last_intent": "Finish reset now that the block is centered in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "active_job_id": null, + "activity": [ + { + "intent": "Retreat the pusher left to clear contact before measuring the centered block.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 48, + "time": 1791748757.1141179 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 7 reserved", + "seq": 49, + "time": 1791748757.249968 + }, + { + "intent": "Measure with the block centered in the target region and the pusher clear of contact.", + "kind": "dispatch", + "outcome": "executed: measure", + "seq": 50, + "time": 1791748763.792654 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 8 reserved", + "seq": 51, + "time": 1791748764.077049 + }, + { + "intent": "Begin the reset sequence after the verified measurement.", + "kind": "dispatch", + "outcome": "executed: begin_reset", + "seq": 52, + "time": 1791748768.943161 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 9 reserved", + "seq": 53, + "time": 1791748769.218656 + }, + { + "intent": "Enter the upper bypass lane before crossing to the block's right side.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 54, + "time": 1791748776.686862 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 10 reserved", + "seq": 55, + "time": 1791748776.915343 + }, + { + "intent": "Cross the upper bypass lane to position the pusher safely right of the block.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 56, + "time": 1791748784.087341 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 11 reserved", + "seq": 57, + "time": 1791748784.352294 + }, + { + "intent": "Return from the bypass lane to align on the block's right side for a leftward push.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 58, + "time": 1791748791.344933 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 12 reserved", + "seq": 59, + "time": 1791748791.558492 + }, + { + "intent": "Push the block left from its right side until its center reaches the home zone.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 60, + "time": 1791748799.1835608 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 13 reserved", + "seq": 61, + "time": 1791748799.412058 + }, + { + "intent": "Retreat right to clear contact with the home-positioned block before entering the bypass lane.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 62, + "time": 1791748809.6114829 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 14 reserved", + "seq": 63, + "time": 1791748809.81729 + }, + { + "intent": "Enter the upper bypass lane before crossing left toward the pusher home position.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 64, + "time": 1791748817.115353 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 15 reserved", + "seq": 65, + "time": 1791748817.392006 + }, + { + "intent": "Cross the upper bypass lane to align above the pusher home position.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 66, + "time": 1791748824.084478 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 16 reserved", + "seq": 67, + "time": 1791748824.3450701 + }, + { + "intent": "Lower the safely bypassed pusher to its home position while leaving the block centered in the home zone.", + "kind": "dispatch", + "outcome": "executed: move", + "seq": 68, + "time": 1791748831.661006 + }, + { + "intent": "Recovery inspection", + "kind": "inference", + "outcome": "Model call 17 reserved", + "seq": 69, + "time": 1791748831.861367 + }, + { + "intent": "Finish reset now that the block is centered in the home zone and the pusher is at its home position.", + "kind": "dispatch", + "outcome": "executed: finish_reset", + "seq": 70, + "time": 1791748838.118604 + }, + { + "intent": "Recovery inspection", + "kind": "completed", + "outcome": "Saved measurement and contact reset verified", + "seq": 71, + "time": 1791748838.1658392 + } + ], + "usage": { + "calls": 31, + "input_tokens": 388482, + "output_tokens": 4804, + "reported_calls": 30, + "token_usage_complete": false + }, + "readiness": { + "ready": false, + "reason": "Restarted; inspect retained state and explicitly resume" + }, + "current_frame": { + "generation": 24, + "image_url": "/api/frame?generation=24&sha256=010748ac551827d5579da25ccf5ef0a1618f26a60826a7c5d5c452904d1eb68b", + "available": true + } + }, + "scope": "same retained origin and body, no unfinished job replay or additional model call" +} \ No newline at end of file diff --git a/jevdual/results/bench-operator-20261011/source-freeze.json b/jevdual/results/bench-operator-20261011/source-freeze.json new file mode 100644 index 0000000..28c0e59 --- /dev/null +++ b/jevdual/results/bench-operator-20261011/source-freeze.json @@ -0,0 +1,23 @@ +{ + "commit": "1415f594ccc91dbc6f7856ba9b2ab0252d45cfdb", + "files": { + "tools/camera-capture-experiment/capture.py": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "tools/physical-workcell/agent_bench.py": "e120dbfc9a96ca07fedb15226f27282265203755866210b86d5f856f6e3f5e07", + "tools/physical-workcell/bench.py": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "tools/physical-workcell/bench_operator.html": "f91275d998dc528b7701086def6007d78b30025660bf5076678e23bf63dcbf54", + "tools/physical-workcell/bench_operator.py": "dad93159cad4e9cd8c4d2780af5c495951af9b70f6405f25ca6ed696e6662024", + "tools/physical-workcell/codex-action.schema.json": "e57197e4e73aa4c78145814a460ca77b9c6dc5e49aaf4c91adc0b521b7c3d833", + "tools/physical-workcell/codex-policy.md": "ce947200b2a652e0766b422f3b404bd5095ceb398569341466b2c5f4dd9647bc", + "tools/physical-workcell/codex_policy.py": "40fe73e01d97ee1e5cfdb813650b11edadbea29534784ab10cc1ef4e7f4d5418", + "tools/physical-workcell/episode_cases.py": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "tools/physical-workcell/image_guided.py": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961", + "tools/physical-workcell/measurement.py": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "tools/physical-workcell/operator_runtime.py": "13d4c23cc2a95dbd76d408ff5e52b302be0fab791b659fde22839ccf9d5ddb48", + "tools/physical-workcell/order_protocol.py": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "tools/physical-workcell/qualify_bench.py": "524c537c1b310a0f0ae493acee99a069966a5e7c4b0a783daadf347094db58ef", + "tools/physical-workcell/scene.xml": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "tools/physical-workcell/score_operator.py": "d6548eadde719517ced687874d88025c00bc7494ef042932c46937e6abd0b220", + "tools/physical-workcell/workcell.py": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2" + }, + "qualification_version": 2 +} diff --git a/jevdual/results/bench-operator-20261011/v1/completed-reload.png b/jevdual/results/bench-operator-20261011/v1/completed-reload.png new file mode 100644 index 0000000000000000000000000000000000000000..46cdb3ab4386a7fadafe351a94bb751fa8d77046 GIT binary patch literal 69488 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

?7r_{<#)tJ|e>CrB$W0xm%3 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 literal 0 HcmV?d00001 diff --git a/jevdual/results/bench-operator-20261011/v1/conformance-summary.json b/jevdual/results/bench-operator-20261011/v1/conformance-summary.json new file mode 100644 index 0000000..0f8b4c6 --- /dev/null +++ b/jevdual/results/bench-operator-20261011/v1/conformance-summary.json @@ -0,0 +1,93 @@ +{ + "suites": [ + { + "suite": "runtime", + "passed": true, + "tests": 19, + "elapsed_s": 14.808, + "cases": [ + "test_cancelled_reply_stays_withheld_after_event_clears (test_operator_runtime.OperatorTests.test_cancelled_reply_stays_withheld_after_event_clears)", + "test_frame_identity_changes_when_zone_repaint_keeps_generation (test_operator_runtime.OperatorTests.test_frame_identity_changes_when_zone_repaint_keeps_generation)", + "test_get_state_and_frame_do_not_capture_or_call_model (test_operator_runtime.OperatorTests.test_get_state_and_frame_do_not_capture_or_call_model)", + "test_global_reserved_call_budget_blocks_starting_another_job (test_operator_runtime.OperatorTests.test_global_reserved_call_budget_blocks_starting_another_job)", + "test_http_origin_identity_duplicate_keys_and_body_schema (test_operator_runtime.OperatorTests.test_http_origin_identity_duplicate_keys_and_body_schema)", + "test_interrupted_start_intent_blocks_restart_without_replay (test_operator_runtime.OperatorTests.test_interrupted_start_intent_blocks_restart_without_replay)", + "test_invalid_finish_reset_refuses_native_guard (test_operator_runtime.OperatorTests.test_invalid_finish_reset_refuses_native_guard)", + "test_model_cannot_claim_completion_or_bypass_guard (test_operator_runtime.OperatorTests.test_model_cannot_claim_completion_or_bypass_guard)", + "test_model_unavailable_pauses_counts_attempt_and_never_completes (test_operator_runtime.OperatorTests.test_model_unavailable_pauses_counts_attempt_and_never_completes)", + "test_mutated_operator_manifest_and_fabricated_completion_refuse (test_operator_runtime.OperatorTests.test_mutated_operator_manifest_and_fabricated_completion_refuse)", + "test_new_identity_bound_to_separate_persistent_bench (test_operator_runtime.OperatorTests.test_new_identity_bound_to_separate_persistent_bench)", + "test_pause_during_model_prevents_late_reply_dispatch (test_operator_runtime.OperatorTests.test_pause_during_model_prevents_late_reply_dispatch)", + "test_queue_validation_duplicate_and_path_schema (test_operator_runtime.OperatorTests.test_queue_validation_duplicate_and_path_schema)", + "test_restart_retains_body_and_queue_without_replay (test_operator_runtime.OperatorTests.test_restart_retains_body_and_queue_without_replay)", + "test_shutdown_cancelled_model_exit_persists_stopped_after_worker_exits (test_operator_runtime.OperatorTests.test_shutdown_cancelled_model_exit_persists_stopped_after_worker_exits)", + "test_source_change_refuses_mutation (test_operator_runtime.OperatorTests.test_source_change_refuses_mutation)", + "test_stop_decision_pauses_without_completion (test_operator_runtime.OperatorTests.test_stop_decision_pauses_without_completion)", + "test_two_jobs_replay_public_action_fixture_and_disturbance_guard (test_operator_runtime.OperatorTests.test_two_jobs_replay_public_action_fixture_and_disturbance_guard)", + "test_unknown_native_blocks_resume_and_no_reset (test_operator_runtime.OperatorTests.test_unknown_native_blocks_resume_and_no_reset)" + ], + "private_log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-final-runtime-tests.log" + }, + { + "suite": "policy", + "passed": true, + "tests": 3, + "elapsed_s": 0.559, + "cases": [ + "test_closed_action_schema_finite_targets_and_no_success_flag (test_codex_policy.PolicyTests.test_closed_action_schema_finite_targets_and_no_success_flag)", + "test_fake_cli_bound_image_schema_tool_isolation_and_reservation (test_codex_policy.PolicyTests.test_fake_cli_bound_image_schema_tool_isolation_and_reservation)", + "test_usage_optional_and_any_tool_event_refuses (test_codex_policy.PolicyTests.test_usage_optional_and_any_tool_event_refuses)" + ], + "private_log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-final-policy-tests.log" + }, + { + "suite": "agent", + "passed": true, + "tests": 15, + "elapsed_s": 3.689, + "cases": [ + "test_challenge_has_only_images_task_and_public_observation (test_agent_bench.AgentBenchTests.test_challenge_has_only_images_task_and_public_observation)", + "test_changed_challenge_image_refuses (test_agent_bench.AgentBenchTests.test_changed_challenge_image_refuses)", + "test_changed_proposal_refuses_before_dispatch (test_agent_bench.AgentBenchTests.test_changed_proposal_refuses_before_dispatch)", + "test_error_after_real_move_stays_unknown_even_if_bench_ready (test_agent_bench.AgentBenchTests.test_error_after_real_move_stays_unknown_even_if_bench_ready)", + "test_foreign_challenge_and_unsafe_identity_refuse (test_agent_bench.AgentBenchTests.test_foreign_challenge_and_unsafe_identity_refuse)", + "test_measurement_placement_refusal_does_not_create_sqlite (test_agent_bench.AgentBenchTests.test_measurement_placement_refusal_does_not_create_sqlite)", + "test_measurement_worker_failure_retains_unknown_and_blocks_replay (test_agent_bench.AgentBenchTests.test_measurement_worker_failure_retains_unknown_and_blocks_replay)", + "test_move_executes_once_duplicate_returns_exact_result (test_agent_bench.AgentBenchTests.test_move_executes_once_duplicate_returns_exact_result)", + "test_nonfinite_and_conflicting_arguments_never_create_proposal (test_agent_bench.AgentBenchTests.test_nonfinite_and_conflicting_arguments_never_create_proposal)", + "test_proposal_persists_intent_without_effect (test_agent_bench.AgentBenchTests.test_proposal_persists_intent_without_effect)", + "test_public_cli_measurement_reset_and_status_strip_detector_locations (test_agent_bench.AgentBenchTests.test_public_cli_measurement_reset_and_status_strip_detector_locations)", + "test_source_change_and_foreign_bench_identity_block_dispatch (test_agent_bench.AgentBenchTests.test_source_change_and_foreign_bench_identity_block_dispatch)", + "test_stale_move_refuses_and_returns_fresh_image (test_agent_bench.AgentBenchTests.test_stale_move_refuses_and_returns_fresh_image)", + "test_unresolved_intent_blocks_same_and_new_proposal (test_agent_bench.AgentBenchTests.test_unresolved_intent_blocks_same_and_new_proposal)", + "test_wrong_reset_phase_preserves_bench (test_agent_bench.AgentBenchTests.test_wrong_reset_phase_preserves_bench)" + ], + "private_log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-final-agent-tests.log" + }, + { + "suite": "bench", + "passed": true, + "tests": 14, + "elapsed_s": 5.049, + "cases": [ + "test_corrupted_image_refuses_measurement_and_does_not_create_a_database (test_bench.BenchBehaviorTests.test_corrupted_image_refuses_measurement_and_does_not_create_a_database)", + "test_corrupted_native_state_never_causes_an_implicit_reset (test_bench.BenchBehaviorTests.test_corrupted_native_state_never_causes_an_implicit_reset)", + "test_corrupted_retained_model_refuses_without_recreating_the_body (test_bench.BenchBehaviorTests.test_corrupted_retained_model_refuses_without_recreating_the_body)", + "test_corrupted_source_binding_refuses_without_a_new_generation (test_bench.BenchBehaviorTests.test_corrupted_source_binding_refuses_without_a_new_generation)", + "test_diagnostic_force_needs_explicit_enablement_and_finite_bounds (test_bench.BenchBehaviorTests.test_diagnostic_force_needs_explicit_enablement_and_finite_bounds)", + "test_exact_motion_replay_retains_one_native_effect_and_conflicts_refuse (test_bench.BenchBehaviorTests.test_exact_motion_replay_retains_one_native_effect_and_conflicts_refuse)", + "test_external_force_invalidates_stale_motion_and_measurement_before_dispatch (test_bench.BenchBehaviorTests.test_external_force_invalidates_stale_motion_and_measurement_before_dispatch)", + "test_foreign_or_modified_observation_cannot_authorize_a_motion (test_bench.BenchBehaviorTests.test_foreign_or_modified_observation_cannot_authorize_a_motion)", + "test_measurement_column_corruption_is_not_hidden_by_an_unchanged_receipt (test_bench.BenchBehaviorTests.test_measurement_column_corruption_is_not_hidden_by_an_unchanged_receipt)", + "test_measurement_is_a_separate_process_with_exact_persisted_image_binding (test_bench.BenchBehaviorTests.test_measurement_is_a_separate_process_with_exact_persisted_image_binding)", + "test_measurement_receipt_corruption_refuses_historical_replay (test_bench.BenchBehaviorTests.test_measurement_receipt_corruption_refuses_historical_replay)", + "test_measurement_replay_is_historical_and_does_not_run_another_worker (test_bench.BenchBehaviorTests.test_measurement_replay_is_historical_and_does_not_run_another_worker)", + "test_retained_interrupted_intent_blocks_all_new_dispatch (test_bench.BenchBehaviorTests.test_retained_interrupted_intent_blocks_all_new_dispatch)", + "test_successive_job_gate_requires_measurement_and_verified_reset (test_bench.BenchBehaviorTests.test_successive_job_gate_requires_measurement_and_verified_reset)" + ], + "private_log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-final-bench-tests.log" + } + ], + "total_tests": 51, + "scope": "labelled conformance; fake policies are not actual AI completion evidence" +} \ No newline at end of file diff --git a/jevdual/results/bench-operator-20261011/v1/initial.json b/jevdual/results/bench-operator-20261011/v1/initial.json new file mode 100644 index 0000000..c0bca72 --- /dev/null +++ b/jevdual/results/bench-operator-20261011/v1/initial.json @@ -0,0 +1,25 @@ +{ + "active_job": null, + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "diagnostic_enabled": true, + "generation": 0, + "jobs": {}, + "native_time_s": 1.0000000000000007, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 +} diff --git a/jevdual/results/bench-operator-20261011/v1/pause-check.json b/jevdual/results/bench-operator-20261011/v1/pause-check.json new file mode 100644 index 0000000..57fb772 --- /dev/null +++ b/jevdual/results/bench-operator-20261011/v1/pause-check.json @@ -0,0 +1,93 @@ +{ + "state": { + "app_id": "6f81d519dcfb43c0a7fb05292e0c97d7", + "simulation": true, + "runner_status": "paused", + "jobs": [ + { + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "label": "Baseline inspection", + "target": "A", + "disturbance_test": false, + "status": "paused", + "phase": "prepare", + "call_count": 1, + "last_intent": "", + "measurement": null, + "error": "operator_pause_requested" + } + ], + "model_request_pending": false, + "active_job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "activity": [ + { + "seq": 1, + "time": 1791747955.0840802, + "kind": "queued", + "intent": "Baseline inspection", + "outcome": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef" + }, + { + "seq": 2, + "time": 1791747955.0969112, + "kind": "start_intent", + "intent": "Baseline inspection", + "outcome": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef" + }, + { + "seq": 3, + "time": 1791747955.1905348, + "kind": "inference", + "intent": "Baseline inspection", + "outcome": "Model call 1 reserved" + }, + { + "seq": 4, + "time": 1791747957.950015, + "kind": "pause", + "intent": "", + "outcome": "Paused; an in-flight native action may finish before the next boundary" + }, + { + "seq": 5, + "time": 1791747957.9677608, + "kind": "halt", + "intent": "", + "outcome": "operator_pause_requested" + } + ], + "usage": { + "calls": 1, + "input_tokens": 0, + "output_tokens": 0, + "reported_calls": 0, + "token_usage_complete": false + }, + "readiness": { + "ready": false, + "reason": "operator_pause_requested" + }, + "current_frame": { + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "available": true + } + }, + "outcome": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 2.4791216669837013, + "exit_code": 0, + "image_sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "outcome": "cancelled", + "pid": 43768, + "process_exit_observed": true, + "provider": "codex_cli", + "reason": "operator_pause_requested", + "request_sha256": "1ea7c320b8e069ddb9033b30e87ef09550f86a19f2d3842f10594ffa83c495e3", + "started_at": 1791747955.481091, + "usage": null + }, + "proposal_exists": false, + "dispatch_exists": false, + "native_generation": 0 +} \ No newline at end of file diff --git a/jevdual/results/bench-operator-20261011/v1/qualification-score.json b/jevdual/results/bench-operator-20261011/v1/qualification-score.json new file mode 100644 index 0000000..fa7d2dd --- /dev/null +++ b/jevdual/results/bench-operator-20261011/v1/qualification-score.json @@ -0,0 +1,1483 @@ +{ + "attempt": 1, + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "calls": [ + { + "call": 1, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-01", + "exact_image": true, + "image_sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 2.4791216669837013, + "exit_code": 0, + "image_sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "outcome": "cancelled", + "pid": 43768, + "process_exit_observed": true, + "provider": "codex_cli", + "reason": "operator_pause_requested", + "request_sha256": "1ea7c320b8e069ddb9033b30e87ef09550f86a19f2d3842f10594ffa83c495e3", + "started_at": 1791747955.481091, + "usage": null + } + }, + { + "call": 2, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-02", + "decision": { + "action": "move", + "intent": "Push the block right until its center reaches the target zone.", + "target_x": 0.015, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 7.849983792053536, + "exit_code": 0, + "image_sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7", + "outcome": "decision", + "pid": 44387, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "1ea7c320b8e069ddb9033b30e87ef09550f86a19f2d3842f10594ffa83c495e3", + "started_at": 1791748002.4942029, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 12612, + "output_tokens": 205 + } + }, + "reason": "" + }, + { + "call": 3, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-03", + "decision": { + "action": "move", + "intent": "Retract the pusher left to clear contact before measuring.", + "target_x": -0.05, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "cb4221e600bbb24aec549f49924fc9224876a1ad8d04159fe0cc3798658d8357", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 7.667845832998864, + "exit_code": 0, + "image_sha256": "cb4221e600bbb24aec549f49924fc9224876a1ad8d04159fe0cc3798658d8357", + "outcome": "decision", + "pid": 44900, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "63b5c518ef3926c4dddf0f6134737c5e1dafa71e505a2c0e819017d7eff0842c", + "started_at": 1791748010.667745, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13099, + "output_tokens": 173 + } + }, + "reason": "" + }, + { + "call": 4, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-04", + "decision": { + "action": "measure", + "intent": "Measure with the block centered in the target zone and the pusher clear.", + "target_x": null, + "target_y": null + }, + "exact_image": true, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 6.881987208034843, + "exit_code": 0, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "outcome": "decision", + "pid": 45415, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "3b8abc9063677d968e4568281b662ce535bb78d425d6e2a24249129ae0c113e2", + "started_at": 1791748018.6216419, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 12752, + "output_tokens": 120 + } + }, + "reason": "" + }, + { + "call": 5, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-05", + "decision": { + "action": "begin_reset", + "intent": "Begin reset after the verified measurement.", + "target_x": null, + "target_y": null + }, + "exact_image": true, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 4.3645455840742216, + "exit_code": 0, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "outcome": "decision", + "pid": 45925, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "234ec7c30702c2fcff25c81b82a4c9b2e881fdd13325a285df83fe1f13349dd1", + "started_at": 1791748026.124774, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 12819, + "output_tokens": 36 + } + }, + "reason": "" + }, + { + "call": 6, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-06", + "decision": { + "action": "move", + "intent": "Enter the upper bypass lane before crossing to the block's right side.", + "target_x": -0.05, + "target_y": 0.135 + }, + "exact_image": true, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 7.16687750001438, + "exit_code": 0, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "outcome": "decision", + "pid": 46434, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "e021570c95c0f3c592f9e9e4dd9557e739b3ce0b5f1c849fd3a1e3ac60582697", + "started_at": 1791748030.9481258, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 12878, + "output_tokens": 191 + } + }, + "reason": "" + }, + { + "call": 7, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-07", + "decision": { + "action": "move", + "intent": "Cross horizontally through the upper bypass lane to clear the block's right side.", + "target_x": 0.14, + "target_y": 0.135 + }, + "exact_image": true, + "image_sha256": "aeb57b730bc64cb1ec47fbf9a42ef0acce36a927702e60d6df1d751e4d240d1e", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 5.60894104198087, + "exit_code": 0, + "image_sha256": "aeb57b730bc64cb1ec47fbf9a42ef0acce36a927702e60d6df1d751e4d240d1e", + "outcome": "decision", + "pid": 46949, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "997c133c62de6f0728296dca32f078c8724c141ae634ba18e418a30929cb1044", + "started_at": 1791748038.544946, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12949, + "output_tokens": 144 + } + }, + "reason": "" + }, + { + "call": 8, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-08", + "decision": { + "action": "move", + "intent": "Descend from the bypass lane to align on the block's right side.", + "target_x": 0.14, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "c62187cd908d71592bdd7193b83ec80666e6f350e90968204d2d87a7169d12dc", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 7.800459083053283, + "exit_code": 0, + "image_sha256": "c62187cd908d71592bdd7193b83ec80666e6f350e90968204d2d87a7169d12dc", + "outcome": "decision", + "pid": 47455, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "f2a90b5784c11ee2709eb5eb54f01e79c43cc02e7afcbc89443a675705584e0a", + "started_at": 1791748044.5946538, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13021, + "output_tokens": 233 + } + }, + "reason": "" + }, + { + "call": 9, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-09", + "decision": { + "action": "move", + "intent": "Push the block left from its right side until its center reaches the home zone.", + "target_x": -0.065, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "e6f35d68a39eccb69ef08ffb81de2aed231bbe097a530bc31bb48ffda662a3f1", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 6.44600391597487, + "exit_code": 0, + "image_sha256": "e6f35d68a39eccb69ef08ffb81de2aed231bbe097a530bc31bb48ffda662a3f1", + "outcome": "decision", + "pid": 47967, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "18844fa9c6b4610d70f4d6f818204ab593467ce49d03474eaaa3505facc64594", + "started_at": 1791748052.853769, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13024, + "output_tokens": 191 + } + }, + "reason": "" + }, + { + "call": 10, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-10", + "decision": { + "action": "move", + "intent": "Retreat slightly right to release contact before entering the bypass lane.", + "target_x": -0.03, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "6c4785ad11fbf959867ca24381e9caf3a051c777b86c8e5357697aa2cdea5f67", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 6.274478291976266, + "exit_code": 0, + "image_sha256": "6c4785ad11fbf959867ca24381e9caf3a051c777b86c8e5357697aa2cdea5f67", + "outcome": "decision", + "pid": 48473, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "fc1027ce3a3f8c2dfbce7515e3f73caad702d7924d5cb0fdd57d3bb9ff214aa2", + "started_at": 1791748059.7891278, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13028, + "output_tokens": 205 + } + }, + "reason": "" + }, + { + "call": 11, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-11", + "decision": { + "action": "move", + "intent": "Enter the upper bypass lane before crossing left to the pusher home position.", + "target_x": -0.03, + "target_y": 0.135 + }, + "exact_image": true, + "image_sha256": "18e16fad85b15cc6b6c095191c6d8f1be9d3e1a605f05ae0ac11954d420d7c38", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 9.480418457998894, + "exit_code": 0, + "image_sha256": "18e16fad85b15cc6b6c095191c6d8f1be9d3e1a605f05ae0ac11954d420d7c38", + "outcome": "decision", + "pid": 48981, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "ed4d631901be126bad3f215cf2680783f6b35a9f8c396a706192f9c2bc77fd9f", + "started_at": 1791748066.594038, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13032, + "output_tokens": 177 + } + }, + "reason": "" + }, + { + "call": 12, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-12", + "decision": { + "action": "move", + "intent": "Cross left through the upper bypass lane to align above the pusher home position.", + "target_x": -0.3, + "target_y": 0.135 + }, + "exact_image": true, + "image_sha256": "18207abc055796d1b37f4b94528d52bfd960be835625169fc997360f0ec4d906", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 6.573040917050093, + "exit_code": 0, + "image_sha256": "18207abc055796d1b37f4b94528d52bfd960be835625169fc997360f0ec4d906", + "outcome": "decision", + "pid": 49516, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "6b4b53027012b1938db3e9fbb5a86e27954b84c4f9f79deb3fda8e946174ddb5", + "started_at": 1791748076.550199, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13045, + "output_tokens": 139 + } + }, + "reason": "" + }, + { + "call": 13, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-13", + "decision": { + "action": "move", + "intent": "Descend from the bypass lane to place the pusher at its home position.", + "target_x": -0.3, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "cda2378ead3e165186825aa560540c8495d01f07acff067406513a16ee92db65", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 4.563002625014633, + "exit_code": 0, + "image_sha256": "cda2378ead3e165186825aa560540c8495d01f07acff067406513a16ee92db65", + "outcome": "decision", + "pid": 50028, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "6f523f547452e42c1b16fa8bdc3262e08ec177eb04909c34719045c02e58322a", + "started_at": 1791748083.629318, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13047, + "output_tokens": 102 + } + }, + "reason": "" + }, + { + "call": 14, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/089965b9-90b8-4bc3-a4a0-71bcfc9bbeef-14", + "decision": { + "action": "finish_reset", + "intent": "Verify the block center and pusher are both at their home positions.", + "target_x": null, + "target_y": null + }, + "exact_image": true, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "input_has_no_private_pose": true, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 5.43770991708152, + "exit_code": 0, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "outcome": "decision", + "pid": 50527, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "d3ef7cb828ecfbcca3c2b6d94b8d74206e4dc3883724628489257a7a7ef9f3d3", + "started_at": 1791748088.6519191, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13048, + "output_tokens": 98 + } + }, + "reason": "" + }, + { + "call": 1, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-01", + "decision": { + "action": "move", + "intent": "Push the block rightward so its center enters the measurement region.", + "target_x": 0.02, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 7.025500625022687, + "exit_code": 0, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "outcome": "decision", + "pid": 51046, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "2b9935035d2ca76af7eeff020bc20cd89ceeca8ac70b78942df9190e20c0e10a", + "started_at": 1791748094.602582, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12608, + "output_tokens": 214 + } + }, + "reason": "" + }, + { + "call": 2, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-02", + "decision": { + "action": "move", + "intent": "Retreat the pusher left to clear contact before measuring.", + "target_x": -0.02, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "9dcda84f7fbb7dc6fefb739e5c03d41844904990de78d0ff166f200ac4b64d75", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 9.081188458018005, + "exit_code": 0, + "image_sha256": "9dcda84f7fbb7dc6fefb739e5c03d41844904990de78d0ff166f200ac4b64d75", + "outcome": "decision", + "pid": 51559, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "d5da5eeba589aad084d8341bc7c6f0c4ab352c59919387966d4bbe9f14791093", + "started_at": 1791748102.1232471, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12680, + "output_tokens": 194 + } + }, + "reason": "" + }, + { + "call": 3, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-03", + "decision": { + "action": "measure", + "intent": "Measure now that the block center is inside the target region and the pusher is clear.", + "target_x": null, + "target_y": null + }, + "exact_image": true, + "image_sha256": "fe4391474faf68c9747d98a5ccab2cb3e67bba7c701d34243160ebfa15dc88f3", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "refused", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 6.434076459030621, + "exit_code": 0, + "image_sha256": "fe4391474faf68c9747d98a5ccab2cb3e67bba7c701d34243160ebfa15dc88f3", + "outcome": "decision", + "pid": 52079, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "8eb42d1af7e9fc2b9c62d8ba5f898a4dad7a2e98a7b7364c07c2dd6f4a97b318", + "started_at": 1791748111.682272, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12749, + "output_tokens": 146 + } + }, + "reason": "observation is stale or foreign; no requested effect dispatched" + }, + { + "call": 4, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-04", + "decision": { + "action": "move", + "intent": "Push the block rightward until its center is securely inside the measurement region.", + "target_x": 0.01, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "b5090ea13b11819d9bb20df20761d158f9fc0371a22b0536b64ae9c75c199ad9", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 7.509735166095197, + "exit_code": 0, + "image_sha256": "b5090ea13b11819d9bb20df20761d158f9fc0371a22b0536b64ae9c75c199ad9", + "outcome": "decision", + "pid": 52590, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "b9bb9447f22ada733ca7f89cb5eb7331277e8e6097006242db95c5203cc90e31", + "started_at": 1791748118.5814898, + "usage": { + "cached_input_tokens": 10752, + "input_tokens": 13246, + "output_tokens": 213 + } + }, + "reason": "" + }, + { + "call": 5, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-05", + "decision": { + "action": "move", + "intent": "Retreat the pusher left to clear contact before measuring.", + "target_x": -0.03, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "9558a7e6223404d532dbe2fd33ea8423ca309bdbed0426b5f78ddb756dfb3dc0", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 8.427244249964133, + "exit_code": 0, + "image_sha256": "9558a7e6223404d532dbe2fd33ea8423ca309bdbed0426b5f78ddb756dfb3dc0", + "outcome": "decision", + "pid": 53100, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "c20289e474af81f88587306e8a49a38a28da12890457c78e185655845ccc2f48", + "started_at": 1791748126.5655649, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12902, + "output_tokens": 220 + } + }, + "reason": "" + }, + { + "call": 6, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-06", + "decision": { + "action": "measure", + "intent": "Measure now that the block center is inside the target region and the pusher is clear.", + "target_x": null, + "target_y": null + }, + "exact_image": true, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 8.417126499931328, + "exit_code": 0, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "outcome": "decision", + "pid": 53612, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "25b53c6f4be7e4ce1f606a3585c499d375187b734036d41386e6003ca7ba71f0", + "started_at": 1791748135.447528, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12971, + "output_tokens": 145 + } + }, + "reason": "" + }, + { + "call": 7, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-07", + "decision": { + "action": "begin_reset", + "intent": "Begin resetting after the verified measurement.", + "target_x": null, + "target_y": null + }, + "exact_image": true, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 4.853458332945593, + "exit_code": 0, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "outcome": "decision", + "pid": 54129, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "80136e11af46f16f2c9bec183a4089c6f16ecbe69116813d6d13d56e46356d6e", + "started_at": 1791748144.692519, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13041, + "output_tokens": 36 + } + }, + "reason": "" + }, + { + "call": 8, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-08", + "decision": { + "action": "move", + "intent": "Enter the upper bypass lane before crossing to the block's right side.", + "target_x": -0.03, + "target_y": 0.135 + }, + "exact_image": true, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 5.961126709007658, + "exit_code": 0, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "outcome": "decision", + "pid": 54630, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "f389429f86fdf134e081e4ecf8755c68bbec9c3bc8580d90c4faf1039a6e56d0", + "started_at": 1791748150.1803892, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13030, + "output_tokens": 154 + } + }, + "reason": "" + }, + { + "call": 9, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-09", + "decision": { + "action": "move", + "intent": "Cross the upper bypass lane to position the pusher safely on the block's right side.", + "target_x": 0.13, + "target_y": 0.135 + }, + "exact_image": true, + "image_sha256": "7aace630613576b58a4a90ab5c31f59a361dcaf33122917a4ecea5b0699de0b3", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 9.262546166894026, + "exit_code": 0, + "image_sha256": "7aace630613576b58a4a90ab5c31f59a361dcaf33122917a4ecea5b0699de0b3", + "outcome": "decision", + "pid": 55230, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "484495d5c496d831f25d497c04c8ae1b75aab4654e0686e0d49b3f3ea9dd4e11", + "started_at": 1791748156.7521942, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13032, + "output_tokens": 194 + } + }, + "reason": "" + }, + { + "call": 10, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-10", + "decision": { + "action": "move", + "intent": "Descend from the bypass lane to align safely on the block's right side.", + "target_x": 0.13, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "7cde902d68c7974bbf1fef5aa77c002f75c09b1f1bf2af83e75656a30212a995", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 7.034838500083424, + "exit_code": 0, + "image_sha256": "7cde902d68c7974bbf1fef5aa77c002f75c09b1f1bf2af83e75656a30212a995", + "outcome": "decision", + "pid": 55743, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "47eb58a72576319e857f0209c0e2fbbb429b570997c6059ea5213479c5ef2181", + "started_at": 1791748166.634509, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13026, + "output_tokens": 218 + } + }, + "reason": "" + }, + { + "call": 11, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-11", + "decision": { + "action": "move", + "intent": "Push the block left from its right side until its center reaches the home zone.", + "target_x": -0.065, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "a37ce97b1710cb0bdee031f6bfebee784c4f376e2f43a1d9b88883cf7a0b2a22", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 6.248244917020202, + "exit_code": 0, + "image_sha256": "a37ce97b1710cb0bdee031f6bfebee784c4f376e2f43a1d9b88883cf7a0b2a22", + "outcome": "decision", + "pid": 56253, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "fc697fc9959c09ee32f3171b63f643866e368fcca13632a8fa174052c5bd9d69", + "started_at": 1791748174.340254, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13027, + "output_tokens": 186 + } + }, + "reason": "" + }, + { + "call": 12, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-12", + "decision": { + "action": "move", + "intent": "Retreat slightly right to release contact before entering the bypass lane.", + "target_x": -0.03, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "7b672da1a7c7fc13edb2fce73f7849a65de4fd59fd4d5fbee7b777ae250ff951", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 6.222484749974683, + "exit_code": 0, + "image_sha256": "7b672da1a7c7fc13edb2fce73f7849a65de4fd59fd4d5fbee7b777ae250ff951", + "outcome": "decision", + "pid": 56766, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "cabc9d7bf03d68b5ed1dacf38a501e8f59a73fa3174c1704aed8e10129d0f976", + "started_at": 1791748181.269278, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13031, + "output_tokens": 177 + } + }, + "reason": "" + }, + { + "call": 13, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-13", + "decision": { + "action": "move", + "intent": "Enter the upper bypass lane before returning the pusher to its home position.", + "target_x": -0.03, + "target_y": 0.135 + }, + "exact_image": true, + "image_sha256": "ddd63e8e81f9bda9ae7aa090d918e00f57a11698fbd5de91678b5571b58e449e", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 7.362335458979942, + "exit_code": 0, + "image_sha256": "ddd63e8e81f9bda9ae7aa090d918e00f57a11698fbd5de91678b5571b58e449e", + "outcome": "decision", + "pid": 57270, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "b999d7bcf66542d894b3956c663771fd5e9db9b98215eb124dc34b3ddab1ed50", + "started_at": 1791748188.1343849, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13448, + "output_tokens": 172 + } + }, + "reason": "" + }, + { + "call": 14, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-14", + "decision": { + "action": "move", + "intent": "Cross the upper bypass lane to align above the pusher home position.", + "target_x": -0.3, + "target_y": 0.135 + }, + "exact_image": true, + "image_sha256": "1adaf7fe8dfee1cd5b5d2555f77541dc5fd312d5af140b3e710e69f3c3723568", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 5.290408417000435, + "exit_code": 0, + "image_sha256": "1adaf7fe8dfee1cd5b5d2555f77541dc5fd312d5af140b3e710e69f3c3723568", + "outcome": "decision", + "pid": 57777, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "35aab4696cafad1fb8b4b3800f757cd8db0b9f155c0a307831e8eeda92c37041", + "started_at": 1791748196.1089122, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13045, + "output_tokens": 124 + } + }, + "reason": "" + }, + { + "call": 15, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-15", + "decision": { + "action": "move", + "intent": "Descend from the bypass lane to place the pusher at its home position.", + "target_x": -0.3, + "target_y": 0.0 + }, + "exact_image": true, + "image_sha256": "77c82130db457b8ca7683d63d7869756967ad36785728429d25e99bc489b7b64", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 4.851276458008215, + "exit_code": 0, + "image_sha256": "77c82130db457b8ca7683d63d7869756967ad36785728429d25e99bc489b7b64", + "outcome": "decision", + "pid": 58281, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "60c2e07a3a346f67ac5f2abd81660440a8120b2da58976a777abc53ae08c358d", + "started_at": 1791748202.050539, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13045, + "output_tokens": 109 + } + }, + "reason": "" + }, + { + "call": 16, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim8-qualified-20261011-v1/calls/dcbe6123-1fc6-4442-bea9-e75b683c1f68-16", + "decision": { + "action": "finish_reset", + "intent": "Verify the block center and pusher are both at their home positions.", + "target_x": null, + "target_y": null + }, + "exact_image": true, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "input_has_no_private_pose": true, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "outcome": "executed", + "process": { + "cli_version": "codex-cli 0.147.0", + "elapsed_s": 5.12791329191532, + "exit_code": 0, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "outcome": "decision", + "pid": 58785, + "process_exit_observed": true, + "provider": "codex_cli", + "request_sha256": "e3916fe8fc35c920638457603be4cdca82c8d239dcd4980ca95e2700962edb65", + "started_at": 1791748207.581609, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13043, + "output_tokens": 87 + } + }, + "reason": "" + } + ], + "completed_cycles": 2, + "current_status": { + "active_job": null, + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "diagnostic_enabled": true, + "generation": 23, + "jobs": { + "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef": { + "completed_generation": 10, + "completed_native_time_s": 21.81399999999879, + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "measurement_operation_id": "agent-afd48d867d2346f4a01d3659c4aec982", + "measurement_receipt": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "generation": 2, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.533999999999613, + "operation_id": "agent-afd48d867d2346f4a01d3659c4aec982", + "source_kind": "mujoco_simulation", + "state_sha256": "ebb7a34ed4811733325084e937c4752a7fe9349c170fff8a2f3d5243bae73cf3", + "version": 1, + "worker_pid": 45916 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "kind": "finish_reset", + "native_time_s": 21.81399999999879, + "operation_id": "agent-a52f04d4553c46fa8023896307981195", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8140, + "state_sha256": "ff7af086a1eea92c53736c30a05c8102da4417d39f0423b48573218144fcb713" + }, + "reset_started_generation": 2, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "dcbe6123-1fc6-4442-bea9-e75b683c1f68": { + "completed_generation": 23, + "completed_native_time_s": 45.86000000001008, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "measurement_operation_id": "agent-ab389fc3848a4fc5a17b18e1fe931de0", + "measurement_receipt": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "generation": 15, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "measurement": { + "block_box": [ + 336, + 159, + 378, + 201 + ], + "block_center_xy": [ + 0.06166666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 356.0365217391304, + 179.5304347826087 + ], + "footprint_area_m2": 0.004791666666666666, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1725 + }, + "native_time_s": 29.845999999994337, + "operation_id": "agent-ab389fc3848a4fc5a17b18e1fe931de0", + "source_kind": "mujoco_simulation", + "state_sha256": "99f7e539e079b784ca4c8e530b34d3f5a96514d0c661f2e137c66c34cb2d19f4", + "version": 1, + "worker_pid": 54121 + }, + "moves": 12, + "phase": "completed", + "reset_receipt": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "block_home_verified": true, + "generation": 23, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "kind": "finish_reset", + "native_time_s": 45.86000000001008, + "operation_id": "agent-86a32a4e78e64aaf9322558f4d9d0853", + "pusher_home_verified": true, + "reset_contact_samples": 3112, + "reset_native_steps": 8007, + "state_sha256": "ab359450848224f47ced5d9c79542dc8a733034a8d40053381de7c7569fd3115" + }, + "reset_started_generation": 15, + "started_generation": 10, + "started_native_time_s": 21.81399999999879, + "target_zone": { + "x_max": 0.115, + "x_min": 0.045, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 45.86000000001008, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "fault_chain": { + "after": { + "block_center_in_zone": false, + "block_xyz": [ + 0.03101368936485668, + -2.3636102442079535e-09, + 0.03499824550643647 + ], + "external_force_cleared": true, + "generation": 13, + "native_time_s": 27.375999999995706, + "pusher_home": false, + "pusher_xyz": [ + -0.023983540317720375, + 1.7203059752249304e-17, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "c231f845db47170cb50d5a98b52fd2304ff320967fd89fae6c21dab71ac24936" + }, + "before": { + "block_center_in_zone": true, + "block_xyz": [ + 0.07079077670575931, + -2.363612923572088e-09, + 0.03499573045536986 + ], + "external_force_cleared": true, + "generation": 12, + "native_time_s": 26.21599999999635, + "pusher_home": false, + "pusher_xyz": [ + -0.019999970650332433, + -3.5065733542877396e-26, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "e9a6f4f2aac925aa4018c27cbb9dfd3fb75852b71e68e8a13d1221605eae01ae" + }, + "displacement_m": 0.039777087420414255, + "force": { + "receipt": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "force_x_n": -1.5, + "forced_steps": 80, + "generation": 13, + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "kind": "diagnostic_external_force", + "native_steps": 580, + "native_time_s": 27.375999999995706, + "operation_id": "disturb-ae433d5c49634285847f2c50aa67355b", + "state_sha256": "c231f845db47170cb50d5a98b52fd2304ff320967fd89fae6c21dab71ac24936" + }, + "request": { + "force_x_n": -1.5, + "kind": "disturb", + "steps": 80 + } + }, + "fresh_model_move_bound_to_force_image": true, + "immutable_chain_bound": true, + "no_measurement_effect": true, + "passed": true, + "saved_proposal_id": "proposal-d76c7e8666f8478baf4ce0cf6174f8a4", + "stale_call": 3 + }, + "fresh_model_move_after_refusal": true, + "model_boundaries_passed": true, + "passed": false, + "qualification_version": 1, + "scope": "separate post-trial native/SQLite and retained model-boundary scoring; browser evidence recorded separately", + "scores": [ + { + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "label": "Baseline inspection", + "measurement": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "generation": 2, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.533999999999613, + "operation_id": "agent-afd48d867d2346f4a01d3659c4aec982", + "source_kind": "mujoco_simulation", + "state_sha256": "ebb7a34ed4811733325084e937c4752a7fe9349c170fff8a2f3d5243bae73cf3", + "version": 1, + "worker_pid": 45916 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06582868246696554, + -8.393868978677625e-11, + 0.034995730455369786 + ], + "external_force_cleared": true, + "generation": 2, + "native_time_s": 5.533999999999613, + "pusher_home": false, + "pusher_xyz": [ + -0.049999969408768885, + 8.057882667829012e-26, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "ebb7a34ed4811733325084e937c4752a7fe9349c170fff8a2f3d5243bae73cf3" + }, + "model_calls": 14, + "motion_count": 10, + "passed": true, + "reset": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "kind": "finish_reset", + "native_time_s": 21.81399999999879, + "operation_id": "agent-a52f04d4553c46fa8023896307981195", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8140, + "state_sha256": "ff7af086a1eea92c53736c30a05c8102da4417d39f0423b48573218144fcb713" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11582763630912812, + -2.3633644648884637e-09, + 0.03499573045536985 + ], + "external_force_cleared": true, + "generation": 10, + "native_time_s": 21.81399999999879, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "ff7af086a1eea92c53736c30a05c8102da4417d39f0423b48573218144fcb713" + } + }, + { + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "label": "Recovery inspection", + "measurement": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "generation": 15, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "measurement": { + "block_box": [ + 336, + 159, + 378, + 201 + ], + "block_center_xy": [ + 0.06166666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 356.0365217391304, + 179.5304347826087 + ], + "footprint_area_m2": 0.004791666666666666, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1725 + }, + "native_time_s": 29.845999999994337, + "operation_id": "agent-ab389fc3848a4fc5a17b18e1fe931de0", + "source_kind": "mujoco_simulation", + "state_sha256": "99f7e539e079b784ca4c8e530b34d3f5a96514d0c661f2e137c66c34cb2d19f4", + "version": 1, + "worker_pid": 54121 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.060828133227863616, + -2.363604036670241e-09, + 0.03499573045536984 + ], + "external_force_cleared": true, + "generation": 15, + "native_time_s": 29.845999999994337, + "pusher_home": false, + "pusher_xyz": [ + -0.02999997064612875, + -6.834842985587421e-26, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "99f7e539e079b784ca4c8e530b34d3f5a96514d0c661f2e137c66c34cb2d19f4" + }, + "model_calls": 16, + "motion_count": 12, + "passed": true, + "reset": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "block_home_verified": true, + "generation": 23, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "kind": "finish_reset", + "native_time_s": 45.86000000001008, + "operation_id": "agent-86a32a4e78e64aaf9322558f4d9d0853", + "pusher_home_verified": true, + "reset_contact_samples": 3112, + "reset_native_steps": 8007, + "state_sha256": "ab359450848224f47ced5d9c79542dc8a733034a8d40053381de7c7569fd3115" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11577112750257858, + -5.9658799447144094e-09, + 0.03499573045536983 + ], + "external_force_cleared": true, + "generation": 23, + "native_time_s": 45.86000000001008, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "ab359450848224f47ced5d9c79542dc8a733034a8d40053381de7c7569fd3115" + } + } + ], + "source_commit": "e7b716a8221db6b69c876dde030235f59d643460", + "source_unchanged": false, + "sqlite": { + "count": 2, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "generation": 2, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "operation_id": "agent-afd48d867d2346f4a01d3659c4aec982", + "receipt": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "generation": 2, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "job_id": "089965b9-90b8-4bc3-a4a0-71bcfc9bbeef", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.533999999999613, + "operation_id": "agent-afd48d867d2346f4a01d3659c4aec982", + "source_kind": "mujoco_simulation", + "state_sha256": "ebb7a34ed4811733325084e937c4752a7fe9349c170fff8a2f3d5243bae73cf3", + "version": 1, + "worker_pid": 45916 + }, + "state_sha256": "ebb7a34ed4811733325084e937c4752a7fe9349c170fff8a2f3d5243bae73cf3" + }, + { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "generation": 15, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "operation_id": "agent-ab389fc3848a4fc5a17b18e1fe931de0", + "receipt": { + "bench_id": "809a7e27db014f759e4e323e83dff8a7", + "generation": 15, + "image_sha256": "9cb34f24c00f6647c2c9763ca17e4d7189620c96ff40059736b25ff0d67d3dcc", + "job_id": "dcbe6123-1fc6-4442-bea9-e75b683c1f68", + "measurement": { + "block_box": [ + 336, + 159, + 378, + 201 + ], + "block_center_xy": [ + 0.06166666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 356.0365217391304, + 179.5304347826087 + ], + "footprint_area_m2": 0.004791666666666666, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1725 + }, + "native_time_s": 29.845999999994337, + "operation_id": "agent-ab389fc3848a4fc5a17b18e1fe931de0", + "source_kind": "mujoco_simulation", + "state_sha256": "99f7e539e079b784ca4c8e530b34d3f5a96514d0c661f2e137c66c34cb2d19f4", + "version": 1, + "worker_pid": 54121 + }, + "state_sha256": "99f7e539e079b784ca4c8e530b34d3f5a96514d0c661f2e137c66c34cb2d19f4" + } + ] + }, + "stale_measure_refused": true, + "usage": { + "calls": 30, + "input_tokens": 376278, + "output_tokens": 4603, + "reported_calls": 29 + }, + "version": 1 +} diff --git a/jevdual/results/bench-operator-20261011/v1/score-attempt1.json b/jevdual/results/bench-operator-20261011/v1/score-attempt1.json new file mode 100644 index 0000000..8fbc17c --- /dev/null +++ b/jevdual/results/bench-operator-20261011/v1/score-attempt1.json @@ -0,0 +1 @@ +{"outcome": "refused", "reason": "another process owns this application directory", "no_score_created": true, "next": "close owned UI/server before independent read-only scoring"} \ No newline at end of file diff --git a/jevdual/results/bench-operator-20261011/v1/score-attempt2.json b/jevdual/results/bench-operator-20261011/v1/score-attempt2.json new file mode 100644 index 0000000..46ef899 --- /dev/null +++ b/jevdual/results/bench-operator-20261011/v1/score-attempt2.json @@ -0,0 +1 @@ +{"outcome": "refused", "reason": "PNG read used 64 KiB protocol-data bound; no score written", "next": "preregistered scorer repair with 1 MiB image bound"} \ No newline at end of file diff --git a/jevdual/results/bench-operator-20261011/v1/source-freeze.json b/jevdual/results/bench-operator-20261011/v1/source-freeze.json new file mode 100644 index 0000000..f6c8ece --- /dev/null +++ b/jevdual/results/bench-operator-20261011/v1/source-freeze.json @@ -0,0 +1,22 @@ +{ + "commit": "e7b716a8221db6b69c876dde030235f59d643460", + "files": { + "tools/camera-capture-experiment/capture.py": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "tools/physical-workcell/agent_bench.py": "e120dbfc9a96ca07fedb15226f27282265203755866210b86d5f856f6e3f5e07", + "tools/physical-workcell/bench.py": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "tools/physical-workcell/bench_operator.html": "f91275d998dc528b7701086def6007d78b30025660bf5076678e23bf63dcbf54", + "tools/physical-workcell/bench_operator.py": "dad93159cad4e9cd8c4d2780af5c495951af9b70f6405f25ca6ed696e6662024", + "tools/physical-workcell/codex-action.schema.json": "e57197e4e73aa4c78145814a460ca77b9c6dc5e49aaf4c91adc0b521b7c3d833", + "tools/physical-workcell/codex-policy.md": "ce947200b2a652e0766b422f3b404bd5095ceb398569341466b2c5f4dd9647bc", + "tools/physical-workcell/codex_policy.py": "40fe73e01d97ee1e5cfdb813650b11edadbea29534784ab10cc1ef4e7f4d5418", + "tools/physical-workcell/episode_cases.py": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "tools/physical-workcell/image_guided.py": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961", + "tools/physical-workcell/measurement.py": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "tools/physical-workcell/operator_runtime.py": "1960a526b47c95d9abdefb92388adacc4d6447706782e10aad61f4b49bf304a3", + "tools/physical-workcell/order_protocol.py": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "tools/physical-workcell/qualify_bench.py": "524c537c1b310a0f0ae493acee99a069966a5e7c4b0a783daadf347094db58ef", + "tools/physical-workcell/scene.xml": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "tools/physical-workcell/score_operator.py": "d4846a5d4741f67f1041b6588363c959cb02507638914ea8e6922b7745380b25", + "tools/physical-workcell/workcell.py": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2" + } +} diff --git a/tools/physical-workcell/README.md b/tools/physical-workcell/README.md index 8cd6475..064eb9e 100644 --- a/tools/physical-workcell/README.md +++ b/tools/physical-workcell/README.md @@ -5,9 +5,10 @@ then stage a local software work-order result only when the observed block cente the order's inspection zone. Footwork independently checks the saved result bytes. Every observation, action, render and software result is labeled `mujoco_simulation`. -There is no real robot, camera acquisition, learned policy, visual-recognition claim, -cloud call or external task creation. State readback comes directly from the native -simulator. This package is an isolated experiment, rather than a production Footwork adapter. +The base commands on this page use native simulator state and do not call a learned +policy or cloud model. The linked routes below add RGB control, actual model decisions +and independent verification. All routes use simulation; real robots and camera +acquisition remain outside this isolated experiment. For RGB-driven agent control, use the separate [image-guided route](IMAGE_GUIDED.md). It keeps native poses out of planner packets and adds a fresh visual gate before computer staging. From 3e6e06ddc12ea4c810dfa10227dca0f8a0d2c7a1 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:18:00 -0400 Subject: [PATCH 107/216] Record human guest setup and live SIP readback --- jevdual/docs/notebook/2026-10-11-u2-vm-provision.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md index 493c6e9..b4e5e4a 100644 --- a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md +++ b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md @@ -88,3 +88,8 @@ Established: pinned launchers/artifact provenance, safe supported Tart flags/sto Uncertain: guest SIP runtime status, denied Accessibility baseline, actual ISO guest read-only/hash readback and the complete installed U2 effect/restart/report/cleanup journey. Tart Gatekeeper diagnostics reported Unnotarized Developer ID even though normal CLI/create/run succeeded without policy overrides. Decision: hand the running guest and all GUI ownership to root at the explicit human setup/license boundary; keep VM3 and UO2 open. Refs: output/u2-vm-provision-20261011/delivery-record/report.md; output/u2-vm-provision-20261011/delivery-record/summary.json + +## VMU9 · update · 2026-10-11 16:18 +Observed: the user reports accepting the macOS license and creating the disposable guest account. Root observed the unlocked desktop and launched the guest interactive Terminal, com.apple.Terminal version2.15. Guest sw_vers reports macOS26.6.2 build25G83; csrutil reports SIP enabled. diskutil reports both media and volume read-only at /Volumes/FOOTWORK_U2 with the exact six staged filenames. Guest payload checksum verification is running; VM3 remains open until those results are observed. Native CUA modifier-key input is not reliably forwarded by the VM; unmodified menu navigation and printf octal-decoded commands execute in the same Terminal without clipboard sharing. No Accessibility grant or product installation has occurred. +Next: finish guest media verification, install verified prerequisites, then capture the denied installed diagnostic and fixture before any permission grant. +Refs: root native CUA tool images in this chat; guest /Users/tom/footwork-u2/baseline.txt; guest /Users/tom/footwork-u2/media-hashes.txt From c54ddf29b01fc4e2a6505b1b9670d24d030f27f6 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:18:27 -0400 Subject: [PATCH 108/216] Record independent guest read-only asset verification --- jevdual/docs/notebook/2026-10-11-u2-vm-provision.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md index b4e5e4a..9f0f154 100644 --- a/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md +++ b/jevdual/docs/notebook/2026-10-11-u2-vm-provision.md @@ -93,3 +93,9 @@ Refs: output/u2-vm-provision-20261011/delivery-record/report.md; output/u2-vm-pr Observed: the user reports accepting the macOS license and creating the disposable guest account. Root observed the unlocked desktop and launched the guest interactive Terminal, com.apple.Terminal version2.15. Guest sw_vers reports macOS26.6.2 build25G83; csrutil reports SIP enabled. diskutil reports both media and volume read-only at /Volumes/FOOTWORK_U2 with the exact six staged filenames. Guest payload checksum verification is running; VM3 remains open until those results are observed. Native CUA modifier-key input is not reliably forwarded by the VM; unmodified menu navigation and printf octal-decoded commands execute in the same Terminal without clipboard sharing. No Accessibility grant or product installation has occurred. Next: finish guest media verification, install verified prerequisites, then capture the denied installed diagnostic and fixture before any permission grant. Refs: root native CUA tool images in this chat; guest /Users/tom/footwork-u2/baseline.txt; guest /Users/tom/footwork-u2/media-hashes.txt + +## VMU10 · update · 2026-10-11 16:18 +Resolves: VM3 = held +Observed: the guest read-only qualification volume contains the exact six staged files. The guest shasum check reports OK for all four executable/archive payloads, including packetv3. Root observed the completed output in the native viewer; guest media-hashes.txt preserves it. The prior host ISO parser verified the metadata files and payload bytes; the guest readback now establishes transport to the same independent environment. +Next: install verified prerequisites and execute UO2; preparation and media verification do not establish first-use permission or native effect success. +Refs: guest /Users/tom/footwork-u2/media-hashes.txt; output/u2-vm-provision-20261011/iso-verification.json; root native CUA tool images in this chat From 33ed0f2511eb7dd968777d132e4aaa3bfb91aabb Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:22:08 -0400 Subject: [PATCH 109/216] Preserve observed clean guest qualification gates at authentication handoff --- .../2026-10-10-independent-onboarding.md | 5 +++ .../report.md | 11 +++++ .../summary.json | 40 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/report.md create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/summary.json diff --git a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md index a8a327c..b21d936 100644 --- a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md +++ b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md @@ -44,3 +44,8 @@ Established: self-checked transportable packet, immutable source verification, g Uncertain: independent environment, actual denied-to-approved TCC/host transition, native U2 postconditions and Claude's queued review remain unavailable. Internal7.9GiB free disk constrains a local guest; no launcher/image/guest was installed. Decision: deliver this bounded preparation on a local branch, keep UO2 open, and require an independent Mac or selected VM/storage environment before its runtime lane. Do not present source/helper checks as first-use qualification. Refs: results/independent-onboarding-preparation-20261010/report.md; aa971782 + +## UOU4 · update · 2026-10-11 16:22 +Observed: the independently provisioned guest is at the desktop after human license/account setup. Root observed SIP enabled, the exact read-only qualification volume, four payload checksum passes and guest Terminal com.apple.Terminal2.15. Packetv3 is freshly extracted and uv0.12.5 runs. The human approved the Python3.14.7 license at its actual Agree dialog; root accepted it. Installation now requires guest administrator authentication, handed to the human to keep credentials out of tool logs. Chrome image is mounted read-only with signature assessment pending. No installed diagnostic, TCC grant or native oracle has run; UO2 remains open. +Next: resume at installer authentication, then pristine packet verification and cold dependency install before the denied Accessibility baseline. +Refs: results/u2-independent-onboarding-20261011-v1; guest /Users/tom/footwork-u2; root native CUA tool images in this chat diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md new file mode 100644 index 0000000..34467b6 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md @@ -0,0 +1,11 @@ +# U2 independent guest qualification v1: partial record + +The independent guest is running after the human accepted the macOS license and created its account. This records observed setup gates; it does not qualify the installed permission journey. + +Root observed macOS 26.6.2 build 25G83, SIP enabled, and the guest interactive Terminal identified as com.apple.Terminal version 2.15. Guest diskutil reports both media and volume read-only at /Volumes/FOOTWORK_U2. The six staged filenames match the source inventory; shasum reports OK for all four payloads. Guest baseline.txt and media-hashes.txt under /Users/tom/footwork-u2 preserve these outputs. Their contents have not yet been exported to the host. Native CUA tool images in the chat are the independently observed evidence; no local screenshot path is claimed. + +The packet is freshly extracted and uv 0.12.5 runs. The official Python 3.14.7 installer reached its actual Agree dialog; the human approved that license, root accepted it, and installation is waiting for guest administrator authentication. Credential entry is handed to the human to keep it out of tool logs. Chrome's verified image is mounted read-only; codesign and Gatekeeper assessment were launched but their completion has not yet been observed. + +Synthetic modifier keys do not reliably reach this VM: sw_vers initially arrived as sw-vers. Root retained that failed command and verified a printf octal-decoded route with the same public command, then continued through the same guest Terminal without clipboard sharing or SSH. This input workaround is qualification infrastructure, not a product change or permission grant. + +Next gates: authenticate the guest installer; verify installed Python and pristine packet members; verify and install Chrome; run the frozen cold dependency installer; capture strict denied Accessibility diagnostics and fixture refusal; obtain the human's exact responsible-host grant, restart and read back; run the native append/restart/report oracle and qualify owned-resource cleanup. UO2 remains open. No Accessibility grant, product dependency install, native effect or cleanup test has run. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json new file mode 100644 index 0000000..5f59589 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json @@ -0,0 +1,40 @@ +{ + "recorded_at": "2026-10-11T16:22:00-04:00", + "status": "in_progress_waiting_for_guest_installer_authentication", + "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", + "packet_sha256": "769c08c89061731368db33d78b180e7c8c96d531190f43bee44263642a76fd0f", + "guest": { + "os": "macOS", + "version": "26.6.2", + "build": "25G83", + "sip": "enabled", + "responsible_host": "com.apple.Terminal", + "responsible_host_version": "2.15" + }, + "media": { + "mount": "/Volumes/FOOTWORK_U2", + "media_read_only": true, + "volume_read_only": true, + "visible_files": 6, + "payload_checksum_checks": 4, + "payload_checksum_passes": 4 + }, + "prerequisites": { + "uv_version": "0.12.5", + "python_installed": false, + "python_license": "human_approved_and_accepted", + "python_installer": "waiting_for_guest_admin_authentication", + "chrome_dmg": "mounted_read_only", + "chrome_signature": "assessment_started_result_not_yet_observed" + }, + "qualification": { + "packet_member_verification": "pending_installed_python", + "cold_dependency_install": "not_run", + "denied_accessibility_baseline": "not_run", + "permission_transition": "not_run", + "native_effect_restart_report": "not_run", + "cleanup": "not_run", + "qualified": false + }, + "evidence_location": "Guest /Users/tom/footwork-u2 and native CUA tool images in the current chat; guest receipts not exported yet" +} From c976508a29a97d53de1d23a9f271f9056d3240ba Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:22:33 -0400 Subject: [PATCH 110/216] Preregister persistent network body fault qualification --- .../experiments/SIM9-network-body-adapter.md | 19 +++++++++++++++ .../2026-10-11-network-body-adapter.md | 8 +++++++ tools/physical-workcell/NETWORK_CONTRACT.md | 23 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 jevdual/docs/experiments/SIM9-network-body-adapter.md create mode 100644 jevdual/docs/notebook/2026-10-11-network-body-adapter.md create mode 100644 tools/physical-workcell/NETWORK_CONTRACT.md diff --git a/jevdual/docs/experiments/SIM9-network-body-adapter.md b/jevdual/docs/experiments/SIM9-network-body-adapter.md new file mode 100644 index 0000000..830a02b --- /dev/null +++ b/jevdual/docs/experiments/SIM9-network-body-adapter.md @@ -0,0 +1,19 @@ +# SIM9: Persistent body over a network + +Hypothesis: a durable TCP adapter can separate visual planning from the persistent simulated body while preserving local effect authority under transport failures. + +Predictions if true: exact duplicate commands retain one result and one effect; lost replies require read-only reconciliation; expired leases fence late commands; restart retains body identity and state without replay; insufficient lower-level evidence remains unknown and blocks new actions. + +Predictions if false: network ambiguity permits duplicate motion, stale observations reach effects, restart erases uncertainty or changes body identity, or recovery requires direct native-state manipulation. + +Design: one loopback HTTP body service, separate durable client and fault proxy on this Mac. Keep existing Bench and AgentBench guards unchanged. Pin adapter/body/source identities; persist command intent before dispatch; use server-monotonic leases revoked on every boot. Images cross TCP and are hash checked before model input. This qualifies a same-host network boundary, not authentication, WAN operation or hardware. + +Primary metric: all 12 required mechanical cases pass: successive cycles; bounded delay; drop before acceptance; drop after effect; exact concurrent duplicate; conflicting duplicate; stale observation; delay past lease expiry; identity/source/exclusive lease fencing; service restart after terminal result; restart after lower receipt before transport receipt; unresolved accepted intent plus client restart remains blocked. + +Secondary qualification: two successive actual Codex image-guided jobs on one network body, with at least one lost dispatch reply reconciled without resending. Independently inspect retained native states, measurement SQLite and contact reset receipts after stopping run-owned processes. Conformance planners do not count as AI evidence. + +Guardrails: no direct move endpoint, no teleport, no native pose supplied to the model, no automatic uncertain-command retry, no source edits during frozen qualification. Admission leases do not promise interruption of an already accepted bounded action. Preserve all failures and attempts; paid/model runs start only at committed measured source. + +Decision rule: adopt the adapter as a loopback simulated prototype only if the mechanical matrix and independent model qualification pass. Report partial or inconclusive evidence explicitly; lower-receipt absence remains unknown. + +References: tools/physical-workcell/agent_bench.py; tools/physical-workcell/bench.py; SIM8-bench-operator.md. Local LeRobot reference b9cb121cb7d4e3e26ec5c906d08dda68d151ba52, src/lerobot/async_inference/policy_server.py and robot_client.py, informs remote observation/planning separation. Its observation queue is not used as an effect receipt protocol. diff --git a/jevdual/docs/notebook/2026-10-11-network-body-adapter.md b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md new file mode 100644 index 0000000..25dcc60 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md @@ -0,0 +1,8 @@ +# Persistent network body adapter + +## SIM9-P1 · prediction · 2026-10-11 16:21 +Hypothesis: durable transport intent, short-lived admission leases and exact lower receipts preserve one-body authority under delays, disconnects, duplicates and process restart without replaying uncertain effects. +Test: implement a separate HTTP service/client around unchanged Bench and AgentBench; drive the twelve preregistered real-socket cases, then freeze source and run two actual image-guided Codex cycles with a lost dispatch reply. +Predicts: duplicate command results match without extra generation; read-only reconciliation settles proven effects; expired or revoked leases fence late requests; missing lower proof remains unknown and blocks dispatch; model cycles retain native/SQLite/contact evidence on one body. +Against: duplicate native effects, admitted stale/expired/wrong-body commands, automatic uncertain retry, erased unknown intent, body recreation on restart, private pose in model input, or independent cycle scoring failure. +Refs: docs/experiments/SIM9-network-body-adapter.md; tools/physical-workcell/output/sim9-network-body/; results/network-body-adapter-20261011/ diff --git a/tools/physical-workcell/NETWORK_CONTRACT.md b/tools/physical-workcell/NETWORK_CONTRACT.md new file mode 100644 index 0000000..85aeb80 --- /dev/null +++ b/tools/physical-workcell/NETWORK_CONTRACT.md @@ -0,0 +1,23 @@ +# Persistent body adapter contract + +Caller: BodyClient connects once to a loopback BodyService, pins identity, acquires a lease, starts a job, fetches an image challenge, proposes a typed action and dispatches its proposal. An uncertain reply blocks new commands until read-only reconciliation settles it. The original local browser product remains available. + +Server owns native Bench, AgentBench, transport command journal and current lease. Client owns pinned identity, immutable outgoing requests, unknown outcomes and downloaded PNGs. The proxy owns only diagnostic transport faults. Native sources remain unchanged. + +Protocol: `footwork.body/1`. Identity fields `protocol, adapter_id, body_id, source_sha256, epoch, simulation`. Server restart changes epoch and revokes leases while retaining adapter/body identity. Source SHA pins core sources plus body_protocol.py and body_network.py. Private owned roots live under output. Lifetime server root flock and serialized admission protect concurrency. + +Endpoints: GET /identity; GET /state; POST /lease with client_id, expected_epoch, duration_s (0.05..30); POST /commands; GET /commands/ with client_id, lease_id, epoch, request_sha256 query; GET /images/. Pinned requests use X-Body-Id, X-Adapter-Id, X-Source-Sha256 headers. No redirects, browser Origin, CORS, arbitrary files or non-loopback bind. + +Command exact fields: protocol, adapter_id, body_id, source_sha256, client_id, lease_id, epoch, command_id, operation, arguments. Operations: start_job {job_id,target_zone}; observe {}; propose {challenge_id,action,intent,target_x,target_y}, using null targets for non-move; dispatch {proposal_id}; diagnostic disturb {operation_id,force_x_n,steps} only when enabled. Validate before admission, persist canonical digest and request before effect. Refused admission creates no accepted intent. Budgets: 256 retained commands and bounded JSON/media. + +Response envelope: protocol, adapter_id, body_id, source_sha256, command_id, request_sha256, state, result, reason, receipt_scope, recorded_epoch. States completed, refused, unknown, not_seen, not_accepted. completed means known RPC result; dispatch's inner outcome remains executed/refused/unknown. receipt_scope is retained_command_result. Exact ID/digest returns original envelope; conflicting digest refuses. Results are historical, never fresh observations. Known core unknown remains unknown. + +Reconcile: query exact original ID/digest. Missing journal plus valid lease is not_seen (inflight remains possible). Missing journal plus expired/revoked lease or changed boot epoch is not_accepted (late request fenced). Accepted missing result is unknown. On boot only dispatch intents with an indexed, hash-verified stored AgentBench result may be reconciled read-only; never call dispatch to repair a receipt. Other missing lower proof remains blocked. + +Lease acquire rotates lease ID, even for same client. Other unexpired holder refuses. Check server monotonic expiry and boot epoch inside admission lock. A lease fences new actions; an already admitted native action may finish within its existing local bounds after disconnect or expiry. + +Client public API: BodyClient(root, origin, timeout=15), acquire(duration_s=30), start_job(job_id,zone), observe(), propose(challenge_id,action,intent,target_x=None,target_y=None), dispatch(proposal_id), disturb(operation_id,force_x_n,steps), status(), reconcile(command_id=None). Unknown raises Uncertain carrying command_id; expose pending IDs. Known refusal raises Refusal. Persist outgoing request before one send. No auto-resend. Reconcile may resolve not_accepted without dispatching a replacement. Observe downloads exact PNG over HTTP, verifies SHA, replaces top-level image_path only; original observation packet stays bound to server challenge. + +Service API: initialize(root, diagnostic_enabled=False); BodyService(root, host='127.0.0.1',port=0, barrier=None), start(), origin, close(). CLI --root --port with optional --initialize --diagnostic and --barrier before_dispatch|after_dispatch. Diagnostic barrier writes root/barrier.json after accepted intent (before/after lower dispatch), then SIGSTOP; harness kills only its owned process. Restart never auto-executes. Proxy API FaultProxy(origin, root), start(), origin, arm(mode, operation='dispatch', delay_s=.2), close(). Modes delay_before, delay_after, drop_before, drop_after, duplicate; one-shot exact payload forwarding, bounded event retention, release proxy lock before sleeps. + +Implementation order: server and schemas; independent client/proxy; public-boundary fault tests; source freeze; actual model runner and independent post-trial scoring. Native guards and existing operator files are outside this package's edit scope. From ed7b848ef9a0b7af04d78699c3809a7d78e2e607 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:22:51 -0400 Subject: [PATCH 111/216] Record actual guest Chrome integrity assessment --- jevdual/docs/notebook/2026-10-10-independent-onboarding.md | 5 +++++ .../results/u2-independent-onboarding-20261011-v1/report.md | 2 ++ .../u2-independent-onboarding-20261011-v1/summary.json | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md index b21d936..9dc6a12 100644 --- a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md +++ b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md @@ -49,3 +49,8 @@ Refs: results/independent-onboarding-preparation-20261010/report.md; aa971782 Observed: the independently provisioned guest is at the desktop after human license/account setup. Root observed SIP enabled, the exact read-only qualification volume, four payload checksum passes and guest Terminal com.apple.Terminal2.15. Packetv3 is freshly extracted and uv0.12.5 runs. The human approved the Python3.14.7 license at its actual Agree dialog; root accepted it. Installation now requires guest administrator authentication, handed to the human to keep credentials out of tool logs. Chrome image is mounted read-only with signature assessment pending. No installed diagnostic, TCC grant or native oracle has run; UO2 remains open. Next: resume at installer authentication, then pristine packet verification and cold dependency install before the denied Accessibility baseline. Refs: results/u2-independent-onboarding-20261011-v1; guest /Users/tom/footwork-u2; root native CUA tool images in this chat + +## UOU5 · update · 2026-10-11 16:22 +Observed: Chrome guest assessment completed with deep strict codesign valid, Google LLC Team EQHXZ8M8AV, stapled ticket and spctl accepted Notarized Developer ID. The bundle version is155.0.8059.40. Copy to the previously absent guest Applications destination is running; installation completion is not yet observed. Python remains at administrator authentication. +Next: leave the guest authentication prompt for human entry and resume the remaining UO2 gates afterward. +Refs: results/u2-independent-onboarding-20261011-v1; guest /Users/tom/footwork-u2/chrome-signature.txt diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md index 34467b6..07e35da 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md @@ -9,3 +9,5 @@ The packet is freshly extracted and uv 0.12.5 runs. The official Python 3.14.7 i Synthetic modifier keys do not reliably reach this VM: sw_vers initially arrived as sw-vers. Root retained that failed command and verified a printf octal-decoded route with the same public command, then continued through the same guest Terminal without clipboard sharing or SSH. This input workaround is qualification infrastructure, not a product change or permission grant. Next gates: authenticate the guest installer; verify installed Python and pristine packet members; verify and install Chrome; run the frozen cold dependency installer; capture strict denied Accessibility diagnostics and fixture refusal; obtain the human's exact responsible-host grant, restart and read back; run the native append/restart/report oracle and qualify owned-resource cleanup. UO2 remains open. No Accessibility grant, product dependency install, native effect or cleanup test has run. + +Chrome assessment subsequently completed: deep strict codesign reports valid on disk and satisfies its designated requirement; Google LLC Team EQHXZ8M8AV; stapled notarization ticket; spctl accepted Notarized Developer ID. The bundle reports version 155.0.8059.40. Copy into the previously absent guest /Applications/Google Chrome.app has started; its completion remains pending observation. Guest chrome-signature.txt preserves the assessment. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json index 5f59589..4c41dc7 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json @@ -25,7 +25,9 @@ "python_license": "human_approved_and_accepted", "python_installer": "waiting_for_guest_admin_authentication", "chrome_dmg": "mounted_read_only", - "chrome_signature": "assessment_started_result_not_yet_observed" + "chrome_signature": "deep strict codesign valid; spctl accepted Notarized Developer ID; stapled ticket", + "chrome_version": "155.0.8059.40", + "chrome_installation": "copy started; completion not yet observed" }, "qualification": { "packet_member_verification": "pending_installed_python", From 8fe805760e319b24d116f6f8f979dc4d10148a02 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:23:22 -0400 Subject: [PATCH 112/216] Record completed guest Chrome installation readback --- jevdual/results/u2-independent-onboarding-20261011-v1/report.md | 2 ++ .../results/u2-independent-onboarding-20261011-v1/summary.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md index 07e35da..d98f5a2 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md @@ -11,3 +11,5 @@ Synthetic modifier keys do not reliably reach this VM: sw_vers initially arrived Next gates: authenticate the guest installer; verify installed Python and pristine packet members; verify and install Chrome; run the frozen cold dependency installer; capture strict denied Accessibility diagnostics and fixture refusal; obtain the human's exact responsible-host grant, restart and read back; run the native append/restart/report oracle and qualify owned-resource cleanup. UO2 remains open. No Accessibility grant, product dependency install, native effect or cleanup test has run. Chrome assessment subsequently completed: deep strict codesign reports valid on disk and satisfies its designated requirement; Google LLC Team EQHXZ8M8AV; stapled notarization ticket; spctl accepted Notarized Developer ID. The bundle reports version 155.0.8059.40. Copy into the previously absent guest /Applications/Google Chrome.app has started; its completion remains pending observation. Guest chrome-signature.txt preserves the assessment. + +Chrome copy subsequently completed and the installed bundle version readback is 155.0.8059.40. Root left the guest Installer password field focused for human authentication; Python and all dependent qualification gates remain pending. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json index 4c41dc7..a16e785 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json @@ -27,7 +27,7 @@ "chrome_dmg": "mounted_read_only", "chrome_signature": "deep strict codesign valid; spctl accepted Notarized Developer ID; stapled ticket", "chrome_version": "155.0.8059.40", - "chrome_installation": "copy started; completion not yet observed" + "chrome_installation": "completed at /Applications/Google Chrome.app; installed bundle version readback 155.0.8059.40" }, "qualification": { "packet_member_verification": "pending_installed_python", From 680004482b0addc5c7f11a3cf18b23b2388a4a6c Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:32:03 -0400 Subject: [PATCH 113/216] Record network conformance finding and predict terminal journal consistency repair --- .../notebook/2026-10-11-network-body-adapter.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-network-body-adapter.md b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md index 25dcc60..47fd3cf 100644 --- a/jevdual/docs/notebook/2026-10-11-network-body-adapter.md +++ b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md @@ -6,3 +6,16 @@ Test: implement a separate HTTP service/client around unchanged Bench and AgentB Predicts: duplicate command results match without extra generation; read-only reconciliation settles proven effects; expired or revoked leases fence late requests; missing lower proof remains unknown and blocks dispatch; model cycles retain native/SQLite/contact evidence on one body. Against: duplicate native effects, admitted stale/expired/wrong-body commands, automatic uncertain retry, erased unknown intent, body recreation on restart, private pose in model input, or independent cycle scoring failure. Refs: docs/experiments/SIM9-network-body-adapter.md; tools/physical-workcell/output/sim9-network-body/; results/network-body-adapter-20261011/ + +## SIM9-U1 · update · 2026-10-11 16:29 +Observed: the first server conformance run passed five cases and failed seven because a stray simulation field made retained response envelopes fail their closed schema. The original log is retained. Review also identified that an unbound HTTP error after an effect must preserve client uncertainty, and that leases must be rechecked after potentially slow validation. +Inferred: strict envelope checks exposed a transport serialization bug before qualification. Neither the first conformance run nor the repairs establish complete network recovery. +Next: remove the stray field, retain unknown outcomes for unbound errors, recheck lease admission immediately before intent persistence, and rerun public-boundary checks before freezing the model trial. +Refs: tools/physical-workcell/output/sim9-body-server-tests-first.log; tools/physical-workcell/test_body_network.py; tools/physical-workcell/test_body_client.py + +## SIM9-JOURNAL · prediction · 2026-10-11 16:31 +Hypothesis: failure while committing the terminal intent pointer leaves the current implementation's cached record inconsistent with its durable unknown intent, even though admission rereads disk and remains fenced. Updating the cache only after successful persistence removes this inconsistency. +Test: inject an intent persistence failure after a real native dispatch and terminal file creation; assert unchanged cached intent pointer, unknown public state and blocked fresh admission. Preserve the first failure, repair mutation order, then restart and prove read-only lower-receipt recovery with no extra motion. +Predicts: the current cached-pointer assertion fails; after repair cache and disk both remain unknown, admission remains blocked, and restart recovers the indexed core result without replay. +Against: no cache inconsistency occurs before repair, the repair admits fresh actions or loses the effect receipt, or restart changes native generation while recovering. +Refs: tools/physical-workcell/body_network.py; tools/physical-workcell/test_body_network.py From 7ea9fbdd83987b8a8d9b099f26fb7b0f20a0470d Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:35:50 -0400 Subject: [PATCH 114/216] Record fault matrix and preregister bounded client journal capacity check --- .../notebook/2026-10-11-network-body-adapter.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-network-body-adapter.md b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md index 47fd3cf..e93189b 100644 --- a/jevdual/docs/notebook/2026-10-11-network-body-adapter.md +++ b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md @@ -19,3 +19,17 @@ Test: inject an intent persistence failure after a real native dispatch and term Predicts: the current cached-pointer assertion fails; after repair cache and disk both remain unknown, admission remains blocked, and restart recovers the indexed core result without replay. Against: no cache inconsistency occurs before repair, the repair admits fresh actions or loses the effect receipt, or restart changes native generation while recovering. Refs: tools/physical-workcell/body_network.py; tools/physical-workcell/test_body_network.py + +## SIM9-U2 · update · 2026-10-11 16:35 +Resolves: SIM9-JOURNAL = held +Observed: injected terminal-pointer persistence failure reproduced the cached digest inconsistency while disk-based admission remained blocked. Copying the record and persisting it before updating the cache passes the regression; thirteen server checks pass. The second complete twelve-case matrix passes with unchanged recorded source and all owned processes reaped; ten client checks and twenty-nine unchanged-core checks pass. Static serialization also shows a normal 256-entry client index exceeds the 64 KiB wire JSON decoder bound. +Inferred: transport authority fences hold on these cases, but the client journal needs its own bounded reader before the advertised 256-command capacity is consistent. +Next: retain failures, add a strictly bounded local journal decoder without changing wire limits, rerun affected checks, then freeze measured source for the actual-model trial. +Refs: tools/physical-workcell/output/sim9-terminal-pointer-before-fix.log; tools/physical-workcell/output/sim9-terminal-pointer-after-fix.log; tools/physical-workcell/output/n9-matrix-v2/unittest.log; tools/physical-workcell/output/sim9-client-tests-v3/unittest.log; tools/physical-workcell/output/sim9-core-regression.log + +## SIM9-CAPACITY · prediction · 2026-10-11 16:35 +Hypothesis: a separate 128 KiB strict decoder for the local client journal can retain the declared 256-command index while preserving the existing 64 KiB network-message bound and pending-command integrity. +Test: load an exact hash-bound full-capacity journal, reject duplicate keys and oversized local journals, refuse a fresh command at capacity without sending, and rerun client and network fault checks. +Predicts: the full journal reloads without effects, capacity refuses the next send, malformed journals refuse, and unchanged wire decoding still rejects oversized messages. +Against: 256 entries still cannot reload, malformed data or oversized wire messages are admitted, unresolved commands disappear, or network recovery changes. +Refs: tools/physical-workcell/body_client.py; tools/physical-workcell/test_body_client.py From 413686b802efa56bde1eb360ca22b505fb57e1b5 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:36:25 -0400 Subject: [PATCH 115/216] Record clean guest cold install and initial Accessibility denial --- .../notebook/2026-10-10-independent-onboarding.md | 5 +++++ .../report.md | 2 ++ .../summary.json | 15 ++++++++------- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md index 9dc6a12..8377a7b 100644 --- a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md +++ b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md @@ -54,3 +54,8 @@ Refs: results/u2-independent-onboarding-20261011-v1; guest /Users/tom/footwork-u Observed: Chrome guest assessment completed with deep strict codesign valid, Google LLC Team EQHXZ8M8AV, stapled ticket and spctl accepted Notarized Developer ID. The bundle version is155.0.8059.40. Copy to the previously absent guest Applications destination is running; installation completion is not yet observed. Python remains at administrator authentication. Next: leave the guest authentication prompt for human entry and resume the remaining UO2 gates afterward. Refs: results/u2-independent-onboarding-20261011-v1; guest /Users/tom/footwork-u2/chrome-signature.txt + +## UOU6 · update · 2026-10-11 16:36 +Observed: the human completed guest installer authentication. Guest Python3.14.7 executes; pristine packet verification exits0 with14members, source33e1afb and the reviewed wheel hash. Frozen cold installer exits0 with115packages, all seven command stages return0. Initial isolated strict doctor exits1 with accessibility_not_granted; Screen Recording is not_granted and advisory. The frozen fixture exits2 with the exact Accessibility refusal, and its run directory is absent. No grant or admitted native action has occurred. Pure-Python fallback emits a noisy unavailable-core warning but executes the permission gate. An initial post-install command reached Finder while Installer opened its folder; root restored Terminal focus and the actual verifier then ran successfully. +Next: record the human approval and exact Terminal Accessibility grant in guest settings, restart the responsible host and read back strict doctor before the native oracle. +Refs: results/u2-independent-onboarding-20261011-v1; guest /Users/tom/footwork-u2/packet-verification.txt; guest packet output/install-v1/receipt.json; guest packet output/doctor-before.json; guest denied-fixture.txt and exit files; root native CUA tool images in this chat diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md index d98f5a2..71460e6 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md @@ -13,3 +13,5 @@ Next gates: authenticate the guest installer; verify installed Python and pristi Chrome assessment subsequently completed: deep strict codesign reports valid on disk and satisfies its designated requirement; Google LLC Team EQHXZ8M8AV; stapled notarization ticket; spctl accepted Notarized Developer ID. The bundle reports version 155.0.8059.40. Copy into the previously absent guest /Applications/Google Chrome.app has started; its completion remains pending observation. Guest chrome-signature.txt preserves the assessment. Chrome copy subsequently completed and the installed bundle version readback is 155.0.8059.40. Root left the guest Installer password field focused for human authentication; Python and all dependent qualification gates remain pending. + +The human completed installer authentication. Python 3.14.7 runs and the pristine member verifier exits0 with14members and matching frozen source/wheel hashes. The frozen cold installer completed all seven stages at exit0 and reports115packages. Initial isolated strict doctor exits1 with accessibility_not_granted; Screen Recording is not_granted and remains advisory. The frozen fixture exits2 with the exact Accessibility refusal, and its run directory is absent. No native effect has been admitted. The denied baseline is valid; grant, restart, native oracle and cleanup remain pending. The pure-Python fallback emits a noisy unavailable-core warning, retained in the guest stderr; it does not prevent the actual permission refusal. Guest receipts remain in the guest and have not yet been exported. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json index a16e785..4fc8477 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json @@ -1,6 +1,6 @@ { "recorded_at": "2026-10-11T16:22:00-04:00", - "status": "in_progress_waiting_for_guest_installer_authentication", + "status": "in_progress_denied_baseline_observed_permission_grant_pending", "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", "packet_sha256": "769c08c89061731368db33d78b180e7c8c96d531190f43bee44263642a76fd0f", "guest": { @@ -21,18 +21,19 @@ }, "prerequisites": { "uv_version": "0.12.5", - "python_installed": false, + "python_installed": true, "python_license": "human_approved_and_accepted", - "python_installer": "waiting_for_guest_admin_authentication", + "python_installer": "human authentication completed", "chrome_dmg": "mounted_read_only", "chrome_signature": "deep strict codesign valid; spctl accepted Notarized Developer ID; stapled ticket", "chrome_version": "155.0.8059.40", - "chrome_installation": "completed at /Applications/Google Chrome.app; installed bundle version readback 155.0.8059.40" + "chrome_installation": "completed at /Applications/Google Chrome.app; installed bundle version readback 155.0.8059.40", + "python_version": "3.14.7" }, "qualification": { - "packet_member_verification": "pending_installed_python", - "cold_dependency_install": "not_run", - "denied_accessibility_baseline": "not_run", + "packet_member_verification": "passed 14 members, exit0", + "cold_dependency_install": "passed 115 packages, seven stages exit0, installer exit0", + "denied_accessibility_baseline": "observed not_granted, strict doctor exit1, fixture exit2, fixture directory absent", "permission_transition": "not_run", "native_effect_restart_report": "not_run", "cleanup": "not_run", From 730b66604f45fb5e9c8d4cc0f113f513a98b8715 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:38:54 -0400 Subject: [PATCH 116/216] Preserve exact guest Terminal permission handoff --- jevdual/docs/notebook/2026-10-10-independent-onboarding.md | 6 ++++++ .../results/u2-independent-onboarding-20261011-v1/report.md | 2 ++ .../u2-independent-onboarding-20261011-v1/summary.json | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md index 8377a7b..70213ad 100644 --- a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md +++ b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md @@ -59,3 +59,9 @@ Refs: results/u2-independent-onboarding-20261011-v1; guest /Users/tom/footwork-u Observed: the human completed guest installer authentication. Guest Python3.14.7 executes; pristine packet verification exits0 with14members, source33e1afb and the reviewed wheel hash. Frozen cold installer exits0 with115packages, all seven command stages return0. Initial isolated strict doctor exits1 with accessibility_not_granted; Screen Recording is not_granted and advisory. The frozen fixture exits2 with the exact Accessibility refusal, and its run directory is absent. No grant or admitted native action has occurred. Pure-Python fallback emits a noisy unavailable-core warning but executes the permission gate. An initial post-install command reached Finder while Installer opened its folder; root restored Terminal focus and the actual verifier then ran successfully. Next: record the human approval and exact Terminal Accessibility grant in guest settings, restart the responsible host and read back strict doctor before the native oracle. Refs: results/u2-independent-onboarding-20261011-v1; guest /Users/tom/footwork-u2/packet-verification.txt; guest packet output/install-v1/receipt.json; guest packet output/doctor-before.json; guest denied-fixture.txt and exit files; root native CUA tool images in this chat + +## UOS2 · summary · 2026-10-11 16:38 +Established: actual independent SIP-enabled guest Python/prerequisite setup, pristine packet verification, frozen115package cold install and a valid installed Accessibility-denied baseline with no fixture directory. Guest Settings visibly attributes the off Accessibility switch to Terminal. Evidence is retained in the guest and observed CUA tool images, with sanitized partial host record at413686b. +Uncertain: human Terminal permission decision, host restart/readback, installed native append/restart/report and owned cleanup remain unexecuted. Full raw guest receipt export is pending. Claude has the concrete baseline review request but no new verdict has arrived. +Decision: keep UO2 open and pause dependent native execution at the exact guest Terminal Accessibility grant confirmation. The permission is scoped to the disposable guest, and host Mac permissions remain untouched. +Refs: results/u2-independent-onboarding-20261011-v1; Claude request1791751059206860000; root native CUA tool images in this chat diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md index 71460e6..6a287f3 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md @@ -15,3 +15,5 @@ Chrome assessment subsequently completed: deep strict codesign reports valid on Chrome copy subsequently completed and the installed bundle version readback is 155.0.8059.40. Root left the guest Installer password field focused for human authentication; Python and all dependent qualification gates remain pending. The human completed installer authentication. Python 3.14.7 runs and the pristine member verifier exits0 with14members and matching frozen source/wheel hashes. The frozen cold installer completed all seven stages at exit0 and reports115packages. Initial isolated strict doctor exits1 with accessibility_not_granted; Screen Recording is not_granted and remains advisory. The frozen fixture exits2 with the exact Accessibility refusal, and its run directory is absent. No native effect has been admitted. The denied baseline is valid; grant, restart, native oracle and cleanup remain pending. The pure-Python fallback emits a noisy unavailable-core warning, retained in the guest stderr; it does not prevent the actual permission refusal. Guest receipts remain in the guest and have not yet been exported. + +At the handoff, guest System Settings > Privacy & Security > Accessibility visibly lists Terminal with its switch off. Human confirmation is requested before enabling that exact guest host. Claude has the actual baseline review request1791751059206860000, without a new verdict yet. UO2 remains open; no post-grant result is claimed. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json index 4fc8477..9b72de9 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json @@ -34,7 +34,7 @@ "packet_member_verification": "passed 14 members, exit0", "cold_dependency_install": "passed 115 packages, seven stages exit0, installer exit0", "denied_accessibility_baseline": "observed not_granted, strict doctor exit1, fixture exit2, fixture directory absent", - "permission_transition": "not_run", + "permission_transition": "pending human confirmation; guest Settings shows Terminal switch off", "native_effect_restart_report": "not_run", "cleanup": "not_run", "qualified": false From e8c7e9b502f852639a89932aa30884a40a432ca9 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:40:17 -0400 Subject: [PATCH 117/216] Add guarded persistent body TCP adapter with durable client and fault qualification --- .../2026-10-11-network-body-adapter.md | 7 + tools/physical-workcell/NETWORK_BODY.md | 65 ++ tools/physical-workcell/body_client.py | 453 +++++++++++ tools/physical-workcell/body_network.py | 437 +++++++++++ tools/physical-workcell/body_protocol.py | 67 ++ .../physical-workcell/network_fault_proxy.py | 199 +++++ .../physical-workcell/qualify_network_body.py | 175 +++++ tools/physical-workcell/score_network_body.py | 151 ++++ tools/physical-workcell/test_body_client.py | 277 +++++++ tools/physical-workcell/test_body_network.py | 241 ++++++ .../test_network_body_faults.py | 731 ++++++++++++++++++ 11 files changed, 2803 insertions(+) create mode 100644 tools/physical-workcell/NETWORK_BODY.md create mode 100644 tools/physical-workcell/body_client.py create mode 100644 tools/physical-workcell/body_network.py create mode 100644 tools/physical-workcell/body_protocol.py create mode 100644 tools/physical-workcell/network_fault_proxy.py create mode 100644 tools/physical-workcell/qualify_network_body.py create mode 100644 tools/physical-workcell/score_network_body.py create mode 100644 tools/physical-workcell/test_body_client.py create mode 100644 tools/physical-workcell/test_body_network.py create mode 100644 tools/physical-workcell/test_network_body_faults.py diff --git a/jevdual/docs/notebook/2026-10-11-network-body-adapter.md b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md index e93189b..e6b6fcd 100644 --- a/jevdual/docs/notebook/2026-10-11-network-body-adapter.md +++ b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md @@ -33,3 +33,10 @@ Test: load an exact hash-bound full-capacity journal, reject duplicate keys and Predicts: the full journal reloads without effects, capacity refuses the next send, malformed journals refuse, and unchanged wire decoding still rejects oversized messages. Against: 256 entries still cannot reload, malformed data or oversized wire messages are admitted, unresolved commands disappear, or network recovery changes. Refs: tools/physical-workcell/body_client.py; tools/physical-workcell/test_body_client.py + +## SIM9-U3 · update · 2026-10-11 16:40 +Resolves: SIM9-CAPACITY = held +Observed: the full-capacity reload failed before repair at the 64 KiB reader. The separate strict 128 KiB journal reader passes full-capacity reload, refusal before send 257, duplicate/nonfinite/oversized journal rejection and unchanged oversized-wire refusal. Eleven client checks pass. The third twelve-case matrix passes on the final source, with all owned processes reaped and all recorded source hashes unchanged. Thirteen server checks and twenty-nine core checks also pass. +Inferred: the 65 conformance checks support the bounded same-host network adapter and its retained authority under these faults; they do not establish actual-model network completion. +Next: commit measured source, freeze its exact bytes, and run two actual Codex image-guided network cycles with lost-reply reconciliation, duplicate and delayed dispatches. Score native states, SQLite and exact model/transport receipts separately after process cleanup. +Refs: tools/physical-workcell/output/sim9-client-capacity-before/unittest.log; tools/physical-workcell/output/sim9-client-tests-v4/unittest.log; tools/physical-workcell/output/n9-matrix-v3/aggregate.json; tools/physical-workcell/output/sim9-core-regression.log diff --git a/tools/physical-workcell/NETWORK_BODY.md b/tools/physical-workcell/NETWORK_BODY.md new file mode 100644 index 0000000..b9916ab --- /dev/null +++ b/tools/physical-workcell/NETWORK_BODY.md @@ -0,0 +1,65 @@ +# Persistent simulated body + +The body service retains a MuJoCo bench while a separate client plans from camera images received over TCP. The local service checks proposals and owns every physical effect. This adapter lives inside Footwork's existing workcell package; the browser bench remains a separate local interface. + +Start from the repository root with the existing pinned Python environment: + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/body_network.py \ + --root tools/physical-workcell/output/my-network-body --initialize --port 64371 +``` + +Restart the same body by omitting `--initialize`. Body identity, generation, native time, jobs and receipts persist. Restart revokes all leases. The service binds to loopback; this version does not provide authentication or remote deployment. + +The Python client provides the action boundary: + +```python +from body_client import BodyClient, Uncertain + +client = BodyClient("tools/physical-workcell/output/my-network-client", + "http://127.0.0.1:64371") +client.acquire() +client.start_job("desk-job-1", { + "x_min": .035, "x_max": .105, "y_min": -.025, "y_max": .025, +}) +challenge = client.observe() # SHA-verified PNG downloaded into the client root +# A visual model chooses action, intent and finite target coordinates. +proposal = client.propose(challenge["challenge_id"], "move", + "Approach the block from its left side", -.25, 0) +try: + result = client.dispatch(proposal["proposal_id"]) +except Uncertain as uncertain: + receipt = client.reconcile(uncertain.command_id) # reads; never resends +client.close() +``` + +The example is one approach move, not a complete manipulation policy. The frozen qualification runner uses actual Codex image decisions for placement, measurement, contact reset and a second job. It needs the already authenticated Codex CLI and retains model inputs, decisions, usage and process outcomes. + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/qualify_network_body.py \ + --root tools/physical-workcell/output/my-network-qualification \ + --source-commit COMMITTED_SOURCE_SHA +tools/physical-workcell/.venv/bin/python tools/physical-workcell/score_network_body.py \ + --root tools/physical-workcell/output/my-network-qualification +``` + +Run the scorer after the runner has stopped its service and proxy. It reads native states and SQLite separately from planning. Results and the qualification scope are recorded under `jevdual/results/network-body-adapter-20261011/` when available. + +Commands have persistent IDs and content digests. Exact duplicates return the historical receipt. Changed arguments under the same ID refuse. If a reply disappears, the client records an unknown outcome and blocks new commands. Receipt lookup can settle a completed command; an expired or revoked lease can prove that an unaccepted command cannot arrive later. An accepted intent without lower-level proof remains unknown. Neither restarting nor reconnecting clears it. + +A lease limits admission of new commands. An already admitted action can finish after a disconnect within the existing local force, speed and time limits. This prototype does not claim an emergency stop, robot safety certification, hardware recovery, power-loss durability or secure control across machines. + +The diagnostic fault proxy injects bounded delays, discarded requests/replies and exact duplicates. Crash barriers are enabled only for test services and intentionally stop the owned service process so the harness can test receipt recovery. They are absent from normal startup. + +Reference: [protocol and ownership](NETWORK_CONTRACT.md); [preregistered experiment](../../jevdual/docs/experiments/SIM9-network-body-adapter.md). + +Verification recipe (from this directory): + +```sh +.venv/bin/python -m unittest -v test_body_network test_body_client test_network_body_faults +../../jevdual/.venv/bin/ruff check body_protocol.py body_network.py body_client.py \ + network_fault_proxy.py qualify_network_body.py score_network_body.py \ + test_body_network.py test_body_client.py test_network_body_faults.py +``` + +The twelve-case matrix covers network delay, dropped traffic, concurrent duplicates, stale proposals, lease and identity fences, retained restarts, read-only receipt recovery and unresolved crash intents. Server/client checks cover bounded schemas, ownership, malformed replies and image integrity. The actual-model run and its separate scorer qualify the complete camera-to-motion-to-computer workflow; deterministic checks alone do not establish model performance. diff --git a/tools/physical-workcell/body_client.py b/tools/physical-workcell/body_client.py new file mode 100644 index 0000000..aaeacaf --- /dev/null +++ b/tools/physical-workcell/body_client.py @@ -0,0 +1,453 @@ +"""Durable single-send client for a pinned loopback simulated body. + +BodyClient returns RPC results, except reconcile() returns the historical envelope. +A pending command blocks new commands and lease rotation. Request files and send +intent are durable before HTTP; reconciliation only issues GET and never replays. +""" +import fcntl +import http.client +import json +import os +import stat +import threading +import uuid +from urllib.parse import urlencode, urlsplit + +import order_protocol as protocol + +PROTOCOL = "footwork.body/1" +MAX_IMAGE = 8 * 1024 * 1024 +MAX_CLIENT_JOURNAL = 128 * 1024 +IDENTITY_KEYS = {"protocol", "adapter_id", "body_id", "source_sha256", "epoch", "simulation"} +ENVELOPE_KEYS = {"protocol", "adapter_id", "body_id", "source_sha256", "command_id", "request_sha256", "state", + "result", "reason", "receipt_scope", "recorded_epoch"} +Refusal = protocol.Refusal + + +class Uncertain(Refusal): + def __init__(self, command_id, reason="command outcome is unknown"): + self.command_id = command_id + super().__init__(reason) + + +def endpoint(origin): + if not isinstance(origin, str): + raise Refusal("body endpoint must be text") + parsed = urlsplit(origin) + try: + port = parsed.port + except ValueError as exc: + raise Refusal("invalid loopback endpoint") from exc + if (parsed.scheme != "http" or parsed.hostname != "127.0.0.1" or not port or + parsed.username is not None or parsed.password is not None or parsed.path or parsed.query or parsed.fragment or + origin != f"http://127.0.0.1:{port}"): + raise Refusal("body endpoint must be an exact literal IPv4 loopback HTTP origin") + return "127.0.0.1", port + + +def identity(value): + protocol.fields(value, IDENTITY_KEYS, "body identity") + if value["protocol"] != PROTOCOL or value["simulation"] is not True: + raise Refusal("unsupported body protocol or simulation identity") + for key in ("adapter_id", "body_id"): + protocol.identity(value[key]) + if not isinstance(value["source_sha256"], str) or not protocol.DIGEST.fullmatch(value["source_sha256"]): + raise Refusal("body source digest is invalid") + protocol.revision(value["epoch"]) + return value + + +def pinned_headers(value): + return {"X-Body-Id": value["body_id"], "X-Adapter-Id": value["adapter_id"], + "X-Source-Sha256": value["source_sha256"]} + + +def http_call(origin, method, path, headers=None, content=None, timeout=15, maximum=protocol.MAX_BYTES): + host, port = endpoint(origin) + connection = http.client.HTTPConnection(host, port, timeout=timeout) + try: + request_headers = dict(headers or {}) + if content is not None: + request_headers["Content-Type"] = "application/json" + connection.request(method, path, body=content, headers=request_headers) + response = connection.getresponse() + length = response.getheader("Content-Length") + if length is not None and (not length.isdigit() or int(length) > maximum): + raise Refusal("body response exceeds its bounded size") + body = response.read(maximum + 1) + if len(body) > maximum: + raise Refusal("body response exceeds its bounded size") + if 300 <= response.status < 400: + raise Refusal("body redirects are refused") + return response.status, body + finally: + connection.close() + + +def read_journal(path): + """The bounded local index holds 256 records; wire JSON keeps its 64 KiB cap.""" + content = protocol.read_bytes(path, maximum=MAX_CLIENT_JOURNAL) + + def unique(pairs): + result = {} + for key, value in pairs: + if key in result: + raise Refusal("duplicate local client journal key") + result[key] = value + return result + + def nonfinite(_): + raise Refusal("nonfinite local client journal value") + + try: + return json.loads(content, object_pairs_hook=unique, parse_constant=nonfinite) + except (UnicodeError, json.JSONDecodeError) as exc: + raise Refusal("invalid local client journal JSON") from exc + + +class BodyClient: + def __init__(self, root, origin, timeout=15): + endpoint(origin) + self.timeout = protocol.finite(timeout) + if not .01 <= self.timeout <= 30: + raise Refusal("client timeout must be between .01 and 30 seconds") + self.root = protocol.directory(root, create=True) + self.origin = origin + self._mutex = threading.RLock() + self._closed = False + self._fd = os.open(self.root / "client.lock", os.O_RDWR | os.O_CREAT | os.O_NOFOLLOW, 0o600) + try: + if not stat.S_ISREG(os.fstat(self._fd).st_mode): + raise Refusal("invalid client lock") + try: + fcntl.flock(self._fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except BlockingIOError as exc: + raise Refusal("another client process owns this journal") from exc + if (self.root / "client.json").exists(): + self._load() + else: + if any(p.name != "client.lock" for p in self.root.iterdir()): + raise Refusal("new client journal requires an empty private directory") + status, content = http_call(origin, "GET", "/identity", timeout=self.timeout) + if status != 200: + raise Refusal("body identity was unavailable") + remote = identity(protocol.decode(content)) + for name in ("requests", "responses", "events", "images"): + (self.root / name).mkdir(mode=0o700) + self._save({"version": 1, "origin": origin, "client_id": "client-" + uuid.uuid4().hex, + "identity": remote, "lease": None, "commands": {}, "pending_command_ids": [], "sequence": 0}) + except Exception: + os.close(self._fd) + self._closed = True + raise + + def close(self): + with self._mutex: + if not self._closed: + os.close(self._fd) + self._closed = True + + def __enter__(self): + return self + + def __exit__(self, *_): + self.close() + + def _load(self): + if self._closed: + raise Refusal("client is closed") + m = read_journal(self.root / "client.json") + protocol.fields(m, ("version", "origin", "client_id", "identity", "lease", "commands", "pending_command_ids", "sequence"), + "client journal") + if type(m["version"]) is not int or m["version"] != 1 or m["origin"] != self.origin: + raise Refusal("client endpoint or journal version changed") + identity(m["identity"]) + protocol.identity(m["client_id"]) + if not isinstance(m["commands"], dict) or len(m["commands"]) > 256 or not isinstance(m["pending_command_ids"], list): + raise Refusal("client journal budget or pending schema is invalid") + expected_pending = [] + for token, record in m["commands"].items(): + protocol.fields(record, {"request_sha256", "state", "send_count"} | + ({"response_sha256"} if "response_sha256" in record else set()), "client command index") + if type(record["send_count"]) is not int or record["send_count"] != 1: + raise Refusal("client command must retain exactly one send intent") + request, _ = self._request(m, token) + if "response_sha256" in record: + digest = record["response_sha256"] + if not isinstance(digest, str) or not protocol.DIGEST.fullmatch(digest): + raise Refusal("client response digest is invalid") + content = protocol.read_bytes(self.root / "responses" / (token + "-" + digest + ".json")) + if protocol.sha(content) != digest: + raise Refusal("durable client response changed") + value = self._envelope(m, request, content) + if record["state"] != value["state"]: + raise Refusal("client indexed command state changed") + terminal = self._terminal(value) + else: + if record["state"] != "unknown": + raise Refusal("command without a durable response cannot be resolved") + terminal = False + if not terminal: + expected_pending.append(token) + if (len(m["pending_command_ids"]) != len(set(m["pending_command_ids"])) or + set(m["pending_command_ids"]) != set(expected_pending)): + raise Refusal("client pending commands disagree with their durable responses") + return m + + def _save(self, m): + if len(protocol.encoded(m)) > MAX_CLIENT_JOURNAL: + raise Refusal("client journal exceeds its 128 KiB capacity") + protocol.persist(self.root / "client.json", m) + + def _event(self, m, kind, data): + if type(m["sequence"]) is not int or not 0 <= m["sequence"] < 2048: + raise Refusal("client event budget exhausted") + m["sequence"] += 1 + protocol.create_file(self.root / "events" / f"{m['sequence']:06d}.json", + protocol.encoded({"sequence": m["sequence"], "kind": kind, "data": data})) + self._save(m) + + def _request(self, m, token): + protocol.identity(token) + content = protocol.read_bytes(self.root / "requests" / (token + ".json")) + if protocol.sha(content) != m["commands"][token]["request_sha256"]: + raise Refusal("durable outgoing request changed") + request = protocol.decode(content) + if request["command_id"] != token or request["client_id"] != m["client_id"]: + raise Refusal("durable command identity changed") + return request, content + + def _pin(self, m, remote): + identity(remote) + for key in IDENTITY_KEYS - {"epoch"}: + if remote[key] != m["identity"][key]: + raise Refusal("body, adapter or source identity changed") + + def _blocked(self, m): + if m["pending_command_ids"]: + raise Uncertain(m["pending_command_ids"][0], "an unknown command blocks fresh commands and lease rotation") + + def acquire(self, duration_s=30): + duration = protocol.finite(duration_s) + if not .05 <= duration <= 30: + raise Refusal("lease duration must be between .05 and 30 seconds") + with self._mutex: + m = self._load() + self._blocked(m) + status, content = http_call(self.origin, "GET", "/identity", pinned_headers(m["identity"]), timeout=self.timeout) + if status != 200: + raise Refusal("body identity could not be refreshed") + remote = identity(protocol.decode(content)) + self._pin(m, remote) + m["identity"] = remote + m["lease"] = None + self._save(m) + request = {"client_id": m["client_id"], "expected_epoch": remote["epoch"], "duration_s": duration} + status, content = http_call(self.origin, "POST", "/lease", pinned_headers(remote), + protocol.encoded(request), self.timeout) + result = protocol.decode(content) + if status != 200: + raise Refusal(result.get("reason", "lease acquisition refused")) + protocol.fields(result, ("client_id", "lease_id", "epoch", "duration_s"), "lease") + if (result["client_id"] != m["client_id"] or type(result["epoch"]) is not int or + result["epoch"] != remote["epoch"] or protocol.finite(result["duration_s"]) != duration or + not isinstance(result["lease_id"], str) or not protocol.UUID.fullmatch(result["lease_id"])): + raise Refusal("lease response identity changed") + m["lease"] = result + self._event(m, "lease_acquired", result) + return result + + def _envelope(self, m, request, content): + value = protocol.decode(content) + protocol.fields(value, ENVELOPE_KEYS, "command result envelope") + for key in ("protocol", "adapter_id", "body_id", "source_sha256", "command_id"): + if value[key] != request[key]: + raise Refusal("command result identity changed") + if (value["request_sha256"] != m["commands"][request["command_id"]]["request_sha256"] or + value["receipt_scope"] != "retained_command_result" or + (not isinstance(value["state"], str) or value["state"] not in {"completed", "refused", "unknown", "not_seen", "not_accepted"})): + raise Refusal("command result digest, scope or state is invalid") + protocol.revision(value["recorded_epoch"]) + if value["recorded_epoch"] != request["epoch"]: + raise Refusal("historical command epoch changed") + if value["reason"] is not None and not isinstance(value["reason"], str): + raise Refusal("command reason must be text or null") + result = value["result"] + if result is not None and not isinstance(result, dict): + raise Refusal("command result must be an object or null") + if value["state"] == "completed": + if not isinstance(result, dict): + raise Refusal("completed command needs its typed result") + operation = request["operation"] + if operation == "observe": + self._challenge(m, result) + elif operation == "dispatch": + if (result.get("proposal_id") != request["arguments"]["proposal_id"] or + (not isinstance(result.get("outcome"), str) or result["outcome"] not in {"executed", "refused", "unknown"})): + raise Refusal("dispatch result identity or outcome changed") + if result.get("next_observation") is not None: + self._challenge(m, result["next_observation"]) + elif operation == "propose": + if (not isinstance(result.get("proposal_id"), str) or + result.get("challenge_id") != request["arguments"]["challenge_id"]): + raise Refusal("proposal result identity changed") + protocol.identity(result["proposal_id"]) + elif result.get("bench_id") != m["identity"]["body_id"]: + raise Refusal("body result identity changed") + return value + + @staticmethod + def _terminal(value): + lower_unknown = isinstance(value["result"], dict) and value["result"].get("outcome") == "unknown" + return value["state"] in {"completed", "refused", "not_accepted"} and not lower_unknown + + def _challenge(self, m, challenge): + protocol.fields(challenge, ("challenge_id", "session_id", "sequence", "observation_sha256", + "observation", "task", "image_path"), "body challenge") + protocol.identity(challenge["challenge_id"]) + packet = challenge["observation"] + if (not isinstance(packet, dict) or not isinstance(challenge["image_path"], str) or + protocol.sha(protocol.encoded(packet)) != challenge["observation_sha256"] or + packet.get("bench_id") != m["identity"]["body_id"] or + not isinstance(packet.get("image_sha256"), str) or not protocol.DIGEST.fullmatch(packet["image_sha256"]) or + challenge["image_path"] != packet.get("image_path")): + raise Refusal("body image challenge binding changed") + return packet + + def _retain(self, m, token, value): + content = protocol.encoded(value) + digest = protocol.sha(content) + path = self.root / "responses" / (token + "-" + digest + ".json") + if path.exists(): + if protocol.read_bytes(path) != content: + raise Refusal("retained command response changed") + else: + protocol.create_file(path, content) + terminal = self._terminal(value) + m["commands"][token].update(state=value["state"], response_sha256=digest) + if terminal and token in m["pending_command_ids"]: + m["pending_command_ids"].remove(token) + self._event(m, "response_read", {"command_id": token, "state": value["state"], "response_sha256": digest, + "historical": True}) + if not terminal: + raise Uncertain(token, value["reason"] or "command outcome remains unknown") + return value + + def _download(self, m, challenge): + if challenge is None: + return None + packet = self._challenge(m, challenge) + status, content = http_call(self.origin, "GET", "/images/" + challenge["challenge_id"], pinned_headers(m["identity"]), + timeout=self.timeout, maximum=MAX_IMAGE) + if status != 200 or protocol.sha(content) != packet["image_sha256"] or not content.startswith(b"\x89PNG\r\n\x1a\n"): + raise Refusal("downloaded body image failed its exact PNG digest check") + path = self.root / "images" / (challenge["challenge_id"] + "-" + packet["image_sha256"] + ".png") + if path.exists(): + if protocol.read_bytes(path, maximum=MAX_IMAGE) != content: + raise Refusal("client image changed") + else: + protocol.create_file(path, content) + return {**challenge, "image_path": str(path)} + + def _result(self, m, operation, result): + if operation == "observe": + return self._download(m, result) + return result + + def _command(self, operation, arguments): + with self._mutex: + m = self._load() + self._blocked(m) + if m["lease"] is None or len(m["commands"]) >= 256: + raise Refusal("an acquired lease and remaining command budget are required") + token = "command-" + uuid.uuid4().hex + pinned = m["identity"] + request = {"protocol": PROTOCOL, "adapter_id": pinned["adapter_id"], "body_id": pinned["body_id"], + "source_sha256": pinned["source_sha256"], "client_id": m["client_id"], + "lease_id": m["lease"]["lease_id"], "epoch": m["lease"]["epoch"], "command_id": token, + "operation": operation, "arguments": arguments} + content = protocol.encoded(request) + if len(content) > protocol.MAX_BYTES: + raise Refusal("command exceeds bounded JSON size") + protocol.create_file(self.root / "requests" / (token + ".json"), content) + m["commands"][token] = {"request_sha256": protocol.sha(content), "state": "unknown", "send_count": 1} + m["pending_command_ids"].append(token) + self._event(m, "send_intent", {"command_id": token, "request_sha256": protocol.sha(content), "send_count": 1}) + try: + _, reply = http_call(self.origin, "POST", "/commands", pinned_headers(pinned), content, self.timeout) + value = self._envelope(m, request, reply) + except (TimeoutError, OSError, http.client.HTTPException, Refusal) as exc: + self._event(m, "transport_unknown", {"command_id": token, "reason": str(exc)}) + raise Uncertain(token, "reply is uncertain; reconcile exact command without resending") from exc + value = self._retain(m, token, value) + if value["state"] in {"refused", "not_accepted"}: + raise Refusal(value["reason"] or "body command refused") + return self._result(m, operation, value["result"]) + + def start_job(self, job_id, zone): + protocol.identity(job_id) + protocol.validate_zone(zone) + return self._command("start_job", {"job_id": job_id, "target_zone": zone}) + + def observe(self): + return self._command("observe", {}) + + def propose(self, challenge_id, action, intent, target_x=None, target_y=None): + protocol.identity(challenge_id) + if action not in {"move", "measure", "begin_reset", "finish_reset"} or not isinstance(intent, str) or not 1 <= len(intent.strip()) <= 2000: + raise Refusal("proposal needs a supported action and bounded intent") + if action == "move": + target_x, target_y = protocol.finite(target_x), protocol.finite(target_y) + elif target_x is not None or target_y is not None: + raise Refusal("only movement proposals accept targets") + return self._command("propose", {"challenge_id": challenge_id, "action": action, "intent": intent, + "target_x": target_x, "target_y": target_y}) + + def dispatch(self, proposal_id): + protocol.identity(proposal_id) + return self._command("dispatch", {"proposal_id": proposal_id}) + + def disturb(self, operation_id, force_x_n, steps): + protocol.identity(operation_id) + force = protocol.finite(force_x_n) + if type(steps) is not int: + raise Refusal("diagnostic steps must be an integer") + return self._command("disturb", {"operation_id": operation_id, "force_x_n": force, "steps": steps}) + + def reconcile(self, command_id=None): + with self._mutex: + m = self._load() + if command_id is None: + if not m["pending_command_ids"]: + raise Refusal("no unknown command requires reconciliation") + command_id = m["pending_command_ids"][0] + if command_id not in m["commands"]: + raise Refusal("command is not owned by this client") + request, _ = self._request(m, command_id) + query = urlencode({"client_id": request["client_id"], "lease_id": request["lease_id"], "epoch": request["epoch"], + "request_sha256": m["commands"][command_id]["request_sha256"]}) + try: + _, content = http_call(self.origin, "GET", "/commands/" + command_id + "?" + query, + pinned_headers(m["identity"]), timeout=self.timeout) + value = self._envelope(m, request, content) + except (TimeoutError, OSError, http.client.HTTPException, Refusal) as exc: + self._event(m, "reconciliation_unknown", {"command_id": command_id, "reason": str(exc)}) + raise Uncertain(command_id, "read-only reconciliation is unavailable or untrusted") from exc + value = self._retain(m, command_id, value) + if value["state"] == "completed": + return {**value, "result": self._result(m, request["operation"], value["result"])} + return value + + def status(self): + with self._mutex: + m = self._load() + try: + status, content = http_call(self.origin, "GET", "/state", pinned_headers(m["identity"]), timeout=self.timeout) + remote = protocol.decode(content) + if status != 200: + raise Refusal("body state was unavailable") + self._pin(m, remote["identity"]) + except (TimeoutError, OSError, http.client.HTTPException, Refusal, KeyError) as exc: + remote = {"state": "unavailable", "reason": str(exc)} + return {"identity": m["identity"], "lease": m["lease"], "pending_command_ids": m["pending_command_ids"], + "server_state": remote} diff --git a/tools/physical-workcell/body_network.py b/tools/physical-workcell/body_network.py new file mode 100644 index 0000000..e9b32b7 --- /dev/null +++ b/tools/physical-workcell/body_network.py @@ -0,0 +1,437 @@ +"""Durable loopback body server; uncertainty never causes an effect replay.""" +import argparse +import os +import signal +import threading +import time +import uuid +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from pathlib import Path +from urllib.parse import parse_qs, urlsplit + +import agent_bench as agent +import bench +import body_protocol as wire +import order_protocol as storage + +BASE = Path(__file__).resolve().parent + + +def sources(): + return {**agent.sources(), **{name: storage.sha(storage.read_bytes(BASE / name)) + for name in ("body_protocol.py", "body_network.py")}} + + +def source_sha(): + return storage.sha(storage.encoded(sources())) + + +def initialize(root, diagnostic_enabled=False): + root = storage.directory(root, create=True) + with storage.locked(root): + if any(p.name != "app.lock" for p in root.iterdir()): + raise wire.Refusal("body initialization requires an empty owned directory") + native = bench.initialize(root / "bench", diagnostic_enabled=diagnostic_enabled) + agent.initialize(root / "agent", root / "bench") + (root / "commands").mkdir(mode=0o700) + identity = {"protocol": wire.PROTOCOL, "adapter_id": uuid.uuid4().hex, + "body_id": native["bench_id"], "source_sha256": source_sha(), "simulation": True} + storage.create_file(root / "identity.json", storage.encoded(identity)) + storage.persist(root / "service.json", {"epoch": 0, "identity_sha256": storage.sha(storage.encoded(identity))}) + return identity + + +class BodyService: + def __init__(self, root, host="127.0.0.1", port=0, barrier=None): + if host != "127.0.0.1" or type(port) is not int or not 0 <= port <= 65535: + raise wire.Refusal("body service must bind literal IPv4 loopback") + if barrier not in (None, "before_dispatch", "after_dispatch"): + raise wire.Refusal("unknown diagnostic barrier") + self.root = storage.directory(root) + self.lock = threading.RLock() + self.owner = storage.locked(self.root) + self.owner.__enter__() + self.closed = False + self.lease = None + self.barrier = barrier + self.thread = None + try: + self.pinned = storage.decode(storage.read_bytes(self.root / "identity.json")) + storage.fields(self.pinned, ("protocol", "adapter_id", "body_id", "source_sha256", "simulation"), "adapter identity") + m = storage.decode(storage.read_bytes(self.root / "service.json")) + storage.fields(m, ("epoch", "identity_sha256"), "service boot record") + if m["identity_sha256"] != storage.sha(storage.encoded(self.pinned)) or type(m["epoch"]) is not int: + raise wire.Refusal("adapter identity or boot record changed") + self.epoch = wire.epoch(m["epoch"] + 1) + self.body = bench.Bench(self.root / "bench") + self.agent = agent.AgentBench(self.root / "agent") + self._identity_guard() + storage.persist(self.root / "service.json", {"epoch": self.epoch, "identity_sha256": m["identity_sha256"]}) + self.records = {} + self._restore() + self.http = _Server((host, port), self) + self.origin = f"http://127.0.0.1:{self.http.server_address[1]}" + except Exception: + self.owner.__exit__(None, None, None) + raise + + def _identity_guard(self): + if (self.pinned["protocol"] != wire.PROTOCOL or self.pinned["simulation"] is not True or + self.pinned["source_sha256"] != source_sha() or + storage.decode(storage.read_bytes(self.root / "identity.json")) != self.pinned or + self.body.status()["bench_id"] != self.pinned["body_id"]): + raise wire.Refusal("pinned adapter, body, or measured source changed") + + def identity(self): + with self.lock: + self._identity_guard() + return {**self.pinned, "epoch": self.epoch} + + def start(self): + if self.thread is not None: + raise wire.Refusal("body service has already started") + self.thread = threading.Thread(target=self.http.serve_forever, kwargs={"poll_interval": .1}, daemon=True) + self.thread.start() + return self + + def close(self): + self.closed = True + if self.thread: + self.http.shutdown() + self.thread.join(5) + self.http.server_close() + with self.lock: + self.lease = None + self.owner.__exit__(None, None, None) + + def _directory(self, command_id): + wire.identity(command_id) + return self.root / "commands" / storage.sha(command_id.encode()) + + def _envelope(self, request, state, result=None, reason=None): + return {**{k: self.pinned[k] for k in ("protocol", "adapter_id", "body_id", "source_sha256")}, "command_id": request["command_id"], "request_sha256": wire.command_digest(request), + "state": state, "result": result, "reason": reason, "receipt_scope": "retained_command_result", + "recorded_epoch": request["epoch"]} + + def _reply(self, request, state, result=None, reason=None): + value = self._envelope(request, state, result, reason) + return value + + def _read_record(self, directory): + raw = storage.read_bytes(directory / "intent.json") + record = storage.decode(raw) + storage.fields(record, ("request", "request_sha256", "result_sha256"), "command journal") + request = wire.validate_command(record["request"]) + if (record["request_sha256"] != wire.command_digest(request) or directory != self._directory(request["command_id"]) or + any(request[key] != self.pinned[key] for key in ("protocol", "adapter_id", "body_id", "source_sha256"))): + raise wire.Refusal("retained command request or identity changed") + if record["result_sha256"] is not None: + wire.digest(record["result_sha256"]) + content = storage.read_bytes(directory / "result.json") + result = storage.decode(content) + storage.fields(result, wire.ENVELOPE_FIELDS, "command result") + if result["state"] not in {"completed", "refused", "unknown"}: + raise wire.Refusal("retained result state is invalid") + if storage.sha(content) != record["result_sha256"] or any(result[k] != self._reply(request, result["state"])[k] + for k in ("protocol", "adapter_id", "body_id", "source_sha256", "command_id", "request_sha256", "recorded_epoch", "receipt_scope")): + raise wire.Refusal("retained terminal result changed") + return record + + def _terminal(self, directory, record, envelope): + content = storage.encoded(envelope) + path = directory / "result.json" + # An orphan transport result is never an authority source; retain it separately. + if path.exists(): + path.rename(directory / ("orphan-result-" + uuid.uuid4().hex + ".json")) + storage.create_file(path, content) + terminal = {**record, "result_sha256": storage.sha(content)} + storage.persist(directory / "intent.json", terminal) + record.update(terminal) + + def _restore(self): + entries = list((self.root / "commands").iterdir()) + if len(entries) > wire.MAX_COMMANDS: + raise wire.Refusal("retained command budget exceeded") + for directory in entries: + if directory.is_symlink() or not directory.is_dir(): + raise wire.Refusal("command journal must contain owned directories") + if not (directory / "intent.json").exists(): + # No accepted intent implies no effect; admission has not happened. + continue + record = self._read_record(directory) + request = record["request"] + self.records[request["command_id"]] = record + if record["result_sha256"] is None and request["operation"] == "dispatch": + # Recover only indexed, SHA-verified historical lower proof. Never dispatch. + try: + with storage.locked(self.root / "agent"): + manifest, _ = self.agent._load() + proposal_id = request["arguments"]["proposal_id"] + self.agent._read(manifest, "proposals", proposal_id) + self.agent._read(manifest, "intents", proposal_id) + result = self.agent._read(manifest, "results", proposal_id) + if result["proposal_id"] != proposal_id: + raise wire.Refusal("lower dispatch identity differs") + outer = "unknown" if result["outcome"] == "unknown" else "completed" + self._terminal(directory, record, self._reply(request, outer, agent.public_response(result), + "read-only lower receipt recovered after restart")) + except Exception as exc: # noqa: BLE001 - absent lower proof must remain unresolved. + storage.persist(directory / f"recovery-{self.epoch}.json", {"reason": str(exc), "state": "unknown"}) + + def _unresolved(self): + unknown = [] + for key in self.records: + record = self._read_record(self._directory(key)) + if record["result_sha256"] is None or storage.decode(storage.read_bytes( + self._directory(key) / "result.json"))["state"] == "unknown": + unknown.append(key) + return unknown + + def _known_body(self): + status = self.agent.status() + if status["bench"]["state"] != "ready" or status["unresolved_proposals"] or self._unresolved(): + raise wire.Refusal("accepted outcome is unknown; new commands are blocked") + return status["bench"] + + def state(self): + with self.lock: + self._identity_guard() + native = self.agent.status() + unresolved = self._unresolved() + lease = None + if self.lease: + lease = {k: self.lease[k] for k in ("client_id", "lease_id", "epoch")} + lease["expires_in_s"] = max(0, self.lease["expires_at"] - time.monotonic()) + return {"identity": {**self.pinned, "epoch": self.epoch}, "state": "unknown" if unresolved or + native["unresolved_proposals"] or native["bench"]["state"] != "ready" else "ready", + "bench": agent.public_response(native["bench"]), "unresolved_commands": unresolved, "lease": lease} + + def _lease_valid(self, client_id, lease_id, epoch): + return bool(self.lease and epoch == self.epoch == self.lease["epoch"] and + client_id == self.lease["client_id"] and lease_id == self.lease["lease_id"] and + time.monotonic() < self.lease["expires_at"]) + + def acquire(self, value): + storage.fields(value, ("client_id", "expected_epoch", "duration_s"), "lease request") + wire.identity(value["client_id"]) + wire.epoch(value["expected_epoch"]) + duration = wire.finite(value["duration_s"]) + if not .05 <= duration <= 30: + raise wire.Refusal("lease duration must be between 0.05 and 30 seconds") + with self.lock: + self._identity_guard() + if self.closed or value["expected_epoch"] != self.epoch: + raise wire.Refusal("requested boot epoch is no longer current") + if self.lease and time.monotonic() < self.lease["expires_at"] and self.lease["client_id"] != value["client_id"]: + raise wire.Refusal("another client owns the unexpired body lease") + self.lease = {"client_id": value["client_id"], "lease_id": uuid.uuid4().hex, "epoch": self.epoch, + "expires_at": time.monotonic() + duration} + return {k: self.lease[k] for k in ("client_id", "lease_id", "epoch")} | {"duration_s": duration} + + def reconcile(self, command_id, value): + wire.identity(command_id) + storage.fields(value, ("client_id", "lease_id", "epoch", "request_sha256"), "reconcile query") + for key in ("client_id", "lease_id"): + wire.identity(value[key]) + wire.epoch(value["epoch"]) + wire.digest(value["request_sha256"]) + with self.lock: + self._identity_guard() + record = self.records.get(command_id) + if record: + record = self._read_record(self._directory(command_id)) + request = record["request"] + if wire.command_digest(request) != value["request_sha256"] or any( + request[k] != value[k] for k in ("client_id", "lease_id", "epoch")): + raise wire.Refusal("reconcile identity or digest conflicts with retained command") + if record["result_sha256"]: + return storage.decode(storage.read_bytes(self._directory(command_id) / "result.json")) + return self._reply(request, "unknown", reason="accepted intent has no verified terminal proof") + return {**{k: self.pinned[k] for k in ("protocol", "adapter_id", "body_id", "source_sha256")}, + "command_id": command_id, "request_sha256": value["request_sha256"], "state": "not_seen" if + self._lease_valid(value["client_id"], value["lease_id"], value["epoch"]) else "not_accepted", + "result": None, "reason": "no accepted command in retained journal", "receipt_scope": "retained_command_result", + "recorded_epoch": value["epoch"]} + + def _barrier(self, where, request): + if (self.barrier == where and request["operation"] == "dispatch" and + self.body.status()["diagnostic_enabled"]): + storage.persist(self.root / "barrier.json", {"barrier": where, "command_id": request["command_id"], "pid": os.getpid()}) + os.kill(os.getpid(), signal.SIGSTOP) + + def command(self, request): + wire.validate_command(request) + with self.lock: + self._identity_guard() + if any(request[k] != self.pinned[k] for k in ("protocol", "adapter_id", "body_id", "source_sha256")): + return self._reply(request, "not_accepted", reason="pinned command identity changed") + existing = self.records.get(request["command_id"]) + if existing: + existing = self._read_record(self._directory(request["command_id"])) + if existing["request_sha256"] != wire.command_digest(request): + return self._reply(request, "refused", reason="command identity conflicts with its retained digest") + if existing["result_sha256"]: + return storage.decode(storage.read_bytes(self._directory(request["command_id"]) / "result.json")) + return self._reply(request, "unknown", reason="accepted intent has no verified terminal proof") + if self.closed or not self._lease_valid(request["client_id"], request["lease_id"], request["epoch"]): + return self._reply(request, "not_accepted", reason="body lease expired or was revoked before admission") + try: + self._known_body() + except (wire.Refusal, bench.Refusal) as exc: + return self._reply(request, "not_accepted", reason=str(exc)) + if len(self.records) >= wire.MAX_COMMANDS: + return self._reply(request, "not_accepted", reason="body command journal budget exhausted") + args, operation = request["arguments"], request["operation"] + if operation == "disturb" and not self.body.status()["diagnostic_enabled"]: + return self._reply(request, "not_accepted", reason="diagnostic disturbance is disabled") + if not self._lease_valid(request["client_id"], request["lease_id"], request["epoch"]): + return self._reply(request, "not_accepted", reason="body lease expired during admission validation") + directory = self._directory(request["command_id"]) + directory.mkdir(mode=0o700, exist_ok=True) + storage.directory(directory) + record = {"request": request, "request_sha256": wire.command_digest(request), "result_sha256": None} + storage.persist(directory / "intent.json", record) + self.records[request["command_id"]] = record + result, state, reason = None, "unknown", None + try: + self._barrier("before_dispatch", request) + if operation == "start_job": + result = self.body.start_job(**args) + elif operation == "observe": + result = self.agent.observe() + elif operation == "propose": + result = self.agent.propose(**args) + elif operation == "dispatch": + result = self.agent.dispatch(**args) + else: + result = self.body.disturb(**args) + self._barrier("after_dispatch", request) + state = "unknown" if operation == "dispatch" and result["outcome"] == "unknown" else "completed" + except Exception as exc: # noqa: BLE001 - accepted command may have partial effects. + reason = str(exc) + try: + core = self.agent.status() + if isinstance(exc, (wire.Refusal, bench.Refusal)) and core["bench"]["state"] == "ready" and not core["unresolved_proposals"]: + state = "refused" + except Exception as status_error: # noqa: BLE001 - missing native readback cannot resolve uncertainty. + reason += "; native status unresolved: " + str(status_error) + envelope = self._reply(request, state, agent.public_response(result), reason) + try: + self._terminal(directory, record, envelope) + except OSError: + return self._reply(request, "unknown", reason="accepted effect has no durable transport result") + return envelope + + def image(self, challenge_id): + with self.lock: + self._identity_guard() + with storage.locked(self.root / "agent"): + manifest, _ = self.agent._load() + challenge = self.agent._challenge(manifest, challenge_id) + return storage.read_bytes(Path(challenge["image_path"]), maximum=wire.MAX_MEDIA) + + +class _Server(ThreadingHTTPServer): + daemon_threads = True + def __init__(self, address, service): + super().__init__(address, _Handler) + self.service = service + self.host = f"127.0.0.1:{self.server_address[1]}" + + +class _Handler(BaseHTTPRequestHandler): + def log_message(self, *_): + pass + + def reply(self, code, value, mime="application/json"): + content = value if isinstance(value, bytes) else storage.encoded(value) + self.send_response(code) + self.send_header("Content-Type", mime) + self.send_header("Content-Length", str(len(content))) + self.send_header("Cache-Control", "no-store") + self.send_header("Connection", "close") + self.end_headers() + self.wfile.write(content) + self.close_connection = True + + def _headers(self, pinned=True): + if (self.headers.get_all("Host") != [self.server.host] or self.headers.get_all("Origin") is not None): + raise wire.Refusal("exact loopback Host and absence of browser Origin are required") + if pinned: + for name, key in (("X-Body-Id", "body_id"), ("X-Adapter-Id", "adapter_id"), ("X-Source-Sha256", "source_sha256")): + if self.headers.get_all(name) != [self.server.service.pinned[key]]: + raise wire.Refusal("pinned body request headers are required") + + def do_GET(self): + try: + parsed = urlsplit(self.path) + self._headers(pinned=parsed.path != "/identity") + if parsed.path == "/identity" and not parsed.query: + result = self.server.service.identity() + elif parsed.path == "/state" and not parsed.query: + result = self.server.service.state() + elif parsed.path.startswith("/images/") and not parsed.query: + result = self.server.service.image(parsed.path.removeprefix("/images/")) + self.reply(200, result, "image/png") + return + elif parsed.path.startswith("/commands/"): + query = parse_qs(parsed.query, keep_blank_values=True, strict_parsing=True) + if any(len(value) != 1 for value in query.values()): + raise wire.Refusal("reconcile query has duplicate fields") + value = {key: values[0] for key, values in query.items()} + if "epoch" in value and value["epoch"].isascii() and value["epoch"].isdigit(): + value["epoch"] = int(value["epoch"]) + result = self.server.service.reconcile(parsed.path.removeprefix("/commands/"), value) + else: + raise wire.Refusal("unknown body read route") + self.reply(200, result) + except (wire.Refusal, bench.Refusal, OSError, ValueError, TypeError, KeyError) as exc: + self.reply(409, {"state": "not_accepted", "reason": str(exc)}) + + def do_POST(self): + try: + self._headers() + lengths = self.headers.get_all("Content-Length") + if (lengths is None or len(lengths) != 1 or not lengths[0].isascii() or not lengths[0].isdigit() or + not 1 <= int(lengths[0]) <= storage.MAX_BYTES or self.headers.get_all("Transfer-Encoding") or + self.headers.get_all("Content-Type") != ["application/json"]): + raise wire.Refusal("one bounded exact JSON body is required") + self.connection.settimeout(5) + content = self.rfile.read(int(lengths[0])) + if len(content) != int(lengths[0]): + raise wire.Refusal("body request is truncated") + request = storage.decode(content) + if self.path == "/lease": + result = self.server.service.acquire(request) + elif self.path == "/commands": + result = self.server.service.command(request) + else: + raise wire.Refusal("unknown body mutation route") + self.reply(200, result) + except (wire.Refusal, bench.Refusal, OSError, ValueError, TypeError, KeyError) as exc: + self.reply(409, {"state": "not_accepted", "reason": str(exc)}) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, required=True) + parser.add_argument("--port", type=int, default=0) + parser.add_argument("--initialize", action="store_true") + parser.add_argument("--diagnostic", action="store_true") + parser.add_argument("--barrier", choices=("before_dispatch", "after_dispatch")) + args = parser.parse_args() + if args.initialize: + initialize(args.root, args.diagnostic) + service = BodyService(args.root, port=args.port, barrier=args.barrier).start() + print(storage.encoded({"origin": service.origin, "identity": service.identity()}).decode(), flush=True) + stopped = threading.Event() + signal.signal(signal.SIGTERM, lambda *_: stopped.set()) + signal.signal(signal.SIGINT, lambda *_: stopped.set()) + try: + stopped.wait() + finally: + service.close() + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/body_protocol.py b/tools/physical-workcell/body_protocol.py new file mode 100644 index 0000000..d043155 --- /dev/null +++ b/tools/physical-workcell/body_protocol.py @@ -0,0 +1,67 @@ +"""Strict bounded messages for the persistent loopback body adapter.""" +import agent_bench +import bench +import order_protocol as storage + +PROTOCOL = "footwork.body/1" +MAX_COMMANDS = 256 +MAX_MEDIA = 2 * 1024 * 1024 +Refusal = storage.Refusal +decode, encoded, sha = storage.decode, storage.encoded, storage.sha +fields, identity, finite = storage.fields, storage.identity, storage.finite +COMMAND_FIELDS = {"protocol", "adapter_id", "body_id", "source_sha256", "client_id", "lease_id", + "epoch", "command_id", "operation", "arguments"} +ENVELOPE_FIELDS = {"protocol", "adapter_id", "body_id", "source_sha256", "command_id", "request_sha256", + "state", "result", "reason", "receipt_scope", "recorded_epoch"} + + +def epoch(value): + if type(value) is not int or not 1 <= value <= 2147483647: + raise Refusal("boot epoch must be a positive bounded integer") + return value + + +def digest(value): + if not isinstance(value, str) or not storage.DIGEST.fullmatch(value): + raise Refusal("SHA256 must be an exact lowercase digest") + return value + + +def command_digest(request): + return sha(encoded(request)) + + +def validate_command(request): + fields(request, COMMAND_FIELDS, "body command") + if request["protocol"] != PROTOCOL: + raise Refusal("unsupported body protocol") + for key in ("adapter_id", "body_id", "client_id", "lease_id", "command_id"): + identity(request[key]) + digest(request["source_sha256"]) + epoch(request["epoch"]) + operation, arguments = request["operation"], request["arguments"] + if operation == "start_job": + fields(arguments, ("job_id", "target_zone"), "start job") + identity(arguments["job_id"]) + bench.validate_zone(arguments["target_zone"]) + elif operation == "observe": + fields(arguments, (), "observe") + elif operation == "propose": + fields(arguments, ("challenge_id", "action", "intent", "target_x", "target_y"), "proposal") + identity(arguments["challenge_id"]) + agent_bench.AgentBench._validate_action(arguments["action"], arguments["intent"], + arguments["target_x"], arguments["target_y"]) + if arguments["action"] == "move" and not (-.32 <= arguments["target_x"] <= .18 and -.15 <= arguments["target_y"] <= .15): + raise Refusal("proposal target exceeds the qualified pusher bounds") + elif operation == "dispatch": + fields(arguments, ("proposal_id",), "dispatch") + identity(arguments["proposal_id"]) + elif operation == "disturb": + fields(arguments, ("operation_id", "force_x_n", "steps"), "diagnostic disturbance") + identity(arguments["operation_id"]) + force = finite(arguments["force_x_n"]) + if not 0 < abs(force) <= 2 or type(arguments["steps"]) is not int or not 1 <= arguments["steps"] <= 150: + raise Refusal("diagnostic disturbance exceeds its bounded force or step count") + else: + raise Refusal("unsupported body operation") + return request diff --git a/tools/physical-workcell/network_fault_proxy.py b/tools/physical-workcell/network_fault_proxy.py new file mode 100644 index 0000000..aace2f7 --- /dev/null +++ b/tools/physical-workcell/network_fault_proxy.py @@ -0,0 +1,199 @@ +"""One-shot diagnostic TCP faults; command payload bytes are forwarded unchanged. + +FaultProxy(origin, root).start() exposes .origin. arm(mode, operation='dispatch', +delay_s=.2) affects one matching command. Events are immutable private JSON files. +This loopback test instrument is not an authentication or production proxy. +""" +import concurrent.futures +import contextlib +import fcntl +import http.client +import os +import socket +import stat +import threading +import time +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import urlsplit + +import body_client +import order_protocol as protocol + +MODES = {"delay_before", "delay_after", "drop_before", "drop_after", "duplicate"} + + +class FaultProxy: + def __init__(self, origin, root): + self.upstream = origin + body_client.endpoint(origin) + self.root = protocol.directory(root, create=True) + self.origin = None + self._mutex = threading.Lock() + self._arm = None + self._sequence = 0 + self._server = None + self._thread = None + self._fd = None + + def _event(self, kind, **data): + with self._mutex: + if self._sequence >= 2048: + raise protocol.Refusal("proxy event budget exhausted") + self._sequence += 1 + value = {"sequence": self._sequence, "kind": kind, **data} + protocol.create_file(self.root / "events" / f"{self._sequence:06d}.json", protocol.encoded(value)) + return value + + def start(self): + if self._server is not None: + raise protocol.Refusal("proxy already started") + fd = os.open(self.root / "proxy.lock", os.O_RDWR | os.O_CREAT | os.O_NOFOLLOW, 0o600) + try: + if not stat.S_ISREG(os.fstat(fd).st_mode): + raise protocol.Refusal("invalid proxy lock") + fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + if any(path.name != "proxy.lock" for path in self.root.iterdir()): + raise protocol.Refusal("fault proxy requires a fresh private journal") + (self.root / "events").mkdir(mode=0o700) + (self.root / "requests").mkdir(mode=0o700) + owner = self + + class Handler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + + def log_message(self, *_): + pass + + def do_GET(self): + self.handle_request() + + def do_POST(self): + self.handle_request() + + def drop(self): + self.close_connection = True + with contextlib.suppress(OSError): + self.connection.shutdown(socket.SHUT_RDWR) + self.connection.close() + + def handle_request(self): + self.connection.settimeout(30) + try: + host = owner.origin.removeprefix("http://") + if (self.headers.get_all("Host") != [host] or self.headers.get("Transfer-Encoding") is not None or + self.headers.get("Origin") is not None or urlsplit(self.path).scheme or + not self.path.startswith("/")): + raise protocol.Refusal("proxy request shape refused") + for name in ("X-Body-Id", "X-Adapter-Id", "X-Source-Sha256"): + if len(self.headers.get_all(name, [])) > 1: + raise protocol.Refusal("proxy refuses duplicate identity headers") + if self.command == "POST" and self.headers.get_all("Content-Type") != ["application/json"]: + raise protocol.Refusal("proxy requires one exact JSON content type") + lengths = self.headers.get_all("Content-Length", []) + if len(lengths) > 1 or (lengths and (not lengths[0].isdigit() or int(lengths[0]) > protocol.MAX_BYTES)): + raise protocol.Refusal("proxy request exceeds bounded size") + length = int(lengths[0]) if lengths else 0 + payload = self.rfile.read(length) + if len(payload) != length: + raise protocol.Refusal("proxy request body is incomplete") + operation, command_id = None, None + if self.command == "POST" and self.path == "/commands": + command = protocol.decode(payload) + operation, command_id = command.get("operation"), command.get("command_id") + elif self.command == "POST" and self.path == "/lease": + operation = "lease" + headers = {key: value for key, value in self.headers.items() + if key.lower() not in {"host", "connection", "content-length", "transfer-encoding"}} + headers["Content-Length"] = str(length) + with owner._mutex: + fault = owner._arm if owner._arm and owner._arm["operation"] == operation else None + if fault: + owner._arm = None + event = owner._event("received", operation=operation, command_id=command_id, + method=self.command, path=self.path, payload_sha256=protocol.sha(payload), + fault=fault) + request_file = owner.root / "requests" / f"{event['sequence']:06d}.bin" + protocol.create_file(request_file, payload) + mode = fault["mode"] if fault else None + if mode == "drop_before": + owner._event("dropped_before", command_id=command_id) + self.drop() + return + if mode == "delay_before": + owner._event("delay_before", command_id=command_id, delay_s=fault["delay_s"]) + time.sleep(fault["delay_s"]) + + def forward(copy_index): + owner._event("forwarded", command_id=command_id, copy_index=copy_index, + payload_sha256=protocol.sha(payload)) + status, content = body_client.http_call(owner.upstream, self.command, self.path, + headers, payload if self.command == "POST" else None, + timeout=30, maximum=body_client.MAX_IMAGE) + owner._event("upstream_reply", command_id=command_id, copy_index=copy_index, + http_status=status, response_sha256=protocol.sha(content)) + return status, content + + if mode == "duplicate": + with concurrent.futures.ThreadPoolExecutor(max_workers=2) as pool: + futures = [pool.submit(forward, index) for index in (1, 2)] + responses = [future.result() for future in futures] + status, content = responses[0] + owner._event("duplicate_replies", command_id=command_id, + same_reply=responses[0] == responses[1]) + else: + status, content = forward(1) + if mode == "delay_after": + owner._event("delay_after", command_id=command_id, delay_s=fault["delay_s"]) + time.sleep(fault["delay_s"]) + if mode == "drop_after": + owner._event("dropped_after", command_id=command_id) + self.drop() + return + self.send_response(status) + self.send_header("Content-Type", "image/png" if self.path.startswith("/images/") else "application/json") + self.send_header("Content-Length", str(len(content))) + self.send_header("Connection", "close") + self.close_connection = True + self.end_headers() + self.wfile.write(content) + owner._event("reply_sent", command_id=command_id, http_status=status) + except (OSError, http.client.HTTPException, protocol.Refusal, KeyError, ValueError) as exc: + with contextlib.suppress(Exception): + owner._event("transport_failure", reason=str(exc)) + self.drop() + + self._server = ThreadingHTTPServer(("127.0.0.1", 0), Handler) + self._server.daemon_threads = False + self.origin = f"http://127.0.0.1:{self._server.server_port}" + self._fd = fd + self._thread = threading.Thread(target=self._server.serve_forever, name="body-fault-proxy", daemon=True) + self._thread.start() + self._event("started", origin=self.origin, upstream=self.upstream) + return self + except Exception: + os.close(fd) + raise + + def arm(self, mode, operation="dispatch", delay_s=.2): + if mode not in MODES or operation not in {"start_job", "observe", "propose", "dispatch", "disturb", "lease"}: + raise protocol.Refusal("unsupported one-shot proxy fault") + delay = protocol.finite(delay_s) + if not 0 <= delay <= 2: + raise protocol.Refusal("proxy delay exceeds its two-second budget") + with self._mutex: + if self._server is None or self._arm is not None: + raise protocol.Refusal("proxy must be running with no outstanding fault") + self._arm = {"mode": mode, "operation": operation, "delay_s": delay} + self._event("armed", mode=mode, operation=operation, delay_s=delay) + + def close(self): + if self._server is not None: + self._server.shutdown() + try: + self._server.server_close() + self._thread.join(timeout=2) + self._event("closed") + finally: + self._server = None + os.close(self._fd) + self._fd = None diff --git a/tools/physical-workcell/qualify_network_body.py b/tools/physical-workcell/qualify_network_body.py new file mode 100644 index 0000000..f3fc9d0 --- /dev/null +++ b/tools/physical-workcell/qualify_network_body.py @@ -0,0 +1,175 @@ +"""Frozen actual-model network trial; native-state scoring is post-trial only.""" + +import argparse +import json +import socket +import subprocess +import threading +import time +import traceback +import urllib.request +from pathlib import Path + +import agent_bench +import body_client +import codex_policy +import network_fault_proxy +import order_protocol as protocol + +BASE = Path(__file__).resolve().parent +REPO = BASE.parents[1] +SOURCES = [BASE / name for name in ( + "body_protocol.py", "body_network.py", "body_client.py", "network_fault_proxy.py", + "qualify_network_body.py", "score_network_body.py", "codex_policy.py", "codex-policy.md", + "codex-action.schema.json", "agent_bench.py", "bench.py", "measurement.py", "workcell.py", + "image_guided.py", "episode_cases.py", "order_protocol.py", "scene.xml", "qualify_bench.py")] +SOURCES.append(BASE.parent / "camera-capture-experiment" / "capture.py") +ZONES = ({"x_min": .035, "x_max": .105, "y_min": -.025, "y_max": .025}, + {"x_min": .045, "x_max": .115, "y_min": -.025, "y_max": .025}) + + +def retain(path, value): + protocol.create_file(path, protocol.encoded(value)) + + +def freeze(root, commit): + if subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=REPO, text=True).strip() != commit: + raise protocol.Refusal("trial must start at named source commit") + files = {} + for path in SOURCES: + name = str(path.relative_to(REPO)) + content = protocol.read_bytes(path) + if subprocess.check_output(["git", "show", f"{commit}:{name}"], cwd=REPO) != content: + raise protocol.Refusal("source differs from named commit: " + name) + files[name] = protocol.sha(content) + retain(root / "source-freeze.json", {"commit": commit, "files": files}) + + +def available_port(): + with socket.socket() as sock: + sock.bind(("127.0.0.1", 0)) + return sock.getsockname()[1] + + +def run(root, commit): + root = protocol.directory(root, create=True) + freeze(root, commit) + port = available_port() + origin = f"http://127.0.0.1:{port}" + log = (root / "service.log").open("xb") + process = subprocess.Popen([str(BASE / ".venv/bin/python"), str(BASE / "body_network.py"), + "--root", str(root / "body"), "--port", str(port), + "--initialize", "--diagnostic"], stdout=log, stderr=log) + proxy, client = None, None + ledger = {"attempt": 1, "planner": "actual_codex_cli_images_over_TCP", "jobs": [], + "faults": [], "service_pid": process.pid, "body_origin": origin, "passed": False} + try: + deadline = time.monotonic() + 20 + while True: + try: + with urllib.request.urlopen(origin + "/identity", timeout=1) as response: + identity = protocol.decode(response.read(protocol.MAX_BYTES + 1)) + break + except (OSError, ValueError): + if process.poll() is not None or time.monotonic() >= deadline: + raise RuntimeError("body service failed to start") + time.sleep(.1) + retain(root / "identity.json", identity) + proxy = network_fault_proxy.FaultProxy(origin, root / "proxy") + proxy.start() + client = body_client.BodyClient(root / "client", proxy.origin, timeout=15) + client.acquire() + retain(root / "initial-public.json", client.status()) + (root / "calls").mkdir(mode=0o700) + injected = set() + for index, zone in enumerate(ZONES, 1): + job_id = f"network-ai-{index}" + history = [] + client.acquire() + client.start_job(job_id, zone) + entry = {"job_id": job_id, "calls": 0, "completed": False} + ledger["jobs"].append(entry) + for number in range(1, 33): + client.acquire() + challenge = client.observe() + directory = root / "calls" / f"job-{index}-call-{number:03d}" + directory.mkdir(mode=0o700) + retain(directory / "reservation.json", {"job_id": job_id, "call": number, + "challenge": challenge, "history": history[-6:]}) + action, metadata = codex_policy.decide(challenge, history[-6:], directory, threading.Event()) + retain(directory / "decision.json", {"action": action, "metadata": metadata}) + entry["calls"] += 1 + if action["action"] == "stop": + raise RuntimeError("model stopped: " + action["intent"]) + client.acquire() + proposal = client.propose(challenge["challenge_id"], action["action"], action["intent"], + action["target_x"], action["target_y"]) + retain(directory / "proposal.json", proposal) + mode = None + if action["action"] == "move": + for candidate in ("drop_after", "duplicate", "delay_after"): + if candidate not in injected: + mode = candidate + injected.add(mode) + proxy.arm(mode, operation="dispatch", delay_s=.2) + break + try: + outcome = client.dispatch(proposal["proposal_id"]) + except body_client.Uncertain as exc: + # Only read the original command's result. Never send dispatch again. + reconciliation = client.reconcile(exc.command_id) + retain(directory / "reconciliation.json", reconciliation) + if reconciliation["state"] != "completed": + raise RuntimeError("dispatch remains unresolved") from exc + outcome = reconciliation["result"] + ledger["faults"].append({"mode": mode, "command_id": exc.command_id, + "reconciled_state": reconciliation["state"], + "read_only": True, "call": str(directory.relative_to(root))}) + if mode and mode != "drop_after": + ledger["faults"].append({"mode": mode, "call": str(directory.relative_to(root))}) + outcome = agent_bench.public_response(outcome) + retain(directory / "dispatch.json", outcome) + history.append({"action": action, "outcome": outcome["outcome"], + "reason": outcome.get("reason", "")}) + if outcome["outcome"] == "unknown": + raise RuntimeError("local guard returned unknown") + print(json.dumps({"job": job_id, "call": number, "action": action["action"], + "outcome": outcome["outcome"], "fault": mode}), flush=True) + if action["action"] == "finish_reset" and outcome["outcome"] == "executed": + entry["completed"] = True + break + if not entry["completed"]: + raise RuntimeError("model job exhausted 32-call bound") + retain(root / "final-public.json", client.status()) + ledger["passed"] = len(ledger["jobs"]) == 2 and all(job["completed"] for job in ledger["jobs"]) + except Exception as exc: + ledger["error"] = type(exc).__name__ + ": " + str(exc) + (root / "failure.txt").write_text(traceback.format_exc()) + raise + finally: + if client and hasattr(client, "close"): + client.close() + if proxy: + proxy.close() + process.terminate() + try: + process.wait(timeout=15) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + log.close() + ledger["service_exit_observed"] = process.poll() is not None + retain(root / "attempt.json", ledger) + return ledger + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, required=True) + parser.add_argument("--source-commit", required=True) + args = parser.parse_args() + run(args.root, args.source_commit) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/score_network_body.py b/tools/physical-workcell/score_network_body.py new file mode 100644 index 0000000..a45d472 --- /dev/null +++ b/tools/physical-workcell/score_network_body.py @@ -0,0 +1,151 @@ +"""Independent post-trial native, SQLite, model-input and network receipt checks.""" + +import argparse +import json +from pathlib import Path + +import agent_bench +import bench +import body_client +import order_protocol as protocol +import qualify_bench + +BASE = Path(__file__).resolve().parent +REPO = BASE.parents[1] + + +def read(path): + return protocol.decode(protocol.read_bytes(path)) + + +def private_fields(value): + if isinstance(value, dict): + return bool(set(value) & (agent_bench.DERIVED_LOCATION_FIELDS | {"qpos", "qvel", "values"})) or any( + private_fields(item) for item in value.values()) + if isinstance(value, list): + return any(private_fields(item) for item in value) + return False + + +def score(root): + root = protocol.directory(root) + frozen = read(root / "source-freeze.json") + unchanged = all(protocol.sha(protocol.read_bytes(REPO / name)) == digest for name, digest in frozen["files"].items()) + attempt = read(root / "attempt.json") + identity = read(root / "identity.json") + native_root = root / "body" / "bench" + status = bench.Bench(native_root).status() + initial_content = protocol.read_bytes(bench.body.state_path(native_root, 0)) + initial = qualify_bench.native_score(native_root, 0, protocol.sha(initial_content), bench.HOME_ZONE) + database = qualify_bench.sqlite_score(native_root) + agent_root = root / "body" / "agent" + agent_manifest = read(agent_root / "agent.json") + client_manifest = body_client.read_journal(root / "client" / "client.json") + proxy_events = [read(path) for path in sorted((root / "proxy" / "events").glob("*.json"))] + transport = [] + for directory in (root / "body" / "commands").iterdir(): + record = read(directory / "intent.json") + request = record["request"] + content = protocol.read_bytes(directory / "result.json") + result = protocol.decode(content) + valid = (record["request_sha256"] == protocol.sha(protocol.encoded(request)) == result["request_sha256"] and + record["result_sha256"] == protocol.sha(content) and + directory.name == protocol.sha(request["command_id"].encode()) and + all(result[key] == request[key] for key in ("protocol", "adapter_id", "body_id", "source_sha256", "command_id"))) + transport.append({"request": request, "result": result, "valid": valid}) + jobs, calls = [], [] + previous_generation, previous_time = 0, initial["native_time_s"] + for item in attempt["jobs"]: + job = status["jobs"].get(item["job_id"]) + if not job or job["phase"] != "completed": + jobs.append({"job_id": item["job_id"], "passed": False}) + continue + measurement, reset = job["measurement_receipt"], job["reset_receipt"] + stage = qualify_bench.native_score(native_root, measurement["generation"], measurement["state_sha256"], job["target_zone"]) + home = qualify_bench.native_score(native_root, reset["generation"], reset["state_sha256"], bench.HOME_ZONE) + rows = [row for row in database["rows"] if row["job_id"] == item["job_id"]] + ok = bool(item["completed"] and len(rows) == 1 and rows[0]["receipt"] == measurement and + stage["block_center_in_zone"] and home["block_center_in_zone"] and home["pusher_home"] and + stage["external_force_cleared"] and home["external_force_cleared"] and + reset["reset_contact_samples"] > 0 and reset["reset_native_steps"] > 0 and + reset["bench_id"] == measurement["bench_id"] == identity["body_id"] == status["bench_id"] and + job["started_generation"] == previous_generation and + job["started_native_time_s"] == previous_time) + jobs.append({"job_id": item["job_id"], "passed": ok, "measurement_state": stage, + "reset_state": home, "measurement_receipt": measurement, "reset_receipt": reset, + "motion_count": job["moves"], "model_calls": item["calls"]}) + previous_generation, previous_time = job["completed_generation"], job["completed_native_time_s"] + for directory in sorted((root / "calls").iterdir()): + reservation = read(directory / "reservation.json") + challenge = reservation["challenge"] + image_sha = challenge["observation"]["image_sha256"] + image_path = Path(challenge["image_path"]) + downloaded = root / "client" in image_path.parents + exact = downloaded and protocol.sha(protocol.read_bytes(image_path, maximum=1024 * 1024)) == image_sha + exact &= protocol.sha(protocol.read_bytes(directory / "input.png", maximum=1024 * 1024)) == image_sha + image_requests = [event for event in proxy_events if event["kind"] == "received" and + event.get("path") == "/images/" + challenge["challenge_id"] and event.get("method") == "GET"] + exact &= len(image_requests) == 1 + prompt = json.loads(protocol.read_bytes(directory / "prompt.txt").decode().split("\n", 1)[1]) + proposal = read(directory / "proposal.json") + content = protocol.read_bytes(agent_root / "proposals" / (proposal["proposal_id"] + ".json")) + lower_proposal = protocol.decode(content) + bound = protocol.sha(content) == agent_manifest["proposals"][proposal["proposal_id"]] and lower_proposal == proposal + content = protocol.read_bytes(agent_root / "results" / (proposal["proposal_id"] + ".json")) + lower_result = protocol.decode(content) + bound &= protocol.sha(content) == agent_manifest["results"][proposal["proposal_id"]] + bound &= agent_bench.public_response(lower_result) == read(directory / "dispatch.json") + decision = read(directory / "decision.json")["action"] + bound &= all(proposal[key] == decision[key] for key in ("action", "intent", "target_x", "target_y")) + bound &= proposal["challenge_id"] == challenge["challenge_id"] and proposal["observation_sha256"] == challenge["observation_sha256"] + dispatch_commands = [t for t in transport if t["request"]["operation"] == "dispatch" and + t["request"]["arguments"]["proposal_id"] == proposal["proposal_id"]] + bound &= len(dispatch_commands) == 1 and dispatch_commands[0]["valid"] and ( + dispatch_commands[0]["result"]["result"] == agent_bench.public_response(lower_result)) + network_bound = False + if len(dispatch_commands) == 1: + request = dispatch_commands[0]["request"] + command_id = request["command_id"] + received = [event for event in proxy_events if event["kind"] == "received" and event.get("command_id") == command_id] + local_request = read(root / "client" / "requests" / (command_id + ".json")) + network_bound = len(received) == 1 and local_request == request and client_manifest["commands"][command_id]["send_count"] == 1 + if received: + sent = protocol.read_bytes(root / "proxy" / "requests" / f"{received[0]['sequence']:06d}.bin") + network_bound &= protocol.decode(sent) == request and protocol.sha(sent) == received[0]["payload_sha256"] + model = read(directory / "outcome.json") + reconciled = None + if (directory / "reconciliation.json").exists(): + reconciled = read(directory / "reconciliation.json") + bound &= reconciled["state"] == "completed" and reconciled["result"] == agent_bench.public_response(lower_result) + bound &= len(dispatch_commands) == 1 and dispatch_commands[0]["result"] == reconciled + calls.append({"job_id": reservation["job_id"], "call": reservation["call"], "exact_TCP_image": bool(exact), + "no_private_pose": not private_fields(reservation) and not private_fields(prompt), + "model_process_reaped": model.get("process_exit_observed", False), "core_receipt_bound": bool(bound), + "one_client_send_bound": bool(network_bound), + "action": decision["action"], "outcome": lower_result["outcome"], + "usage": model.get("usage"), "reconciled_command_id": reconciled["command_id"] if reconciled else None}) + model_ok = bool(calls and all(c["exact_TCP_image"] and c["no_private_pose"] and c["model_process_reaped"] and + c["core_receipt_bound"] and c["one_client_send_bound"] for c in calls)) + faults_ok = any(f["mode"] == "drop_after" and f.get("read_only") and f["reconciled_state"] == "completed" for f in attempt["faults"]) + passed = bool(unchanged and attempt["passed"] and attempt["service_exit_observed"] and + len(jobs) == database["count"] == 2 and all(j["passed"] for j in jobs) and model_ok and faults_ok and + transport and all(t["valid"] for t in transport) and not client_manifest["pending_command_ids"] and + status["state"] == "ready" and status["active_job"] is None) + result = {"passed": passed, "source_unchanged": unchanged, "source_commit": frozen["commit"], + "scope": "loopback TCP simulation, actual Codex image policy, independent post-trial native/SQLite checks", + "body_id": identity["body_id"], "completed_cycles": sum(j["passed"] for j in jobs), + "model_boundaries_passed": model_ok, "lost_reply_reconciled": faults_ok, + "transport_journal_bound": all(t["valid"] for t in transport), "transport_command_count": len(transport), + "scores": jobs, "sqlite": database, "calls": calls, "faults": attempt["faults"]} + protocol.create_file(root / "qualification-score.json", protocol.encoded(result)) + return {key: result[key] for key in ("passed", "source_unchanged", "completed_cycles", "model_boundaries_passed", "lost_reply_reconciled")} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", required=True, type=Path) + print(json.dumps(score(parser.parse_args().root), sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/test_body_client.py b/tools/physical-workcell/test_body_client.py new file mode 100644 index 0000000..d002e52 --- /dev/null +++ b/tools/physical-workcell/test_body_client.py @@ -0,0 +1,277 @@ +"""Client/proxy development checks over real sockets and retained native bodies.""" +import socket +import time +import unittest +import uuid +from pathlib import Path + +import body_client +import body_network +import network_fault_proxy +import order_protocol as storage + +BASE = Path(__file__).resolve().parent +ZONE = {"x_min": .04, "x_max": .10, "y_min": -.025, "y_max": .025} + + +class BodyClientTests(unittest.TestCase): + def setUp(self): + self.root = BASE / "output" / ("sim9-client-" + uuid.uuid4().hex[:12]) + self.root.mkdir(mode=0o700) + body_network.initialize(self.root / "server", diagnostic_enabled=True) + self.server = body_network.BodyService(self.root / "server").start() + self.proxy = network_fault_proxy.FaultProxy(self.server.origin, self.root / "proxy").start() + self.client = body_client.BodyClient(self.root / "client", self.proxy.origin, timeout=.5) + self.clients = [self.client] + self.evidence = [] + + def tearDown(self): + for client in self.clients: + client.close() + self.proxy.close() + self.server.close() + result = self._outcome.result + failed = any(test is self for test, _ in (*result.failures, *result.errors)) + storage.create_file(self.root / "conformance.json", storage.encoded({"test_id": self.id(), "passed": not failed, + "scenario_kind": "actual_tcp_native_client_proxy", "evidence": self.evidence})) + + def event(self, value): + self.evidence.append(value) + return value + + def proposal(self): + self.client.acquire() + self.client.start_job("job", ZONE) + observation = self.client.observe() + return self.client.propose(observation["challenge_id"], "move", "bounded native approach", -.19, 0) + + def events(self): + return [storage.decode(storage.read_bytes(path)) for path in sorted((self.root / "proxy" / "events").glob("*.json"))] + + def test_images_are_downloaded_hash_bound_without_changing_nested_packet(self): + self.client.acquire() + self.client.start_job("job", ZONE) + challenge = self.event(self.client.observe()) + image = Path(challenge["image_path"]) + self.assertEqual(image.parent, self.root / "client" / "images") + self.assertNotEqual(challenge["image_path"], challenge["observation"]["image_path"]) + self.assertEqual(storage.sha(storage.read_bytes(image, maximum=body_client.MAX_IMAGE)), challenge["observation"]["image_sha256"]) + self.assertEqual(storage.sha(storage.encoded(challenge["observation"])), challenge["observation_sha256"]) + self.assertTrue(any(event.get("path", "").startswith("/images/") for event in self.events())) + + def test_drop_after_native_effect_reconciles_without_resending(self): + proposal = self.proposal() + before = self.server.state()["bench"]["generation"] + self.proxy.arm("drop_after") + with self.assertRaises(body_client.Uncertain) as caught: + self.client.dispatch(proposal["proposal_id"]) + token = caught.exception.command_id + self.event(self.client.status()) + with self.assertRaises(body_client.Uncertain): + self.client.observe() + envelope = self.event(self.client.reconcile(token)) + self.assertEqual(envelope["state"], "completed") + self.assertEqual(envelope["result"]["outcome"], "executed") + self.assertEqual(self.server.state()["bench"]["generation"], before + 1) + forwards = [event for event in self.events() if event["kind"] == "forwarded" and event.get("command_id") == token] + self.assertEqual(len(forwards), 1) + manifest = storage.decode(storage.read_bytes(self.root / "client" / "client.json")) + self.assertEqual(manifest["commands"][token]["send_count"], 1) + self.assertFalse(manifest["pending_command_ids"]) + + def test_drop_before_remains_unknown_across_client_restart_until_lease_fence(self): + self.client.acquire(duration_s=.25) + self.proxy.arm("drop_before", operation="observe") + with self.assertRaises(body_client.Uncertain) as caught: + self.client.observe() + token = caught.exception.command_id + self.client.close() + restarted = body_client.BodyClient(self.root / "client", self.proxy.origin, timeout=.5) + self.clients.append(restarted) + self.assertEqual(restarted.status()["pending_command_ids"], [token]) + with self.assertRaises(body_client.Uncertain): + restarted.acquire() + with self.assertRaises(body_client.Uncertain): + restarted.reconcile(token) + time.sleep(.3) + envelope = self.event(restarted.reconcile(token)) + self.assertEqual(envelope["state"], "not_accepted") + self.assertFalse(restarted.status()["pending_command_ids"]) + self.assertFalse([event for event in self.events() if event["kind"] == "forwarded" and event.get("command_id") == token]) + restarted.acquire() + self.assertIn("challenge_id", restarted.observe()) + + def test_duplicate_real_socket_dispatch_has_one_native_effect(self): + proposal = self.proposal() + before = self.server.state()["bench"]["generation"] + self.proxy.arm("duplicate") + result = self.event(self.client.dispatch(proposal["proposal_id"])) + self.assertEqual(result["outcome"], "executed") + self.assertEqual(self.server.state()["bench"]["generation"], before + 1) + duplicates = [event for event in self.events() if event["kind"] == "duplicate_replies"] + self.assertEqual(len(duplicates), 1) + self.assertTrue(duplicates[0]["same_reply"]) + self.assertEqual(len([event for event in self.events() if event["kind"] == "forwarded" and + event.get("command_id") == duplicates[0]["command_id"]]), 2) + + def test_delays_before_and_after_forwarding_use_real_transport(self): + self.client.acquire() + for mode in ("delay_before", "delay_after"): + self.proxy.arm(mode, operation="observe", delay_s=.03) + challenge = self.event(self.client.observe()) + self.assertIn("challenge_id", challenge) + self.assertEqual(len([event for event in self.events() if event["kind"] in {"delay_before", "delay_after"}]), 2) + + def test_rotating_lease_and_exclusive_client_holder(self): + first = self.client.acquire() + second = self.client.acquire() + self.assertNotEqual(first["lease_id"], second["lease_id"]) + outsider = body_client.BodyClient(self.root / "outsider", self.proxy.origin) + self.clients.append(outsider) + with self.assertRaises(body_client.Refusal): + outsider.acquire() + self.assertEqual(self.client.status()["server_state"]["lease"]["lease_id"], second["lease_id"]) + + def test_unbound_error_after_native_success_stays_pending(self): + proposal = self.proposal() + original = self.server.command + + def broken_reply(request): + response = original(request) + if request["operation"] == "dispatch": + return {"state": "not_accepted", "reason": "injected unbound terminal transport error"} + return response + + self.server.command = broken_reply + with self.assertRaises(body_client.Uncertain) as caught: + self.client.dispatch(proposal["proposal_id"]) + self.server.command = original + token = caught.exception.command_id + self.assertEqual(self.server.state()["bench"]["generation"], 1) + with self.assertRaises(body_client.Uncertain): + self.client.start_job("other", ZONE) + reconciled = self.event(self.client.reconcile(token)) + self.assertEqual(reconciled["state"], "completed") + self.assertEqual(self.server.state()["bench"]["generation"], 1) + + def test_unknown_request_corruption_cannot_clear_or_resend(self): + self.client.acquire() + self.proxy.arm("drop_before", operation="observe") + with self.assertRaises(body_client.Uncertain) as caught: + self.client.observe() + token = caught.exception.command_id + path = self.root / "client" / "requests" / (token + ".json") + request = storage.decode(storage.read_bytes(path)) + request["epoch"] += 1 + path.write_bytes(storage.encoded(request)) + with self.assertRaises(body_client.Refusal): + self.client.reconcile(token) + self.assertFalse([event for event in self.events() if event["kind"] == "forwarded" and event.get("command_id") == token]) + + def test_malformed_proxy_headers_never_forward_or_admit_a_native_command(self): + proposal = self.proposal() + manifest = storage.decode(storage.read_bytes(self.root / "client" / "client.json")) + pinned = manifest["identity"] + request = {"protocol": body_client.PROTOCOL, "adapter_id": pinned["adapter_id"], "body_id": pinned["body_id"], + "source_sha256": pinned["source_sha256"], "client_id": manifest["client_id"], + "lease_id": manifest["lease"]["lease_id"], "epoch": manifest["lease"]["epoch"], + "command_id": "command-malformed-" + uuid.uuid4().hex, "operation": "dispatch", + "arguments": {"proposal_id": proposal["proposal_id"]}} + payload = storage.encoded(request) + host, port = body_client.endpoint(self.proxy.origin) + good = [("Host", f"{host}:{port}"), ("Content-Type", "application/json"), + *body_client.pinned_headers(pinned).items(), ("Content-Length", str(len(payload)))] + invalid = [good + [(name, dict(good)[name])] for name in + ("Host", "Content-Type", "X-Body-Id", "X-Adapter-Id", "X-Source-Sha256")] + invalid += [[(name, "foreign.example" if name == "Host" else value) for name, value in good], + [(name, "text/plain" if name == "Content-Type" else value) for name, value in good]] + before = {str(path.relative_to(self.root / "server" / "commands")): path.read_bytes() + for path in (self.root / "server" / "commands").rglob("*") if path.is_file()} + generation = self.server.state()["bench"]["generation"] + self.event({"rejected_command": request}) + for headers in invalid: + self.event({"header_attempt": headers}) + wire = ("POST /commands HTTP/1.1\r\n" + "".join(f"{name}: {value}\r\n" for name, value in headers) + + "\r\n").encode() + payload + with socket.create_connection((host, port), timeout=2) as connection: + connection.sendall(wire) + try: + reply = connection.recv(1024) + except ConnectionResetError: + reply = b"" + self.assertEqual(reply, b"") + after = {str(path.relative_to(self.root / "server" / "commands")): path.read_bytes() + for path in (self.root / "server" / "commands").rglob("*") if path.is_file()} + self.assertEqual(after, before) + self.assertEqual(self.server.state()["bench"]["generation"], generation) + self.assertFalse([event for event in self.events() if event["kind"] == "forwarded" and + event.get("command_id") == request["command_id"]]) + failures = [event for event in self.events() if event["kind"] == "transport_failure"] + self.assertEqual(len(failures), len(invalid)) + self.event({"malformed_header_attempts": len(invalid), "accepted_intents_unchanged": True, + "native_generation_unchanged": generation}) + + def test_exact_256_record_client_journal_reloads_and_refuses_send_257(self): + self.client.acquire() + self.client.observe() + manifest = storage.decode(storage.read_bytes(self.root / "client" / "client.json")) + original_id = next(iter(manifest["commands"])) + original_record = manifest["commands"][original_id] + original_request = storage.decode(storage.read_bytes(self.root / "client" / "requests" / (original_id + ".json"))) + response_path = self.root / "client" / "responses" / (original_id + "-" + original_record["response_sha256"] + ".json") + original_response = storage.decode(storage.read_bytes(response_path)) + for index in range(255): + token = "command-capacity-" + f"{index:032x}" + request = {**original_request, "command_id": token} + content = storage.encoded(request) + digest = storage.sha(content) + storage.create_file(self.root / "client" / "requests" / (token + ".json"), content) + response = {**original_response, "command_id": token, "request_sha256": digest} + reply = storage.encoded(response) + reply_sha = storage.sha(reply) + storage.create_file(self.root / "client" / "responses" / (token + "-" + reply_sha + ".json"), reply) + manifest["commands"][token] = {"request_sha256": digest, "state": "completed", "send_count": 1, + "response_sha256": reply_sha} + raw = storage.encoded(manifest) + self.assertGreater(len(raw), storage.MAX_BYTES) + self.assertLess(len(raw), 128 * 1024) + storage.persist(self.root / "client" / "client.json", manifest) + self.event({"fixture_kind": "256 local bound records derived from one real RPC; not 256 native effects", + "serialized_bytes": len(raw), "records": len(manifest["commands"])}) + self.client.close() + reopened = body_client.BodyClient(self.root / "client", self.proxy.origin) + self.clients.append(reopened) + self.assertEqual(reopened.status()["pending_command_ids"], []) + requests_before = len([event for event in self.events() if event["kind"] == "received"]) + with self.assertRaises(body_client.Refusal): + reopened.observe() + self.assertEqual(len([event for event in self.events() if event["kind"] == "received"]), requests_before) + self.assertEqual((self.root / "client" / "client.json").read_bytes(), raw) + reopened.close() + invalid = {"duplicate": raw.replace(b'"version": 1', b'"version": 1, "version": 1'), + "nonfinite": raw.replace(b'"sequence": 3', b'"sequence": NaN'), + "oversized": raw + b" " * (128 * 1024)} + # Find the actual current sequence rather than relying on fixture event order. + invalid["nonfinite"] = raw.replace(f'"sequence": {manifest["sequence"]}'.encode(), b'"sequence": NaN') + for label, malformed in invalid.items(): + storage.create_file(self.root / ("capacity-invalid-" + label + ".json"), malformed) + (self.root / "client" / "client.json").write_bytes(malformed) + with self.assertRaises(body_client.Refusal): + body_client.BodyClient(self.root / "client", self.proxy.origin) + (self.root / "client" / "client.json").write_bytes(raw) + with self.assertRaises(storage.Refusal): + storage.decode(b" " * (storage.MAX_BYTES + 1)) + + def test_endpoint_pin_and_lifetime_client_lock(self): + with self.assertRaises(body_client.Refusal): + body_client.BodyClient(self.root / "client", self.proxy.origin) + for origin in (self.server.origin + "/", "http://localhost:80", "http://127.0.0.1:80?x=1"): + with self.assertRaises(body_client.Refusal): + body_client.BodyClient(self.root / "other", origin) + self.client.close() + with self.assertRaises(body_client.Refusal): + body_client.BodyClient(self.root / "client", self.server.origin) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/physical-workcell/test_body_network.py b/tools/physical-workcell/test_body_network.py new file mode 100644 index 0000000..0f790fa --- /dev/null +++ b/tools/physical-workcell/test_body_network.py @@ -0,0 +1,241 @@ +"""Actual TCP/native conformance; no model calls or uncertain effect retries.""" +import concurrent.futures +import json +import time +import unittest +import uuid +from http.client import HTTPConnection +from unittest import mock +from urllib.parse import urlencode, urlsplit + +import body_network as body +import body_protocol as wire +import order_protocol as storage + +ZONE = {"x_min": .035, "x_max": .105, "y_min": -.025, "y_max": .025} + + +class BodyNetworkTests(unittest.TestCase): + def setUp(self): + self.root = body.BASE / "output" / ("body-net-test-" + uuid.uuid4().hex[:10]) + body.initialize(self.root, diagnostic_enabled=True) + self.service = body.BodyService(self.root).start() + self.identity = self.get("/identity") + self.headers = {"X-Body-Id": self.identity["body_id"], "X-Adapter-Id": self.identity["adapter_id"], + "X-Source-Sha256": self.identity["source_sha256"]} + self.lease = self.post("/lease", {"client_id": "diagnostic-client", "expected_epoch": self.identity["epoch"], "duration_s": 30}) + self.events = [] + + def tearDown(self): + if self.service: + self.service.close() + failed = any(test is self for test, _ in (*self._outcome.result.failures, *self._outcome.result.errors)) + storage.create_file(self.root / "conformance.json", storage.encoded( + {"test_id": self.id(), "passed": not failed, "events": self.events})) + + def http(self, method, path, value=None, headers=None): + parsed = urlsplit(self.service.origin) + connection = HTTPConnection(parsed.hostname, parsed.port, timeout=10) + request_headers = getattr(self, "headers", {}) | (headers or {}) + content = None if value is None else storage.encoded(value) + if content is not None: + request_headers["Content-Type"] = "application/json" + connection.request(method, path, body=content, headers=request_headers) + response = connection.getresponse() + content = response.read() + connection.close() + result = content if path.startswith("/images/") else json.loads(content) + if hasattr(self, "events"): + self.events.append({"method": method, "path": path, "status": response.status, + "response": "PNG" if isinstance(result, bytes) else result}) + return response.status, result + + def get(self, path): + return self.http("GET", path)[1] + + def post(self, path, value): + return self.http("POST", path, value)[1] + + def request(self, operation, arguments, command_id=None): + return {**{k: self.identity[k] for k in ("protocol", "adapter_id", "body_id", "source_sha256")}, + **{k: self.lease[k] for k in ("client_id", "lease_id", "epoch")}, + "command_id": command_id or "command-" + uuid.uuid4().hex, + "operation": operation, "arguments": arguments} + + def command(self, operation, arguments): + request = self.request(operation, arguments) + reply = self.post("/commands", request) + self.assertEqual(reply["state"], "completed", reply) + return request, reply["result"] + + def start_and_propose(self): + self.command("start_job", {"job_id": "test-job", "target_zone": ZONE}) + _, challenge = self.command("observe", {}) + _, proposal = self.command("propose", {"challenge_id": challenge["challenge_id"], "action": "move", + "intent": "Diagnostic fixture", "target_x": -.25, "target_y": 0}) + return challenge, proposal + + def query(self, request): + return "/commands/" + request["command_id"] + "?" + urlencode({ + **{k: request[k] for k in ("client_id", "lease_id", "epoch")}, "request_sha256": wire.command_digest(request)}) + + def test_image_crosses_tcp_with_exact_challenge_sha(self): + self.command("start_job", {"job_id": "test-job", "target_zone": ZONE}) + _, challenge = self.command("observe", {}) + status, image = self.http("GET", "/images/" + challenge["challenge_id"]) + self.assertEqual(status, 200) + self.assertEqual(storage.sha(image), challenge["observation"]["image_sha256"]) + self.assertNotIn("block_center_xy", json.dumps(challenge)) + + def test_exact_concurrent_duplicate_executes_one_native_effect(self): + _, proposal = self.start_and_propose() + request = self.request("dispatch", {"proposal_id": proposal["proposal_id"]}) + with concurrent.futures.ThreadPoolExecutor(2) as pool: + replies = list(pool.map(lambda _: self.post("/commands", request), range(2))) + self.assertEqual(replies[0], replies[1]) + self.assertEqual(replies[0]["result"]["outcome"], "executed") + self.assertEqual(self.get("/state")["bench"]["generation"], 1) + self.assertEqual(self.get(self.query(request)), replies[0]) + + def test_conflicting_duplicate_refuses_without_second_effect(self): + _, proposal = self.start_and_propose() + request = self.request("dispatch", {"proposal_id": proposal["proposal_id"]}) + first = self.post("/commands", request) + conflicting = dict(request, operation="observe", arguments={}) + self.assertEqual(self.post("/commands", conflicting)["state"], "refused") + self.assertEqual(self.get(self.query(request)), first) + self.assertEqual(self.get("/state")["bench"]["generation"], 1) + + def test_expired_and_rotated_leases_fence_new_admission(self): + first = self.request("observe", {}) + self.lease = self.post("/lease", {"client_id": "diagnostic-client", "expected_epoch": self.identity["epoch"], "duration_s": .05}) + self.assertEqual(self.post("/commands", first)["state"], "not_accepted") + late = self.request("observe", {}) + time.sleep(.07) + self.assertEqual(self.post("/commands", late)["state"], "not_accepted") + self.assertEqual(self.get(self.query(late))["state"], "not_accepted") + self.assertEqual(self.service.records, {}) + + def test_lease_rechecked_after_slow_validation_before_intent(self): + self.lease = self.post("/lease", {"client_id": "diagnostic-client", "expected_epoch": self.identity["epoch"], "duration_s": .05}) + request = self.request("observe", {}) + original = self.service._known_body + def slow(): + time.sleep(.08) + return original() + with mock.patch.object(self.service, "_known_body", side_effect=slow): + reply = self.post("/commands", request) + self.assertEqual(reply["state"], "not_accepted") + self.assertEqual(self.service.records, {}) + + def test_identity_source_origin_and_exclusive_lease_refuse(self): + request = self.request("observe", {}) + self.assertEqual(self.http("POST", "/commands", request, {"Origin": self.service.origin})[0], 409) + for key, value in (("adapter_id", "foreign"), ("body_id", "foreign"), ("source_sha256", "0" * 64)): + self.assertEqual(self.post("/commands", dict(request, **{key: value}))["state"], "not_accepted") + reply = self.post("/lease", {"client_id": "other-client", "expected_epoch": self.identity["epoch"], "duration_s": 30}) + self.assertEqual(reply["state"], "not_accepted") + self.assertEqual(self.service.records, {}) + + def test_known_result_survives_restart_and_old_lease_is_fenced(self): + _, proposal = self.start_and_propose() + request = self.request("dispatch", {"proposal_id": proposal["proposal_id"]}) + first = self.post("/commands", request) + self.service.close() + self.service = body.BodyService(self.root).start() + new_identity = self.get("/identity") + self.assertEqual(new_identity["body_id"], self.identity["body_id"]) + self.assertEqual(new_identity["adapter_id"], self.identity["adapter_id"]) + self.assertGreater(new_identity["epoch"], self.identity["epoch"]) + self.assertEqual(self.get(self.query(request)), first) + self.assertEqual(self.post("/commands", request), first) + late = self.request("observe", {}) + self.assertEqual(self.post("/commands", late)["state"], "not_accepted") + self.assertEqual(self.get("/state")["bench"]["generation"], 1) + + def test_read_only_recovery_requires_indexed_hash_verified_lower_receipt(self): + _, proposal = self.start_and_propose() + request = self.request("dispatch", {"proposal_id": proposal["proposal_id"]}) + # A precise diagnostic interruption after lower receipt, before transport terminal. + with mock.patch.object(self.service, "_terminal", side_effect=OSError("fixture terminal storage failure")): + reply = self.post("/commands", request) + self.assertEqual(reply["state"], "unknown") + self.assertEqual(self.get("/state")["state"], "unknown") + self.service.close() + with mock.patch.object(body.agent.AgentBench, "dispatch", side_effect=AssertionError("recovery replayed dispatch")): + self.service = body.BodyService(self.root).start() + recovered = self.get(self.query(request)) + self.assertEqual(recovered["state"], "completed") + self.assertEqual(recovered["result"]["outcome"], "executed") + self.assertEqual(self.get("/state")["bench"]["generation"], 1) + + def test_terminal_pointer_persist_failure_keeps_cache_and_disk_unknown(self): + _, proposal = self.start_and_propose() + request = self.request("dispatch", {"proposal_id": proposal["proposal_id"]}) + directory = self.service._directory(request["command_id"]) + original = storage.persist + def fail_pointer(path, value): + if path == directory / "intent.json" and value["result_sha256"] is not None: + self.assertTrue((directory / "result.json").exists()) + raise OSError("fixture terminal pointer persistence failure") + return original(path, value) + with mock.patch.object(storage, "persist", side_effect=fail_pointer): + reply = self.post("/commands", request) + self.assertEqual(reply["state"], "unknown") + durable = storage.decode(storage.read_bytes(directory / "intent.json")) + cached_pointer = self.service.records[request["command_id"]]["result_sha256"] + self.events.append({"kind": "partial_terminal_persistence", "cached_result_sha256": cached_pointer, + "durable_result_sha256": durable["result_sha256"]}) + self.assertIsNone(durable["result_sha256"]) + self.assertEqual(self.get("/state")["state"], "unknown") + blocked = self.post("/commands", self.request("observe", {})) + self.assertEqual(blocked["state"], "not_accepted") + self.assertEqual(self.get("/state")["bench"]["generation"], 1) + self.service.close() + with mock.patch.object(body.agent.AgentBench, "dispatch", side_effect=AssertionError("recovery replayed dispatch")): + self.service = body.BodyService(self.root).start() + recovered = self.get(self.query(request)) + self.assertEqual(recovered["state"], "completed") + self.assertEqual(recovered["result"]["outcome"], "executed") + self.assertEqual(self.get("/state")["bench"]["generation"], 1) + self.assertIsNone(cached_pointer, "cached terminal pointer must change only after durable commit") + + def test_accepted_intent_without_lower_receipt_blocks_restart(self): + _, proposal = self.start_and_propose() + request = self.request("dispatch", {"proposal_id": proposal["proposal_id"]}) + directory = self.service._directory(request["command_id"]) + directory.mkdir(mode=0o700) + storage.persist(directory / "intent.json", {"request": request, "request_sha256": wire.command_digest(request), "result_sha256": None}) + self.service.close() + self.service = body.BodyService(self.root).start() + self.assertEqual(self.get(self.query(request))["state"], "unknown") + new = self.get("/identity") + self.lease = self.post("/lease", {"client_id": "diagnostic-client", "expected_epoch": new["epoch"], "duration_s": 30}) + self.identity = new + self.assertEqual(self.post("/commands", self.request("observe", {}))["state"], "not_accepted") + self.assertEqual(self.get("/state")["bench"]["generation"], 0) + + def test_missing_command_not_seen_then_not_accepted_after_lease_expiry(self): + self.lease = self.post("/lease", {"client_id": "diagnostic-client", "expected_epoch": self.identity["epoch"], "duration_s": .05}) + request = self.request("observe", {}) + self.assertEqual(self.get(self.query(request))["state"], "not_seen") + time.sleep(.06) + self.assertEqual(self.get(self.query(request))["state"], "not_accepted") + + def test_stale_observation_is_retained_known_dispatch_refusal(self): + _, proposal = self.start_and_propose() + self.command("disturb", {"operation_id": "diagnostic-force", "force_x_n": -.4, "steps": 50}) + _, result = self.command("dispatch", {"proposal_id": proposal["proposal_id"]}) + self.assertEqual(result["outcome"], "refused") + self.assertIn("stale", result["reason"]) + self.assertEqual(self.get("/state")["bench"]["generation"], 1) + + def test_invalid_arguments_never_create_intent(self): + for arguments in ({"job_id": "job", "target_zone": dict(ZONE, x_min=True)}, {"job_id": "../bad", "target_zone": ZONE}): + self.assertEqual(self.http("POST", "/commands", self.request("start_job", arguments))[0], 409) + self.assertEqual(self.http("POST", "/commands", dict(self.request("observe", {}), success=True))[0], 409) + self.assertEqual(self.service.records, {}) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/physical-workcell/test_network_body_faults.py b/tools/physical-workcell/test_network_body_faults.py new file mode 100644 index 0000000..b9f47c9 --- /dev/null +++ b/tools/physical-workcell/test_network_body_faults.py @@ -0,0 +1,731 @@ +"""SIM9 mechanical TCP faults; deterministic RGB conformance is not AI evidence. + +Each case retains inputs, socket replies, native proof, logs and its outcome under +output/n9test-*. Only this harness's child processes are stopped during cleanup. +""" + +import concurrent.futures +import copy +import hashlib +import http.client +import json +import math +import socket +import sqlite3 +import subprocess +import sys +import threading +import time +import unittest +import uuid +from pathlib import Path +from urllib.parse import urlencode, urlsplit + +import body_client +import image_guided as vision +import network_fault_proxy +import order_protocol as storage +import workcell as body + +BASE = Path(__file__).resolve().parent +ZONE = {"x_min": .04, "x_max": .11, "y_min": -.025, "y_max": .025} +CORE_FILES = ("body_protocol.py", "body_network.py", "body_client.py", "network_fault_proxy.py", + "agent_bench.py", "bench.py", "measurement.py", "workcell.py", "image_guided.py", + "episode_cases.py", "order_protocol.py", "scene.xml", "../camera-capture-experiment/capture.py") + + +def retain(path, value): + storage.create_file(path, storage.encoded(value)) + + +def port(): + with socket.socket() as connection: + connection.bind(("127.0.0.1", 0)) + return connection.getsockname()[1] + + +def tcp(origin, method, path, value=None, pinned=None, headers=None, timeout=15): + """Exercise the same public wire as clients, never call service methods.""" + parsed = urlsplit(origin) + request_headers = {} + if pinned: + request_headers.update({"X-Body-Id": pinned["body_id"], + "X-Adapter-Id": pinned["adapter_id"], + "X-Source-Sha256": pinned["source_sha256"]}) + content = None + if value is not None: + content = storage.encoded(value) + request_headers["Content-Type"] = "application/json" + request_headers.update(headers or {}) + connection = http.client.HTTPConnection(parsed.hostname, parsed.port, timeout=timeout) + try: + connection.request(method, path, content, request_headers) + response = connection.getresponse() + data = response.read(storage.MAX_BYTES + 1) + return {"http_status": response.status, "body": storage.decode(data)} + finally: + connection.close() + + +class NetworkRGBPlanner: + """Only public client calls and their hash-checked PNGs guide this policy.""" + + def __init__(self, client, record): + self.client, self.record = client, record + self.actions = 0 + + def observe(self): + self.client.acquire() + challenge = self.client.observe() + packet = challenge["observation"] + content = Path(challenge["image_path"]).read_bytes() + if hashlib.sha256(content).hexdigest() != packet["image_sha256"]: + raise AssertionError("downloaded public image digest differs") + if not packet["calibration"]["valid"]: + raise AssertionError("RGB policy requires valid published calibration") + located = vision.locate(vision.decode_png(content)) + block = vision.image_world_center(located["block"]["box"]) + pusher = vision.image_world_center(located["pusher"]["box"]) + self.record("deterministic_RGB_observation", challenge=challenge, + rgb_block_xy=block, rgb_pusher_xy=pusher) + return challenge, block, pusher + + def dispatch(self, challenge, action, intent, target=None): + self.actions += 1 + if self.actions > 64: + raise AssertionError("deterministic RGB action budget exhausted") + self.client.acquire() + proposal = self.client.propose(challenge["challenge_id"], action, intent, + *(target or (None, None))) + result = self.client.dispatch(proposal["proposal_id"]) + self.record("deterministic_RGB_dispatch", proposal=proposal, result=result) + if result["outcome"] != "executed": + raise AssertionError("RGB action did not execute: " + str(result)) + return result + + def move(self, challenge, pusher, target, intent): + delta = [target[i] - pusher[i] for i in (0, 1)] + distance = math.hypot(*delta) + if distance > .11: + target = [pusher[i] + delta[i] * .11 / distance for i in (0, 1)] + return self.dispatch(challenge, "move", intent, target) + + def position(self, center, intent): + for _ in range(48): + challenge, block, pusher = self.observe() + if abs(block[1]) > .018: + raise AssertionError("RGB block left supported axial corridor") + if abs(block[0] - center) <= .012: + return + direction = 1 if center > block[0] else -1 + side = block[0] - direction * .065 + if direction * (block[0] - pusher[0]) < .050: + target = [pusher[0], .135] if pusher[1] < .125 else [side, .135] + elif abs(pusher[1]) > .006: + target = [side, pusher[1]] if abs(pusher[0] - side) > .010 else [pusher[0], 0] + else: + gap = max(0, direction * (block[0] - pusher[0]) - .055) + target = [pusher[0] + direction * min(.09, abs(center - block[0]) + gap), 0] + if not -.32 <= target[0] <= .18: + raise AssertionError("RGB target outside published workspace") + self.move(challenge, pusher, target, intent) + raise AssertionError("RGB positioning did not converge") + + def park(self): + for _ in range(24): + challenge, block, pusher = self.observe() + if abs(pusher[0] + .3) <= .004 and abs(pusher[1]) <= .004: + return challenge + if pusher[0] > block[0] - .065 and pusher[1] < .125: + target = [pusher[0], .135] + elif pusher[0] > -.29: + target = [-.3, pusher[1]] + else: + target = [-.3, 0] + self.move(challenge, pusher, target, "deterministic RGB clear and park pusher") + raise AssertionError("RGB parking did not converge") + + def cycle(self, job_id, zone): + self.actions = 0 + self.client.acquire() + started = self.client.start_job(job_id, zone) + self.record("network_job_started", result=started) + self.position((zone["x_min"] + zone["x_max"]) / 2, "deterministic RGB prepare part") + measured = self.dispatch(self.park(), "measure", "measure image-guided placement") + challenge, _, _ = self.observe() + self.dispatch(challenge, "begin_reset", "start contact reset after measurement") + self.position(-.12, "deterministic RGB contact return to home") + reset = self.dispatch(self.park(), "finish_reset", "verify RGB part and pusher at home") + return {"job_id": job_id, "zone": zone, "measurement": measured, + "reset": reset, "actions": self.actions} + + +class NetworkBodyFaultTests(unittest.TestCase): + def setUp(self): + self.root = BASE / "output" / ("n9test-" + uuid.uuid4().hex[:10]) + self.root.mkdir(mode=0o700) + self.server_root = self.root / "body" + self.events, self.processes, self.logs, self.proxies, self.clients = [], [], [], [], [] + self.sources = {name: hashlib.sha256((BASE / name).read_bytes()).hexdigest() + for name in CORE_FILES} + self.process = None + self.client = None + self.record("case_started", test_id=self.id(), preregistration="c976508", + planner="mechanical_deterministic_RGB_only_not_AI") + + def tearDown(self): + for client in reversed(self.clients): + client.close() + for proxy in reversed(self.proxies): + try: + proxy.close() + except Exception as exc: # noqa: BLE001 - retain cleanup failures while reaping owned children. + self.record("proxy_cleanup_error", error=str(exc)) + for process in self.processes: + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + for handle in self.logs: + handle.close() + result = self._outcome.result + errors = [trace for test, trace in (*result.failures, *result.errors) + if test is self or getattr(test, "test_case", None) is self] + unchanged = self.sources == {name: hashlib.sha256((BASE / name).read_bytes()).hexdigest() + for name in CORE_FILES} + retain(self.root / "conformance.json", {"test_id": self.id(), "passed": not errors and unchanged, + "source_unchanged": unchanged, "source_sha256": self.sources, + "scope": "real_loopback_TCP_native_body_mechanical_fault_matrix", + "processes_reaped": all(p.poll() is not None for p in self.processes), + "errors": errors, "events": self.events}) + self.assertTrue(unchanged, "network/core source changed during mechanical case") + + def record(self, kind, **value): + event = {"sequence": len(self.events), "kind": kind, **value} + retain(self.root / f"event-{len(self.events):04d}.json", event) + self.events.append(event) + return value + + def start(self, *, initialize=True, barrier=None): + number = len(self.processes) + chosen_port = getattr(self, "server_port", None) or port() + self.server_port = chosen_port + self.origin = f"http://127.0.0.1:{chosen_port}" + log = (self.root / f"service-{number}.log").open("xb") + self.logs.append(log) + command = [sys.executable, str(BASE / "body_network.py"), "--root", str(self.server_root), + "--port", str(chosen_port)] + if initialize: + command += ["--initialize", "--diagnostic"] + if barrier: + command += ["--barrier", barrier] + self.process = subprocess.Popen(command, stdout=log, stderr=log) + self.processes.append(self.process) + deadline = time.monotonic() + 20 + while True: + try: + reply = tcp(self.origin, "GET", "/identity", timeout=.5) + if reply["http_status"] == 200: + self.identity = reply["body"] + break + except (OSError, http.client.HTTPException, ValueError): + pass + if self.process.poll() is not None or time.monotonic() >= deadline: + raise AssertionError("owned body service did not become ready; inspect retained service log") + time.sleep(.05) + self.record("service_ready", identity=self.identity, pid=self.process.pid, + initialize=initialize, barrier=barrier) + return self.identity + + def stop(self, *, crash=False): + process = self.process + if process.poll() is None: + if crash: + process.kill() + else: + process.terminate() + process.wait(timeout=8) + self.record("owned_service_stopped", pid=process.pid, crashed=crash, + returncode=process.returncode) + + def connect(self, *, timeout=15, proxy=False): + origin = self.origin + if proxy: + self.proxy = network_fault_proxy.FaultProxy(origin, self.root / "proxy") + self.proxy.start() + self.proxies.append(self.proxy) + origin = self.proxy.origin + self.client = body_client.BodyClient(self.root / "client", origin, timeout=timeout) + self.clients.append(self.client) + self.lease = self.client.acquire() + self.record("client_acquired", lease=self.lease, via_proxy=proxy) + return self.client + + def state(self): + reply = tcp(self.origin, "GET", "/state", pinned=self.identity) + self.assertEqual(reply["http_status"], 200, reply) + return reply["body"] + + def generation(self): + return self.state()["bench"]["generation"] + + def proposal(self): + self.client.start_job("fault-job", ZONE) + challenge = self.client.observe() + proposal = self.client.propose(challenge["challenge_id"], "move", + "mechanical network conformance motion", -.25, 0) + self.record("public_proposal", challenge=challenge, proposal=proposal) + return proposal + + def command(self, operation, arguments, *, token=None): + return {**{k: self.identity[k] for k in ("protocol", "adapter_id", "body_id", "source_sha256")}, + **{k: self.lease[k] for k in ("client_id", "lease_id", "epoch")}, + "command_id": token or "matrix-" + uuid.uuid4().hex, + "operation": operation, "arguments": arguments} + + def send(self, request, *, pinned=None): + reply = tcp(self.origin, "POST", "/commands", request, pinned=pinned or self.identity) + self.record("raw_public_command", request=request, reply=reply) + return reply + + def retained_dispatch_request(self, command_id): + # Fault assertions may inspect outgoing bytes. Policy never reads these. + for path in (self.root / "client").rglob("*.json"): + try: + value = json.loads(path.read_bytes()) + except (ValueError, OSError): + continue + if isinstance(value, dict) and value.get("command_id") == command_id and value.get("operation") == "dispatch": + return value + if isinstance(value, dict) and isinstance(value.get("request"), dict): + request = value["request"] + if request.get("command_id") == command_id and request.get("operation") == "dispatch": + return request + raise AssertionError("immutable outgoing dispatch request not found") + + def uncertain_dispatch(self, proposal): + with self.assertRaises(body_client.Uncertain) as error: + self.client.dispatch(proposal["proposal_id"]) + token = error.exception.command_id + self.record("client_uncertain", command_id=token, status=self.client.status()) + return token + + def reconcile(self, token, *, expected=None): + if expected in {"unknown", "not_seen"}: + with self.assertRaises(body_client.Uncertain) as error: + self.client.reconcile(token) + self.assertEqual(error.exception.command_id, token) + request = self.retained_dispatch_request(token) + query = urlencode({**{key: request[key] for key in ("client_id", "lease_id", "epoch")}, + "request_sha256": storage.sha(storage.encoded(request))}) + response = tcp(self.origin, "GET", "/commands/" + token + "?" + query, pinned=self.identity) + self.assertEqual(response["http_status"], 200) + reply = response["body"] + self.assertEqual(reply["state"], expected) + self.assertIn(token, self.client.status()["pending_command_ids"]) + else: + reply = self.client.reconcile(token) + self.record("read_only_reconciliation", command_id=token, reply=reply) + return reply + + def assert_single_send(self, token): + journal = storage.decode((self.root / "client" / "client.json").read_bytes()) + request = self.retained_dispatch_request(token) + entry = journal["commands"][token] + self.assertEqual(entry["send_count"], 1) + self.assertEqual(entry["request_sha256"], storage.sha(storage.encoded(request))) + self.record("independent_single_send_journal_check", command_id=token, + request_sha256=entry["request_sha256"], send_count=entry["send_count"]) + + def journal_count(self): + return len(list((self.server_root / "commands").glob("*/intent.json"))) + + def barrier(self, expected): + path = self.server_root / "barrier.json" + deadline = time.monotonic() + 12 + while time.monotonic() < deadline: + if path.exists(): + value = storage.decode(path.read_bytes()) + self.assertEqual(value["barrier"], expected) + self.assertEqual(value["pid"], self.process.pid) + self.record("actual_process_barrier", evidence=value) + return value + if self.process.poll() is not None: + break + time.sleep(.02) + raise AssertionError("owned service never reached crash barrier") + + def frozen_effects(self): + """Independent persisted effects; no authority inferred from current scene.""" + roots = (self.server_root / "bench", self.server_root / "agent") + return {str(path.relative_to(self.server_root)): hashlib.sha256(path.read_bytes()).hexdigest() + for root in roots for path in root.rglob("*") if path.is_file() + and path.name != "app.lock"} + + def assert_no_private_pose(self, value): + if isinstance(value, dict): + self.assertFalse({"block_xyz", "pusher_xyz", "qpos", "qvel", "values", "native_pose"} & value.keys()) + for item in value.values(): + self.assert_no_private_pose(item) + elif isinstance(value, list): + for item in value: + self.assert_no_private_pose(item) + + def score_native(self, receipt, zone): + root = self.server_root / "bench" + content = body.read_bytes(body.state_path(root, receipt["generation"])) + self.assertEqual(body.sha(content), receipt["state_sha256"]) + state = body.decoded(content) + manifest = storage.decode((root / "bench.json").read_bytes()) + self.assertEqual(hashlib.sha256((root / "model.xml").read_bytes()).hexdigest(), manifest["model_sha256"]) + model = body.mujoco.MjModel.from_xml_path(str(root / "model.xml")) + data = body.mujoco.MjData(model) + body.mujoco.mj_setState(model, data, body.np.asarray(state["values"]), + body.mujoco.mjtState.mjSTATE_INTEGRATION) + body.mujoco.mj_forward(model, data) + block = data.xpos[model.body("block").id].tolist() + pusher = data.xpos[model.body("pusher").id].tolist() + proof = {"role": "independent_native_read_only_scorer", "block_xyz": block, + "pusher_xyz": pusher, "generation": receipt["generation"], + "state_sha256": receipt["state_sha256"], "native_time_s": float(data.time)} + self.record("independent_native_proof", proof=proof) + self.assertTrue(zone["x_min"] <= block[0] <= zone["x_max"]) + self.assertTrue(zone["y_min"] <= block[1] <= zone["y_max"]) + self.assertTrue(.02 <= block[2] <= .08) + self.assertFalse(body.np.any(data.xfrc_applied)) + return proof + + def test_01_successive_network_cycles_with_RGB_only_policy(self): + self.start() + self.connect() + planner = NetworkRGBPlanner(self.client, self.record) + first = planner.cycle("tcp-cycle-one", ZONE) + second_zone = {"x_min": .035, "x_max": .105, "y_min": -.025, "y_max": .025} + second = planner.cycle("tcp-cycle-two", second_zone) + public = self.state() + self.assert_no_private_pose(public) + self.stop() + root = self.server_root / "bench" + manifest = storage.decode((root / "bench.json").read_bytes()) + self.assertIsNone(manifest["active_job"]) + self.assertEqual(len(manifest["jobs"]), 2) + with sqlite3.connect((root / "measurements.sqlite").as_uri() + "?mode=ro", uri=True) as db: + rows = db.execute("SELECT job_id,bench_id,generation,state_sha256,receipt_json FROM measurements ORDER BY job_id").fetchall() + self.record("independent_SQLite_readback", rows=rows) + self.assertEqual(len(rows), 2) + previous_generation = 0 + previous_time = None + for cycle in (first, second): + job = manifest["jobs"][cycle["job_id"]] + measured = job["measurement_receipt"] + reset = job["reset_receipt"] + self.assertEqual(job["phase"], "completed") + self.assertEqual(job["started_generation"], previous_generation) + if previous_time is not None: + self.assertEqual(job["started_native_time_s"], previous_time) + stage = self.score_native(measured, cycle["zone"]) + home = self.score_native(reset, {"x_min": -.16, "x_max": -.08, "y_min": -.03, "y_max": .03}) + self.assertLess(stage["native_time_s"], home["native_time_s"]) + self.assertAlmostEqual(home["pusher_xyz"][0], -.3, delta=.005) + self.assertAlmostEqual(home["pusher_xyz"][1], 0, delta=.005) + self.assertGreater(reset["reset_contact_samples"], 0) + self.assertGreater(reset["reset_native_steps"], 0) + self.assertEqual(measured["bench_id"], self.identity["body_id"]) + row = next(row for row in rows if row[0] == cycle["job_id"]) + self.assertEqual(json.loads(row[4]), measured) + self.assertEqual(row[1:4], (measured["bench_id"], measured["generation"], measured["state_sha256"])) + for key, item in (("measurement", cycle["measurement"]), ("reset", cycle["reset"])): + self.assertEqual(item["outcome"], "executed", key) + previous_generation, previous_time = job["completed_generation"], job["completed_native_time_s"] + + def test_02_bounded_delays_preserve_exact_effect(self): + self.start() + self.connect(proxy=True) + proposal = self.proposal() + for mode in ("delay_before", "delay_after"): + if mode == "delay_after": + challenge = self.client.observe() + proposal = self.client.propose(challenge["challenge_id"], "move", "second delayed motion", -.2, 0) + before = self.generation() + self.proxy.arm(mode, operation="dispatch", delay_s=.15) + started = time.monotonic() + result = self.client.dispatch(proposal["proposal_id"]) + elapsed = time.monotonic() - started + self.record("bounded_delay_result", mode=mode, elapsed_s=elapsed, result=result) + self.assertGreaterEqual(elapsed, .13) + self.assertLess(elapsed, 10) + self.assertEqual(result["outcome"], "executed") + self.assertEqual(self.generation(), before + 1) + + def test_03_drop_before_acceptance_stays_pending_until_fenced(self): + self.start() + self.connect(proxy=True) + proposal = self.proposal() + self.client.acquire(duration_s=2) + before, count = self.generation(), self.journal_count() + self.proxy.arm("drop_before", operation="dispatch") + token = self.uncertain_dispatch(proposal) + self.assertEqual(self.reconcile(token, expected="not_seen")["state"], "not_seen") + with self.assertRaises((body_client.Refusal, body_client.Uncertain)): + self.client.observe() + self.assertEqual(self.journal_count(), count) + time.sleep(2.1) + self.assertEqual(self.reconcile(token)["state"], "not_accepted") + self.assertEqual(self.generation(), before) + self.assertEqual(self.journal_count(), count) + self.assert_single_send(token) + self.client.acquire() + self.client.observe() + + def test_04_drop_after_effect_reconciles_without_resending(self): + self.start() + self.connect(proxy=True) + proposal = self.proposal() + before, count = self.generation(), self.journal_count() + self.proxy.arm("drop_after", operation="dispatch") + token = self.uncertain_dispatch(proposal) + effects = self.frozen_effects() + reconciled = self.reconcile(token) + self.assertEqual(reconciled["state"], "completed") + self.assertEqual(reconciled["result"]["outcome"], "executed") + self.assertEqual(self.reconcile(token), reconciled) + self.assertEqual(self.generation(), before + 1) + self.assertEqual(self.journal_count(), count + 1) + self.assertEqual(self.frozen_effects(), effects) + self.assert_single_send(token) + + def test_05_exact_concurrent_duplicate_has_one_result_one_motion(self): + self.start() + self.connect() + proposal = self.proposal() + request = self.command("dispatch", {"proposal_id": proposal["proposal_id"]}) + before, count = self.generation(), self.journal_count() + gate = threading.Barrier(3) + + def concurrent_send(): + gate.wait(timeout=5) + started = time.monotonic() + reply = tcp(self.origin, "POST", "/commands", request, self.identity) + return {"started": started, "ended": time.monotonic(), "reply": reply} + + with concurrent.futures.ThreadPoolExecutor(max_workers=2) as pool: + futures = [pool.submit(concurrent_send) for _ in range(2)] + gate.wait(timeout=5) + calls = [future.result(timeout=20) for future in futures] + replies = [call["reply"] for call in calls] + self.assertLess(max(call["started"] for call in calls), min(call["ended"] for call in calls)) + self.record("actual_concurrent_duplicate", request=request, calls=calls) + self.assertEqual(replies[0], replies[1]) + self.assertEqual(replies[0]["body"]["state"], "completed") + self.assertEqual(replies[0]["body"]["result"]["outcome"], "executed") + self.assertEqual(self.generation(), before + 1) + self.assertEqual(self.journal_count(), count + 1) + frozen = self.frozen_effects() + self.assertEqual(self.send(request), replies[0]) + self.assertEqual(self.frozen_effects(), frozen) + + def test_06_conflicting_duplicate_refuses_without_second_effect(self): + self.start() + self.connect() + proposal = self.proposal() + request = self.command("dispatch", {"proposal_id": proposal["proposal_id"]}) + self.assertEqual(self.send(request)["body"]["state"], "completed") + frozen, count = self.frozen_effects(), self.journal_count() + conflict = copy.deepcopy(request) + conflict["arguments"]["proposal_id"] = "proposal-" + uuid.uuid4().hex + reply = self.send(conflict) + self.assertIn(reply["body"]["state"], ("refused", "not_accepted")) + self.assertEqual(self.frozen_effects(), frozen) + self.assertEqual(self.journal_count(), count) + + def test_07_stale_image_proposal_cannot_dispatch_effect(self): + self.start() + self.connect() + proposal = self.proposal() + self.client.disturb("external-force", -.4, 50) + before = self.generation() + result = self.client.dispatch(proposal["proposal_id"]) + self.record("stale_public_dispatch", result=result) + self.assertEqual(result["outcome"], "refused") + self.assertEqual(self.generation(), before) + self.assertGreater(result["next_observation"]["observation"]["generation"], 0) + + def test_08_delay_past_lease_expiry_never_admits_late_effect(self): + self.start() + self.connect(proxy=True) + proposal = self.proposal() + self.client.acquire(duration_s=.2) + before, count = self.generation(), self.journal_count() + self.client.timeout = .1 + self.proxy.arm("delay_before", operation="dispatch", delay_s=.5) + token = self.uncertain_dispatch(proposal) + time.sleep(.7) + self.assertEqual(self.reconcile(token)["state"], "not_accepted") + self.proxy.close() # Drain actual late-forward threads before checking physical state. + events = [storage.decode(path.read_bytes()) for path in sorted((self.root / "proxy" / "events").glob("*.json"))] + self.assertTrue(any(event["kind"] == "forwarded" and event.get("command_id") == token for event in events)) + self.record("late_proxy_threads_drained", proxy_events=events) + self.assertEqual(self.generation(), before) + self.assertEqual(self.journal_count(), count) + self.assert_single_send(token) + self.record("late_admission_fenced", command_id=token) + + def test_09_identity_source_epoch_and_exclusive_lease_fence(self): + self.start() + self.connect() + proposal = self.proposal() + request = self.command("dispatch", {"proposal_id": proposal["proposal_id"]}) + frozen, count = self.frozen_effects(), self.journal_count() + for key, value in (("body_id", uuid.uuid4().hex), ("adapter_id", uuid.uuid4().hex), + ("source_sha256", "0" * 64), ("epoch", self.identity["epoch"] + 1)): + foreign = copy.deepcopy(request) + foreign[key] = value + reply = self.send(foreign) + self.assertIn(reply["body"]["state"], ("not_accepted", "refused")) + for key in ("body_id", "adapter_id", "source_sha256"): + headers = dict(self.identity) + headers[key] = "0" * (64 if key == "source_sha256" else 32) + self.assertEqual(self.send(request, pinned=headers)["http_status"], 409) + other = body_client.BodyClient(self.root / "other-client", self.origin) + self.clients.append(other) + with self.assertRaises(body_client.Refusal): + other.acquire() + old_lease = dict(self.lease) + self.lease = self.client.acquire() + self.assertNotEqual(old_lease["lease_id"], self.lease["lease_id"]) + self.assertEqual(self.send(request)["body"]["state"], "not_accepted") + self.assertEqual(self.frozen_effects(), frozen) + self.assertEqual(self.journal_count(), count) + + def test_10_process_restart_preserves_terminal_history_and_body(self): + self.start() + self.connect(proxy=True) + proposal = self.proposal() + self.proxy.arm("drop_after", operation="dispatch") + token = self.uncertain_dispatch(proposal) + original_identity = dict(self.identity) + effects = self.frozen_effects() + self.stop(crash=True) + self.start(initialize=False) + self.assertEqual(self.identity["body_id"], original_identity["body_id"]) + self.assertEqual(self.identity["adapter_id"], original_identity["adapter_id"]) + self.assertGreater(self.identity["epoch"], original_identity["epoch"]) + reply = self.reconcile(token) + self.assertEqual(reply["state"], "completed") + self.assertEqual(reply["recorded_epoch"], original_identity["epoch"]) + self.assertEqual(reply["result"]["outcome"], "executed") + self.assertEqual(self.frozen_effects(), effects) + self.assert_single_send(token) + self.client.acquire() + self.client.observe() + + def crash_at_boundary(self, boundary): + self.start(barrier=boundary) + self.connect() + proposal = self.proposal() + self.client.timeout = 1 + # Child SIGSTOP occurs before timeout and before this owned SIGKILL. + with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool: + future = pool.submit(self.client.dispatch, proposal["proposal_id"]) + barrier = self.barrier(boundary) + self.stop(crash=True) + with self.assertRaises(body_client.Uncertain) as error: + future.result(timeout=5) + self.assertEqual(error.exception.command_id, barrier["command_id"]) + token = error.exception.command_id + self.record("crash_client_uncertain", command_id=token, boundary=boundary) + effects = self.frozen_effects() + self.start(initialize=False) + return token, effects + + def test_11_restart_recovers_exact_lower_receipt_without_dispatch(self): + token, effects = self.crash_at_boundary("after_dispatch") + reply = self.reconcile(token) + self.assertEqual(reply["state"], "completed") + self.assertEqual(reply["result"]["outcome"], "executed") + self.assertEqual(self.generation(), 1) + self.assertEqual(self.frozen_effects(), effects) + self.assertEqual(self.reconcile(token), reply) + self.assertEqual(self.frozen_effects(), effects) + self.assert_single_send(token) + + def test_12_accepted_without_lower_proof_and_client_restart_stays_unknown(self): + self.start(barrier="before_dispatch") + self.connect() + proposal = self.proposal() + self.client.close() + # Both dispatch and resumed readback have distinct OS process lifetimes. + script = """ +import json,sys +from pathlib import Path +import body_client +client=body_client.BodyClient(Path(sys.argv[1]),sys.argv[2],timeout=3) +try: + try: + client.dispatch(sys.argv[3]) + except body_client.Uncertain as exc: + print(json.dumps({'command_id':exc.command_id,'pending':client.status()['pending_command_ids']}),flush=True) +finally: + client.close() +""" + handle = (self.root / "client-before-crash.log").open("xb") + self.logs.append(handle) + child = subprocess.Popen([sys.executable, "-c", script, str(self.root / "client"), + self.origin, proposal["proposal_id"]], cwd=BASE, stdout=handle, stderr=handle) + self.processes.append(child) + barrier = self.barrier("before_dispatch") + self.stop(crash=True) + child.wait(timeout=8) + self.assertEqual(child.returncode, 0) + token = barrier["command_id"] + effects = self.frozen_effects() + self.start(initialize=False) + resume = """ +import json,sys +from pathlib import Path +import body_client +client=body_client.BodyClient(Path(sys.argv[1]),sys.argv[2],timeout=3) +blocked={} +try: + for name,call in [('reconcile',lambda:client.reconcile(sys.argv[3])),('observe',client.observe),('acquire',client.acquire)]: + try: + call() + blocked[name]=False + except body_client.Uncertain as exc: + blocked[name]=exc.command_id==sys.argv[3] + print(json.dumps({'blocked':blocked,'status':client.status(),'pid':__import__('os').getpid()}),flush=True) +finally: + client.close() +""" + completed = subprocess.run([sys.executable, "-c", resume, str(self.root / "client"), self.origin, token], + cwd=BASE, capture_output=True, timeout=12, check=False) + storage.create_file(self.root / "client-resume.stdout", completed.stdout) + storage.create_file(self.root / "client-resume.stderr", completed.stderr) + self.assertEqual(completed.returncode, 0, completed.stderr.decode()) + resumed = json.loads(completed.stdout) + self.record("actual_client_process_restart", old_pid=child.pid, public_result=resumed, + dispatch_client_exit_observed=child.poll() is not None, + dispatch_client_returncode=child.returncode, resumed_client_returncode=completed.returncode) + self.assert_single_send(token) + self.assertNotEqual(child.pid, resumed["pid"]) + self.assertEqual(resumed["blocked"], {"reconcile": True, "observe": True, "acquire": True}) + self.assertIn(token, resumed["status"]["pending_command_ids"]) + self.assertEqual(self.generation(), 0) + self.assertEqual(self.state()["state"], "unknown") + self.assertEqual(self.frozen_effects(), effects) + # A fresh holder cannot bypass the server's independent unresolved-intent guard. + fresh = body_client.BodyClient(self.root / "fresh-client", self.origin) + self.clients.append(fresh) + self.lease = fresh.acquire() + count = self.journal_count() + self.assertIn(self.send(self.command("observe", {}))["body"]["state"], + ("refused", "not_accepted", "unknown")) + self.assertEqual(self.journal_count(), count) + self.assertEqual(self.frozen_effects(), effects) + + +if __name__ == "__main__": + unittest.main() From 6f9cd4e8604c2eb636093a64e9f691f15c95da4a Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:48:40 -0400 Subject: [PATCH 118/216] Retain qualified network body fault and actual image-model evidence --- .../experiments/SIM9-network-body-adapter.md | 4 + .../2026-10-11-network-body-adapter.md | 13 + .../attempt-ledger.json | 44 + .../conformance-summary.json | 37 + .../fault-matrix.json | 143 ++++ .../final-checks.json | 24 + .../qualification-score.json | 754 ++++++++++++++++++ .../network-body-adapter-20261011/report.md | 30 + .../retained-development-attempts.json | 42 + .../source-freeze.json | 24 + tools/physical-workcell/NETWORK_BODY.md | 6 +- 11 files changed, 1120 insertions(+), 1 deletion(-) create mode 100644 jevdual/results/network-body-adapter-20261011/attempt-ledger.json create mode 100644 jevdual/results/network-body-adapter-20261011/conformance-summary.json create mode 100644 jevdual/results/network-body-adapter-20261011/fault-matrix.json create mode 100644 jevdual/results/network-body-adapter-20261011/final-checks.json create mode 100644 jevdual/results/network-body-adapter-20261011/qualification-score.json create mode 100644 jevdual/results/network-body-adapter-20261011/report.md create mode 100644 jevdual/results/network-body-adapter-20261011/retained-development-attempts.json create mode 100644 jevdual/results/network-body-adapter-20261011/source-freeze.json diff --git a/jevdual/docs/experiments/SIM9-network-body-adapter.md b/jevdual/docs/experiments/SIM9-network-body-adapter.md index 830a02b..6262c78 100644 --- a/jevdual/docs/experiments/SIM9-network-body-adapter.md +++ b/jevdual/docs/experiments/SIM9-network-body-adapter.md @@ -17,3 +17,7 @@ Guardrails: no direct move endpoint, no teleport, no native pose supplied to the Decision rule: adopt the adapter as a loopback simulated prototype only if the mechanical matrix and independent model qualification pass. Report partial or inconclusive evidence explicitly; lower-receipt absence remains unknown. References: tools/physical-workcell/agent_bench.py; tools/physical-workcell/bench.py; SIM8-bench-operator.md. Local LeRobot reference b9cb121cb7d4e3e26ec5c906d08dda68d151ba52, src/lerobot/async_inference/policy_server.py and robot_client.py, informs remote observation/planning separation. Its observation queue is not used as an effect receipt protocol. + +## Result + +2026-10-11: final-source mechanical matrix passed 12/12; 13 server, 11 client and 29 existing core checks passed. The first frozen actual-model attempt at e8c7e9b passed 2/2 successive jobs with 27 image decisions, 21 movements and 83 bound transport commands. Native/SQLite scoring verified placements, measurements, contact resets and one-body continuity. A lost dispatch reply was reconciled with one GET and no repeat POST; exact concurrent duplication and delayed reply also completed. Accepted intent without lower proof remains blocked after service/client restart. All owned trial processes exited; source remained unchanged. Retained failures and scope limits are documented in results/network-body-adapter-20261011/report.md. Adopt as a loopback simulated adapter. diff --git a/jevdual/docs/notebook/2026-10-11-network-body-adapter.md b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md index e6b6fcd..4a3743c 100644 --- a/jevdual/docs/notebook/2026-10-11-network-body-adapter.md +++ b/jevdual/docs/notebook/2026-10-11-network-body-adapter.md @@ -40,3 +40,16 @@ Observed: the full-capacity reload failed before repair at the 64 KiB reader. Th Inferred: the 65 conformance checks support the bounded same-host network adapter and its retained authority under these faults; they do not establish actual-model network completion. Next: commit measured source, freeze its exact bytes, and run two actual Codex image-guided network cycles with lost-reply reconciliation, duplicate and delayed dispatches. Score native states, SQLite and exact model/transport receipts separately after process cleanup. Refs: tools/physical-workcell/output/sim9-client-capacity-before/unittest.log; tools/physical-workcell/output/sim9-client-tests-v4/unittest.log; tools/physical-workcell/output/n9-matrix-v3/aggregate.json; tools/physical-workcell/output/sim9-core-regression.log + +## SIM9-U4 · update · 2026-10-11 16:44 +Resolves: SIM9-P1 = held +Observed: the first frozen actual-model attempt completed two network jobs on one body with 27 exact-image decisions, 21 movements and 83 bound commands. Separate native/SQLite scoring passed placement, measurement, contact reset and generation/time continuity. Proxy evidence binds one lost dispatch reply to one POST and one read-only GET, one concurrent duplicate to equal payloads/replies, and one delayed reply. All model/service processes exited and the proxy closed; source stayed unchanged. The final mechanical matrix and focused checks remain 65/65 passed, with earlier failures retained. +Inferred: the persistent adapter supports this simulated network camera/action/computer loop and preserves uncertainty under the recorded faults; the evidence does not qualify hardware or secure remote deployment. +Next: preserve derived scores and attempt ledgers, keep the previous browser product available, and use the adapter contract as the boundary for a future device-specific local controller. +Refs: e8c7e9b; results/network-body-adapter-20261011/qualification-score.json; results/network-body-adapter-20261011/final-checks.json; results/network-body-adapter-20261011/attempt-ledger.json + +## SIM9-S · summary · 2026-10-11 16:44 +Established: committed persistent body identity, server-owned admission leases, immutable command IDs and receipts, image transport, durable single-send client uncertainty, read-only recovery, diagnostic fault proxy and independently scored actual AI network cycles. Native/core guards are unchanged. All run-owned processes are stopped; the earlier local browser server remains idle. +Uncertain: authentication across machines, physical devices, emergency stopping of accepted motion, power-loss durability, general manipulation and broader model performance. +Decision: adopt the service/client API and qualification CLI inside the existing Footwork workcell package as a loopback simulated prototype. Keep raw/private evidence and failed development attempts; do not infer hardware readiness from this result. +Refs: results/network-body-adapter-20261011/report.md; tools/physical-workcell/NETWORK_BODY.md; docs/experiments/SIM9-network-body-adapter.md diff --git a/jevdual/results/network-body-adapter-20261011/attempt-ledger.json b/jevdual/results/network-body-adapter-20261011/attempt-ledger.json new file mode 100644 index 0000000..6eca62b --- /dev/null +++ b/jevdual/results/network-body-adapter-20261011/attempt-ledger.json @@ -0,0 +1,44 @@ +{ + "actual_model_attempts": [ + { + "attempt": 1, + "completed_cycles": 2, + "faults": [ + { + "call": "calls/job-1-call-001", + "command_id": "command-9b6a7f12d66e4839a33440f6a4dd657e", + "mode": "drop_after", + "read_only": true, + "reconciled_state": "completed" + }, + { + "call": "calls/job-1-call-002", + "mode": "duplicate" + }, + { + "call": "calls/job-1-call-003", + "mode": "delay_after" + } + ], + "jobs": [ + { + "calls": 14, + "completed": true, + "job_id": "network-ai-1" + }, + { + "calls": 13, + "completed": true, + "job_id": "network-ai-2" + } + ], + "outcome": "passed", + "planner": "actual_codex_cli_images_over_TCP", + "run_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim9-network-ai-v1", + "service_exit_observed": true, + "source_commit": "e8c7e9b502f852639a89932aa30884a40a432ca9", + "version": 1 + } + ], + "development_attempts": "retained-development-attempts.json" +} diff --git a/jevdual/results/network-body-adapter-20261011/conformance-summary.json b/jevdual/results/network-body-adapter-20261011/conformance-summary.json new file mode 100644 index 0000000..62edad2 --- /dev/null +++ b/jevdual/results/network-body-adapter-20261011/conformance-summary.json @@ -0,0 +1,37 @@ +{ + "AI_evidence": false, + "checks": 65, + "core_checks": 29, + "network_checks": 36, + "passed": true, + "suites": [ + { + "checks": 13, + "log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim9-terminal-pointer-after-fix.log", + "log_sha256": "bf9c2b85544b0d531bec433d33b02dead4441da7cfea3fd08b786d2a85c06cc3", + "passed": true, + "suite": "server" + }, + { + "checks": 11, + "log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim9-client-tests-v4/unittest.log", + "log_sha256": "cb6fe9cb99ae76fe875e0b8568dc47c6f5b9fb4bed22b51e4899085174fd7413", + "passed": true, + "suite": "client" + }, + { + "checks": 12, + "log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9-matrix-v3/unittest.log", + "log_sha256": "9bfd71157bfe218e82a275ecebaf46f30bc5b2037ae5c9de7085d973addafbd1", + "passed": true, + "suite": "fault-matrix" + }, + { + "checks": 29, + "log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim9-core-regression.log", + "log_sha256": "9ff1fd78da76bc2ff9ce1e146ced78641d99714536e3ee2ad0932e7922629ecb", + "passed": true, + "suite": "unchanged-core" + } + ] +} diff --git a/jevdual/results/network-body-adapter-20261011/fault-matrix.json b/jevdual/results/network-body-adapter-20261011/fault-matrix.json new file mode 100644 index 0000000..6ca4333 --- /dev/null +++ b/jevdual/results/network-body-adapter-20261011/fault-matrix.json @@ -0,0 +1,143 @@ +{ + "AI_evidence": false, + "all_owned_processes_reaped": true, + "all_sources_unchanged": true, + "cases": [ + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-8085197a1c/conformance.json", + "conformance_sha256": "e1983f08fc608f0266d106c8e9395dddec5c1012f99c0906c33331078a50cf5b", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-8085197a1c", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_01_successive_network_cycles_with_RGB_only_policy" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-74599fd771/conformance.json", + "conformance_sha256": "dc76b28c1227183b220c41a1abddf85764ffed8fd5d842a847a9e1c1fc029477", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-74599fd771", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_02_bounded_delays_preserve_exact_effect" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-4d57771bfc/conformance.json", + "conformance_sha256": "5e3c487379bbb4fbf9639a3ea6d94c077862fea9ecfbccb2175892ab32d4438e", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-4d57771bfc", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_03_drop_before_acceptance_stays_pending_until_fenced" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-359640b707/conformance.json", + "conformance_sha256": "8c01fb36b3a72b2b642c8a230aadce9d96709a06ca864bfce210752258777d35", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-359640b707", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_04_drop_after_effect_reconciles_without_resending" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-eb23a92d4a/conformance.json", + "conformance_sha256": "4e79bf94fa256365818b4e481ab2716f593101ca6b953b40fa588789e087cf88", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-eb23a92d4a", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_05_exact_concurrent_duplicate_has_one_result_one_motion" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-e195011a06/conformance.json", + "conformance_sha256": "d34ae8e672789de462d9200f6f6d5fbca0b99dd7f7980423aa4845deb40e5ed1", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-e195011a06", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_06_conflicting_duplicate_refuses_without_second_effect" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-19ab17bcec/conformance.json", + "conformance_sha256": "a8be9d07527d0a4469927bd23a6c0736dd82c8348dd596746533461273f42ba8", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-19ab17bcec", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_07_stale_image_proposal_cannot_dispatch_effect" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-2b1064309f/conformance.json", + "conformance_sha256": "0b162c735e17b80c608c05d05083403637e3bbf223ecb5aca2bfca4e50b36626", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-2b1064309f", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_08_delay_past_lease_expiry_never_admits_late_effect" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-c0f0200063/conformance.json", + "conformance_sha256": "3e748e9144b41adead369e2b1c72caa53b1c502d009e89e9714e3d6277f6ce21", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-c0f0200063", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_09_identity_source_epoch_and_exclusive_lease_fence" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-aa5b68fca2/conformance.json", + "conformance_sha256": "8541f98ffdc413848464fb444e1b70fbe0f68cc029022da48b618aadf36f473c", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-aa5b68fca2", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_10_process_restart_preserves_terminal_history_and_body" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-177873e378/conformance.json", + "conformance_sha256": "22000f17e6100d905f2c967827ceda3cfd52415f8533af1ccaf430dc7d076bef", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-177873e378", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_11_restart_recovers_exact_lower_receipt_without_dispatch" + }, + { + "conformance": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-7d10544d21/conformance.json", + "conformance_sha256": "d633b367b02d67cee8f20f0e61478a1503eaf47e86676524ebbb9f98ce7befc9", + "passed": true, + "processes_reaped": true, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9test-7d10544d21", + "source_unchanged": true, + "test_id": "test_network_body_faults.NetworkBodyFaultTests.test_12_accepted_without_lower_proof_and_client_restart_stays_unknown" + } + ], + "elapsed_s": 53.269, + "log": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9-matrix-v3/unittest.log", + "log_sha256": "9bfd71157bfe218e82a275ecebaf46f30bc5b2037ae5c9de7085d973addafbd1", + "passed": true, + "preregistration": "c976508", + "prior_logs": [ + "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9-matrix-v1/unittest.log", + "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9-matrix-v2/unittest.log" + ], + "source_sha256": { + "../camera-capture-experiment/capture.py": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "agent_bench.py": "e120dbfc9a96ca07fedb15226f27282265203755866210b86d5f856f6e3f5e07", + "bench.py": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "body_client.py": "40388c238192d923888c9852b363314801dcf65c7266aadc8c377d3810aeb33d", + "body_network.py": "95fd21597bcdd9e982a698859cd1219ae4522062e332c50fea233629dbfb343c", + "body_protocol.py": "1d24066768105c28b5cf6f4d46458e4e1b9d86cbde45ed6ce466b30da7ff974f", + "episode_cases.py": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "image_guided.py": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961", + "measurement.py": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "network_fault_proxy.py": "44b0b52f7c213c0f5f93b8997ba72be4e750bc9f1a4f7f6d7b2a8c4f1233b595", + "order_protocol.py": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "scene.xml": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "workcell.py": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2" + }, + "suite": "SIM9 mechanical public TCP boundary", + "test_count": 12, + "test_file": "/Users/thomasmain/projects/footwork/tools/physical-workcell/test_network_body_faults.py", + "test_sha256": "1e83420ed13825d84d03bd3e10da94d6e65f92ab022917629f4ba687ed30fd5e" +} diff --git a/jevdual/results/network-body-adapter-20261011/final-checks.json b/jevdual/results/network-body-adapter-20261011/final-checks.json new file mode 100644 index 0000000..5034085 --- /dev/null +++ b/jevdual/results/network-body-adapter-20261011/final-checks.json @@ -0,0 +1,24 @@ +{ + "actual_proxy_faults_bound": { + "delay_after": 1, + "drop_after": 1, + "duplicate": 1, + "duplicate_exact_payload_and_reply": true, + "lost_dispatch_single_POST_single_read_only_GET": true + }, + "all_owned_model_and_service_pids_absent": true, + "max_axis_actuator_force_n": 1.45171519700936, + "model_processes": 27, + "motion_receipts": 21, + "original_browser_product": { + "active_job_id": null, + "completed_jobs": 2, + "model_request_pending": false, + "runner_status": "running", + "url": "http://127.0.0.1:64370" + }, + "original_browser_server_preserved": true, + "passed": true, + "proxy_closed": true, + "source_unchanged": true +} diff --git a/jevdual/results/network-body-adapter-20261011/qualification-score.json b/jevdual/results/network-body-adapter-20261011/qualification-score.json new file mode 100644 index 0000000..316e1e3 --- /dev/null +++ b/jevdual/results/network-body-adapter-20261011/qualification-score.json @@ -0,0 +1,754 @@ +{ + "body_id": "ab384557b47e442891620c90252a52ca", + "calls": [ + { + "action": "move", + "call": 1, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": "command-9b6a7f12d66e4839a33440f6a4dd657e", + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 12940, + "output_tokens": 187 + } + }, + { + "action": "move", + "call": 2, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12599, + "output_tokens": 130 + } + }, + { + "action": "move", + "call": 3, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12669, + "output_tokens": 171 + } + }, + { + "action": "measure", + "call": 4, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12741, + "output_tokens": 119 + } + }, + { + "action": "begin_reset", + "call": 5, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12808, + "output_tokens": 38 + } + }, + { + "action": "move", + "call": 6, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12869, + "output_tokens": 284 + } + }, + { + "action": "move", + "call": 7, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12941, + "output_tokens": 138 + } + }, + { + "action": "move", + "call": 8, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12940, + "output_tokens": 215 + } + }, + { + "action": "move", + "call": 9, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12947, + "output_tokens": 186 + } + }, + { + "action": "move", + "call": 10, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12948, + "output_tokens": 154 + } + }, + { + "action": "move", + "call": 11, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12952, + "output_tokens": 110 + } + }, + { + "action": "move", + "call": 12, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12963, + "output_tokens": 151 + } + }, + { + "action": "move", + "call": 13, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 11976, + "output_tokens": 109 + } + }, + { + "action": "finish_reset", + "call": 14, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12966, + "output_tokens": 103 + } + }, + { + "action": "move", + "call": 1, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12524, + "output_tokens": 191 + } + }, + { + "action": "move", + "call": 2, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12595, + "output_tokens": 188 + } + }, + { + "action": "measure", + "call": 3, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13080, + "output_tokens": 132 + } + }, + { + "action": "begin_reset", + "call": 4, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12734, + "output_tokens": 39 + } + }, + { + "action": "move", + "call": 5, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12796, + "output_tokens": 180 + } + }, + { + "action": "move", + "call": 6, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12867, + "output_tokens": 168 + } + }, + { + "action": "move", + "call": 7, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 11954, + "output_tokens": 239 + } + }, + { + "action": "move", + "call": 8, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12950, + "output_tokens": 158 + } + }, + { + "action": "move", + "call": 9, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12954, + "output_tokens": 212 + } + }, + { + "action": "move", + "call": 10, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13358, + "output_tokens": 123 + } + }, + { + "action": "move", + "call": 11, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13368, + "output_tokens": 133 + } + }, + { + "action": "move", + "call": 12, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12965, + "output_tokens": 114 + } + }, + { + "action": "finish_reset", + "call": 13, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "network-ai-2", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "outcome": "executed", + "reconciled_command_id": null, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12963, + "output_tokens": 110 + } + } + ], + "completed_cycles": 2, + "faults": [ + { + "call": "calls/job-1-call-001", + "command_id": "command-9b6a7f12d66e4839a33440f6a4dd657e", + "mode": "drop_after", + "read_only": true, + "reconciled_state": "completed" + }, + { + "call": "calls/job-1-call-002", + "mode": "duplicate" + }, + { + "call": "calls/job-1-call-003", + "mode": "delay_after" + } + ], + "lost_reply_reconciled": true, + "model_boundaries_passed": true, + "passed": true, + "scope": "loopback TCP simulation, actual Codex image policy, independent post-trial native/SQLite checks", + "scores": [ + { + "job_id": "network-ai-1", + "measurement_receipt": { + "bench_id": "ab384557b47e442891620c90252a52ca", + "generation": 3, + "image_sha256": "abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b", + "job_id": "network-ai-1", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 6.401999999999517, + "operation_id": "agent-cbce78c4e9b94db6939d8cc4ab710ac3", + "source_kind": "mujoco_simulation", + "state_sha256": "f6e8a7529bd2326775b9043e7a716b126906ab7003fafbc6f229c159b904c7d0", + "version": 1, + "worker_pid": 9467 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06580390404818154, + -1.5285398651025924e-10, + 0.034995730455369904 + ], + "external_force_cleared": true, + "generation": 3, + "native_time_s": 6.401999999999517, + "pusher_home": false, + "pusher_xyz": [ + -0.029999970057503877, + 1.0537612379601558e-25, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "f6e8a7529bd2326775b9043e7a716b126906ab7003fafbc6f229c159b904c7d0" + }, + "model_calls": 14, + "motion_count": 11, + "passed": true, + "reset_receipt": { + "bench_id": "ab384557b47e442891620c90252a52ca", + "block_home_verified": true, + "generation": 11, + "image_sha256": "970fbf7a383c132c204bf8738fb951dbb9e226a02bc458dfa8c1bfca16d9855f", + "job_id": "network-ai-1", + "kind": "finish_reset", + "native_time_s": 22.94599999999816, + "operation_id": "agent-6a5cfaff4f71405b97a18c03642c8b46", + "pusher_home_verified": true, + "reset_contact_samples": 3132, + "reset_native_steps": 8272, + "state_sha256": "c6f5f6647e2a7540d10ee3258a909c0479b719c7814f657a56bfeccea18b9208" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.1157663460691671, + -2.426921464787385e-09, + 0.03499573045536983 + ], + "external_force_cleared": true, + "generation": 11, + "native_time_s": 22.94599999999816, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "c6f5f6647e2a7540d10ee3258a909c0479b719c7814f657a56bfeccea18b9208" + } + }, + { + "job_id": "network-ai-2", + "measurement_receipt": { + "bench_id": "ab384557b47e442891620c90252a52ca", + "generation": 13, + "image_sha256": "7a7e8a845f816ca42d8c548c21596a282e33b047f4f70ae81f9889f8f3582824", + "job_id": "network-ai-2", + "measurement": { + "block_box": [ + 345, + 159, + 387, + 201 + ], + "block_center_xy": [ + 0.07666666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 365.085020242915, + 179.50722961249278 + ], + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 27.481999999995647, + "operation_id": "agent-28a9ec23a725478c919618fc57d36227", + "source_kind": "mujoco_simulation", + "state_sha256": "f6b8e40878229f2a91c4e1702896ed01284d848ea4d1f18e79b51619e1842371", + "version": 1, + "worker_pid": 16109 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.07578006126019292, + -2.4269150856619973e-09, + 0.034995730455369765 + ], + "external_force_cleared": true, + "generation": 13, + "native_time_s": 27.481999999995647, + "pusher_home": false, + "pusher_xyz": [ + -0.029999969671697213, + 3.3521388079464474e-27, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "f6b8e40878229f2a91c4e1702896ed01284d848ea4d1f18e79b51619e1842371" + }, + "model_calls": 13, + "motion_count": 10, + "passed": true, + "reset_receipt": { + "bench_id": "ab384557b47e442891620c90252a52ca", + "block_home_verified": true, + "generation": 21, + "image_sha256": "e2cd823b33e1b80d69fd7f951fa4fab98c72d0231718bb4e9c4f0b7f0a0ebee1", + "job_id": "network-ai-2", + "kind": "finish_reset", + "native_time_s": 43.760000000007516, + "operation_id": "agent-7aa94511d53a4afb9085e18eebc053d9", + "pusher_home_verified": true, + "reset_contact_samples": 3188, + "reset_native_steps": 8139, + "state_sha256": "0b3b7cf03214abcc701e0f72bc11ed5d5b862c11dd31297673bce7bd54938fb0" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11577407045506503, + -4.568246329025581e-09, + 0.03499573045536982 + ], + "external_force_cleared": true, + "generation": 21, + "native_time_s": 43.760000000007516, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "0b3b7cf03214abcc701e0f72bc11ed5d5b862c11dd31297673bce7bd54938fb0" + } + } + ], + "source_commit": "e8c7e9b502f852639a89932aa30884a40a432ca9", + "source_unchanged": true, + "sqlite": { + "count": 2, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "ab384557b47e442891620c90252a52ca", + "generation": 3, + "image_sha256": "abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b", + "job_id": "network-ai-1", + "operation_id": "agent-cbce78c4e9b94db6939d8cc4ab710ac3", + "receipt": { + "bench_id": "ab384557b47e442891620c90252a52ca", + "generation": 3, + "image_sha256": "abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b", + "job_id": "network-ai-1", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 6.401999999999517, + "operation_id": "agent-cbce78c4e9b94db6939d8cc4ab710ac3", + "source_kind": "mujoco_simulation", + "state_sha256": "f6e8a7529bd2326775b9043e7a716b126906ab7003fafbc6f229c159b904c7d0", + "version": 1, + "worker_pid": 9467 + }, + "state_sha256": "f6e8a7529bd2326775b9043e7a716b126906ab7003fafbc6f229c159b904c7d0" + }, + { + "bench_id": "ab384557b47e442891620c90252a52ca", + "generation": 13, + "image_sha256": "7a7e8a845f816ca42d8c548c21596a282e33b047f4f70ae81f9889f8f3582824", + "job_id": "network-ai-2", + "operation_id": "agent-28a9ec23a725478c919618fc57d36227", + "receipt": { + "bench_id": "ab384557b47e442891620c90252a52ca", + "generation": 13, + "image_sha256": "7a7e8a845f816ca42d8c548c21596a282e33b047f4f70ae81f9889f8f3582824", + "job_id": "network-ai-2", + "measurement": { + "block_box": [ + 345, + 159, + 387, + 201 + ], + "block_center_xy": [ + 0.07666666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 365.085020242915, + 179.50722961249278 + ], + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 27.481999999995647, + "operation_id": "agent-28a9ec23a725478c919618fc57d36227", + "source_kind": "mujoco_simulation", + "state_sha256": "f6b8e40878229f2a91c4e1702896ed01284d848ea4d1f18e79b51619e1842371", + "version": 1, + "worker_pid": 16109 + }, + "state_sha256": "f6b8e40878229f2a91c4e1702896ed01284d848ea4d1f18e79b51619e1842371" + } + ] + }, + "transport_command_count": 83, + "transport_journal_bound": true +} diff --git a/jevdual/results/network-body-adapter-20261011/report.md b/jevdual/results/network-body-adapter-20261011/report.md new file mode 100644 index 0000000..8600242 --- /dev/null +++ b/jevdual/results/network-body-adapter-20261011/report.md @@ -0,0 +1,30 @@ +# Persistent network body: qualified in simulation + +The adapter passed its twelve-case TCP fault matrix and the first frozen actual-model attempt: two successive camera-guided jobs on one retained MuJoCo body. Each job placed the block, saved a separately computed measurement in SQLite and reset through physical contact. + +Measured source: `e8c7e9b502f852639a89932aa30884a40a432ca9`. Preregistration: `c976508`. The exact measured files remain unchanged. Existing native guards and the local browser product were not edited. + +| Evidence | Result | +| --- | --- | +| Public TCP fault matrix | 12/12 cases passed on final source | +| Focused server/client checks | 13 + 11 passed | +| Existing bench/agent guard checks | 29 passed | +| Actual Codex image decisions | 27; all dispatched outcomes executed | +| Native movements | 21; maximum recorded axis actuator force 1.452 N, below the existing 4 N limit | +| Independently scored cycles | 2/2; measurement placement, SQLite receipt identity and contact resets passed | +| Transport commands | 83; bound to immutable requests and lower receipts | +| Process cleanup | All 27 model processes and the trial service exited; proxy closed | + +Body `ab384557b47e442891620c90252a52ca` retained generation 0 → 11 → 21, with completed native times 22.946 → 43.760 seconds. Separate native-state reconstruction verified each measured placement and home reset; read-only SQLite scoring verified exactly one measurement per job. Model input contained the exact SHA-verified PNG fetched through TCP, task geometry and bounded history. No native pose or detector locations were supplied to the model. + +The actual-model trial discarded the first movement's reply after the body had acted. The client retained uncertainty and issued one GET for that exact command's receipt, with one original POST and no resubmission. Another movement was forwarded twice concurrently with identical payloads and identical historical replies. A third reply was delayed by 0.2 seconds. All three fault events bind to retained command evidence. + +The mechanical matrix separately covered delays before and after forwarding, dropped requests, dropped replies, concurrent duplicates, conflicting duplicates, stale image proposals, lease expiry during delay, wrong identities/source/epochs, exclusive leases, process restart, crash after lower receipt before transport receipt, and accepted intent without lower proof. Proven receipt recovery reads lower records without dispatch. Missing proof remains unknown and blocks new commands, including after a separate client process restarts. + +The first server suite failed seven cases because an extra envelope field violated its closed schema. Two targeted regressions also reproduced a premature cache update and an undersized local journal reader. Repairs preserve the failures; the complete matrix was rerun on final source. The 256-record capacity fixture tests local journal reload and refusal before send 257; it is not evidence of 256 native effects. All development attempts remain in the ledger and private run directories. + +This qualifies same-host loopback TCP simulation and these two model jobs. Authentication, operation across machines, real hardware, power-loss recovery and broad model repeatability remain unqualified. Leases fence new admissions; an accepted bounded movement can finish after a disconnect. The browser product at port 64370 remains local, open and idle with its two earlier completed jobs. The new adapter is available through its service/client API and qualification CLI. + +Evidence: [independent score](qualification-score.json), [fault matrix](fault-matrix.json), [conformance](conformance-summary.json), [cleanup and actual fault binding](final-checks.json), [source freeze](source-freeze.json), [actual-model attempts](attempt-ledger.json), [development attempts](retained-development-attempts.json). Private raw trial: `tools/physical-workcell/output/sim9-network-ai-v1/`. + +Usage and verification: [network body runbook](../../../tools/physical-workcell/NETWORK_BODY.md). The service owns the persistent body; the client owns image transport and command uncertainty; the existing Bench and AgentBench own local effect guards. No new dependency or language runtime was added. diff --git a/jevdual/results/network-body-adapter-20261011/retained-development-attempts.json b/jevdual/results/network-body-adapter-20261011/retained-development-attempts.json new file mode 100644 index 0000000..7bce3d3 --- /dev/null +++ b/jevdual/results/network-body-adapter-20261011/retained-development-attempts.json @@ -0,0 +1,42 @@ +{ + "attempts": [ + { + "evidence": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim9-body-server-tests-first.log", + "failed_checks": 7, + "kind": "server-conformance", + "outcome": "failed", + "passed_checks": 5, + "reason": "stray response field violated closed retained schema" + }, + { + "authority_remained_fenced": true, + "evidence": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim9-terminal-pointer-before-fix.log", + "kind": "terminal-pointer-regression", + "outcome": "expected_failure" + }, + { + "evidence": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim9-client-capacity-before/unittest.log", + "kind": "client-capacity-regression", + "outcome": "expected_failure", + "reason": "256-entry local journal exceeded 64 KiB reader" + }, + { + "checks": 12, + "evidence": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9-matrix-v1/unittest.log", + "kind": "matrix-v1", + "outcome": "passed" + }, + { + "checks": 12, + "evidence": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9-matrix-v2/unittest.log", + "kind": "matrix-v2", + "outcome": "passed" + }, + { + "checks": 12, + "evidence": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/n9-matrix-v3/aggregate.json", + "kind": "matrix-v3", + "outcome": "passed" + } + ] +} diff --git a/jevdual/results/network-body-adapter-20261011/source-freeze.json b/jevdual/results/network-body-adapter-20261011/source-freeze.json new file mode 100644 index 0000000..bf6cccd --- /dev/null +++ b/jevdual/results/network-body-adapter-20261011/source-freeze.json @@ -0,0 +1,24 @@ +{ + "commit": "e8c7e9b502f852639a89932aa30884a40a432ca9", + "files": { + "tools/camera-capture-experiment/capture.py": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "tools/physical-workcell/agent_bench.py": "e120dbfc9a96ca07fedb15226f27282265203755866210b86d5f856f6e3f5e07", + "tools/physical-workcell/bench.py": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "tools/physical-workcell/body_client.py": "40388c238192d923888c9852b363314801dcf65c7266aadc8c377d3810aeb33d", + "tools/physical-workcell/body_network.py": "95fd21597bcdd9e982a698859cd1219ae4522062e332c50fea233629dbfb343c", + "tools/physical-workcell/body_protocol.py": "1d24066768105c28b5cf6f4d46458e4e1b9d86cbde45ed6ce466b30da7ff974f", + "tools/physical-workcell/codex-action.schema.json": "e57197e4e73aa4c78145814a460ca77b9c6dc5e49aaf4c91adc0b521b7c3d833", + "tools/physical-workcell/codex-policy.md": "ce947200b2a652e0766b422f3b404bd5095ceb398569341466b2c5f4dd9647bc", + "tools/physical-workcell/codex_policy.py": "40fe73e01d97ee1e5cfdb813650b11edadbea29534784ab10cc1ef4e7f4d5418", + "tools/physical-workcell/episode_cases.py": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "tools/physical-workcell/image_guided.py": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961", + "tools/physical-workcell/measurement.py": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "tools/physical-workcell/network_fault_proxy.py": "44b0b52f7c213c0f5f93b8997ba72be4e750bc9f1a4f7f6d7b2a8c4f1233b595", + "tools/physical-workcell/order_protocol.py": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "tools/physical-workcell/qualify_bench.py": "524c537c1b310a0f0ae493acee99a069966a5e7c4b0a783daadf347094db58ef", + "tools/physical-workcell/qualify_network_body.py": "2800cf38afd21b86f8b035c46e994b6f96d966db4ccba1bba703e9e1a22f7c2b", + "tools/physical-workcell/scene.xml": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "tools/physical-workcell/score_network_body.py": "d1f7150a5ff23775664b5656fd21379502ba71175487fd7aadb2b51bffcdaf8c", + "tools/physical-workcell/workcell.py": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2" + } +} diff --git a/tools/physical-workcell/NETWORK_BODY.md b/tools/physical-workcell/NETWORK_BODY.md index b9916ab..1e84965 100644 --- a/tools/physical-workcell/NETWORK_BODY.md +++ b/tools/physical-workcell/NETWORK_BODY.md @@ -11,7 +11,11 @@ tools/physical-workcell/.venv/bin/python tools/physical-workcell/body_network.py Restart the same body by omitting `--initialize`. Body identity, generation, native time, jobs and receipts persist. Restart revokes all leases. The service binds to loopback; this version does not provide authentication or remote deployment. -The Python client provides the action boundary: +The Python client provides the action boundary. To try the following example from the repository root, start an interpreter with: + +```sh +PYTHONPATH=tools/physical-workcell tools/physical-workcell/.venv/bin/python +``` ```python from body_client import BodyClient, Uncertain From 2736b3374e648084d318b0706496834f25fe27c2 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 16:56:57 -0400 Subject: [PATCH 119/216] Record Claude baseline review and authorized grant blocked by guest lock --- .../notebook/2026-10-10-independent-onboarding.md | 6 ++++++ .../report.md | 2 ++ .../summary.json | 14 +++++++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md index 70213ad..682bbb8 100644 --- a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md +++ b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md @@ -65,3 +65,9 @@ Established: actual independent SIP-enabled guest Python/prerequisite setup, pri Uncertain: human Terminal permission decision, host restart/readback, installed native append/restart/report and owned cleanup remain unexecuted. Full raw guest receipt export is pending. Claude has the concrete baseline review request but no new verdict has arrived. Decision: keep UO2 open and pause dependent native execution at the exact guest Terminal Accessibility grant confirmation. The permission is scoped to the disposable guest, and host Mac permissions remain untouched. Refs: results/u2-independent-onboarding-20261011-v1; Claude request1791751059206860000; root native CUA tool images in this chat + +## UOU7 · update · 2026-10-11 16:56 +Observed: the human now explicitly authorizes root to enable the exact guest Terminal Accessibility switch. On inspection the guest is auto-locked; root woke its login display without entering credentials, and no switch was changed. Claude message1791751104201824000 accepts the actual denied baseline, with C1 attribution and C2 receipt-export clarifications. No system control-permission prompt was observed in captured UI states; the Settings list was first inspected only after cold installer diagnostics, strict doctor and fixture refusal, so the exact command that first inserted Terminal cannot be determined retrospectively. Root never manually added it. Source permission_status uses nonprompting AXIsProcessTrusted and CGPreflightScreenCaptureAccess; fixture refuses before importing/creating its CuaDriver. Local Cua source distinguishes those probes from explicit prompting functions, but its currentHEAD is not proof of every transitive effect in the installed0.28.2 build. No permission reset or frozen-wheel change was performed. +Inferred: the observed off entry establishes responsible-host attribution, not the causal claim that a particular command requested a prompt. C1 remains an explicit evidence limitation. +Next: human unlock is needed under the supplied no-credentials-in-logs instruction; thereafter preserve grant authorization, hold guest awake, print denied-receipt SHA256 values, establish a bounded verifiable export route before post-grant execution, then enable Terminal and restart/read back. +Refs: results/u2-independent-onboarding-20261011-v1; Claude message1791751104201824000; python/jevdual/capability/setup.py; scripts/capability_fixture.py; local Cua5458c77b04a6e5e7a099929e0c4d4366e83dd403 libs/cua-driver/rust/crates/cua-driver-sdk/src/lib.rs; root native CUA tool images in this chat diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md index 6a287f3..4b1b917 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md @@ -17,3 +17,5 @@ Chrome copy subsequently completed and the installed bundle version readback is The human completed installer authentication. Python 3.14.7 runs and the pristine member verifier exits0 with14members and matching frozen source/wheel hashes. The frozen cold installer completed all seven stages at exit0 and reports115packages. Initial isolated strict doctor exits1 with accessibility_not_granted; Screen Recording is not_granted and remains advisory. The frozen fixture exits2 with the exact Accessibility refusal, and its run directory is absent. No native effect has been admitted. The denied baseline is valid; grant, restart, native oracle and cleanup remain pending. The pure-Python fallback emits a noisy unavailable-core warning, retained in the guest stderr; it does not prevent the actual permission refusal. Guest receipts remain in the guest and have not yet been exported. At the handoff, guest System Settings > Privacy & Security > Accessibility visibly lists Terminal with its switch off. Human confirmation is requested before enabling that exact guest host. Claude has the actual baseline review request1791751059206860000, without a new verdict yet. UO2 remains open; no post-grant result is claimed. + +Claude reviewed the actual baseline at413686b and accepted it (message1791751104201824000), subject to two evidence clarifications. Terminal was first observed in the off Settings list after the cold installer diagnostic, strict doctor and fixture refusal; the exact inserting command cannot be reconstructed. No OS control-permission prompt was observed in captured states, and root never manually added Terminal. Direct product probes are nonprompting in source; this does not establish all transitive runtime effects or prove when the Settings entry appeared. Preserve that limitation. Before post-grant execution, print guest receipt hashes and establish verifiable raw export. The user has explicitly authorized root to toggle the exact guest Terminal entry, but the guest auto-locked before root could do so; no grant occurred. Human unlock is requested to keep credentials out of tool logs under the supplied AGENTS.md rule. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json index 9b72de9..d8b0719 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json @@ -1,6 +1,6 @@ { "recorded_at": "2026-10-11T16:22:00-04:00", - "status": "in_progress_denied_baseline_observed_permission_grant_pending", + "status": "grant_authorized_waiting_for_guest_unlock", "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", "packet_sha256": "769c08c89061731368db33d78b180e7c8c96d531190f43bee44263642a76fd0f", "guest": { @@ -34,10 +34,18 @@ "packet_member_verification": "passed 14 members, exit0", "cold_dependency_install": "passed 115 packages, seven stages exit0, installer exit0", "denied_accessibility_baseline": "observed not_granted, strict doctor exit1, fixture exit2, fixture directory absent", - "permission_transition": "pending human confirmation; guest Settings shows Terminal switch off", + "permission_transition": "human authorizes root; not applied because guest auto-locked", "native_effect_restart_report": "not_run", "cleanup": "not_run", "qualified": false }, - "evidence_location": "Guest /Users/tom/footwork-u2 and native CUA tool images in the current chat; guest receipts not exported yet" + "evidence_location": "Guest /Users/tom/footwork-u2 and native CUA tool images in the current chat; guest receipts not exported yet", + "claude_baseline_review": { + "message": "1791751104201824000", + "verdict": "valid denied baseline", + "clarifications": [ + "cause of Terminal entry not reconstructible retrospectively; no prompting dialog observed", + "raw receipt export and hashes required before post-grant run" + ] + } } From a0df18066ca5815525fe794140ae5d17c279da11 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:14:00 -0400 Subject: [PATCH 120/216] Preregister bounded post-run receipt export --- jevdual/docs/notebook/2026-10-10-independent-onboarding.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md index 682bbb8..bf71353 100644 --- a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md +++ b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md @@ -71,3 +71,10 @@ Observed: the human now explicitly authorizes root to enable the exact guest Ter Inferred: the observed off entry establishes responsible-host attribution, not the causal claim that a particular command requested a prompt. C1 remains an explicit evidence limitation. Next: human unlock is needed under the supplied no-credentials-in-logs instruction; thereafter preserve grant authorization, hold guest awake, print denied-receipt SHA256 values, establish a bounded verifiable export route before post-grant execution, then enable Terminal and restart/read back. Refs: results/u2-independent-onboarding-20261011-v1; Claude message1791751104201824000; python/jevdual/capability/setup.py; scripts/capability_fixture.py; local Cua5458c77b04a6e5e7a099929e0c4d4366e83dd403 libs/cua-driver/rust/crates/cua-driver-sdk/src/lib.rs; root native CUA tool images in this chat + +## UO4 · prediction · 2026-10-11 17:14 +Hypothesis: a post-run, bounded guest-to-host upload preserves raw qualification evidence without borrowing a host environment or changing the permission baseline. +Test: before the grant, retain and visibly print SHA256 hashes of the denied doctor, fixture refusal and install receipt. After native execution and cleanup, build an allowlisted receipt archive in the guest, print its hash, and upload to one temporary receiver bound only to the VM bridge address. Receiver accepts one fixed path, a bounded archive size, exclusive output creation and a five-minute lifetime; no host file reads or commands. Verify archive and individual baseline hashes on the host before sanitizing results. No share, SSH, clipboard or receiver is enabled during qualification. +Predicts: exported bytes match the observed guest archive and pre-grant baseline hashes, and the receiver shuts down after receipt or timeout. +Against: hashes differ, a receipt is absent, transfer requires widening host access beyond the fixed upload, or the receiver remains active after its bound. +Refs: results/u2-independent-onboarding-20261011-v1; guest denied-baseline.sha256; Claude message1791751104201824000 From 619654603440fded9ecb6d04b78e1b8695fea384 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:15:51 -0400 Subject: [PATCH 121/216] Preregister guarded network browser workbench and recovery qualification --- .../experiments/SIM10-network-workbench.md | 19 +++++++++++++++++++ .../notebook/2026-10-11-network-workbench.md | 8 ++++++++ .../NETWORK_WORKBENCH_CONTRACT.md | 18 ++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 jevdual/docs/experiments/SIM10-network-workbench.md create mode 100644 jevdual/docs/notebook/2026-10-11-network-workbench.md create mode 100644 tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md diff --git a/jevdual/docs/experiments/SIM10-network-workbench.md b/jevdual/docs/experiments/SIM10-network-workbench.md new file mode 100644 index 0000000..88a27d8 --- /dev/null +++ b/jevdual/docs/experiments/SIM10-network-workbench.md @@ -0,0 +1,19 @@ +# SIM10: Browser workbench on a persistent network body + +Hypothesis: an image-guided browser operator can use the existing durable network client while keeping physical authority local and making transport uncertainty recoverable by explicit user controls. + +Predictions if true: successive browser jobs retain one body, independently verified measurements and contact resets; a lost motion reply visibly blocks the queue; disconnect/reconnect and reload do not resend that command; receipt lookup settles only retained evidence and requires explicit Resume before fresh planning. + +Predictions if false: the browser reports completion without proof, hides uncertainty, repeats an uncertain effect, silently resumes after reconnect, replaces body identity, or grants action authority using a retained image. + +Design: separate new browser runtime, HTTP server and HTML from the existing local operator. Reuse BodyClient and BodyService without changing core guards. An owned loopback diagnostic link retains its exact endpoint and provides disconnect, bounded delay, dropped reply and duplicate controls. The browser host uses TCP-only public observations/results, durable queue and pending-stage records, exact identity/source pins and the existing actual Codex image policy. Restart is paused; recovery is read-only and explicit. + +Primary metric: all required product transitions pass in a real browser: enqueue two jobs, show a lost dispatch reply as uncertain, show a disconnected link, refuse receipt recovery while disconnected, reconnect without sending, check the exact receipt, explicitly resume, complete both jobs with measurement and contact reset evidence, and reload without replay or loss of completed history. + +Secondary checks: deterministic real-socket cases cover uncertain start/proposal/dispatch, queue-stage restart recovery, duplicate and delayed dispatches, connection identity, source changes, pause cancellation and cached-image integrity. The frozen actual-model trial is scored separately from native snapshots, SQLite and transport/model receipts. Fake planners are conformance evidence only. + +Guardrails: no direct native calls from the browser host, no teleport, no private pose in model inputs, no uncertain retries, no automatic resume on reconnect or receipt lookup, no source edits during the measured model trial, and no changes to the existing body/core guard files. Lost receipt without proof remains blocked. Already admitted bounded motion may finish after disconnect or pause. Preserve failed attempts. + +Decision rule: adopt and show the network browser product only if conformance checks and the independently scored frozen browser/model trial pass. Otherwise retain the prior idle local product and report the failed boundary. + +Scope: same-Mac loopback simulation; remote authentication, hardware and emergency stopping remain outside this experiment. diff --git a/jevdual/docs/notebook/2026-10-11-network-workbench.md b/jevdual/docs/notebook/2026-10-11-network-workbench.md new file mode 100644 index 0000000..1a23f52 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-11-network-workbench.md @@ -0,0 +1,8 @@ +# Browser workbench on the persistent body + +## SIM10-P1 · prediction · 2026-10-11 17:15 +Hypothesis: a durable pending-stage record around the existing single-send BodyClient lets the browser operator retain queue progress across network loss and restart without inventing completion or replaying effects. +Test: build a separate network operator and retained diagnostic link; check real-socket uncertainty/restart cases, then freeze source and drive two actual Codex jobs through the browser with a lost dispatch reply, disconnect and explicit receipt recovery. +Predicts: the UI preserves identity and cached history, unknown commands block new effects, reconnect is transport-only, read-only receipt lookup applies the exact retained stage once, and explicit resume plans from a fresh TCP image before completing native/SQLite/contact verification. +Against: extra sends or native motion during recovery, silent queue resume, completion without lower proof, private pose used for planning, or independent scoring failure. +Refs: docs/experiments/SIM10-network-workbench.md; tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md; results/network-workbench-20261011/ diff --git a/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md b/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md new file mode 100644 index 0000000..55ef8ae --- /dev/null +++ b/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md @@ -0,0 +1,18 @@ +# Network browser workbench integration contract + +The browser uses a new network Operator; it does not instantiate Bench or AgentBench. BodyClient and the existing body service retain effect authority. The old local operator and its live root remain unchanged. + +New modules: + +- `workbench_link.py`: `WorkbenchLink(origin, root, port=0).start()` exposes `.origin`, `.state()`, `.set_connected(bool)`, `.arm(mode, operation='dispatch', delay_s=.2)` and `.close()`. Modes `drop_after`, `delay_after`, `duplicate`. Exact payload bytes and identity headers are forwarded. The same journal restarts on its retained port and upstream; faults are diagnostic and bounded. Offline requests close without forwarding. Reconnect never replays. The link may run in the browser process; the body is independent. +- `network_operator_runtime.py`: `initialize(root, body_origin, link_port=0)` sets up an app/client/link root and returns app ID. `Operator(root, policy, start_worker=True)` owns the link and durable client, queue, model cancellation and pending-stage context. Existing `state/frame/enqueue/pause/resume/close` interfaces plus `disconnect/reconnect/reconcile/fault(request)`. A manifest has `app_id` for existing origin guards. State retains existing job/camera/activity fields and adds `connection` and `recovery` described below. Source pins cover new product modules, link, client and unchanged model policy; body pins are separate. +- `network_bench_operator.py`: init/serve CLI and guarded loopback HTTP. Mutations require exact Host, Origin and app ID. POST `/api/disconnect`, `/api/reconnect`, `/api/reconcile` take empty JSON; `/api/fault` takes `{mode, delay_s}` with mode above and delay in [0,2], always dispatch-only. Existing job/pause/resume routes retain their schemas. +- `network_bench_operator.html`: live queue, exact downloaded camera frames, computer measurement, reset result, activity and network controls. + +`connection`: `{state: 'connected'|'disconnected'|'unavailable', body_id, adapter_id, epoch, reason, fault: null|{mode, operation, delay_s}}`. Disconnected is the intentional diagnostic gate; unavailable means the real upstream is unreachable. Transport status does not establish freshness of a cached frame. + +`recovery`: `{state: 'none'|'uncertain'|'recovered'|'blocked', command_id: null|string, operation: null|string, reason}`. Unknown blocks effects and lease rotation. Reconcile reads exact retained results and applies the pending host stage once; not-seen remains unknown until fenced. Recovered is paused until explicit Resume. UI shows an old frame as retained and never calls it live. Completed results remain visibly historical during disconnect. + +The host writes stage/job/action/proposal context and the pre-send client command index before a client command, associates the unique new command, and clears the stage only after applying its result to queue/history. On restart, terminal client receipts may be read to settle that exact stage; unknown receipts remain blocked. No restart sends actions or automatically resumes. Resume observes a fresh TCP image before the next model decision. Control calls cancel pending model work; a decision from an earlier control epoch cannot dispatch. + +The final product replaces the idle old browser server only after separate qualification, retaining its old root. The new workbench and body keep their own private output roots and immutable source identities. From 47f38de9d22f75cf62a2e0ebbd55845e9d692c10 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:17:56 -0400 Subject: [PATCH 122/216] Preserve cold fixture timeout and preregister readiness continuation --- .../notebook/2026-10-10-independent-onboarding.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md index bf71353..d3f1ed0 100644 --- a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md +++ b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md @@ -78,3 +78,16 @@ Test: before the grant, retain and visibly print SHA256 hashes of the denied doc Predicts: exported bytes match the observed guest archive and pre-grant baseline hashes, and the receiver shuts down after receipt or timeout. Against: hashes differ, a receipt is absent, transfer requires widening host access beyond the fixed upload, or the receiver remains active after its bound. Refs: results/u2-independent-onboarding-20261011-v1; guest denied-baseline.sha256; Claude message1791751104201824000 + +## UOU8 · update · 2026-10-11 17:18 +Observed: human reports unlock complete. Root observes Terminal Accessibility already on upon reopening Settings; root never toggled it. The change occurred between the earlier off observation and this on observation, with explicit human consent, but its actor/time are not independently captured. Baseline receipt hashes were printed before the post-restart diagnostic, not demonstrably before the actual grant. Guest Terminal quit visibly, then relaunched; strict installed doctor exits0, Accessibility granted, Screen Recording not_granted and no blockers. The first fixture creates its exact TextEdit document but fails its30second identity deadline while guest Chrome first-launch verification is visibly still running. No scope is emitted and no product action runs. Root declines Python local-network discovery and Terminal TextEdit Automation prompts, closes only the unchanged fixture document manually and preserves the failed fixture directory/log. +Inferred: Chrome cold verification is a candidate startup cause, not yet isolated from SDK window visibility or other readiness causes. The permission transition is observed, but the initial complete first-use lane does not pass. The original denied baseline is retained without a permission reset. +Next: export original failure evidence and review it; run a separately recorded development continuation with the same frozen helpers only after vendor verification completes. Never regrade fixture-v1 as success. +Refs: results/u2-independent-onboarding-20261011-v1; guest fixture-console.txt; guest packet output/doctor-after.json; root CUA observations + +## UO5 · prediction · 2026-10-11 17:18 +Hypothesis: the unchanged fixture can identify owned windows once the official Chrome first-launch verification has completed; the initial failure is startup readiness rather than a broken approved AX/SDK seam. +Test: retain fixture-v1 and its refusal/timeout evidence. Observe normal vendor Chrome verification completion, with no Gatekeeper bypass or added permission. Launch the frozen fixture into fresh fixture-v2; if ready, run the existing installed native oracle in new job-v2/native-v2. Keep declined extra permissions and manually close the exact document when automatic cleanup cannot do so. +Predicts: fixture-v2 emits ready and the installed append/repeated-token/report oracle passes with one operation and one effect under the same Terminal Accessibility grant. +Against: Chrome remains unable to launch normally, scope identification fails again, native oracle refuses or duplicates, or additional permission is necessary for native execution. +Refs: docs/experiments/U2-independent-onboarding.md; guest fixture-console.txt; scripts/capability_fixture.py; scripts/capability_installed_trial.py From 0debc7ee5215bd3b3b10cd2511a72a2e7092d351 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:21:36 -0400 Subject: [PATCH 123/216] Retain exported first-use receipts and cold Chrome startup failure --- .../guest-evidence/baseline.txt | 53 + .../chrome-installed-version.txt | 1 + .../guest-evidence/chrome-signature.txt | 54 + .../guest-evidence/denied-baseline.sha256 | 3 + .../guest-evidence/denied-fixture-exit.txt | 1 + .../guest-evidence/denied-fixture.txt | 3 + .../guest-evidence/doctor-after-exit.txt | 1 + .../guest-evidence/doctor-after.stderr.txt | 1 + .../guest-evidence/doctor-before-exit.txt | 1 + .../guest-evidence/doctor-before.stderr.txt | 1 + .../guest-evidence/fixture-console.txt | 20 + .../footwork/output/doctor-after.json | 1 + .../footwork/output/doctor-before.json | 1 + .../output/fixture-v1/fixture-v1-invoice.txt | 1 + .../footwork/output/install-v1/receipt.json | 1523 +++++++++++++++++ .../guest-evidence/install-console.txt | 8 + .../guest-evidence/install-exit.txt | 1 + .../guest-evidence/media-hashes.txt | 4 + .../guest-evidence/packet-verification.txt | 1 + .../report.md | 6 + .../summary.json | 20 +- 21 files changed, 1699 insertions(+), 6 deletions(-) create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/baseline.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/chrome-installed-version.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/chrome-signature.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-baseline.sha256 create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-fixture-exit.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-fixture.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-after-exit.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-after.stderr.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-before-exit.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-before.stderr.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/fixture-console.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/doctor-after.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/doctor-before.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/fixture-v1/fixture-v1-invoice.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/install-v1/receipt.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/install-console.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/install-exit.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/media-hashes.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/packet-verification.txt diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/baseline.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/baseline.txt new file mode 100644 index 0000000..c5b9b50 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/baseline.txt @@ -0,0 +1,53 @@ +ProductName: macOS +ProductVersion: 26.6.2 +BuildVersion: 25G83 +System Integrity Protection status: enabled. + Device Identifier: disk0 + Device Node: /dev/disk0 + Whole: Yes + Part of Whole: disk0 + Device / Media Name: Apple Inc. VirtIO Block Media + + Volume Name: FOOTWORK_U2 + Mounted: Yes + Mount Point: /Volumes/FOOTWORK_U2 + + Content (IOContent): None + File System Personality: ISO Joliet + Type (Bundle): cd9660 + Name (User Visible): ISO 9660 (Joliet) + + OS Can Be Installed: No + Media Type: + Protocol: + SMART Status: Not Supported + + Disk Size: 379.8 MB (379752448 Bytes) (exactly 741704 512-Byte-Units) + Device Block Size: 512 Bytes + + Volume Total Space: 379.8 MB (379752448 Bytes) (exactly 741704 512-Byte-Units) + Volume Used Space: 379.8 MB (379752448 Bytes) (exactly 741704 512-Byte-Units) (100.0%) + Volume Free Space: 0 B (0 Bytes) (exactly 0 512-Byte-Units) (0.0%) + Allocation Block Size: 2048 Bytes + + Media OS Use Only: No + Media Read-Only: Yes + Volume Read-Only: Yes (read-only mount flag set) + + Device Location: Internal + Removable Media: Fixed + + Solid State: Yes + Hardware AES Support: Yes + +total 741608 +drwxr-xr-x 1 tom staff 2048 Oct 11 11:08 . +drwxr-xr-x 4 root wheel 128 Oct 11 13:02 .. +-rwxr-xr-x 1 tom staff 308344 Oct 11 11:08 footwork-onboarding-u2-packet-v3.zip +-rwxr-xr-x 1 tom staff 282304813 Oct 11 11:08 googlechrome.dmg +-rwxr-xr-x 1 tom staff 2340 Oct 11 11:08 PROVENANCE.json +-rwxr-xr-x 1 tom staff 78557763 Oct 11 11:08 python-3.14.7-macos11.pkg +-rwxr-xr-x 1 tom staff 382 Oct 11 11:08 SHA256SUMS.txt +-rwxr-xr-x 1 tom staff 18518284 Oct 11 11:08 uv-0.12.5-aarch64-apple-darwin.tar.gz +com.apple.Terminal +2.15 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/chrome-installed-version.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/chrome-installed-version.txt new file mode 100644 index 0000000..5e0c189 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/chrome-installed-version.txt @@ -0,0 +1 @@ +155.0.8059.40 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/chrome-signature.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/chrome-signature.txt new file mode 100644 index 0000000..3a48196 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/chrome-signature.txt @@ -0,0 +1,54 @@ +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/. +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/app_mode_loader +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/app_mode_loader +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/chrome_crashpad_handler +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/chrome_crashpad_handler +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Alerts).app +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Alerts).app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Aperitif Alerts).app +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Aperitif Alerts).app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Aperitif GPU).app +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Aperitif GPU).app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Aperitif Renderer).app +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Aperitif Renderer).app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Aperitif).app +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Aperitif).app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (GPU).app +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (GPU).app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Renderer).app +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper (Renderer).app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper.app +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/Google Chrome Helper.app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app/Contents/Helpers/GoogleSoftwareUpdate.bundle +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app/Contents/Helpers/GoogleSoftwareUpdate.bundle/Contents/Helpers/ksadmin +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app/Contents/Helpers/GoogleSoftwareUpdate.bundle/Contents/Helpers/ksadmin +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app/Contents/Helpers/GoogleSoftwareUpdate.bundle/Contents/Helpers/ksinstall +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app/Contents/Helpers/GoogleSoftwareUpdate.bundle/Contents/Helpers/ksinstall +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app/Contents/Helpers/GoogleSoftwareUpdate.bundle +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app/Contents/Helpers/launcher +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app/Contents/Helpers/launcher +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app +--prepared:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/web_app_shortcut_copier +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/web_app_shortcut_copier +--validated:/Volumes/Google Chrome/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/. +/Volumes/Google Chrome/Google Chrome.app: valid on disk +/Volumes/Google Chrome/Google Chrome.app: satisfies its Designated Requirement +Executable=/Volumes/Google Chrome/Google Chrome.app/Contents/MacOS/Google Chrome +Identifier=com.google.Chrome +Format=app bundle with Mach-O universal (x86_64 arm64) +CodeDirectory v=20500 size=765 flags=0x12a00(kill,restrict,library-validation,runtime) hashes=13+7 location=embedded +Signature size=8991 +Authority=Developer ID Application: Google LLC (EQHXZ8M8AV) +Authority=Developer ID Certification Authority +Authority=Apple Root CA +Timestamp=Oct 5, 2026 at 10:43:45 PM +Notarization Ticket=stapled +Info.plist entries=44 +TeamIdentifier=EQHXZ8M8AV +Runtime Version=26.5.0 +Sealed Resources version=2 rules=13 files=63 +Internal requirements count=1 size=288 +/Volumes/Google Chrome/Google Chrome.app: accepted +source=Notarized Developer ID +155.0.8059.40 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-baseline.sha256 b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-baseline.sha256 new file mode 100644 index 0000000..c0b8fbe --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-baseline.sha256 @@ -0,0 +1,3 @@ +ead3090a56bc29b4a971b41f991b79872e07099f3f1ba9bb634825495ed32512 /Users/tom/footwork-u2/footwork/output/doctor-before.json +72c307cdccd3ec932c0927ab6143545726664f02cfcd7afdaccd320f8a412cfe /Users/tom/footwork-u2/denied-fixture.txt +54d419eb2b383f6c08172c87f5c084d2b0bb36ac552e695a8b7a9f5d611ea806 /Users/tom/footwork-u2/footwork/output/install-v1/receipt.json diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-fixture-exit.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-fixture-exit.txt new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-fixture-exit.txt @@ -0,0 +1 @@ +2 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-fixture.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-fixture.txt new file mode 100644 index 0000000..88d16cb --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/denied-fixture.txt @@ -0,0 +1,3 @@ +jevdual._core unavailable (cannot import name '_core' from partially initialized module 'jevdual' (most likely due to a circular import) (/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py)); falling back to pure Python +usage: capability_fixture.py [-h] --run-dir RUN_DIR +capability_fixture.py: error: fixture requires existing Accessibility permission; no resources created diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-after-exit.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-after-exit.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-after-exit.txt @@ -0,0 +1 @@ +0 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-after.stderr.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-after.stderr.txt new file mode 100644 index 0000000..f6c4b85 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-after.stderr.txt @@ -0,0 +1 @@ +jevdual._core unavailable (cannot import name '_core' from partially initialized module 'jevdual' (most likely due to a circular import) (/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py)); falling back to pure Python diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-before-exit.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-before-exit.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-before-exit.txt @@ -0,0 +1 @@ +1 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-before.stderr.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-before.stderr.txt new file mode 100644 index 0000000..f6c4b85 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/doctor-before.stderr.txt @@ -0,0 +1 @@ +jevdual._core unavailable (cannot import name '_core' from partially initialized module 'jevdual' (most likely due to a circular import) (/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py)); falling back to pure Python diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/fixture-console.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/fixture-console.txt new file mode 100644 index 0000000..2f559fe --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/fixture-console.txt @@ -0,0 +1,20 @@ +jevdual._core unavailable (cannot import name '_core' from partially initialized module 'jevdual' (most likely due to a circular import) (/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py)); falling back to pure Python +Fixture document cleanup could not be confirmed; browser cleanup continues. +Traceback (most recent call last): + File "/Users/tom/footwork-u2/footwork/jevdual/scripts/capability_fixture.py", line 173, in + main() + ~~~~^^ + File "/Users/tom/footwork-u2/footwork/jevdual/scripts/capability_fixture.py", line 128, in main + scope = asyncio.run(scope_for(browser.pid, url, document)) + File "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/runners.py", line 205, in run + return runner.run(main) + ~~~~~~~~~~^^^^^^ + File "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/runners.py", line 128, in run + return self._loop.run_until_complete(task) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^ + File "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/base_events.py", line 720, in run_until_complete + return future.result() + ~~~~~~~~~~~~~^^ + File "/Users/tom/footwork-u2/footwork/jevdual/scripts/capability_fixture.py", line 82, in scope_for + raise RuntimeError("Owned browser/document windows could not be identified uniquely") +RuntimeError: Owned browser/document windows could not be identified uniquely diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/doctor-after.json b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/doctor-after.json new file mode 100644 index 0000000..66ae255 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/doctor-after.json @@ -0,0 +1 @@ +{"platform": "darwin", "supported": true, "runtime": {"python_version": "3.14.7", "python_requirement": ">=3.11,<4.0", "python_compatible": true, "interpreter": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", "architecture": "arm64", "distribution": {"version": "0.0.1", "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "loaded_modules": {"jevdual": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", "jevdual.capability.setup": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/setup.py", "ApplicationServices": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py", "Quartz": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py"}}, "dependencies": {"browser-use": {"version": "0.13.10", "requirement": "==0.13.10", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "typesafe-sdk": {"version": "0.7.4", "requirement": "<1,>=0.7", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "orjson": {"version": "3.13.0", "requirement": ">=3.10", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "psutil": {"version": "7.2.2", "requirement": "==7.2.2", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "mcp": {"version": "2.1.1", "requirement": "==2.1.1", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "packaging": {"version": "26.3", "requirement": "<27,>=25", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "cua-driver": {"version": "0.28.2", "requirement": "==0.28.2", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-applicationservices": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-quartz": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-cocoa": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}}, "permissions": {"accessibility": "granted", "screen_recording": "not_granted"}, "scope": "not_checked", "journal": "not_checked", "warnings": ["Screen Recording is not qualified. Routes that capture pixels may require it."], "dependency_metadata": "installed distribution", "limitation": "macOS only: one loopback HTTP browser fixture and one identified TextEdit document. Window identity is checked when binding.", "provider_account_required": false, "rust_toolchain_required": false, "blockers": [], "prerequisite_status": "met", "qualification": "Prerequisites only. Window identity, current state, effects and job completion require separate checks."} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/doctor-before.json b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/doctor-before.json new file mode 100644 index 0000000..6da1941 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/doctor-before.json @@ -0,0 +1 @@ +{"platform": "darwin", "supported": true, "runtime": {"python_version": "3.14.7", "python_requirement": ">=3.11,<4.0", "python_compatible": true, "interpreter": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", "architecture": "arm64", "distribution": {"version": "0.0.1", "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "loaded_modules": {"jevdual": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", "jevdual.capability.setup": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/setup.py", "ApplicationServices": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py", "Quartz": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py"}}, "dependencies": {"browser-use": {"version": "0.13.10", "requirement": "==0.13.10", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "typesafe-sdk": {"version": "0.7.4", "requirement": "<1,>=0.7", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "orjson": {"version": "3.13.0", "requirement": ">=3.10", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "psutil": {"version": "7.2.2", "requirement": "==7.2.2", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "mcp": {"version": "2.1.1", "requirement": "==2.1.1", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "packaging": {"version": "26.3", "requirement": "<27,>=25", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "cua-driver": {"version": "0.28.2", "requirement": "==0.28.2", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-applicationservices": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-quartz": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-cocoa": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages"}}, "permissions": {"accessibility": "not_granted", "screen_recording": "not_granted"}, "scope": "not_checked", "journal": "not_checked", "warnings": ["Screen Recording is not qualified. Routes that capture pixels may require it."], "dependency_metadata": "installed distribution", "limitation": "macOS only: one loopback HTTP browser fixture and one identified TextEdit document. Window identity is checked when binding.", "provider_account_required": false, "rust_toolchain_required": false, "blockers": ["accessibility_not_granted"], "prerequisite_status": "blocked", "qualification": "Prerequisites only. Window identity, current state, effects and job completion require separate checks."} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/fixture-v1/fixture-v1-invoice.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/fixture-v1/fixture-v1-invoice.txt new file mode 100644 index 0000000..14cfbd2 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/fixture-v1/fixture-v1-invoice.txt @@ -0,0 +1 @@ +Invoice report diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/install-v1/receipt.json b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/install-v1/receipt.json new file mode 100644 index 0000000..ef1c5fb --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/footwork/output/install-v1/receipt.json @@ -0,0 +1,1523 @@ +{ + "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", + "host": { + "platform": "Darwin", + "machine": "arm64" + }, + "interpreter_requested": "/Library/Frameworks/Python.framework/Versions/3.14/bin/python3.14", + "wheel": "/Users/tom/footwork-u2/footwork/artifacts/jevdual-0.0.1-py3-none-any.whl", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7", + "cache_initially_empty": true, + "system_site_packages": false, + "borrowed_dependencies": false, + "registry": "https://pypi.org/simple", + "binary_only": true, + "commands": [ + { + "stage": "venv", + "argv": [ + "/Users/tom/footwork-u2/tools/uv-aarch64-apple-darwin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/tom/footwork-u2/footwork/output/install-v1/empty-cache", + "--no-python-downloads", + "venv", + "--python", + "/Library/Frameworks/Python.framework/Versions/3.14/bin/python3.14", + "/Users/tom/footwork-u2/footwork/output/install-v1/venv" + ], + "returncode": 0 + }, + { + "stage": "install", + "argv": [ + "/Users/tom/footwork-u2/tools/uv-aarch64-apple-darwin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/tom/footwork-u2/footwork/output/install-v1/empty-cache", + "--no-python-downloads", + "pip", + "install", + "--python", + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "--default-index", + "https://pypi.org/simple", + "--only-binary", + ":all:", + "/Users/tom/footwork-u2/footwork/artifacts/jevdual-0.0.1-py3-none-any.whl" + ], + "returncode": 0 + }, + { + "stage": "consistency", + "argv": [ + "/Users/tom/footwork-u2/tools/uv-aarch64-apple-darwin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/tom/footwork-u2/footwork/output/install-v1/empty-cache", + "--no-python-downloads", + "pip", + "check", + "--python", + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python" + ], + "returncode": 0 + }, + { + "stage": "inventory", + "argv": [ + "/Users/tom/footwork-u2/tools/uv-aarch64-apple-darwin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/tom/footwork-u2/footwork/output/install-v1/empty-cache", + "--no-python-downloads", + "pip", + "list", + "--python", + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "--format", + "json" + ], + "returncode": 0 + }, + { + "stage": "origins", + "argv": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "-I", + "-c", + "\nimport sys,json,importlib.metadata,importlib\nfrom pathlib import Path\nimport jevdual,jevdual.capability.execution_worker as worker\nfrom jevdual._native import BACKEND\nnames=(\"cua_driver\",\"psutil\",\"mcp\",\"ApplicationServices\",\"Quartz\",\"Foundation\",\"packaging\")\nmodules={n:str(importlib.import_module(n).__file__) for n in names}\nprint(json.dumps({\"version\":sys.version,\"prefix\":sys.prefix,\"base_prefix\":sys.base_prefix,\"python\":sys.executable,\"package\":jevdual.__file__,\"worker\":worker.__file__,\"backend\":BACKEND,\"module_origins\":modules,\"sys_path\":sys.path}))\n" + ], + "returncode": 0 + }, + { + "stage": "doctor", + "argv": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/footwork-capability", + "doctor" + ], + "returncode": 0 + }, + { + "stage": "wheel-tags", + "argv": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "-I", + "-c", + "import json,importlib.metadata;print(json.dumps([{\"name\":d.metadata[\"Name\"],\"version\":d.version,\"tags\":[l[5:] for l in (d.read_text(\"WHEEL\") or \"\").splitlines() if l.startswith(\"Tag: \")]} for d in importlib.metadata.distributions()]))" + ], + "returncode": 0 + } + ], + "passed": true, + "limits": "Fresh dependencies on existing host OS/interpreter, not a fresh machine or TCC permission database.", + "origins": { + "version": "3.14.7 (v3.14.7:823f0323ee6, Aug 5 2026, 07:07:01) [Clang 21.0.0 (clang-2100.1.1.101)]", + "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", + "base_prefix": "/Library/Frameworks/Python.framework/Versions/3.14", + "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "package": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", + "worker": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/execution_worker.py", + "backend": "pure-python", + "module_origins": { + "cua_driver": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py", + "psutil": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/psutil/__init__.py", + "mcp": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py", + "ApplicationServices": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py", + "Quartz": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py", + "Foundation": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Foundation/__init__.py", + "packaging": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/packaging/__init__.py" + }, + "sys_path": [ + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python314.zip", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/lib-dynload", + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + ] + }, + "doctor": { + "platform": "darwin", + "supported": true, + "runtime": { + "python_version": "3.14.7", + "python_requirement": ">=3.11,<4.0", + "python_compatible": true, + "interpreter": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "architecture": "arm64", + "distribution": { + "version": "0.0.1", + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "loaded_modules": { + "jevdual": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", + "jevdual.capability.setup": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/setup.py", + "ApplicationServices": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py", + "Quartz": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py" + } + }, + "dependencies": { + "browser-use": { + "version": "0.13.10", + "requirement": "==0.13.10", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "typesafe-sdk": { + "version": "0.7.4", + "requirement": "<1,>=0.7", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "orjson": { + "version": "3.13.0", + "requirement": ">=3.10", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "psutil": { + "version": "7.2.2", + "requirement": "==7.2.2", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "mcp": { + "version": "2.1.1", + "requirement": "==2.1.1", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "packaging": { + "version": "26.3", + "requirement": "<27,>=25", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "cua-driver": { + "version": "0.28.2", + "requirement": "==0.28.2", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "pyobjc-framework-applicationservices": { + "version": "12.2.2", + "requirement": ">=12", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "pyobjc-framework-quartz": { + "version": "12.2.2", + "requirement": ">=12", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "pyobjc-framework-cocoa": { + "version": "12.2.2", + "requirement": ">=12", + "compatible": true, + "location": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + } + }, + "permissions": { + "accessibility": "not_granted", + "screen_recording": "not_granted" + }, + "scope": "not_checked", + "journal": "not_checked", + "warnings": [ + "Screen Recording is not qualified. Routes that capture pixels may require it." + ], + "dependency_metadata": "installed distribution", + "limitation": "macOS only: one loopback HTTP browser fixture and one identified TextEdit document. Window identity is checked when binding.", + "provider_account_required": false, + "rust_toolchain_required": false, + "blockers": [ + "accessibility_not_granted" + ], + "prerequisite_status": "blocked", + "qualification": "Prerequisites only. Window identity, current state, effects and job completion require separate checks." + }, + "inventory": [ + { + "name": "aiofiles", + "version": "25.1.0" + }, + { + "name": "aiohappyeyeballs", + "version": "2.7.1" + }, + { + "name": "aiohttp", + "version": "3.14.3" + }, + { + "name": "aiosignal", + "version": "1.4.0" + }, + { + "name": "annotated-types", + "version": "0.8.0" + }, + { + "name": "anthropic", + "version": "0.76.0" + }, + { + "name": "anyio", + "version": "4.12.1" + }, + { + "name": "attrs", + "version": "26.1.0" + }, + { + "name": "backoff", + "version": "2.2.1" + }, + { + "name": "beautifulsoup4", + "version": "4.15.0" + }, + { + "name": "browser-harness", + "version": "0.1.13" + }, + { + "name": "browser-use", + "version": "0.13.10" + }, + { + "name": "browser-use-sdk", + "version": "3.4.2" + }, + { + "name": "bubus", + "version": "1.5.6" + }, + { + "name": "cdp-use", + "version": "1.4.5" + }, + { + "name": "certifi", + "version": "2026.7.22" + }, + { + "name": "cffi", + "version": "2.1.1" + }, + { + "name": "charset-normalizer", + "version": "3.5.2" + }, + { + "name": "click", + "version": "8.3.3" + }, + { + "name": "cloudpickle", + "version": "3.1.2" + }, + { + "name": "cryptography", + "version": "50.0.2" + }, + { + "name": "cua-driver", + "version": "0.28.2" + }, + { + "name": "cython", + "version": "3.3.0" + }, + { + "name": "distro", + "version": "1.9.0" + }, + { + "name": "docstring-parser", + "version": "0.18.0" + }, + { + "name": "fetch-use", + "version": "0.4.0" + }, + { + "name": "frozenlist", + "version": "1.8.0" + }, + { + "name": "google-api-core", + "version": "2.29.0" + }, + { + "name": "google-api-python-client", + "version": "2.188.0" + }, + { + "name": "google-auth", + "version": "2.48.0" + }, + { + "name": "google-auth-httplib2", + "version": "0.4.4" + }, + { + "name": "google-auth-oauthlib", + "version": "1.2.4" + }, + { + "name": "google-genai", + "version": "1.65.0" + }, + { + "name": "googleapis-common-protos", + "version": "1.75.5" + }, + { + "name": "groq", + "version": "1.0.0" + }, + { + "name": "h11", + "version": "0.16.0" + }, + { + "name": "httpcore", + "version": "1.0.9" + }, + { + "name": "httpcore2", + "version": "2.13.1" + }, + { + "name": "httplib2", + "version": "0.32.0" + }, + { + "name": "httpx", + "version": "0.28.1" + }, + { + "name": "httpx2", + "version": "2.13.1" + }, + { + "name": "idna", + "version": "3.20" + }, + { + "name": "inquirerpy", + "version": "0.3.4" + }, + { + "name": "jevdual", + "version": "0.0.1" + }, + { + "name": "jiter", + "version": "0.17.0" + }, + { + "name": "jsonschema", + "version": "4.26.0" + }, + { + "name": "jsonschema-specifications", + "version": "2025.9.1" + }, + { + "name": "lxml", + "version": "6.1.3" + }, + { + "name": "markdown-it-py", + "version": "4.2.0" + }, + { + "name": "markdownify", + "version": "1.2.2" + }, + { + "name": "mcp", + "version": "2.1.1" + }, + { + "name": "mcp-types", + "version": "2.1.1" + }, + { + "name": "mdurl", + "version": "0.1.2" + }, + { + "name": "multidict", + "version": "6.9.1" + }, + { + "name": "oauthlib", + "version": "4.0.0" + }, + { + "name": "ollama", + "version": "0.6.1" + }, + { + "name": "openai", + "version": "2.26.0" + }, + { + "name": "opentelemetry-api", + "version": "1.45.1" + }, + { + "name": "orjson", + "version": "3.13.0" + }, + { + "name": "packaging", + "version": "26.3" + }, + { + "name": "pfzy", + "version": "0.3.4" + }, + { + "name": "pillow", + "version": "12.3.0" + }, + { + "name": "portalocker", + "version": "4.4.0" + }, + { + "name": "posthog", + "version": "7.7.0" + }, + { + "name": "prompt-toolkit", + "version": "3.0.53" + }, + { + "name": "propcache", + "version": "0.5.4" + }, + { + "name": "proto-plus", + "version": "1.29.0" + }, + { + "name": "protobuf", + "version": "6.33.6" + }, + { + "name": "psutil", + "version": "7.2.2" + }, + { + "name": "pyasn1", + "version": "0.6.4" + }, + { + "name": "pyasn1-modules", + "version": "0.4.2" + }, + { + "name": "pycparser", + "version": "3.11" + }, + { + "name": "pydantic", + "version": "2.13.5" + }, + { + "name": "pydantic-core", + "version": "2.46.5" + }, + { + "name": "pydantic-settings", + "version": "2.15.0" + }, + { + "name": "pygments", + "version": "2.21.0" + }, + { + "name": "pyjwt", + "version": "2.15.1" + }, + { + "name": "pyobjc-core", + "version": "12.2.2" + }, + { + "name": "pyobjc-framework-applicationservices", + "version": "12.2.2" + }, + { + "name": "pyobjc-framework-cocoa", + "version": "12.2.2" + }, + { + "name": "pyobjc-framework-coretext", + "version": "12.2.2" + }, + { + "name": "pyobjc-framework-quartz", + "version": "12.2.2" + }, + { + "name": "pyotp", + "version": "2.9.0" + }, + { + "name": "pyparsing", + "version": "3.3.3" + }, + { + "name": "pypdf", + "version": "6.16.2" + }, + { + "name": "python-dateutil", + "version": "2.9.0.post0" + }, + { + "name": "python-docx", + "version": "1.2.0" + }, + { + "name": "python-dotenv", + "version": "1.2.2" + }, + { + "name": "python-multipart", + "version": "0.0.32" + }, + { + "name": "referencing", + "version": "0.37.0" + }, + { + "name": "reportlab", + "version": "4.4.9" + }, + { + "name": "requests", + "version": "2.33.0" + }, + { + "name": "requests-oauthlib", + "version": "2.0.0" + }, + { + "name": "rich", + "version": "14.3.3" + }, + { + "name": "rpds-py", + "version": "2026.9.1" + }, + { + "name": "rsa", + "version": "4.9.1" + }, + { + "name": "screeninfo", + "version": "0.8.1" + }, + { + "name": "six", + "version": "1.17.0" + }, + { + "name": "sniffio", + "version": "1.3.1" + }, + { + "name": "soupsieve", + "version": "3.0.1" + }, + { + "name": "sse-starlette", + "version": "3.5.0" + }, + { + "name": "starlette", + "version": "1.7.0" + }, + { + "name": "tenacity", + "version": "9.1.4" + }, + { + "name": "tqdm", + "version": "4.70.1" + }, + { + "name": "truststore", + "version": "0.10.4" + }, + { + "name": "typesafe-sdk", + "version": "0.7.4" + }, + { + "name": "typing-extensions", + "version": "4.15.0" + }, + { + "name": "typing-inspection", + "version": "0.4.4" + }, + { + "name": "uritemplate", + "version": "4.2.0" + }, + { + "name": "urllib3", + "version": "2.8.0" + }, + { + "name": "uuid7", + "version": "0.1.0" + }, + { + "name": "uvicorn", + "version": "0.54.0" + }, + { + "name": "wcwidth", + "version": "0.9.2" + }, + { + "name": "websockets", + "version": "15.0.1" + }, + { + "name": "yarl", + "version": "1.25.1" + } + ], + "wheel_tags": [ + { + "name": "anyio", + "version": "4.12.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "uvicorn", + "version": "0.54.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "groq", + "version": "1.0.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "oauthlib", + "version": "4.0.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "cloudpickle", + "version": "3.1.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyobjc-framework-CoreText", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "portalocker", + "version": "4.4.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "lxml", + "version": "6.1.3", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "packaging", + "version": "26.3", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "Pygments", + "version": "2.21.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "inquirerpy", + "version": "0.3.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "browser-harness", + "version": "0.1.13", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "prompt_toolkit", + "version": "3.0.53", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "jsonschema-specifications", + "version": "2025.9.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "jiter", + "version": "0.17.0", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "typesafe-sdk", + "version": "0.7.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "jevdual", + "version": "0.0.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-api-python-client", + "version": "2.188.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "yarl", + "version": "1.25.1", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "posthog", + "version": "7.7.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "jsonschema", + "version": "4.26.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "orjson", + "version": "3.13.0", + "tags": [ + "cp314-cp314-macosx_15_0_arm64" + ] + }, + { + "name": "google-auth-oauthlib", + "version": "1.2.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "requests", + "version": "2.33.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "PyJWT", + "version": "2.15.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "opentelemetry-api", + "version": "1.45.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pydantic_core", + "version": "2.46.5", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "browser-use-sdk", + "version": "3.4.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyotp", + "version": "2.9.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "docstring_parser", + "version": "0.18.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "propcache", + "version": "0.5.4", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "mcp", + "version": "2.1.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "rich", + "version": "14.3.3", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "uritemplate", + "version": "4.2.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "reportlab", + "version": "4.4.9", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "tenacity", + "version": "9.1.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "aiofiles", + "version": "25.1.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyobjc-framework-Quartz", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "httpcore", + "version": "1.0.9", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "aiohappyeyeballs", + "version": "2.7.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "cryptography", + "version": "50.0.2", + "tags": [ + "cp311-abi3-macosx_11_0_arm64" + ] + }, + { + "name": "pyobjc-framework-Cocoa", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "wcwidth", + "version": "0.9.2", + "tags": [ + "cp310-abi3-macosx_11_0_arm64" + ] + }, + { + "name": "googleapis-common-protos", + "version": "1.75.5", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-genai", + "version": "1.65.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "tqdm", + "version": "4.70.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "urllib3", + "version": "2.8.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "python-dotenv", + "version": "1.2.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "h11", + "version": "0.16.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pydantic", + "version": "2.13.5", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "protobuf", + "version": "6.33.6", + "tags": [ + "cp39-abi3-macosx_10_9_universal2" + ] + }, + { + "name": "pydantic-settings", + "version": "2.15.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "sniffio", + "version": "1.3.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "rsa", + "version": "4.9.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyasn1", + "version": "0.6.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "screeninfo", + "version": "0.8.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "mdurl", + "version": "0.1.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "python-multipart", + "version": "0.0.32", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyobjc-framework-ApplicationServices", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "fetch-use", + "version": "0.4.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "python-dateutil", + "version": "2.9.0.post0", + "tags": [ + "py2-none-any", + "py3-none-any" + ] + }, + { + "name": "openai", + "version": "2.26.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyobjc-core", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "click", + "version": "8.3.3", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "markdownify", + "version": "1.2.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "frozenlist", + "version": "1.8.0", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "cffi", + "version": "2.1.1", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "uuid7", + "version": "0.1.0", + "tags": [ + "py2-none-any", + "py3-none-any" + ] + }, + { + "name": "typing_extensions", + "version": "4.15.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "aiosignal", + "version": "1.4.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "certifi", + "version": "2026.7.22", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "browser-use", + "version": "0.13.10", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "annotated-types", + "version": "0.8.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "referencing", + "version": "0.37.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-auth-httplib2", + "version": "0.4.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pycparser", + "version": "3.11", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "markdown-it-py", + "version": "4.2.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "soupsieve", + "version": "3.0.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-auth", + "version": "2.48.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "bubus", + "version": "1.5.6", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "typing-inspection", + "version": "0.4.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "starlette", + "version": "1.7.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "distro", + "version": "1.9.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pfzy", + "version": "0.3.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "rpds-py", + "version": "2026.9.1", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "httplib2", + "version": "0.32.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "python-docx", + "version": "1.2.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "attrs", + "version": "26.1.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "ollama", + "version": "0.6.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "websockets", + "version": "15.0.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pypdf", + "version": "6.16.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "httpx", + "version": "0.28.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "httpx2", + "version": "2.13.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "sse-starlette", + "version": "3.5.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "backoff", + "version": "2.2.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyasn1_modules", + "version": "0.4.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-api-core", + "version": "2.29.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "beautifulsoup4", + "version": "4.15.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "psutil", + "version": "7.2.2", + "tags": [ + "cp36-abi3-macosx_11_0_arm64" + ] + }, + { + "name": "aiohttp", + "version": "3.14.3", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "cdp-use", + "version": "1.4.5", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "truststore", + "version": "0.10.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "charset-normalizer", + "version": "3.5.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "pillow", + "version": "12.3.0", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "Cython", + "version": "3.3.0", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "proto-plus", + "version": "1.29.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "httpcore2", + "version": "2.13.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyparsing", + "version": "3.3.3", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "cua-driver", + "version": "0.28.2", + "tags": [ + "py3-none-macosx_13_0_universal2" + ] + }, + { + "name": "six", + "version": "1.17.0", + "tags": [ + "py2-none-any", + "py3-none-any" + ] + }, + { + "name": "requests-oauthlib", + "version": "2.0.0", + "tags": [ + "py2-none-any", + "py3-none-any" + ] + }, + { + "name": "multidict", + "version": "6.9.1", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "anthropic", + "version": "0.76.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "mcp-types", + "version": "2.1.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "idna", + "version": "3.20", + "tags": [ + "py3-none-any" + ] + } + ], + "cache_bytes_after_install": 391978745, + "private_state": { + "private-home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", + "private-config": "/Users/tom/footwork-u2/footwork/output/install-v1/private-config", + "private-cache": "/Users/tom/footwork-u2/footwork/output/install-v1/private-cache", + "private-temp": "/Users/tom/footwork-u2/footwork/output/install-v1/private-temp" + } +} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/install-console.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/install-console.txt new file mode 100644 index 0000000..07c54b2 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/install-console.txt @@ -0,0 +1,8 @@ +{"stage": "venv", "returncode": 0} +{"stage": "install", "returncode": 0} +{"stage": "consistency", "returncode": 0} +{"stage": "inventory", "returncode": 0} +{"stage": "origins", "returncode": 0} +{"stage": "doctor", "returncode": 0} +{"stage": "wheel-tags", "returncode": 0} +{"passed": true, "packages": 115, "python": "3.14.7"} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/install-exit.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/install-exit.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/install-exit.txt @@ -0,0 +1 @@ +0 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/media-hashes.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/media-hashes.txt new file mode 100644 index 0000000..3b484a8 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/media-hashes.txt @@ -0,0 +1,4 @@ +footwork-onboarding-u2-packet-v3.zip: OK +python-3.14.7-macos11.pkg: OK +uv-0.12.5-aarch64-apple-darwin.tar.gz: OK +googlechrome.dmg: OK diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/packet-verification.txt b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/packet-verification.txt new file mode 100644 index 0000000..6656f83 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/guest-evidence/packet-verification.txt @@ -0,0 +1 @@ +{"verified": true, "members": 14, "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7"} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md index 4b1b917..dea4270 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md @@ -19,3 +19,9 @@ The human completed installer authentication. Python 3.14.7 runs and the pristin At the handoff, guest System Settings > Privacy & Security > Accessibility visibly lists Terminal with its switch off. Human confirmation is requested before enabling that exact guest host. Claude has the actual baseline review request1791751059206860000, without a new verdict yet. UO2 remains open; no post-grant result is claimed. Claude reviewed the actual baseline at413686b and accepted it (message1791751104201824000), subject to two evidence clarifications. Terminal was first observed in the off Settings list after the cold installer diagnostic, strict doctor and fixture refusal; the exact inserting command cannot be reconstructed. No OS control-permission prompt was observed in captured states, and root never manually added Terminal. Direct product probes are nonprompting in source; this does not establish all transitive runtime effects or prove when the Settings entry appeared. Preserve that limitation. Before post-grant execution, print guest receipt hashes and establish verifiable raw export. The user has explicitly authorized root to toggle the exact guest Terminal entry, but the guest auto-locked before root could do so; no grant occurred. Human unlock is requested to keep credentials out of tool logs under the supplied AGENTS.md rule. + +After human unlock, Terminal switch was already on when root reopened Settings. Root did not toggle it; actor/time are not captured. Guest Terminal visibly quit/relaunched; installed strict doctor exits0 with Accessibility granted, Screen Recording not_granted and blockers empty. Original denied receipt hashes were captured before this diagnostic, but not demonstrably before the actual grant. + +The first post-grant fixture-v1 failed its30second identity deadline while normal Chrome first-launch verification was still visibly active. It emitted no scope and no product action ran. Python local-network discovery and Terminal TextEdit Automation prompts were declined. Only the unchanged owned document was closed manually. Preserve this failure; a separately preregistered development continuation uses fresh fixture-v2 and never replaces v1. + +The raw20member guest evidence archive was exported through a bridge-only, source-IP/size/hash-restricted receiver, which closed after one successful upload. The archive hash and three observed baseline hashes match; sanitized evidence copies are under guest-evidence. Claude received actual failure request1791753574080407000. U2 complete first-use qualification remains false. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json index d8b0719..b7a70f2 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/summary.json @@ -1,6 +1,6 @@ { - "recorded_at": "2026-10-11T16:22:00-04:00", - "status": "grant_authorized_waiting_for_guest_unlock", + "recorded_at": "2026-10-11T17:19:00-04:00", + "status": "cold_fixture_timeout_preserved", "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", "packet_sha256": "769c08c89061731368db33d78b180e7c8c96d531190f43bee44263642a76fd0f", "guest": { @@ -34,12 +34,12 @@ "packet_member_verification": "passed 14 members, exit0", "cold_dependency_install": "passed 115 packages, seven stages exit0, installer exit0", "denied_accessibility_baseline": "observed not_granted, strict doctor exit1, fixture exit2, fixture directory absent", - "permission_transition": "human authorizes root; not applied because guest auto-locked", - "native_effect_restart_report": "not_run", - "cleanup": "not_run", + "permission_transition": "Settings on observed after human unlock; actor/time not captured; Terminal quit/relaunched; strict doctor exit0 Accessibility granted", + "native_effect_restart_report": "not_run: fixture-v1 identity deadline expired during Chrome first-launch verification", + "cleanup": "exact unchanged TextEdit document manually closed after declining Automation; fixture browser cleanup completed", "qualified": false }, - "evidence_location": "Guest /Users/tom/footwork-u2 and native CUA tool images in the current chat; guest receipts not exported yet", + "evidence_location": "guest-evidence sanitized copies; exact raw archive output/u2-export-v1/evidence-v1.zip", "claude_baseline_review": { "message": "1791751104201824000", "verdict": "valid denied baseline", @@ -47,5 +47,13 @@ "cause of Terminal entry not reconstructible retrospectively; no prompting dialog observed", "raw receipt export and hashes required before post-grant run" ] + }, + "export": { + "sha256": "b9dcde6aae648d760d1730bfe979756c6165549b46d7f6eaf6d00dcd9561ea18", + "bytes": 11988, + "members": 20, + "baseline_hashes_matched": 3, + "receiver_closed": true, + "hash_timing": "before doctor-after, actual grant timing not captured" } } From 5eb8550fc6997017e05cec237a070e3ca9190e4a Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:24:19 -0400 Subject: [PATCH 124/216] Record link selector evidence and predict idle network health detection --- .../docs/notebook/2026-10-11-network-workbench.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-network-workbench.md b/jevdual/docs/notebook/2026-10-11-network-workbench.md index 1a23f52..f664ec3 100644 --- a/jevdual/docs/notebook/2026-10-11-network-workbench.md +++ b/jevdual/docs/notebook/2026-10-11-network-workbench.md @@ -6,3 +6,16 @@ Test: build a separate network operator and retained diagnostic link; check real Predicts: the UI preserves identity and cached history, unknown commands block new effects, reconnect is transport-only, read-only receipt lookup applies the exact retained stage once, and explicit resume plans from a fresh TCP image before completing native/SQLite/contact verification. Against: extra sends or native motion during recovery, silent queue resume, completion without lower proof, private pose used for planning, or independent scoring failure. Refs: docs/experiments/SIM10-network-workbench.md; tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md; results/network-workbench-20261011/ + +## SIM10-U1 · update · 2026-10-11 17:21 +Observed: the first diagnostic-link run passed eight checks; the duplicate-receipt check selected an observation command by lexical journal order instead of the exact dispatch command. Its mismatched result was a test-selector failure, with the original log retained. Read-only review also found the draft scorer treated missing dispatch evidence as a withheld decision without explicit cancellation; it now requires a cancelled model outcome and no associated dispatch. +Inferred: the link's first run does not establish the complete browser workflow. Exact command identity is required in both conformance and independent scoring. +Next: bind the conformance selector to its proposal, finish runtime integration, rerun affected checks and freeze all measured source before browser/model qualification. +Refs: tools/physical-workcell/output/sim10-link-tests-v1/unittest.log; tools/physical-workcell/test_workbench_link.py; tools/physical-workcell/score_network_workbench.py + +## SIM10-HEALTH · prediction · 2026-10-11 17:24 +Hypothesis: cached connection state alone leaves an idle upstream outage invisible; a bounded read-only health poll can detect it without delaying browser state reads, changing completed history or sending commands. +Test: stop the real body endpoint while the host is idle, check that the UI-facing connection becomes unavailable and state reads stay responsive, then restore the same endpoint and prove reconnect remains paused with unchanged command count. +Predicts: the original cached-state path misses the outage; after repair the health check changes only connection/admission state, preserves body identity and historical results, and cannot dispatch during recovery. +Against: the original path already detects an idle outage, the poll blocks browser reads for a body timeout, sends commands, clears uncertainty, or resumes the queue automatically. +Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py From 3d5cb91283da2d3028ed10e258e3627231119c82 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:25:08 -0400 Subject: [PATCH 125/216] Predict resume readback race before adversarial control check --- jevdual/docs/notebook/2026-10-11-network-workbench.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-network-workbench.md b/jevdual/docs/notebook/2026-10-11-network-workbench.md index f664ec3..ec3a4d3 100644 --- a/jevdual/docs/notebook/2026-10-11-network-workbench.md +++ b/jevdual/docs/notebook/2026-10-11-network-workbench.md @@ -19,3 +19,10 @@ Test: stop the real body endpoint while the host is idle, check that the UI-faci Predicts: the original cached-state path misses the outage; after repair the health check changes only connection/admission state, preserves body identity and historical results, and cannot dispatch during recovery. Against: the original path already detects an idle outage, the poll blocks browser reads for a body timeout, sends commands, clears uncertainty, or resumes the queue automatically. Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py + +## SIM10-RESUME · prediction · 2026-10-11 17:25 +Hypothesis: Resume's readback gap can overwrite a newer Pause because it clears cancellation after HTTP without rechecking the control epoch. Binding its commit to the unchanged control epoch will preserve the newer control. +Test: delay the real HTTP status response while Resume waits, issue Pause, then release the response; retain the first failing result and rerun after the epoch check. +Predicts: the original Resume returns to running despite the newer Pause; the repaired path stays paused with no command POST and does not clear uncertainty or disconnect state. +Against: the original path already preserves Pause, the repaired path still resumes or sends effects, or the test does not exercise the unlocked readback gap. +Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py From cb0932457e2dc32791fb7a9741bacb71c9575948 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:26:34 -0400 Subject: [PATCH 126/216] Specify durable host admission and pause limits before control-boundary checks --- jevdual/docs/experiments/SIM10-network-workbench.md | 4 ++++ jevdual/docs/notebook/2026-10-11-network-workbench.md | 7 +++++++ tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md | 4 +++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/jevdual/docs/experiments/SIM10-network-workbench.md b/jevdual/docs/experiments/SIM10-network-workbench.md index 88a27d8..9922b97 100644 --- a/jevdual/docs/experiments/SIM10-network-workbench.md +++ b/jevdual/docs/experiments/SIM10-network-workbench.md @@ -17,3 +17,7 @@ Guardrails: no direct native calls from the browser host, no teleport, no privat Decision rule: adopt and show the network browser product only if conformance checks and the independently scored frozen browser/model trial pass. Otherwise retain the prior idle local product and report the failed boundary. Scope: same-Mac loopback simulation; remote authentication, hardware and emergency stopping remain outside this experiment. + +## Amendment · 2026-10-11 17:27 + +Host admission is the durable checked stage write, before handing the exact command to BodyClient. Pause/Disconnect prevent later host admissions; an admitted request may reach the body after the control returns. The body retains its separate lease/freshness/effect checks. Qualification must not claim that Pause interrupts this in-flight request. Add a control-boundary check: pause before admission yields no command; pause after admission permits only that command to settle and admits no successor. diff --git a/jevdual/docs/notebook/2026-10-11-network-workbench.md b/jevdual/docs/notebook/2026-10-11-network-workbench.md index ec3a4d3..5e66927 100644 --- a/jevdual/docs/notebook/2026-10-11-network-workbench.md +++ b/jevdual/docs/notebook/2026-10-11-network-workbench.md @@ -20,6 +20,13 @@ Predicts: the original cached-state path misses the outage; after repair the hea Against: the original path already detects an idle outage, the poll blocks browser reads for a body timeout, sends commands, clears uncertainty, or resumes the queue automatically. Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py +## SIM10-ADMISSION · prediction · 2026-10-11 17:27 +Hypothesis: persisting a checked host stage is a usable admission boundary for Pause over TCP: an admitted request can settle after Pause while all later commands remain suppressed, without holding browser state reads behind network I/O. +Test: pause before durable stage admission and assert no send; pause after stage admission while delivery waits, then release delivery and assert at most that admitted command settles and no successor is sent. Keep the body guards unchanged. +Predicts: the queue remains paused, known admitted results are applied once, unknown results remain blocked, and state reads remain responsive during the network wait. +Against: a later command sends, Pause silently resumes, an uncertain request is resent, or browser state waits behind the HTTP timeout. +Refs: tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md; docs/experiments/SIM10-network-workbench.md; tools/physical-workcell/test_network_operator.py + ## SIM10-RESUME · prediction · 2026-10-11 17:25 Hypothesis: Resume's readback gap can overwrite a newer Pause because it clears cancellation after HTTP without rechecking the control epoch. Binding its commit to the unchanged control epoch will preserve the newer control. Test: delay the real HTTP status response while Resume waits, issue Pause, then release the response; retain the first failing result and rerun after the epoch check. diff --git a/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md b/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md index 55ef8ae..6410c69 100644 --- a/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md +++ b/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md @@ -13,6 +13,8 @@ New modules: `recovery`: `{state: 'none'|'uncertain'|'recovered'|'blocked', command_id: null|string, operation: null|string, reason}`. Unknown blocks effects and lease rotation. Reconcile reads exact retained results and applies the pending host stage once; not-seen remains unknown until fenced. Recovered is paused until explicit Resume. UI shows an old frame as retained and never calls it live. Completed results remain visibly historical during disconnect. -The host writes stage/job/action/proposal context and the pre-send client command index before a client command, associates the unique new command, and clears the stage only after applying its result to queue/history. On restart, terminal client receipts may be read to settle that exact stage; unknown receipts remain blocked. No restart sends actions or automatically resumes. Resume observes a fresh TCP image before the next model decision. Control calls cancel pending model work; a decision from an earlier control epoch cannot dispatch. +The host writes stage/job/action/proposal context and the pre-send client command index before a client command, associates the unique new command, and clears the stage only after applying its result to queue/history. On restart, terminal client receipts may be read to settle that exact stage; unknown receipts remain blocked. No restart sends actions or automatically resumes. Resume observes a fresh TCP image before the next model decision. Control calls cancel pending model work; an unadmitted decision from an earlier control epoch cannot become a command. + +Host admission occurs when the checked command stage is durably persisted under the control lock. After this point its network request is in flight and may reach the body after Pause or Disconnect; those controls prevent subsequent admissions. The body separately checks its own lease, freshness and limits before accepting any physical effect. Pause is not an interruption guarantee for a command already admitted by the host. If transport disappears, retain and reconcile that exact command. The final product replaces the idle old browser server only after separate qualification, retaining its old root. The new workbench and body keep their own private output roots and immutable source identities. From edc139c2e2d9afffd8a5ce603305e3301bbd4a31 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:29:20 -0400 Subject: [PATCH 127/216] Record reviewed installed guest pass and preserve first-use limits --- .../experiments/U2-independent-onboarding.md | 6 + .../2026-10-10-independent-onboarding.md | 25 ++ .../report.md | 2 + .../guest-evidence/cleanup-v2.json | 10 + .../guest-evidence/config-v2-console.txt | 2 + .../guest-evidence/config-v2-exit.txt | 1 + .../guest-evidence/fixture-v2-console.txt | 3 + .../output/fixture-v2/fixture-v2-invoice.txt | 2 + .../footwork/output/fixture-v2/fixture.json | 7 + .../footwork/output/fixture-v2/scope.json | 13 + .../footwork/output/job-v2/host.json | 24 ++ .../op_19f9d53bc4e6/claimed.json | 1 + .../op_19f9d53bc4e6/input_started.json | 1 + .../op_19f9d53bc4e6/packet.json | 1 + .../op_19f9d53bc4e6/registration.json | 1 + .../op_19f9d53bc4e6/result.json | 1 + .../footwork/output/job-v2/scope.json | 13 + .../output/native-v2/origin-probe.json | 16 + .../footwork/output/native-v2/receipt.json | 372 ++++++++++++++++++ .../server-42481-1791753862176581000.json | 1 + .../server-42481-1791753862535644000.json | 1 + .../server-42481-1791753863241269000.json | 1 + .../server-42640-1791753865106768000.json | 1 + .../worker-42605-1791753864068183000.json | 1 + .../footwork/output/native-v2/scope.json | 1 + .../output/native-v2/worker-observations.json | 23 ++ .../guest-evidence/native-v2-console.txt | 2 + .../guest-evidence/native-v2-exit.txt | 1 + .../journal-readback.json | 16 + .../report.md | 27 ++ .../summary.json | 39 ++ 31 files changed, 615 insertions(+) create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/cleanup-v2.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/config-v2-console.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/config-v2-exit.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/fixture-v2-console.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/fixture-v2-invoice.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/fixture.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/scope.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/host.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/claimed.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/input_started.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/packet.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/registration.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/result.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/scope.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/origin-probe.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/receipt.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753862176581000.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753862535644000.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753863241269000.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42640-1791753865106768000.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/worker-42605-1791753864068183000.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/scope.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/worker-observations.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/native-v2-console.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/native-v2-exit.txt create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/journal-readback.json create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/report.md create mode 100644 jevdual/results/u2-independent-onboarding-20261011-v2-dev/summary.json diff --git a/jevdual/docs/experiments/U2-independent-onboarding.md b/jevdual/docs/experiments/U2-independent-onboarding.md index b2dd165..bee6148 100644 --- a/jevdual/docs/experiments/U2-independent-onboarding.md +++ b/jevdual/docs/experiments/U2-independent-onboarding.md @@ -25,3 +25,9 @@ Primary criterion: one valid independently provisioned lane with an observed den ## Decision rule Close packet preparation after artifact verification, helper import/launch checks and Claude review. Keep U2 runtime qualification open until the independent lane passes all required observations. Preserve failures under a new run version; do not reset the host's grants to manufacture a baseline or regrade existing U1/A2 results. + +## Result · 2026-10-11 + +Full first-use qualification does not pass. A fresh SIP-enabled guest cold-installed the frozenv3 packet and exhibited a valid denied Accessibility baseline. The grant actor/time was not captured, the first fixture failed during normal Chrome verification, and automatic document cleanup could not be confirmed after Automation was declined. Preserve results/u2-independent-onboarding-20261011-v1. + +Separately preregistered development continuation UO5 passes after ordinary Chrome verification: unchanged helpers and installed wheel, one native effect/ledger row, actual isolated detached worker, same-token server restart and accepted structured completion report. Owned process/listener cleanup passes; exact document close required the operator and persistence remains not_checked. Claude independently reviewed the raw receipts/journal and confirmed these limits. See results/u2-independent-onboarding-20261011-v2-dev. This continuation does not regrade the initial failure. Future packet fixes and a captured fresh transition remain required before a complete first-use claim. diff --git a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md index d3f1ed0..a61de85 100644 --- a/jevdual/docs/notebook/2026-10-10-independent-onboarding.md +++ b/jevdual/docs/notebook/2026-10-10-independent-onboarding.md @@ -91,3 +91,28 @@ Test: retain fixture-v1 and its refusal/timeout evidence. Observe normal vendor Predicts: fixture-v2 emits ready and the installed append/repeated-token/report oracle passes with one operation and one effect under the same Terminal Accessibility grant. Against: Chrome remains unable to launch normally, scope identification fails again, native oracle refuses or duplicates, or additional permission is necessary for native execution. Refs: docs/experiments/U2-independent-onboarding.md; guest fixture-console.txt; scripts/capability_fixture.py; scripts/capability_installed_trial.py + +## UOU9 · update · 2026-10-11 17:28 +Resolves: UO5 = held +Observed: unchanged fixture-v2 emits ready after ordinary Chrome verification completes. Config and installed native oracle exit0; AX oracle matches once, installed detached worker contexts are retained, same-token server restart returns the same operation, and read-only journal/report show one final applied row. Exact fixture/browser/worker processes are absent and loopback is closed after cleanup; exact document close requires the operator because Automation was declined. Claude independently verifies the raw archive/journal and accepts the bounded development pass without new runtime blockers. +Inferred: startup readiness is supported as the initial fixture failure explanation, but no isolated causal test proves Gatekeeper was the only cause. Additional TCC grants were unnecessary for product execution. +Next: retain this post-grant continuation separately; develop fixture/setup improvements in a new packet before another complete first-use qualification. +Refs: results/u2-independent-onboarding-20261011-v2-dev; Claude1791754065071525000; preregistration47f38de + +## UOU10 · update · 2026-10-11 17:28 +Resolves: UO2 = inconclusive +Observed: denied installed diagnostics and no-resource refusal are valid; post-restart doctor and the separate post-grant installed native flow pass. The actual grant actor/time remain uncaptured, the initial fixture times out and automatic document close remains unconfirmed. Claude flags the original transition pass condition as unmet. Earlier UOU8 phrase permission transition is observed means only separated off/on states, not a captured grant event; it cannot satisfy the transition gate. +Next: keep full first-use U2 unqualified. A new captured denied-to-approved lane requires an explicitly approved guest reset or fresh environment; no reset is performed here. +Refs: results/u2-independent-onboarding-20261011-v1; results/u2-independent-onboarding-20261011-v2-dev; Claude1791753660836044000 + +## UOU11 · update · 2026-10-11 17:28 +Resolves: UO4 = inconclusive +Observed: both allowlisted raw guest exports match the observed archive hashes; original denied doctor/refusal/install receipt hashes also match byte-for-byte. Both fixed-source-IP/path/size/hash bridge receivers terminate after one upload and are absent during qualification. However the baseline hashes were printed before post-restart doctor, not demonstrably before the actual grant, so the prediction's pre-grant timing claim is not established. +Next: preserve raw and sanitized receipts and use contemporaneous grant capture in the next first-use lane. +Refs: output/u2-export-v1; output/u2-export-v2; results/u2-independent-onboarding-20261011-v2-dev/summary.json + +## UOS3 · summary · 2026-10-11 17:28 +Established: fresh SIP-enabled guest cold install, truthful denied baseline, post-grant installed browser-to-desktop execution, isolated actual detached worker, same-token restart deduplication, journal-validated completion report and bounded receipt export; independently reviewed by Claude. Original first-use failure remains preserved. Only exact owned fixture resources were closed; document cleanup required the operator. +Uncertain: grant actor/time, complete first-use transition, automatic document cleanup and disk persistence. Discovery attribution remains a hypothesis. No new packet or permission reset has been tested. +Decision: close this measured package as a reviewed post-grant development pass and an unqualified full first-use lane. Next packet should use exact-document AX cleanup, distinct browser startup/identity phases and a separately tested discovery-flag hypothesis, grounded in Arc CUA, Chrome DevTools MCP and browser-use source. Keep frozenv3 and product wheel unchanged. +Refs: results/u2-independent-onboarding-20261011-v2-dev/report.md; Claude1791754065071525000; results/u2-independent-onboarding-20261011-v1 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md index dea4270..b1c8acd 100644 --- a/jevdual/results/u2-independent-onboarding-20261011-v1/report.md +++ b/jevdual/results/u2-independent-onboarding-20261011-v1/report.md @@ -25,3 +25,5 @@ After human unlock, Terminal switch was already on when root reopened Settings. The first post-grant fixture-v1 failed its30second identity deadline while normal Chrome first-launch verification was still visibly active. It emitted no scope and no product action ran. Python local-network discovery and Terminal TextEdit Automation prompts were declined. Only the unchanged owned document was closed manually. Preserve this failure; a separately preregistered development continuation uses fresh fixture-v2 and never replaces v1. The raw20member guest evidence archive was exported through a bridge-only, source-IP/size/hash-restricted receiver, which closed after one successful upload. The archive hash and three observed baseline hashes match; sanitized evidence copies are under guest-evidence. Claude received actual failure request1791753574080407000. U2 complete first-use qualification remains false. + +Claude independently reviewed the raw v1 archive (1791753660836044000): valid denied baseline and post-grant doctor, but failed first-use journey and unmet permission-transition gate. The separate v2 development continuation passed after normal Chrome verification; see ../u2-independent-onboarding-20261011-v2-dev. This does not change the original failure or qualify full first use. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/cleanup-v2.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/cleanup-v2.json new file mode 100644 index 0000000..a2ee843 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/cleanup-v2.json @@ -0,0 +1,10 @@ +{ + "owned_pids_absent": { + "24765": true, + "24766": true, + "42605": true + }, + "fixture_loopback_closed": true, + "document_closed_by_operator": "exact fixture-v2 title observed then closed using native CUA; persistence not checked", + "automation_grant": "declined" +} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/config-v2-console.txt b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/config-v2-console.txt new file mode 100644 index 0000000..37111d3 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/config-v2-console.txt @@ -0,0 +1,2 @@ +jevdual._core unavailable (cannot import name '_core' from partially initialized module 'jevdual' (most likely due to a circular import) (/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py)); falling back to pure Python +{"task": "task_a5de7021e73f434e8713e86c651d73f7", "host_config": "/Users/tom/footwork-u2/footwork/output/job-v2/host.json", "scope": "/Users/tom/footwork-u2/footwork/output/job-v2/scope.json", "report_schema": "/Users/tom/footwork-u2/footwork/output/job-v2/report-schema.json", "report_adapter": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", "-I", "-m", "jevdual.capability.cli", "report", "--journal", "/Users/tom/footwork-u2/footwork/output/job-v2/operations.sqlite", "--task", "task_a5de7021e73f434e8713e86c651d73f7"], "limitation": "macOS only: one loopback HTTP browser fixture and one identified TextEdit document. Window identity is checked when binding.", "publication": "Validate the structured final report through report_adapter and publish only trusted_summary. Never fall back to raw host prose.", "lifecycle": "Reuse this task only for reconnect/restart of this job. Generate a new run directory for each new job."} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/config-v2-exit.txt b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/config-v2-exit.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/config-v2-exit.txt @@ -0,0 +1 @@ +0 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/fixture-v2-console.txt b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/fixture-v2-console.txt new file mode 100644 index 0000000..8725dc4 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/fixture-v2-console.txt @@ -0,0 +1,3 @@ +jevdual._core unavailable (cannot import name '_core' from partially initialized module 'jevdual' (most likely due to a circular import) (/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py)); falling back to pure Python +{"ready": true, "scope": "/Users/tom/footwork-u2/footwork/output/fixture-v2/scope.json"} +Fixture document cleanup could not be confirmed; browser cleanup continues. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/fixture-v2-invoice.txt b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/fixture-v2-invoice.txt new file mode 100644 index 0000000..c0b3c07 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/fixture-v2-invoice.txt @@ -0,0 +1,2 @@ +Invoice report +17.25 USD \ No newline at end of file diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/fixture.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/fixture.json new file mode 100644 index 0000000..37330be --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/fixture.json @@ -0,0 +1,7 @@ +{ + "url": "http://127.0.0.1:49175/", + "document": "/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt", + "value": "17.25 USD", + "prefix": "Invoice report\n", + "browser_pid": 24766 +} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/scope.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/scope.json new file mode 100644 index 0000000..ea1d375 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/fixture-v2/scope.json @@ -0,0 +1,13 @@ +{ + "task": "fixture-v2", + "source": { + "pid": 24766, + "window_id": 237, + "url": "http://127.0.0.1:49175/" + }, + "destination": { + "pid": 2817, + "window_id": 235, + "document": "/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt" + } +} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/host.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/host.json new file mode 100644 index 0000000..0796ee9 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/host.json @@ -0,0 +1,24 @@ +{ + "mcpServers": { + "footwork": { + "command": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "env": { + "PYTHONPATH": "", + "PYTHONHOME": "", + "PYTHONNOUSERSITE": "1", + "ANONYMIZED_TELEMETRY": "false", + "BROWSER_USE_CLOUD_SYNC": "false" + }, + "args": [ + "-I", + "-m", + "jevdual.capability.cli", + "server", + "--scope", + "/Users/tom/footwork-u2/footwork/output/job-v2/scope.json", + "--journal", + "/Users/tom/footwork-u2/footwork/output/job-v2/operations.sqlite" + ] + } + } +} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/claimed.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/claimed.json new file mode 100644 index 0000000..574ac7f --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/claimed.json @@ -0,0 +1 @@ +{"nonce":"956396088a8145bdba8a6442d25010b5","operation_id":"op_19f9d53bc4e6","packet_digest":"cfca1696986e68585305a237764bef3804c998ee31d8558c91e1950c35067376","request_digest":"6375e2777f8b4f59302959bb0c1b5c53537b1957c052f105f5e306520c0847a7","version":1} \ No newline at end of file diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/input_started.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/input_started.json new file mode 100644 index 0000000..f225d10 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/input_started.json @@ -0,0 +1 @@ +{"nonce":"956396088a8145bdba8a6442d25010b5","operation_id":"op_19f9d53bc4e6","packet_digest":"cfca1696986e68585305a237764bef3804c998ee31d8558c91e1950c35067376","request_digest":"6375e2777f8b4f59302959bb0c1b5c53537b1957c052f105f5e306520c0847a7","t":1791753864.227186,"version":1} \ No newline at end of file diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/packet.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/packet.json new file mode 100644 index 0000000..7c3aa58 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/packet.json @@ -0,0 +1 @@ +{"args":{"text":"17.25 USD"},"operation_id":"op_19f9d53bc4e6","recovery":{"before":{"length":15,"sha256":"ac11060594d5bcde616f5e88156ea7c0f55e2cca74c2de52c4da375fbde33339"},"expected":{"length":24,"sha256":"783172d2e6ac11f2c5450015856703ebe655b8c2aa86ca81b802ab1d8d210aee"},"field":{"frame":[118.0,89.0,656.0,384.0],"role":"AXTextArea"},"identity":{"boot":"11EBDE2F-6F02-4282-B73B-6DB59AABD9A1","device":16777233,"document":"/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt","inode":118886,"pid":2817,"start":"0x1.ab2ff26e1fcadp+30"},"nonce":"956396088a8145bdba8a6442d25010b5","route":"textedit-ax-append-v1","scope":{"destination":{"document":"/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt","pid":2817,"window_id":235},"source":{"pid":24766,"url":"http://127.0.0.1:49175/","window_id":237},"task":"task_a5de7021e73f434e8713e86c651d73f7"},"scope_digest":"4c6a65aaa0f5f9c2dd294e474ceddd63355e05bca6655e088563c33359d95a5f","version":1},"request":{"args":{"text":"17.25 USD"},"move":"append","observation":"obs_0714d47266514cc982e9185127f221b0","resource":"native:2817:235","target":"target_e9ef6b07fc344d6f9f4172ea50d2ff2a","task":"task_a5de7021e73f434e8713e86c651d73f7"},"request_digest":"6375e2777f8b4f59302959bb0c1b5c53537b1957c052f105f5e306520c0847a7","version":1} \ No newline at end of file diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/registration.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/registration.json new file mode 100644 index 0000000..e7555df --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/registration.json @@ -0,0 +1 @@ +{"nonce":"956396088a8145bdba8a6442d25010b5","operation_id":"op_19f9d53bc4e6","packet_digest":"cfca1696986e68585305a237764bef3804c998ee31d8558c91e1950c35067376","pgid":42605,"pid":42605,"request_digest":"6375e2777f8b4f59302959bb0c1b5c53537b1957c052f105f5e306520c0847a7","start":"0x1.ab2ffa1db2863p+30","version":1} \ No newline at end of file diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/result.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/result.json new file mode 100644 index 0000000..aa2128a --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/result.json @@ -0,0 +1 @@ +{"disposition":"applied","error":null,"evidence":{"after":{"length":24,"sha256":"783172d2e6ac11f2c5450015856703ebe655b8c2aa86ca81b802ab1d8d210aee"},"before":{"length":15,"sha256":"ac11060594d5bcde616f5e88156ea7c0f55e2cca74c2de52c4da375fbde33339"},"driver_effect":"confirmed","identity":{"boot":"11EBDE2F-6F02-4282-B73B-6DB59AABD9A1","device":16777233,"document":"/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt","inode":118886,"pid":2817,"start":"0x1.ab2ff26e1fcadp+30"},"identity_after":{"boot":"11EBDE2F-6F02-4282-B73B-6DB59AABD9A1","device":16777233,"document":"/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt","inode":118886,"pid":2817,"start":"0x1.ab2ff26e1fcadp+30"},"readback":{"kind":"exact_field_readback","passed":true,"persistence":"not_checked"}},"nonce":"956396088a8145bdba8a6442d25010b5","operation_id":"op_19f9d53bc4e6","packet_digest":"cfca1696986e68585305a237764bef3804c998ee31d8558c91e1950c35067376","phase":"sent","request_digest":"6375e2777f8b4f59302959bb0c1b5c53537b1957c052f105f5e306520c0847a7","version":1} \ No newline at end of file diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/scope.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/scope.json new file mode 100644 index 0000000..5bf0108 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/job-v2/scope.json @@ -0,0 +1,13 @@ +{ + "task": "task_a5de7021e73f434e8713e86c651d73f7", + "source": { + "pid": 24766, + "window_id": 237, + "url": "http://127.0.0.1:49175/" + }, + "destination": { + "pid": 2817, + "window_id": 235, + "document": "/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt" + } +} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/origin-probe.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/origin-probe.json new file mode 100644 index 0000000..4d62793 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/origin-probe.json @@ -0,0 +1,16 @@ +{ + "artifact_version": "0.0.1", + "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", + "kernel_executable": "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python", + "kernel_argv0": "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python", + "package": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", + "worker": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/execution_worker.py", + "backend": "pure-python", + "sys_path": [ + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python314.zip", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/lib-dynload", + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + ] +} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/receipt.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/receipt.json new file mode 100644 index 0000000..868940f --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/receipt.json @@ -0,0 +1,372 @@ +{ + "passed": true, + "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", + "origins": { + "artifact_version": "0.0.1", + "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", + "kernel_executable": "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python", + "kernel_argv0": "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python", + "package": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", + "worker": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/execution_worker.py", + "backend": "pure-python", + "sys_path": [ + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python314.zip", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/lib-dynload", + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages" + ] + }, + "actual_runtime_contexts": [ + { + "role": "server", + "operation": null, + "pid": 42481, + "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": null, + "mcp": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py" + ], + "ApplicationServices": null, + "Quartz": null, + "Foundation": null + }, + "cua_library": null, + "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791753862176581000 + }, + { + "role": "server", + "operation": null, + "pid": 42481, + "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py" + ], + "mcp": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py" + ], + "ApplicationServices": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py" + ], + "Quartz": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py" + ], + "Foundation": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Foundation/__init__.py" + ] + }, + "cua_library": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/libcua_driver_sdk.dylib", + "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791753863241269000 + }, + { + "role": "server", + "operation": null, + "pid": 42640, + "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": null, + "mcp": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py" + ], + "ApplicationServices": null, + "Quartz": null, + "Foundation": null + }, + "cua_library": null, + "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791753865106768000 + }, + { + "role": "server", + "operation": null, + "pid": 42481, + "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py" + ], + "mcp": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py" + ], + "ApplicationServices": null, + "Quartz": null, + "Foundation": null + }, + "cua_library": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/libcua_driver_sdk.dylib", + "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791753862535644000 + }, + { + "role": "worker", + "operation": "op_19f9d53bc4e6", + "pid": 42605, + "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py" + ], + "mcp": null, + "ApplicationServices": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py" + ], + "Quartz": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py" + ], + "Foundation": [ + "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Foundation/__init__.py" + ] + }, + "cua_library": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/libcua_driver_sdk.dylib", + "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791753864068183000 + } + ], + "emitted_configuration_checked": true, + "initialized": { + "capabilities": { + "experimental": {}, + "tools": { + "listChanged": false + } + }, + "protocolVersion": "2025-06-18", + "serverInfo": { + "name": "footwork-capability", + "version": "0.0.1" + } + }, + "worker_proofs": [ + { + "registration": { + "nonce": "956396088a8145bdba8a6442d25010b5", + "operation_id": "op_19f9d53bc4e6", + "packet_digest": "cfca1696986e68585305a237764bef3804c998ee31d8558c91e1950c35067376", + "pgid": 42605, + "pid": 42605, + "request_digest": "6375e2777f8b4f59302959bb0c1b5c53537b1957c052f105f5e306520c0847a7", + "start": "0x1.ab2ffa1db2863p+30", + "version": 1 + }, + "cmdline": [ + "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python", + "-I", + "-m", + "jevdual.capability.execution_worker", + "--packet", + "/Users/tom/footwork-u2/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/packet.json" + ], + "executable": "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python" + } + ], + "action": { + "is_error": false, + "schema_version": "1", + "operation_id": "op_19f9d53bc4e6", + "disposition": "applied", + "state": "final", + "phase": "sent", + "summary": "Historical append confirmed by retained execution evidence; current agreement is separate.", + "repeat": false, + "evidence": { + "execution_receipt": { + "disposition": "applied", + "error": null, + "evidence": { + "after": { + "length": 24, + "sha256": "783172d2e6ac11f2c5450015856703ebe655b8c2aa86ca81b802ab1d8d210aee" + }, + "before": { + "length": 15, + "sha256": "ac11060594d5bcde616f5e88156ea7c0f55e2cca74c2de52c4da375fbde33339" + }, + "driver_effect": "confirmed", + "identity": { + "boot": "11EBDE2F-6F02-4282-B73B-6DB59AABD9A1", + "device": 16777233, + "document": "/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt", + "inode": 118886, + "pid": 2817, + "start": "0x1.ab2ff26e1fcadp+30" + }, + "identity_after": { + "boot": "11EBDE2F-6F02-4282-B73B-6DB59AABD9A1", + "device": 16777233, + "document": "/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt", + "inode": 118886, + "pid": 2817, + "start": "0x1.ab2ff26e1fcadp+30" + }, + "readback": { + "kind": "exact_field_readback", + "passed": true, + "persistence": "not_checked" + } + }, + "nonce": "956396088a8145bdba8a6442d25010b5", + "operation_id": "op_19f9d53bc4e6", + "packet_digest": "cfca1696986e68585305a237764bef3804c998ee31d8558c91e1950c35067376", + "phase": "sent", + "request_digest": "6375e2777f8b4f59302959bb0c1b5c53537b1957c052f105f5e306520c0847a7", + "version": 1 + }, + "readback": { + "kind": "exact_field_readback", + "passed": true, + "persistence": "not_checked", + "outcome": "applied", + "historical": true + } + }, + "reporting": { + "historical_effect": "applied", + "disk_persistence": "not_checked", + "guidance": "Disk persistence was not checked. Do not claim the file is saved or unsaved. Report the retained execution result separately from current document agreement." + }, + "client_token": "installed-once" + }, + "repeat": { + "is_error": false, + "schema_version": "1", + "operation_id": "op_19f9d53bc4e6", + "disposition": "applied", + "state": "final", + "phase": "sent", + "summary": "Historical append confirmed by retained execution evidence; current agreement is separate.", + "repeat": true, + "evidence": { + "execution_receipt": { + "disposition": "applied", + "error": null, + "evidence": { + "after": { + "length": 24, + "sha256": "783172d2e6ac11f2c5450015856703ebe655b8c2aa86ca81b802ab1d8d210aee" + }, + "before": { + "length": 15, + "sha256": "ac11060594d5bcde616f5e88156ea7c0f55e2cca74c2de52c4da375fbde33339" + }, + "driver_effect": "confirmed", + "identity": { + "boot": "11EBDE2F-6F02-4282-B73B-6DB59AABD9A1", + "device": 16777233, + "document": "/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt", + "inode": 118886, + "pid": 2817, + "start": "0x1.ab2ff26e1fcadp+30" + }, + "identity_after": { + "boot": "11EBDE2F-6F02-4282-B73B-6DB59AABD9A1", + "device": 16777233, + "document": "/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt", + "inode": 118886, + "pid": 2817, + "start": "0x1.ab2ff26e1fcadp+30" + }, + "readback": { + "kind": "exact_field_readback", + "passed": true, + "persistence": "not_checked" + } + }, + "nonce": "956396088a8145bdba8a6442d25010b5", + "operation_id": "op_19f9d53bc4e6", + "packet_digest": "cfca1696986e68585305a237764bef3804c998ee31d8558c91e1950c35067376", + "phase": "sent", + "request_digest": "6375e2777f8b4f59302959bb0c1b5c53537b1957c052f105f5e306520c0847a7", + "version": 1 + }, + "readback": { + "kind": "exact_field_readback", + "passed": true, + "persistence": "not_checked", + "outcome": "applied", + "historical": true + } + }, + "reporting": { + "historical_effect": "applied", + "disk_persistence": "not_checked", + "guidance": "Disk persistence was not checked. Do not claim the file is saved or unsaved. Report the retained execution result separately from current document agreement." + }, + "client_token": "installed-once" + }, + "report": { + "schema_version": "1", + "scope": "all_admitted_task_operations", + "validation": { + "accepted": true, + "reasons": [] + }, + "operation_completion": "completed", + "operations": [ + { + "operation": "op_19f9d53bc4e6", + "state": "final", + "disposition": "applied", + "updated": 1791753864.586184, + "created": 1791753863.419928 + } + ], + "persistence": "not_checked", + "current_state": "not_checked", + "task": "task_a5de7021e73f434e8713e86c651d73f7", + "snapshot_digest": "022a90f5f38fb30054c9a799a0ed885ebd524d702629cb1b0776e0746644c7b4", + "ledger_span": { + "first_created": 1791753863.419928, + "last_updated": 1791753864.586184, + "count": 1 + }, + "accepted_host_claim": "completed", + "as_of": 1791753865.3063118, + "trusted_summary": "1 recorded operations confirmed applied; 0 attempts confirmed no input. These are historical effects, not certification of the host job. Full task ledger: 1 records, 2026-10-11T21:24:23.419928+00:00 through 2026-10-11T21:24:24.586184+00:00. Current document state and disk persistence are not certified by this report." + }, + "oracle_actual": "Invoice report\n17.25 USD", + "owned_worker_finished": true, + "limits": "Existing host OS/system frameworks/permissions. Fresh dependency/private-home qualification." +} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753862176581000.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753862176581000.json new file mode 100644 index 0000000..4865ad8 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753862176581000.json @@ -0,0 +1 @@ +{"role": "server", "operation": null, "pid": 42481, "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", "modules": {"jevdual": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py"], "jevdual.capability.execution_worker": null, "cua_driver": null, "mcp": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py"], "ApplicationServices": null, "Quartz": null, "Foundation": null}, "cua_library": null, "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", "user_site_disabled": true, "browser_telemetry_disabled": true, "browser_cloud_sync_disabled": true, "as_of_ns": 1791753862176581000} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753862535644000.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753862535644000.json new file mode 100644 index 0000000..12e5068 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753862535644000.json @@ -0,0 +1 @@ +{"role": "server", "operation": null, "pid": 42481, "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", "modules": {"jevdual": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py"], "jevdual.capability.execution_worker": null, "cua_driver": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py"], "mcp": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py"], "ApplicationServices": null, "Quartz": null, "Foundation": null}, "cua_library": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/libcua_driver_sdk.dylib", "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", "user_site_disabled": true, "browser_telemetry_disabled": true, "browser_cloud_sync_disabled": true, "as_of_ns": 1791753862535644000} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753863241269000.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753863241269000.json new file mode 100644 index 0000000..cdd66ca --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42481-1791753863241269000.json @@ -0,0 +1 @@ +{"role": "server", "operation": null, "pid": 42481, "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", "modules": {"jevdual": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py"], "jevdual.capability.execution_worker": null, "cua_driver": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py"], "mcp": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py"], "ApplicationServices": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py"], "Quartz": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py"], "Foundation": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Foundation/__init__.py"]}, "cua_library": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/libcua_driver_sdk.dylib", "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", "user_site_disabled": true, "browser_telemetry_disabled": true, "browser_cloud_sync_disabled": true, "as_of_ns": 1791753863241269000} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42640-1791753865106768000.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42640-1791753865106768000.json new file mode 100644 index 0000000..a7a1ba9 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/server-42640-1791753865106768000.json @@ -0,0 +1 @@ +{"role": "server", "operation": null, "pid": 42640, "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", "modules": {"jevdual": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py"], "jevdual.capability.execution_worker": null, "cua_driver": null, "mcp": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py"], "ApplicationServices": null, "Quartz": null, "Foundation": null}, "cua_library": null, "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", "user_site_disabled": true, "browser_telemetry_disabled": true, "browser_cloud_sync_disabled": true, "as_of_ns": 1791753865106768000} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/worker-42605-1791753864068183000.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/worker-42605-1791753864068183000.json new file mode 100644 index 0000000..0fc594e --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/runtime-context/worker-42605-1791753864068183000.json @@ -0,0 +1 @@ +{"role": "worker", "operation": "op_19f9d53bc4e6", "pid": 42605, "python": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/bin/python", "prefix": "/Users/tom/footwork-u2/footwork/output/install-v1/venv", "modules": {"jevdual": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py"], "jevdual.capability.execution_worker": null, "cua_driver": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py"], "mcp": null, "ApplicationServices": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py"], "Quartz": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py"], "Foundation": ["/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/Foundation/__init__.py"]}, "cua_library": "/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/libcua_driver_sdk.dylib", "home": "/Users/tom/footwork-u2/footwork/output/install-v1/private-home", "user_site_disabled": true, "browser_telemetry_disabled": true, "browser_cloud_sync_disabled": true, "as_of_ns": 1791753864068183000} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/scope.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/scope.json new file mode 100644 index 0000000..c24c2ab --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/scope.json @@ -0,0 +1 @@ +{"task": "task_a5de7021e73f434e8713e86c651d73f7", "source": {"pid": 24766, "window_id": 237, "url": "http://127.0.0.1:49175/"}, "destination": {"pid": 2817, "window_id": 235, "document": "/Users/tom/footwork-u2/footwork/output/fixture-v2/fixture-v2-invoice.txt"}} \ No newline at end of file diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/worker-observations.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/worker-observations.json new file mode 100644 index 0000000..2489199 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/footwork/output/native-v2/worker-observations.json @@ -0,0 +1,23 @@ +[ + { + "registration": { + "nonce": "956396088a8145bdba8a6442d25010b5", + "operation_id": "op_19f9d53bc4e6", + "packet_digest": "cfca1696986e68585305a237764bef3804c998ee31d8558c91e1950c35067376", + "pgid": 42605, + "pid": 42605, + "request_digest": "6375e2777f8b4f59302959bb0c1b5c53537b1957c052f105f5e306520c0847a7", + "start": "0x1.ab2ffa1db2863p+30", + "version": 1 + }, + "cmdline": [ + "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python", + "-I", + "-m", + "jevdual.capability.execution_worker", + "--packet", + "/Users/tom/footwork-u2/footwork/output/job-v2/operations.sqlite.executions/op_19f9d53bc4e6/packet.json" + ], + "executable": "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python" + } +] diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/native-v2-console.txt b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/native-v2-console.txt new file mode 100644 index 0000000..c09d1d2 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/native-v2-console.txt @@ -0,0 +1,2 @@ +jevdual._core unavailable (cannot import name '_core' from partially initialized module 'jevdual' (most likely due to a circular import) (/Users/tom/footwork-u2/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py)); falling back to pure Python +{"passed": true, "backend": "pure-python", "installed_worker_observed": true} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/native-v2-exit.txt b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/native-v2-exit.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/guest-evidence/native-v2-exit.txt @@ -0,0 +1 @@ +0 diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/journal-readback.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/journal-readback.json new file mode 100644 index 0000000..759cd8e --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/journal-readback.json @@ -0,0 +1,16 @@ +{ + "read_only": true, + "count": 1, + "operations": [ + { + "id": "op_19f9d53bc4e6", + "task": "task_a5de7021e73f434e8713e86c651d73f7", + "client_token": "installed-once", + "state": "final", + "disposition": "applied", + "phase": "sent", + "created": 1791753863.419928, + "updated": 1791753864.586184 + } + ] +} diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/report.md b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/report.md new file mode 100644 index 0000000..1f87033 --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/report.md @@ -0,0 +1,27 @@ +# U2 development continuation: installed public path passes + +After ordinary Chrome first-launch verification completed, the unchanged frozen packet identified the fresh fixture-v2 windows. The generated host configuration and installed native trial both exited0. This is a post-grant development continuation, preregistered as UO5; the original fixture-v1 failure is retained separately and never regraded. + +The AX oracle read exactly `Invoice report\n17.25 USD`. The installed MCP server admitted one append; after server restart the same token returned the same operation with repeat=true. A read-only inspection of the exported SQLite journal found exactly one final/applied/sent row. The structured final report was accepted against that full task ledger, with persistence and current-state certification explicitly not_checked. See guest-evidence/footwork/output/native-v2/receipt.json and journal-readback.json. + +Actual server and detached-worker contexts show installed venv module/dylib origins, private HOME, disabled user site and telemetry. They ran with -I outside the packet source, with hostile cwd shadow packages. The receipt identifies frozen source33e1afb and the reviewed pure-Python wheel; no helper or product bytes changed during the continuation. + +Cleanup stopped exact fixture PID24765 through its SIGINT handler. Fixture PID24765, browser24766 and worker42605 were absent, and the loopback listener refused connection. Automation had been declined, so the fixture could not confirm its TextEdit close. The operator visually verified the exact fixture-v2 title and one appended value, then closed that document using native CUA. Save/discard and disk persistence were not checked. See guest-evidence/cleanup-v2.json. No other app/process was targeted. + +The raw28member archive was exported only after execution and cleanup through a bridge-only, fixed-source-IP/path/size/hash receiver. Guest and host SHA256 match; the receiver exited after the upload. The raw archive and journal remain under output/u2-export-v2; sanitized JSON/text evidence is retained here. + +Claude independently verified the archive, exits, oracle, replay identity, runtime contexts, journal row and cleanup receipt (mailbox1791754065071525000). Verdict: valid post-grant development pass, no new runtime blockers. + +## Limits and first-use decision + +This was a fresh SIP-enabled guest OS and fresh dependency install. An Accessibility-denied baseline was observed. Terminal was already enabled when Settings was reopened; the grant actor and time were not captured. Root restarted Terminal and observed the strict installed doctor pass. Screen Recording remained denied and was unnecessary for this AX-based trial. Python Local Network discovery and Terminal-to-TextEdit Automation were declined. Document cleanup required the operator. + +Full first-use U2 remains unqualified: the original first fixture timed out, the required grant transition was not captured, and automatic document cleanup did not pass. The receipt's generic U1 limits string must not be read as a full U2 qualification claim. A later qualification needs a separately approved, captured denied-to-granted baseline; this run performed no TCC reset. + +## Reference-backed next packet work + +1. Replace cleanup-only Apple Events with exact-document AX close and freshly observed save-sheet handling. Arc CUA6b353039111c08c2c64c5229083606941e364eaf demonstrates AXDocument/AXCloseButton/AXPress in benchmarks/workflows.py:533. Its substring match is insufficient for Footwork: retain exact normalized document-path and unique-window checks, and confirm disappearance before reporting cleanup. +2. Separate bounded browser-launch readiness from the unchanged identity-resolution deadline; record normal vendor first launch as a prerequisite and use typed failure receipts. Chrome DevTools MCPf08dbe152502d66e75fa07fb2588dc0feb42bc20 separates abandoned launch attempts and owned-browser cleanup in src/BrowserManager.ts:132 and:438. Do not extend identity authority merely because launch is slow. +3. Test disabling MediaRouter and DialMediaRouteProvider in the owned fixture to reduce unnecessary local discovery. Browser-usec75e8476e26d18b7617643bc2ae082fae8eae431 disables both in browser_use/browser/profile.py:58 and:70. Attribution to child Chrome discovery is still a hypothesis; this continuation does not establish it or qualify changed flags. + +These belong in a new development packet and tests, not changes to the frozen v3 measurement. Claude agreed with this scope in1791753660836044000 and1791754065071525000. diff --git a/jevdual/results/u2-independent-onboarding-20261011-v2-dev/summary.json b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/summary.json new file mode 100644 index 0000000..f8b89ac --- /dev/null +++ b/jevdual/results/u2-independent-onboarding-20261011-v2-dev/summary.json @@ -0,0 +1,39 @@ +{ + "status": "reviewed_post_grant_development_pass", + "full_first_use_qualified": false, + "recorded_at": "2026-10-11T17:28:00-04:00", + "source_commit": "33e1afb06710e2d2a57a0f7d1aea7ea0e19a878d", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7", + "config_exit": 0, + "native_exit": 0, + "operation_count": 1, + "same_token_restart_same_operation": true, + "native_oracle_passed": true, + "installed_worker_observed": true, + "structured_report_accepted": true, + "disk_persistence": "not_checked", + "cleanup": { + "owned_processes_absent": true, + "fixture_loopback_closed": true, + "document_close": "operator via native CUA", + "fixture_automatic_document_cleanup": "unconfirmed", + "automation_grant": "declined" + }, + "permissions": { + "initial_denial_observed": true, + "grant_actor_and_time": "not_observed", + "accessibility_after_restart": "granted", + "screen_recording": "not_granted" + }, + "archive": { + "path": "output/u2-export-v2/evidence-v2.zip", + "bytes": 18394, + "members": 28, + "sha256": "b7e6672e59e8aa5aaaab5c8722f62e577a99236cb5e2b29af67d28c18ddf6add", + "receiver_closed": true + }, + "claude_review": { + "message": "1791754065071525000", + "verdict": "valid post-grant development pass; no new blockers; full first-use remains unqualified" + } +} From fd12a269ff7724fb3ca5edef30e578fbd895eca6 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:30:41 -0400 Subject: [PATCH 128/216] Retain reproduced network health and pause-resume failures before qualification --- jevdual/docs/notebook/2026-10-11-network-workbench.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-network-workbench.md b/jevdual/docs/notebook/2026-10-11-network-workbench.md index 5e66927..e14b601 100644 --- a/jevdual/docs/notebook/2026-10-11-network-workbench.md +++ b/jevdual/docs/notebook/2026-10-11-network-workbench.md @@ -33,3 +33,9 @@ Test: delay the real HTTP status response while Resume waits, issue Pause, then Predicts: the original Resume returns to running despite the newer Pause; the repaired path stays paused with no command POST and does not clear uncertainty or disconnect state. Against: the original path already preserves Pause, the repaired path still resumes or sends effects, or the test does not exercise the unlocked readback gap. Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py + +## SIM10-U2 · update · 2026-10-11 17:30 +Observed: the original idle connection path missed a stopped real TCP body endpoint. A delayed real HTTP status read also reproduced Resume overwriting a newer Pause. Both failing logs are retained; neither fixture sent model or physical commands. Nine diagnostic-link checks and six HTTP boundary checks now pass. +Inferred: the two control/status predictions are supported at reproduction, but the repairs still require their resolving checks. Host admission is explicitly defined at the durable stage write so Pause does not promise interruption of an in-flight request. +Next: finish bounded read-only health and epoch-checked Resume, check stage recovery and control boundaries, then freeze the browser/model trial. +Refs: tools/physical-workcell/output/sim10-idle-health-before-fix.log; tools/physical-workcell/output/sim10-resume-before-fix.log; tools/physical-workcell/output/sim10-link-tests-v2/unittest.log; tools/physical-workcell/output/sim10-http-tests-v1/unittest.log From cfff5993e660bf49eb4bc3d540235a481b712fd7 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:32:35 -0400 Subject: [PATCH 129/216] Predict stale health response across transport admission before regression check --- jevdual/docs/notebook/2026-10-11-network-workbench.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-11-network-workbench.md b/jevdual/docs/notebook/2026-10-11-network-workbench.md index e14b601..e28f7cb 100644 --- a/jevdual/docs/notebook/2026-10-11-network-workbench.md +++ b/jevdual/docs/notebook/2026-10-11-network-workbench.md @@ -39,3 +39,10 @@ Observed: the original idle connection path missed a stopped real TCP body endpo Inferred: the two control/status predictions are supported at reproduction, but the repairs still require their resolving checks. Host admission is explicitly defined at the durable stage write so Pause does not promise interruption of an in-flight request. Next: finish bounded read-only health and epoch-checked Resume, check stage recovery and control boundaries, then freeze the browser/model trial. Refs: tools/physical-workcell/output/sim10-idle-health-before-fix.log; tools/physical-workcell/output/sim10-resume-before-fix.log; tools/physical-workcell/output/sim10-link-tests-v2/unittest.log; tools/physical-workcell/output/sim10-http-tests-v1/unittest.log + +## SIM10-POLL · prediction · 2026-10-11 17:32 +Hypothesis: a background health response that overlaps a newly admitted RPC can mistake the body lock wait for an outage; binding the health result to an unchanged transport epoch prevents this stale status from cancelling a healthy action. +Test: overlap a delayed real TCP health read with a completed network command, then deliver the old failed health response; compare queue/connection status and command count before and after the epoch guard. +Predicts: the original stale response can pause the healthy host; the guarded response is discarded, normal command proof remains applied once, and the next idle read establishes current health. +Against: no false pause occurs before repair, the guarded result still changes current health, or discarding it loses an actual idle outage or command receipt. +Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py From d731ac8ea03f326edef18ea9c1b9cb2027421871 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:37:26 -0400 Subject: [PATCH 130/216] Connect browser workbench to guarded persistent body with explicit network recovery --- .../notebook/2026-10-11-network-workbench.md | 30 + tools/physical-workcell/NETWORK_WORKBENCH.md | 42 ++ .../network_bench_operator.html | 233 ++++++ .../network_bench_operator.py | 160 +++++ .../network_operator_runtime.py | 672 ++++++++++++++++++ .../qualify_network_workbench.py | 140 ++++ .../record_network_workbench.py | 53 ++ .../score_network_workbench.py | 199 ++++++ .../test_network_operator.py | 329 +++++++++ .../test_network_operator_http.py | 137 ++++ .../physical-workcell/test_workbench_link.py | 223 ++++++ tools/physical-workcell/workbench_link.py | 302 ++++++++ 12 files changed, 2520 insertions(+) create mode 100644 tools/physical-workcell/NETWORK_WORKBENCH.md create mode 100644 tools/physical-workcell/network_bench_operator.html create mode 100644 tools/physical-workcell/network_bench_operator.py create mode 100644 tools/physical-workcell/network_operator_runtime.py create mode 100644 tools/physical-workcell/qualify_network_workbench.py create mode 100644 tools/physical-workcell/record_network_workbench.py create mode 100644 tools/physical-workcell/score_network_workbench.py create mode 100644 tools/physical-workcell/test_network_operator.py create mode 100644 tools/physical-workcell/test_network_operator_http.py create mode 100644 tools/physical-workcell/test_workbench_link.py create mode 100644 tools/physical-workcell/workbench_link.py diff --git a/jevdual/docs/notebook/2026-10-11-network-workbench.md b/jevdual/docs/notebook/2026-10-11-network-workbench.md index e28f7cb..4e11918 100644 --- a/jevdual/docs/notebook/2026-10-11-network-workbench.md +++ b/jevdual/docs/notebook/2026-10-11-network-workbench.md @@ -46,3 +46,33 @@ Test: overlap a delayed real TCP health read with a completed network command, t Predicts: the original stale response can pause the healthy host; the guarded response is discarded, normal command proof remains applied once, and the next idle read establishes current health. Against: no false pause occurs before repair, the guarded result still changes current health, or discarding it loses an actual idle outage or command receipt. Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py + +## SIM10-U3 · update · 2026-10-11 17:36 +Resolves: SIM10-HEALTH = held +Observed: the final fourteen-case runtime suite passed on real sockets. Idle outage and delayed Resume reproduce their original failures and pass after bounded read-only health and epoch checks. A known native dispatch advanced generation to one before an older health response falsely paused the original host; transport-epoch binding now discards that response. Pause before host admission sends nothing; after admission the exact command settles once without a successor. Two deterministic cycles with disturbance and all four uncertain RPC stages pass. Earlier broad-suite errors were retained fixture mistakes in the local reader and duplicate host initialization, corrected without relaxing product checks. +Inferred: the host control/recovery boundaries hold on these mechanical cases. This does not establish actual-model completion through the browser. +Next: finish unchanged-core/link/HTTP regression, commit measured source, and drive the frozen actual Codex browser trial. +Refs: tools/physical-workcell/output/sim10-network-runtime-final.log; tools/physical-workcell/output/sim10-network-runtime-tests-first.log; tools/physical-workcell/output/sim10-network-runtime-tests-second.log; tools/physical-workcell/output/sim10-stale-health-before-fix.log; tools/physical-workcell/output/sim10-health-resume-after-fix.log + +## SIM10-U4 · update · 2026-10-11 17:37 +Resolves: SIM10-RESUME = held +Observed: The delayed actual HTTP status collision now refuses stale Resume and leaves the newer Pause intact, with zero command sends. +Next: frozen source and actual browser/model qualification. +Refs: tools/physical-workcell/output/sim10-resume-before-fix.log; output/sim10-health-resume-after-fix.log + +## SIM10-U5 · update · 2026-10-11 17:37 +Resolves: SIM10-POLL = held +Observed: The older failed health response no longer pauses a host after a known native dispatch; the transport epoch binds readback to the observed interval. +Next: frozen source and actual browser/model qualification. +Refs: tools/physical-workcell/output/sim10-stale-health-before-fix.log; output/sim10-network-runtime-final.log + +## SIM10-U6 · update · 2026-10-11 17:37 +Resolves: SIM10-ADMISSION = held +Observed: Both pause boundaries pass: no command before durable admission, and only the admitted command settles after Pause with no successor. Cached state remains responsive. +Next: frozen source and actual browser/model qualification. +Refs: tools/physical-workcell/output/sim10-network-runtime-final.log + +## SIM10-U7 · update · 2026-10-11 17:37 +Observed: the final eighty unchanged-core, adapter, link and HTTP checks passed; combined with the fourteen runtime checks this is 94 passing checks. Ruff, JavaScript syntax, notebook checks and CLI preflight pass. No existing body/core/local-product source changed. One regression launch used an incorrect relative interpreter path and exited before tests; the corrected launch is retained separately. +Next: commit measured source and run the first actual browser/model trial without source edits. +Refs: tools/physical-workcell/output/sim10-core-link-http-regression.log; tools/physical-workcell/output/sim10-core-link-http-regression-v2.log; tools/physical-workcell/output/sim10-network-runtime-final.log diff --git a/tools/physical-workcell/NETWORK_WORKBENCH.md b/tools/physical-workcell/NETWORK_WORKBENCH.md new file mode 100644 index 0000000..5285093 --- /dev/null +++ b/tools/physical-workcell/NETWORK_WORKBENCH.md @@ -0,0 +1,42 @@ +# Browser workbench with a persistent body + +The browser queues camera-guided inspection jobs against a separate simulated body over TCP. The body retains its identity, motion state, measurements and contact resets. The browser host keeps its queue and model history separately. Each job places the part, records its visible footprint with the computer-side measurement worker, then returns the part and pusher home. + +Start a new body from the repository root: + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/body_network.py \ + --root tools/physical-workcell/output/my-workbench-body --initialize --diagnostic --port 64371 +``` + +In a second terminal, initialize and serve the browser host: + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/network_bench_operator.py init \ + --root tools/physical-workcell/output/my-network-workbench --body-origin http://127.0.0.1:64371 +tools/physical-workcell/.venv/bin/python tools/physical-workcell/network_bench_operator.py serve \ + --root tools/physical-workcell/output/my-network-workbench --port 64372 --backend codex +``` + +Open the reported browser URL. Add an inspection, choose Near or Far, and add another job to the queue. The existing authenticated Codex CLI plans from exact camera images downloaded over TCP. New jobs can trigger model requests; Pause cancels planning and prevents the next command admission. A command already recorded as in flight may reach the body and finish after Pause. The body still applies its local bounds. + +Expand **Test the simulated connection** to lose, delay or duplicate the next dispatch reply. These controls exercise the network boundary around the same local guards. A duplicated command keeps its identity and returns its retained result. Losing a reply creates an uncertain outcome and blocks further effects. + +Use **Disconnect** to close the diagnostic link. The last image and completed results remain visible as retained evidence. **Reconnect** restores transport and leaves the agent paused. For an uncertain command, choose **Check receipt**. This reads the exact original result without resending its action. If the receipt proves what happened, choose **Resume** to obtain a fresh observation and continue. Missing proof stays blocked. + +Restart the body by omitting `--initialize`; restart the host with the same root and exact port. Both identities persist. Body restart revokes leases. Host restart pauses the queue, keeps uncertain commands, and never replays them. Reloading the browser does not restart planning or reset the bench. + +The link, client, queue, model inputs and receipts live beneath the host root. Native state and measurement SQLite remain beneath the separate body root. An independent post-trial scorer reads the native records after the trial processes stop; they are not model inputs. The previous local workbench uses different source files and roots. + +Qualification uses committed source: + +```sh +tools/physical-workcell/.venv/bin/python tools/physical-workcell/qualify_network_workbench.py \ + --root tools/physical-workcell/output/my-browser-qualification --source-commit COMMITTED_SOURCE_SHA +``` + +The harness prints the browser URL and owns both trial processes. Drive the recovery sequence through the UI; retain browser observations with `record_network_workbench.py`. Write `stop-request.json` in the trial root when the queue is finished. Then run `score_network_workbench.py --root` against that root. The scorer checks native placement, SQLite, contact reset, model images and receipts, transport send counts, and the browser transition ledger. + +This version binds to loopback and controls a simulation. The queue and model/command journals have finite budgets. It does not provide authenticated control across machines or qualify physical hardware. + +References: [integration contract](NETWORK_WORKBENCH_CONTRACT.md), [body adapter](NETWORK_BODY.md), [preregistered experiment](../../jevdual/docs/experiments/SIM10-network-workbench.md). diff --git a/tools/physical-workcell/network_bench_operator.html b/tools/physical-workcell/network_bench_operator.html new file mode 100644 index 0000000..fbc88d4 --- /dev/null +++ b/tools/physical-workcell/network_bench_operator.html @@ -0,0 +1,233 @@ + + + + + +Footwork · Network bench + + + +

+
FootworkBench
Simulation
+
+ +
+

Bench

Your agent’s physical workspace.

Connecting
+ +
Connecting to body

Checking the persistent workcell connection.

Test the simulated connection

These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.

No reply fault armed.

OVERHEAD CAMERAWaiting for an observation
The bench is connectingCamera observations will appear here.
+
Agent

Connecting to the workcell.

+
1Prepare
2Measure
3Reset
4Ready
+

Measurement

Awaiting job

The part’s visible footprint will be measured after its placement is verified.

Activity

This session

Actions and their outcomes will appear here as the agent works.

    +
    Session details
    Connecting…
    Model usage will appear after the first request.
    +
    +
    +
    +

    New inspection

    Place the part, measure its footprint, then reset the bench.

    Measurement area

    Move the block unexpectedly before measurement. The agent must observe it again and correct its placement.

    + + + diff --git a/tools/physical-workcell/network_bench_operator.py b/tools/physical-workcell/network_bench_operator.py new file mode 100644 index 0000000..87eb191 --- /dev/null +++ b/tools/physical-workcell/network_bench_operator.py @@ -0,0 +1,160 @@ +"""Loopback browser workbench for a separate persistent body service.""" +import argparse +import json +import signal +import threading +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from pathlib import Path +from urllib.parse import urlsplit + +import network_operator_runtime as runtime +import order_protocol as protocol + +BASE = Path(__file__).resolve().parent + + +class Server(ThreadingHTTPServer): + daemon_threads = True + allow_reuse_address = True + + def __init__(self, address, operator): + super().__init__(address, Handler) + self.operator = operator + self.origin = f"http://127.0.0.1:{self.server_address[1]}" + self.host = f"127.0.0.1:{self.server_address[1]}" + + +class Handler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + + def log_message(self, *_): + pass + + def reply(self, code, body, content_type="application/json"): + if isinstance(body, dict): + body = json.dumps(body, allow_nan=False).encode() + self.send_response(code) + self.send_header("Content-Type", content_type) + self.send_header("Content-Length", str(len(body))) + self.send_header("Cache-Control", "no-store") + self.send_header("X-Content-Type-Options", "nosniff") + self.send_header("Referrer-Policy", "no-referrer") + self.send_header("Connection", "close") + self.end_headers() + self.wfile.write(body) + self.close_connection = True + + def exact_header(self, name, value): + return self.headers.get_all(name) == [value] + + def do_GET(self): + try: + if not self.exact_header("Host", self.server.host): + raise protocol.Refusal("exact loopback Host is required") + parsed = urlsplit(self.path) + if parsed.path == "/" and not parsed.query: + self.server.operator._identity() + self.reply(200, protocol.read_bytes(BASE / "network_bench_operator.html"), "text/html; charset=utf-8") + elif parsed.path == "/api/state" and not parsed.query: + self.reply(200, self.server.operator.state()) + elif parsed.path == "/api/frame": + self.reply(200, self.server.operator.frame(self.path), "image/png") + else: + self.reply(404, {"error": "Unknown operator route"}) + except (protocol.Refusal, OSError, ValueError) as exc: + self.reply(409, {"error": str(exc)}) + + def do_POST(self): + try: + app_id = self.server.operator.m["app_id"] + if (not self.exact_header("Host", self.server.host) or + not self.exact_header("Origin", self.server.origin) or + not self.exact_header("X-Footwork-App-ID", app_id)): + raise protocol.Refusal("exact loopback origin and application identity are required before mutation") + lengths = self.headers.get_all("Content-Length") + if (lengths is None or len(lengths) != 1 or not lengths[0].isascii() or + not lengths[0].isdigit() or not 1 <= int(lengths[0]) <= 4096 or + self.headers.get_all("Transfer-Encoding") is not None or + not self.exact_header("Content-Type", "application/json")): + raise protocol.Refusal("request requires one bounded JSON body with an exact content length") + self.connection.settimeout(5) + content = self.rfile.read(int(lengths[0])) + if len(content) != int(lengths[0]): + raise protocol.Refusal("JSON body is incomplete") + request = protocol.decode(content) + if self.path == "/api/jobs": + result = self.server.operator.enqueue(request) + elif self.path in ("/api/pause", "/api/resume", "/api/disconnect", + "/api/reconnect", "/api/reconcile"): + protocol.fields(request, (), "operator control") + result = getattr(self.server.operator, self.path.rsplit("/", 1)[1])() + elif self.path == "/api/fault": + protocol.fields(request, ("mode", "delay_s"), "diagnostic link fault") + if request["mode"] not in ("drop_after", "delay_after", "duplicate"): + raise protocol.Refusal("unsupported diagnostic link fault") + if not 0 <= protocol.finite(request["delay_s"]) <= 2: + raise protocol.Refusal("diagnostic delay must be between zero and two seconds") + result = self.server.operator.fault(request) + else: + raise protocol.Refusal("unknown operator mutation route") + self.reply(200, result) + except (protocol.Refusal, OSError, TypeError, ValueError) as exc: + self.reply(409, {"error": str(exc)}) + + +def serve(root, port, policy): + root = protocol.directory(root) + operator = runtime.Operator(root, policy) + server = None + try: + server = Server(("127.0.0.1", port), operator) + readiness = root / "readiness.json" + if readiness.exists(): + previous = protocol.decode(protocol.read_bytes(readiness)) + if previous["app_id"] != operator.m["app_id"] or previous["origin"] != server.origin: + raise protocol.Refusal("retained application origin changed; restart on its exact port") + protocol.persist(readiness, {"app_id": operator.m["app_id"], "origin": server.origin, + "port": server.server_address[1], "simulation": True}) + print(json.dumps(protocol.decode(protocol.read_bytes(readiness))), flush=True) + def stop(*_): + operator.cancel.set() + threading.Thread(target=server.shutdown, daemon=True).start() + signal.signal(signal.SIGTERM, stop) + signal.signal(signal.SIGINT, stop) + server.serve_forever(poll_interval=.2) + finally: + if server: + server.server_close() + operator.close() + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + commands = parser.add_subparsers(dest="command", required=True) + init = commands.add_parser("init") + init.add_argument("--root", type=Path, required=True) + init.add_argument("--body-origin", required=True) + init.add_argument("--link-port", type=int, default=0) + run = commands.add_parser("serve") + run.add_argument("--root", type=Path, required=True) + run.add_argument("--port", type=int, default=0) + run.add_argument("--backend", choices=("codex",), default="codex") + args = parser.parse_args() + try: + if args.command == "init": + if not 0 <= args.link_port <= 65535: + raise protocol.Refusal("link port must be in the TCP range") + print(json.dumps({"app_id": runtime.initialize(args.root, args.body_origin, args.link_port), "simulation": True})) + else: + if not 0 <= args.port <= 65535: + raise protocol.Refusal("port must be in the TCP range") + from codex_policy import decide + serve(args.root, args.port, decide) + return 0 + except (protocol.Refusal, OSError, ValueError) as exc: + print(json.dumps({"error": str(exc)})) + return 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/physical-workcell/network_operator_runtime.py b/tools/physical-workcell/network_operator_runtime.py new file mode 100644 index 0000000..5ae9c23 --- /dev/null +++ b/tools/physical-workcell/network_operator_runtime.py @@ -0,0 +1,672 @@ +"""Network-only browser host with durable stage application and explicit recovery.""" +import copy +import http.client +import threading +import time +import uuid +from pathlib import Path + +import body_client +import order_protocol as protocol +from workbench_link import WorkbenchLink + +BASE = Path(__file__).resolve().parent +MAX_CALLS, MAX_TOTAL_CALLS, MAX_COMMANDS = 32, 96, 240 +ZONES = {"A": {"x_min": .035, "x_max": .105, "y_min": -.025, "y_max": .025}, + "B": {"x_min": .045, "x_max": .115, "y_min": -.025, "y_max": .025}} + + +def sources(): + return {name: protocol.sha(protocol.read_bytes(BASE / name)) for name in ( + "network_operator_runtime.py", "network_bench_operator.py", "network_bench_operator.html", + "workbench_link.py", "body_client.py", "order_protocol.py", "codex_policy.py", "codex-policy.md", "codex-action.schema.json")} + + +def initialize(root, body_origin, link_port=0): + body_client.endpoint(body_origin) + root = protocol.directory(root, create=True) + with protocol.locked(root): + if any(p.name != "app.lock" for p in root.iterdir()): + raise protocol.Refusal("network workbench needs a new empty owned directory") + link = WorkbenchLink(body_origin, root / "link", port=link_port).start() + client = None + try: + client = body_client.BodyClient(root / "client", link.origin) + pinned = client._load()["identity"] + (root / "calls").mkdir(mode=0o700) + (root / "events").mkdir(mode=0o700) + manifest = {"version": 1, "app_id": uuid.uuid4().hex, "sources": sources(), + "body_origin": body_origin, "link_origin": link.origin, "link_port": body_client.endpoint(link.origin)[1], + "body_identity": pinned, "opened": False, "runner_status": "running", "active_job_id": None, + "jobs": [], "stage": None, "applied_commands": [], "frame": None, "activity": [], "sequence": 0, + "usage": {"calls": 0, "input_tokens": 0, "output_tokens": 0, "reported_calls": 0}, + "connection": {"state": "connected", "body_id": pinned["body_id"], "adapter_id": pinned["adapter_id"], + "epoch": pinned["epoch"], "reason": "Pinned network body", "fault": None}, + "recovery": {"state": "none", "command_id": None, "operation": None, "reason": "No uncertain command"}, + "reason": "Ready for a network inspection"} + protocol.create_file(root / "identity.json", protocol.encoded( + {"app_id": manifest["app_id"], "sources": manifest["sources"], "body_identity": pinned})) + protocol.persist(root / "operator.json", manifest) + return manifest["app_id"] + finally: + if client: + client.close() + link.close() + + +class Operator: + def __init__(self, root, policy, start_worker=True): + self.root = protocol.directory(root) + self.lock = threading.RLock() + self.wake, self.cancel = threading.Event(), threading.Event() + self.closing = self.in_model = self.transport_pending = False + self.control_epoch = 0 + self.transport_epoch = 0 + self.saved_digest = None + self.health_stop = threading.Event() + self.health_serial = threading.Lock() + self.body_ready = False + self.policy = policy + self.owner = protocol.locked(self.root) + self.owner.__enter__() + self.link = self.client = None + try: + self.m = body_client.read_journal(self.root / "operator.json") + self._identity() + self.link = WorkbenchLink(self.m["body_origin"], self.root / "link", port=self.m["link_port"]).start() + if self.link.origin != self.m["link_origin"]: + raise protocol.Refusal("retained network link origin changed") + self.client = body_client.BodyClient(self.root / "client", self.link.origin, timeout=15) + self._client_pin() + if self.m["opened"]: + self.m.update(runner_status="paused", reason="Restarted; inspect the retained stage before explicit Resume") + self.m["opened"] = True + if self.m["stage"]: + self._associate() + self._uncertain("Restarted with a retained command stage; check its exact receipt") + elif self._journal()["pending_command_ids"]: + self._halt("Client has an unknown command without a host stage", blocked=True) + if not self.link.state()["connected"]: + self.m["connection"]["state"] = "disconnected" + self.m["runner_status"] = "paused" + self._save() + self._refresh_health() + self.health_worker = threading.Thread(target=self._health_loop, daemon=True, name="network-health") + self.health_worker.start() + self.worker = threading.Thread(target=self._loop, daemon=True, name="network-workbench") + if start_worker: + self.worker.start() + self.wake.set() + except Exception: + if self.client: + self.client.close() + if self.link: + self.link.close() + self.owner.__exit__(None, None, None) + raise + + def _identity(self): + if self.saved_digest and protocol.sha(protocol.read_bytes(self.root / "operator.json", maximum=body_client.MAX_CLIENT_JOURNAL)) != self.saved_digest: + raise protocol.Refusal("retained host state changed outside its owner") + identity = protocol.decode(protocol.read_bytes(self.root / "identity.json")) + if (type(self.m.get("version")) is not int or self.m["version"] != 1 or self.m["sources"] != sources() or + identity != {k: self.m[k] for k in ("app_id", "sources", "body_identity")}): + raise protocol.Refusal("workbench source or identity changed") + if len(self.m["jobs"]) > 6 or len(self.m["applied_commands"]) > 256: + raise protocol.Refusal("workbench journal capacity exceeded") + + def _journal(self): + return body_client.read_journal(self.root / "client" / "client.json") + + def _client_pin(self): + current = self.client._load()["identity"] + if any(current[k] != self.m["body_identity"][k] for k in body_client.IDENTITY_KEYS - {"epoch"}): + raise protocol.Refusal("body or adapter identity changed") + return current + + def _save(self): + if len(protocol.encoded(self.m)) > body_client.MAX_CLIENT_JOURNAL: + raise protocol.Refusal("local workbench journal exceeds its 128 KiB bound") + protocol.persist(self.root / "operator.json", self.m) + self.saved_digest = protocol.sha(protocol.encoded(self.m)) + + def _event(self, kind, intent="", outcome=""): + self.m["sequence"] += 1 + value = {"seq": self.m["sequence"], "time": time.time(), "kind": kind, + "intent": str(intent)[:1000], "outcome": str(outcome)[:1000]} + protocol.create_file(self.root / "events" / f"{value['seq']:06d}.json", protocol.encoded(value)) + self.m["activity"] = (self.m["activity"] + [value])[-24:] + self._save() + + def _health_loop(self): + while not self.health_stop.wait(1): + with self.lock: + skip = self.closing or self.transport_pending or not self.link.state()["connected"] + if not skip: + self._refresh_health() + + def _refresh_health(self): + with self.health_serial: + with self.lock: + if self.closing or self.transport_pending or not self.link.state()["connected"]: + return False + control_epoch = self.control_epoch + transport_epoch = self.transport_epoch + pinned = dict(self.m["body_identity"]) + remote_identity = pinned + try: + status, content = body_client.http_call(self.link.origin, "GET", "/identity", timeout=.8) + if status != 200: + raise protocol.Refusal("pinned body identity could not be verified") + remote_identity = body_client.identity(protocol.decode(content)) + if any(remote_identity[k] != pinned[k] for k in body_client.IDENTITY_KEYS - {"epoch"}): + raise protocol.Refusal("pinned body or adapter identity changed") + status, content = body_client.http_call(self.link.origin, "GET", "/state", body_client.pinned_headers(pinned), timeout=.8) + remote = protocol.decode(content) + if status != 200 or remote["identity"] != remote_identity: + raise protocol.Refusal("pinned body state could not be verified") + ready = remote.get("state") == "ready" + error = None if ready else "Independent body has unresolved effects" + connection = "connected" + blocked = not ready + except protocol.Refusal as exc: + ready, error, connection, blocked = False, str(exc), "unavailable", True + except (OSError, http.client.HTTPException, ValueError, KeyError) as exc: + ready, error, connection, blocked = False, str(exc), "unavailable", False + remote_identity = pinned + with self.lock: + if (self.closing or self.transport_pending or control_epoch != self.control_epoch or + transport_epoch != self.transport_epoch or not self.link.state()["connected"]): + return False + old = self.m["connection"]["state"] + self.body_ready = ready + self.m["connection"].update(state=connection, reason=error or "Body identity verified by read-only TCP health", epoch=remote_identity["epoch"]) + if not ready and (old != connection or self.m["runner_status"] == "running"): + self.cancel.set() + self.control_epoch += 1 + self._halt(error, blocked=blocked) + self._save() + return ready + + def _retain(self, path, value): + content = protocol.encoded(value) + if path.exists(): + if protocol.read_bytes(path) != content: + raise protocol.Refusal("retained host evidence differs from its exact result") + else: + protocol.create_file(path, content) + + def _job(self, job_id=None): + return next((j for j in self.m["jobs"] if j["id"] == (job_id or self.m["active_job_id"])), None) + + def _halt(self, reason, blocked=False): + self.m.update(runner_status="blocked" if blocked else "paused", reason=str(reason)) + job = self._job() + if job and job["status"] != "completed": + job.update(status="unknown" if blocked else "paused", error=str(reason)) + self._event("halt", outcome=reason) + + def _uncertain(self, reason): + stage = self.m["stage"] + self.m["recovery"] = {"state": "uncertain" if stage and stage.get("command_id") else "blocked", + "command_id": stage.get("command_id") if stage else None, + "operation": stage["operation"] if stage else None, "reason": str(reason)} + self.control_epoch += 1 + self._halt(reason, blocked=True) + + def _cache(self, challenge): + packet = challenge["observation"] + path = Path(challenge["image_path"]) + if (path.parent != self.root / "client" / "images" or packet["bench_id"] != self.m["body_identity"]["body_id"] or + protocol.sha(protocol.read_bytes(path, maximum=body_client.MAX_IMAGE)) != packet["image_sha256"]): + raise protocol.Refusal("camera frame is not an exact downloaded body image") + self.m["frame"] = {"path": str(path), "sha256": packet["image_sha256"], "generation": packet["generation"]} + + def state(self): + with self.lock: + self._identity() + frame = self.m["frame"] + jobs = [{("job_id" if k == "id" else k): v for k, v in j.items() if k not in {"history", "disturbed"}} + for j in self.m["jobs"]] + connection = dict(self.m["connection"]) + connection["fault"] = self.link.state()["fault"] + stage = self.m["stage"] + return copy.deepcopy({"app_id": self.m["app_id"], "simulation": True, "runner_status": self.m["runner_status"], + "jobs": jobs, "active_job_id": self.m["active_job_id"], "model_request_pending": self.in_model, + "transport_pending": self.transport_pending, "pending_operation": stage["operation"] if stage else None, + "activity": self.m["activity"], "usage": {**self.m["usage"], + "token_usage_complete": self.m["usage"]["reported_calls"] == self.m["usage"]["calls"]}, + "readiness": {"ready": self.m["runner_status"] == "running" and connection["state"] == "connected", "reason": self.m["reason"]}, + "current_frame": {"available": frame is not None, "generation": frame["generation"] if frame else None, + "image_url": f"/api/frame?generation={frame['generation']}&sha256={frame['sha256']}" if frame else None}, + "connection": connection, "recovery": self.m["recovery"]}) + + def frame(self, requested_url=None): + with self.lock: + self._identity() + frame = self.m["frame"] + if not frame or Path(frame["path"]).parent != self.root / "client" / "images": + raise protocol.Refusal("no retained downloaded frame") + url = f"/api/frame?generation={frame['generation']}&sha256={frame['sha256']}" + if requested_url is not None and requested_url != url: + raise protocol.Refusal("cached capture identity changed") + content = protocol.read_bytes(Path(frame["path"]), maximum=body_client.MAX_IMAGE) + if protocol.sha(content) != frame["sha256"]: + raise protocol.Refusal("cached downloaded image changed") + return content + + def enqueue(self, request): + protocol.fields(request, ("job_id", "label", "target", "disturbance_test"), "inspection") + protocol.identity(request["job_id"]) + if (not isinstance(request["label"], str) or not 1 <= len(request["label"].strip()) <= 120 or + request["target"] not in ZONES or type(request["disturbance_test"]) is not bool or + request["disturbance_test"] and request["target"] != "B"): + raise protocol.Refusal("inspection needs a label, region A or B, and a bounded recovery test") + with self.lock: + self._identity() + if self.closing or len(self.m["jobs"]) >= 6 or self._job(request["job_id"]): + raise protocol.Refusal("inspection identity reused or queue capacity exhausted") + self.m["jobs"].append({"id": request["job_id"], "label": request["label"].strip(), "target": request["target"], + "disturbance_test": request["disturbance_test"], "disturbed": False, "status": "queued", "phase": None, + "call_count": 0, "last_intent": "", "measurement": None, "reset": None, "error": None, "history": []}) + self._event("queued", request["label"], request["job_id"]) + self.wake.set() + return self.state() + + def pause(self): + self.cancel.set() + with self.lock: + self.control_epoch += 1 + if self.m["runner_status"] != "blocked": + self.m["runner_status"] = "pausing" if self.in_model or self.transport_pending else "paused" + self.m["reason"] = "Pause requested; a command already admitted by this host may finish within body bounds" + self._event("pause", outcome=self.m["reason"]) + return self.state() + + def disconnect(self): + self.cancel.set() + self.link.set_connected(False) + with self.lock: + self.control_epoch += 1 + self.m["connection"].update(state="disconnected", reason="Diagnostic link disconnected; cached observations are retained") + if self.m["runner_status"] != "blocked": + self.m["runner_status"] = "paused" + self._event("disconnect", outcome="Transport only; no body reset or replay") + return self.state() + + def reconnect(self): + with self.lock: + if self.closing: + raise protocol.Refusal("workbench is stopping") + self._identity() + self.control_epoch += 1 + self.cancel.set() + self.link.set_connected(True) + self.m["connection"].update(state="unavailable", reason="Checking the reconnected body identity") + if self.m["runner_status"] != "blocked": + self.m["runner_status"] = "paused" + self._event("reconnect", outcome="No command sent or replayed") + self._refresh_health() + return self.state() + + def fault(self, request): + protocol.fields(request, ("mode", "delay_s"), "diagnostic fault") + delay = protocol.finite(request["delay_s"]) + if request["mode"] not in {"drop_after", "delay_after", "duplicate"} or not 0 <= delay <= 2: + raise protocol.Refusal("unsupported bounded transport fault") + with self.lock: + self._identity() + self.link.arm(request["mode"], operation="dispatch", delay_s=delay) + self._event("fault_armed", outcome=request["mode"]) + return self.state() + + def _associate(self): + stage = self.m["stage"] + if not stage: + return None + journal = self.client._load() + new = set(journal["commands"]) - set(stage["before_commands"]) + if len(new) != 1: + return None + token = next(iter(new)) + request, _ = self.client._request(journal, token) + if (request["operation"] != stage["operation"] or request["arguments"] != stage["arguments"] or + stage.get("command_id") not in (None, token)): + raise protocol.Refusal("pending host stage disagrees with its unique client command") + stage["command_id"] = token + self._save() + return token + + def _local_envelope(self, token): + journal = self.client._load() + record = journal["commands"][token] + if "response_sha256" not in record: + return None + request, _ = self.client._request(journal, token) + content = protocol.read_bytes(self.root / "client" / "responses" / (token + "-" + record["response_sha256"] + ".json")) + return self.client._envelope(journal, request, content) + + def _rpc(self, operation, arguments, context): + with self.lock: + self._identity() + if (self.closing or self.cancel.is_set() or self.m["runner_status"] != "running" or + self.m["connection"]["state"] != "connected" or not self.body_ready or self.m["stage"] or + context.get("decision_epoch", self.control_epoch) != self.control_epoch): + return None + if len(self.client._load()["commands"]) >= MAX_COMMANDS: + self._halt("Conservative network-command budget exhausted") + return None + epoch = self.control_epoch + self.transport_pending = True + self.transport_epoch += 1 + try: + self.client.acquire(30) + with self.lock: + if epoch != self.control_epoch or self.cancel.is_set() or self.closing: + return None + journal = self.client._load() + self.m["connection"]["epoch"] = journal["identity"]["epoch"] + self.m["stage"] = {"operation": operation, "arguments": arguments, "context": context, + "before_commands": list(journal["commands"]), "command_id": None, "control_epoch": epoch} + self._event("rpc_intent", outcome=operation) + if operation == "start_job": + result = self.client.start_job(arguments["job_id"], arguments["target_zone"]) + else: + result = getattr(self.client, operation)(**arguments) + with self.lock: + token = self._associate() + if token is None: + raise protocol.Refusal("RPC result has no uniquely indexed client command") + envelope = self._local_envelope(token) + self._apply(envelope, result) + return result + except body_client.Uncertain as exc: + with self.lock: + self._associate() + self._uncertain(str(exc)) + return None + except Exception as exc: # noqa: BLE001 - preserve possibly accepted command stages. + with self.lock: + if self.m["stage"]: + token = self._associate() + envelope = self._local_envelope(token) if token else None + if envelope and envelope["state"] in {"refused", "not_accepted"}: + self._apply(envelope, None) + else: + self._uncertain(str(exc)) + else: + self.m["connection"].update(state="unavailable", reason=str(exc)) + self._halt(str(exc)) + return None + finally: + with self.lock: + self.transport_pending = False + if self.m["runner_status"] == "pausing": + self.m["runner_status"] = "paused" + self._save() + + def _public_status(self): + status = self.client.status() + remote = status["server_state"] + if remote.get("state") != "ready": + raise protocol.Refusal("public network body state is unavailable or unresolved") + pinned = self.m["body_identity"] + if any(remote["identity"][k] != pinned[k] for k in body_client.IDENTITY_KEYS - {"epoch"}): + raise protocol.Refusal("network status belongs to another pinned body") + return remote["bench"] + + def _apply(self, envelope, result): + with self.lock: + stage = copy.deepcopy(self.m["stage"]) + if not stage or not envelope or stage["command_id"] != envelope["command_id"]: + raise protocol.Refusal("exact host stage is missing for receipt application") + token = stage["command_id"] + if token in self.m["applied_commands"]: + raise protocol.Refusal("host stage was already applied") + context, operation = stage["context"], stage["operation"] + original_job = self._job(context["job_id"]) + if original_job is None: + raise protocol.Refusal("stage inspection identity is not owned by this queue") + job = copy.deepcopy(original_job) + # The only independent effect readback is the pinned public TCP status. + public = self._public_status() if operation == "dispatch" and context["action"]["action"] in {"measure", "finish_reset"} and envelope["state"] == "completed" else None + with self.lock: + if self.m["stage"] != stage: + raise protocol.Refusal("host stage changed while reading its proof") + if envelope["state"] in {"refused", "not_accepted"}: + if operation == "start_job": + self.m["active_job_id"] = None + job["status"] = "queued" + self.m["applied_commands"].append(token) + self.m["stage"] = None + self._halt(envelope["reason"] or "Pinned command refused") + return + if envelope["state"] != "completed" or not isinstance(result, dict): + raise protocol.Refusal("receipt is not a known completed RPC") + if operation == "start_job": + active = result.get("active_job") + if result.get("bench_id") != self.m["body_identity"]["body_id"] or not active or active["job_id"] != job["id"]: + raise protocol.Refusal("started network job differs from requested inspection") + self.m["active_job_id"] = job["id"] + job.update(status="running", phase=active["phase"]) + elif operation == "observe": + if result["observation"]["job_id"] != job["id"]: + raise protocol.Refusal("image is not bound to the active inspection") + self._cache(result) + job["phase"] = result["observation"]["phase"] + elif operation == "propose": + self._retain(Path(context["call_dir"]) / "proposal.json", result) + elif operation == "disturb": + if result.get("operation_id") != stage["arguments"]["operation_id"] or result.get("bench_id") != self.m["body_identity"]["body_id"]: + raise protocol.Refusal("disturbance receipt identity changed") + job["disturbed"] = True + else: + self._apply_dispatch(job, stage, result, public) + original_job.update(job) + self.m["applied_commands"].append(token) + self.m["stage"] = None + self._event("rpc_applied", job["label"], operation + ": " + token) + + def _apply_dispatch(self, job, stage, result, public): + context = stage["context"] + action = context["action"] + if result.get("proposal_id") != stage["arguments"]["proposal_id"] or result.get("outcome") not in {"executed", "refused"}: + raise protocol.Refusal("dispatch lacks a known exact proposal outcome") + self._retain(Path(context["call_dir"]) / "dispatch.json", result) + job["history"] = (job["history"] + [{"action": action, "outcome": result["outcome"], "reason": result.get("reason", "")}])[-6:] + job["last_intent"] = action["intent"] + if result["outcome"] == "refused": + return + receipt = result.get("receipt", {}) + if receipt.get("bench_id") != self.m["body_identity"]["body_id"]: + raise protocol.Refusal("effect receipt belongs to another body") + name = action["action"] + if name == "begin_reset": + active = receipt.get("active_job") + if not active or active["job_id"] != job["id"] or active["phase"] != "resetting": + raise protocol.Refusal("reset-start proof differs from inspection") + job["phase"] = "resetting" + elif name == "measure": + active = public["active_job"] + saved = receipt.get("measurement_receipt") + if not active or active["job_id"] != job["id"] or saved != active.get("measurement_receipt") or active["phase"] != "measured": + raise protocol.Refusal("public body readback lacks the saved computer measurement") + job.update(phase="measured", measurement=saved["measurement"]) + elif name == "finish_reset": + completed = public["jobs"].get(job["id"]) + if (not completed or public["active_job"] is not None or completed["phase"] != "completed" or + completed["reset_receipt"] != receipt or receipt.get("job_id") != job["id"] or + receipt.get("block_home_verified") is not True or receipt.get("pusher_home_verified") is not True or + type(receipt.get("reset_contact_samples")) is not int or receipt["reset_contact_samples"] <= 0 or + type(receipt.get("reset_native_steps")) is not int or receipt["reset_native_steps"] <= 0 or + completed["measurement_receipt"]["bench_id"] != self.m["body_identity"]["body_id"]): + raise protocol.Refusal("completion lacks public measurement and verified contact-reset proof") + job.update(status="completed", phase="completed", measurement=completed["measurement_receipt"]["measurement"], reset=receipt, error=None) + self.m["active_job_id"] = None + + def reconcile(self): + with self.lock: + self._identity() + if self.transport_pending or self.in_model or self.m["connection"]["state"] != "connected": + raise protocol.Refusal("reconnect and wait for owned work before checking its receipt") + token = self._associate() if self.m["stage"] else None + if not token: + raise protocol.Refusal("no uniquely indexed pending host stage can be reconciled safely") + stage = copy.deepcopy(self.m["stage"]) + self.transport_pending = True + self.transport_epoch += 1 + try: + envelope = self.client.reconcile(token) + context = stage["context"] + if context.get("call_dir"): + self._retain(Path(context["call_dir"]) / "reconciliation.json", envelope) + self._apply(envelope, envelope["result"]) + with self.lock: + self.m.update(runner_status="paused", reason="Exact historical stage recovered; explicit Resume observes fresh evidence") + self.m["recovery"] = {"state": "recovered", "command_id": token, "operation": stage["operation"], "reason": self.m["reason"]} + self._event("reconciled", outcome=token) + except Exception as exc: # Untrusted/missing receipt cannot settle effects. + with self.lock: + self._uncertain(str(exc)) + raise + finally: + with self.lock: + self.transport_pending = False + return self.state() + + def resume(self): + with self.lock: + self._identity() + if self.closing or self.in_model or self.transport_pending or self.m["stage"] or self._journal()["pending_command_ids"]: + raise protocol.Refusal("settle the exact pending stage and wait for owned work before Resume") + if self.m["connection"]["state"] != "connected": + raise protocol.Refusal("reconnect the pinned link before Resume") + self.transport_pending = True + self.transport_epoch += 1 + resume_epoch = self.control_epoch + try: + self._public_status() + with self.lock: + if (resume_epoch != self.control_epoch or self.closing or + self.m["connection"]["state"] != "connected"): + raise protocol.Refusal("control changed while Resume was reading body status") + self.control_epoch += 1 + self.cancel.clear() + self.m.update(runner_status="running", reason="Resumed; next decision receives a fresh TCP image") + self.m["recovery"] = {"state": "none", "command_id": None, "operation": None, "reason": "No pending command"} + self._event("resume") + self.wake.set() + finally: + with self.lock: + self.transport_pending = False + if self.m["runner_status"] == "pausing": + self.m["runner_status"] = "paused" + self._save() + return self.state() + + def close(self): + self.cancel.set() + self.health_stop.set() + with self.lock: + self.control_epoch += 1 + self.closing = True + self.m.update(runner_status="pausing", reason="Waiting for owned model/transport work to exit") + self._save() + self.wake.set() + if self.worker.is_alive(): + self.worker.join(35) + if self.worker.is_alive() or self.transport_pending: + raise protocol.Refusal("owned network worker has not exited; ownership retained") + with self.lock: + self.m.update(runner_status="stopped", reason="Stopped; independent network body retained") + self._save() + self.health_worker.join(4) + if self.health_worker.is_alive(): + raise protocol.Refusal("owned health request has not exited") + self.client.close() + self.link.close() + self.owner.__exit__(None, None, None) + + def _loop(self): + while not self.closing: + self.wake.wait(.5) + self.wake.clear() + while not self.closing: + try: + if not self._step(): + break + except Exception as exc: # noqa: BLE001 - model availability is not task success. + with self.lock: + if not self.closing: + if self.m["stage"]: + self._uncertain(str(exc)) + else: + self._halt(str(exc)) + else: + self._event("shutdown_work_exit", outcome=exc) + break + + def _step(self): + with self.lock: + self._identity() + if self.closing or self.cancel.is_set() or self.m["runner_status"] != "running" or self.m["stage"]: + return False + if self.m["usage"]["calls"] >= MAX_TOTAL_CALLS: + self._halt("Lifetime model-call budget exhausted") + return False + job = self._job() or next((j for j in self.m["jobs"] if j["status"] == "queued"), None) + if not job: + return False + if job["call_count"] >= MAX_CALLS: + self._halt("Inspection model-call budget exhausted") + return False + job_id = job["id"] + if (self.m["active_job_id"] is None and + self._rpc("start_job", {"job_id": job_id, "target_zone": ZONES[job["target"]]}, {"job_id": job_id}) is None): + return False + challenge = self._rpc("observe", {}, {"job_id": job_id}) + if challenge is None: + return False + with self.lock: + if self.cancel.is_set() or self.m["runner_status"] != "running": + return False + job.update(status="running", phase=challenge["observation"]["phase"], error=None) + job["call_count"] += 1 + self.m["usage"]["calls"] += 1 + call_dir = self.root / "calls" / f"{job_id}-{job['call_count']:02d}" + call_dir.mkdir(mode=0o700) + self._retain(call_dir / "reservation.json", {"job_id": job_id, "call": job["call_count"], "challenge": challenge, "history": job["history"][-6:]}) + call_epoch = self.control_epoch + self.in_model = True + self._event("inference", job["label"], str(job["call_count"])) + try: + action, metadata = self.policy(challenge, copy.deepcopy(job["history"][-6:]), call_dir, self.cancel) + self._retain(call_dir / "decision.json", {"action": action, "metadata": metadata}) + finally: + with self.lock: + self.in_model = False + if self.m["runner_status"] == "pausing": + self.m["runner_status"] = "paused" + with self.lock: + usage = metadata.get("usage") or {} + if all(type(usage.get(k)) is int and usage[k] >= 0 for k in ("input_tokens", "output_tokens")): + self.m["usage"]["reported_calls"] += 1 + for key in ("input_tokens", "output_tokens"): + self.m["usage"][key] += usage[key] + if call_epoch != self.control_epoch or self.cancel.is_set() or self.m["runner_status"] != "running": + self._event("decision_withheld", outcome="Control changed before model result dispatch") + return False + protocol.fields(action, ("action", "target_x", "target_y", "intent"), "model action") + job["last_intent"] = action["intent"] + if action["action"] == "stop": + self._halt(action["intent"]) + return False + context = {"job_id": job_id, "call_dir": str(call_dir), "action": action, "decision_epoch": call_epoch} + proposal = self._rpc("propose", {"challenge_id": challenge["challenge_id"], **action}, context) + if proposal is None: + return False + if (job["disturbance_test"] and not job["disturbed"] and action["action"] == "measure" and + self._rpc("disturb", {"operation_id": "disturb-" + uuid.uuid4().hex, "force_x_n": -1.5, "steps": 80}, context) is None): + return False + result = self._rpc("dispatch", {"proposal_id": proposal["proposal_id"]}, context) + return result is not None and self.m["runner_status"] == "running" diff --git a/tools/physical-workcell/qualify_network_workbench.py b/tools/physical-workcell/qualify_network_workbench.py new file mode 100644 index 0000000..257a2c3 --- /dev/null +++ b/tools/physical-workcell/qualify_network_workbench.py @@ -0,0 +1,140 @@ +"""Own a frozen browser/model trial's processes; UI actions come from the browser.""" + +import argparse +import json +import signal +import socket +import subprocess +import threading +import time +import urllib.request +from pathlib import Path + +import order_protocol as protocol +import qualify_network_body + +BASE = Path(__file__).resolve().parent +REPO = BASE.parents[1] +SOURCES = qualify_network_body.SOURCES + [BASE / name for name in ( + "workbench_link.py", "network_operator_runtime.py", "network_bench_operator.py", + "network_bench_operator.html", "qualify_network_workbench.py", "score_network_workbench.py", + "score_network_body.py", "record_network_workbench.py")] + + +def retain(path, value): + protocol.create_file(path, protocol.encoded(value)) + + +def available_port(): + with socket.socket() as sock: + sock.bind(("127.0.0.1", 0)) + return sock.getsockname()[1] + + +def wait_json(origin, path, processes): + deadline = time.monotonic() + 30 + while time.monotonic() < deadline: + try: + with urllib.request.urlopen(origin + path, timeout=1) as response: + return protocol.decode(response.read(protocol.MAX_BYTES + 1)) + except (OSError, ValueError): + if any(process.poll() is not None for process in processes): + raise protocol.Refusal("owned trial process exited during startup") + time.sleep(.1) + raise protocol.Refusal("owned trial endpoint did not become ready") + + +def freeze(root, commit): + if subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=REPO, text=True).strip() != commit: + raise protocol.Refusal("start the trial at its committed source") + files = {} + for path in SOURCES: + name = str(path.relative_to(REPO)) + content = protocol.read_bytes(path) + if subprocess.check_output(["git", "show", f"{commit}:{name}"], cwd=REPO) != content: + raise protocol.Refusal("source is not frozen: " + name) + files[name] = protocol.sha(content) + retain(root / "source-freeze.json", {"commit": commit, "files": files}) + + +def run(root, commit): + root = protocol.directory(root, create=True) + freeze(root, commit) + stopped = threading.Event() + signal.signal(signal.SIGTERM, lambda *_: stopped.set()) + signal.signal(signal.SIGINT, lambda *_: stopped.set()) + processes, logs = [], [] + ledger = {"source_commit": commit, "planner": "actual_codex_cli_images_over_TCP", + "simulation": True, "processes": [], "ready": False} + + def launch(name, arguments): + log = (root / (name + ".log")).open("xb") + logs.append(log) + process = subprocess.Popen([str(BASE / ".venv/bin/python"), *arguments], + cwd=REPO, stdout=log, stderr=log) + processes.append(process) + ledger["processes"].append({"role": name, "pid": process.pid}) + return process + + try: + body_origin = f"http://127.0.0.1:{available_port()}" + launch("body", [str(BASE / "body_network.py"), "--root", str(root / "body"), + "--port", body_origin.rsplit(":", 1)[1], "--initialize", "--diagnostic"]) + identity = wait_json(body_origin, "/identity", processes) + retain(root / "identity.json", identity) + browser_origin = f"http://127.0.0.1:{available_port()}" + initialization = subprocess.run([ + str(BASE / ".venv/bin/python"), str(BASE / "network_bench_operator.py"), "init", + "--root", str(root / "operator"), "--body-origin", body_origin], + cwd=REPO, capture_output=True, timeout=30, check=False) + protocol.create_file(root / "initialization.stdout", initialization.stdout) + protocol.create_file(root / "initialization.stderr", initialization.stderr) + if initialization.returncode: + raise protocol.Refusal("network browser initialization failed; evidence retained") + launch("workbench", [str(BASE / "network_bench_operator.py"), "serve", "--root", str(root / "operator"), + "--port", browser_origin.rsplit(":", 1)[1], "--backend", "codex"]) + initial = wait_json(browser_origin, "/api/state", processes) + retain(root / "initial-public.json", initial) + ledger.update(body_origin=body_origin, browser_origin=browser_origin, ready=True, + app_id=initial["app_id"], body_id=identity["body_id"]) + retain(root / "ready.json", ledger) + print(json.dumps(ledger), flush=True) + deadline = time.monotonic() + 1800 + while not stopped.is_set() and not (root / "stop-request.json").exists(): + if any(process.poll() is not None for process in processes): + raise protocol.Refusal("owned trial process exited before requested cleanup") + if time.monotonic() >= deadline: + raise protocol.Refusal("browser qualification exceeded its 30-minute bound") + stopped.wait(.2) + retain(root / "final-public.json", wait_json(browser_origin, "/api/state", processes)) + except Exception as exc: + ledger["error"] = type(exc).__name__ + ": " + str(exc) + raise + finally: + # Stop planning first. The body remains available while the host settles shutdown. + for process in reversed(processes): + process.terminate() + try: + process.wait(timeout=40) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + for record, process in zip(ledger["processes"], processes, strict=True): + record.update(exit_observed=process.poll() is not None, returncode=process.returncode) + for log in logs: + log.close() + ledger["owned_processes_exited"] = all(p.poll() is not None for p in processes) + retain(root / "process-ledger.json", ledger) + return ledger + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, required=True) + parser.add_argument("--source-commit", required=True) + args = parser.parse_args() + print(json.dumps(run(args.root, args.source_commit)), flush=True) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/record_network_workbench.py b/tools/physical-workcell/record_network_workbench.py new file mode 100644 index 0000000..c48f794 --- /dev/null +++ b/tools/physical-workcell/record_network_workbench.py @@ -0,0 +1,53 @@ +"""Retain a browser observation with a read-only public-state and journal readback.""" + +import argparse +import time +import urllib.request +from pathlib import Path + +import body_client +import order_protocol as protocol + + +def record(root, name, text_file, action, screenshot=None): + root = protocol.directory(root) + ready = protocol.decode(protocol.read_bytes(root / "ready.json")) + with urllib.request.urlopen(ready["browser_origin"] + "/api/state", timeout=20) as response: + state = protocol.decode(response.read(protocol.MAX_BYTES + 1)) + if state["app_id"] != ready["app_id"]: + raise protocol.Refusal("browser trial application identity changed") + selected = {key: state[key] for key in ("app_id", "runner_status", "jobs", "connection", "recovery", + "model_request_pending", "active_job_id", "current_frame")} + text_file = Path(text_file).resolve() + if root not in text_file.parents: + raise protocol.Refusal("browser observation must be inside the trial root") + visible_text = protocol.read_bytes(text_file, maximum=16000).decode("utf-8") + client = body_client.read_journal(root / "operator" / "client" / "client.json") + path = root / "ui-ledger.json" + ledger = protocol.decode(protocol.read_bytes(path)) if path.exists() else {"steps": []} + if any(step["name"] == name for step in ledger["steps"]): + raise protocol.Refusal("browser observation identity already retained") + step = {"name": name, "time": time.time(), "browser_action": action, + "visible_text": visible_text, "state": selected, "client_commands": len(client["commands"]), + "pending_command_ids": client["pending_command_ids"], "screenshot": screenshot} + ledger["steps"].append(step) + if len(protocol.encoded(ledger)) > protocol.MAX_BYTES: + raise protocol.Refusal("browser observation ledger exceeded its 64 KiB bound") + protocol.persist(path, ledger) + print(name, selected["runner_status"], selected["connection"]["state"], selected["recovery"]["state"], + "commands=" + str(step["client_commands"])) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, required=True) + parser.add_argument("--name", required=True) + parser.add_argument("--text-file", type=Path, required=True) + parser.add_argument("--action", required=True) + parser.add_argument("--screenshot") + args = parser.parse_args() + record(args.root, args.name, args.text_file, args.action, args.screenshot) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/score_network_workbench.py b/tools/physical-workcell/score_network_workbench.py new file mode 100644 index 0000000..ef65692 --- /dev/null +++ b/tools/physical-workcell/score_network_workbench.py @@ -0,0 +1,199 @@ +"""Post-trial checks independent of the browser planner and displayed verdicts.""" + +import argparse +import json +from pathlib import Path + +import agent_bench +import bench +import body_client +import order_protocol as protocol +import qualify_bench +from score_network_body import private_fields + +BASE = Path(__file__).resolve().parent +REPO = BASE.parents[1] + + +def read(path): + return protocol.decode(protocol.read_bytes(path)) + + +def score(root): + root = protocol.directory(root) + host_root = root / "operator" + frozen = read(root / "source-freeze.json") + unchanged = all(protocol.sha(protocol.read_bytes(REPO / name)) == digest + for name, digest in frozen["files"].items()) + process_ledger = read(root / "process-ledger.json") + public = read(root / "final-public.json") + identity = read(root / "identity.json") + native_root = root / "body" / "bench" + native = bench.Bench(native_root).status() + sqlite = qualify_bench.sqlite_score(native_root) + client = body_client.read_journal(host_root / "client" / "client.json") + agent_root = root / "body" / "agent" + agent_manifest = read(agent_root / "agent.json") + events = [read(path) for path in sorted((host_root / "link" / "events").glob("*.json"))] + transport = {} + for directory in (root / "body" / "commands").iterdir(): + record = read(directory / "intent.json") + request = record["request"] + content = protocol.read_bytes(directory / "result.json") + result = protocol.decode(content) + valid = (record["request_sha256"] == protocol.sha(protocol.encoded(request)) == result["request_sha256"] and + record["result_sha256"] == protocol.sha(content) and + directory.name == protocol.sha(request["command_id"].encode()) and + all(result[key] == request[key] for key in ( + "protocol", "adapter_id", "body_id", "source_sha256", "command_id"))) + transport[request["command_id"]] = {"request": request, "result": result, "valid": valid} + + jobs = [] + previous_generation = 0 + initial_content = protocol.read_bytes(bench.body.state_path(native_root, 0)) + previous_time = qualify_bench.native_score(native_root, 0, protocol.sha(initial_content), bench.HOME_ZONE)["native_time_s"] + for item in public["jobs"]: + job_id = item["job_id"] + job = native["jobs"].get(job_id) + if not job or job["phase"] != "completed": + jobs.append({"job_id": job_id, "passed": False}) + continue + measurement, reset = job["measurement_receipt"], job["reset_receipt"] + stage = qualify_bench.native_score(native_root, measurement["generation"], + measurement["state_sha256"], job["target_zone"]) + home = qualify_bench.native_score(native_root, reset["generation"], reset["state_sha256"], bench.HOME_ZONE) + rows = [row for row in sqlite["rows"] if row["job_id"] == job_id] + ok = bool(item["status"] == "completed" and len(rows) == 1 and rows[0]["receipt"] == measurement and + item["measurement"] == agent_bench.public_response(measurement["measurement"]) and + stage["block_center_in_zone"] and home["block_center_in_zone"] and home["pusher_home"] and + stage["external_force_cleared"] and home["external_force_cleared"] and + reset["reset_contact_samples"] > 0 and reset["reset_native_steps"] > 0 and + reset["bench_id"] == measurement["bench_id"] == identity["body_id"] == native["bench_id"] and + job["started_generation"] == previous_generation and job["started_native_time_s"] == previous_time) + jobs.append({"job_id": job_id, "passed": ok, "measurement_state": stage, "reset_state": home, + "measurement_receipt": measurement, "reset_receipt": reset, + "motion_count": job["moves"], "model_calls": item["call_count"]}) + previous_generation, previous_time = job["completed_generation"], job["completed_native_time_s"] + + calls = [] + for directory in sorted(path for path in (host_root / "calls").iterdir() if path.is_dir()): + reservation = read(directory / "reservation.json") + challenge = reservation["challenge"] + digest = challenge["observation"]["image_sha256"] + image_path = Path(challenge["image_path"]) + exact = (host_root / "client" in image_path.parents and + protocol.sha(protocol.read_bytes(image_path, maximum=1024 * 1024)) == digest and + protocol.sha(protocol.read_bytes(directory / "input.png", maximum=1024 * 1024)) == digest) + image_requests = [e for e in events if e["kind"] == "received" and e.get("method") == "GET" and + e.get("path") == "/images/" + challenge["challenge_id"]] + exact &= bool(image_requests) + prompt = json.loads(protocol.read_bytes(directory / "prompt.txt").decode().split("\n", 1)[1]) + model = read(directory / "outcome.json") + bound, one_send, action = False, False, None + missing_dispatch = not (directory / "dispatch.json").exists() + associated_dispatches = [] + if (directory / "proposal.json").exists(): + candidate = read(directory / "proposal.json") + associated_dispatches = [t for t in transport.values() if t["request"]["operation"] == "dispatch" and + t["request"]["arguments"]["proposal_id"] == candidate["proposal_id"]] + withheld = missing_dispatch and model.get("outcome") == "cancelled" and not associated_dispatches + if not missing_dispatch: + proposal = read(directory / "proposal.json") + decision = read(directory / "decision.json")["action"] + action = decision["action"] + pbytes = protocol.read_bytes(agent_root / "proposals" / (proposal["proposal_id"] + ".json")) + rbytes = protocol.read_bytes(agent_root / "results" / (proposal["proposal_id"] + ".json")) + lower_result = read(agent_root / "results" / (proposal["proposal_id"] + ".json")) + bound = (protocol.sha(pbytes) == agent_manifest["proposals"][proposal["proposal_id"]] and + protocol.decode(pbytes) == proposal and + protocol.sha(rbytes) == agent_manifest["results"][proposal["proposal_id"]] and + agent_bench.public_response(lower_result) == read(directory / "dispatch.json") and + all(proposal[k] == decision[k] for k in ("action", "intent", "target_x", "target_y")) and + proposal["challenge_id"] == challenge["challenge_id"] and + proposal["observation_sha256"] == challenge["observation_sha256"]) + matches = [t for t in transport.values() if t["request"]["operation"] == "dispatch" and + t["request"]["arguments"]["proposal_id"] == proposal["proposal_id"]] + bound &= len(matches) == 1 and matches[0]["valid"] and ( + matches[0]["result"]["result"] == agent_bench.public_response(lower_result)) + if len(matches) == 1: + request = matches[0]["request"] + token = request["command_id"] + received = [e for e in events if e["kind"] == "received" and e.get("method") == "POST" and + e.get("command_id") == token] + one_send = (len(received) == 1 and read(host_root / "client" / "requests" / (token + ".json")) == request and + client["commands"][token]["send_count"] == 1) + if received: + sent = protocol.read_bytes(host_root / "link" / "requests" / f"{received[0]['sequence']:06d}.bin") + one_send &= protocol.decode(sent) == request and protocol.sha(sent) == received[0]["payload_sha256"] + calls.append({"job_id": reservation["job_id"], "call": reservation["call"], "action": action, + "withheld": withheld, "exact_TCP_image": bool(exact), + "no_private_pose": not private_fields(reservation) and not private_fields(prompt), + "model_process_reaped": model.get("process_exit_observed", False), + "core_receipt_bound": bool(bound), "one_client_send_bound": bool(one_send), + "usage": model.get("usage")}) + + boundaries = bool(calls and all(c["exact_TCP_image"] and c["no_private_pose"] and c["model_process_reaped"] and + (c["withheld"] or c["core_receipt_bound"] and c["one_client_send_bound"]) for c in calls)) + ui = read(root / "ui-ledger.json") + steps = {step["name"]: step for step in ui["steps"]} + required = {"uncertain", "disconnected", "offline_receipt", "reconnected", "recovered", "resumed", "completed", "reloaded"} + ui_ok = required <= steps.keys() + recovery_token = None + if ui_ok: + visible_expectations = {"uncertain": "uncertain", "disconnected": "Body disconnected", + "offline_receipt": "Check receipt", "reconnected": "Body connected", + "recovered": "Receipt recovered", "resumed": "Running", + "completed": "Completed", "reloaded": "Completed"} + for name, phrase in visible_expectations.items(): + ui_ok &= phrase.casefold() in steps[name]["visible_text"].casefold() + uncertain = steps["uncertain"]["state"] + recovery_token = uncertain["recovery"]["command_id"] + ui_ok &= uncertain["recovery"]["state"] == "uncertain" and uncertain["runner_status"] != "running" + ui_ok &= steps["disconnected"]["state"]["connection"]["state"] == "disconnected" + for name in ("disconnected", "offline_receipt", "reconnected"): + value = steps[name]["state"] + ui_ok &= value["runner_status"] != "running" and value["recovery"]["command_id"] == recovery_token + ui_ok &= value["recovery"]["state"] in {"uncertain", "blocked"} + ui_ok &= steps[name]["client_commands"] == steps["uncertain"]["client_commands"] + recovered = steps["recovered"]["state"] + ui_ok &= recovered["recovery"]["state"] == "recovered" and recovered["runner_status"] != "running" + ui_ok &= steps["recovered"]["client_commands"] == steps["uncertain"]["client_commands"] + ui_ok &= steps["resumed"]["state"]["runner_status"] == "running" + for name in required: + ui_ok &= steps[name]["state"]["app_id"] == public["app_id"] + ui_ok &= steps[name]["state"]["connection"]["body_id"] == identity["body_id"] + ui_ok &= bool(steps[name]["visible_text"]) and bool(steps[name]["browser_action"]) + ui_ok &= steps["completed"]["state"]["jobs"] == steps["reloaded"]["state"]["jobs"] + ui_ok &= steps["completed"]["client_commands"] == steps["reloaded"]["client_commands"] + dropped = [e for e in events if e["kind"] == "dropped_after" and e.get("command_id") == recovery_token] + reconciliation = [e for e in events if e["kind"] == "received" and e.get("method") == "GET" and + e.get("path", "").startswith("/commands/" + str(recovery_token) + "?")] + received = [e for e in events if e["kind"] == "received" and e.get("method") == "POST" and + e.get("command_id") == recovery_token] + fault_ok = len(dropped) == len(received) == 1 and bool(reconciliation) and recovery_token in transport + fault_ok &= bool(recovery_token in transport and transport[recovery_token]["result"]["state"] == "completed") + passed = bool(unchanged and process_ledger["owned_processes_exited"] and not process_ledger.get("error") and + len(jobs) == sqlite["count"] == 2 and all(j["passed"] for j in jobs) and boundaries and ui_ok and + fault_ok and transport and all(t["valid"] for t in transport.values()) and + not client["pending_command_ids"] and native["state"] == "ready" and native["active_job"] is None) + result = {"passed": passed, "source_commit": frozen["commit"], "source_unchanged": unchanged, + "scope": "browser UI and actual image policy over loopback TCP simulation", + "body_id": identity["body_id"], "completed_cycles": sum(j["passed"] for j in jobs), + "browser_transitions_passed": bool(ui_ok), "model_boundaries_passed": boundaries, + "lost_reply_reconciled_without_resend": bool(fault_ok), + "transport_journal_bound": all(t["valid"] for t in transport.values()), + "transport_command_count": len(transport), "calls": calls, "scores": jobs, "sqlite": sqlite, + "ui_steps": sorted(steps), "owned_processes_exited": process_ledger["owned_processes_exited"]} + protocol.create_file(root / "qualification-score.json", protocol.encoded(result)) + return {k: result[k] for k in ("passed", "completed_cycles", "browser_transitions_passed", "model_boundaries_passed", + "lost_reply_reconciled_without_resend", "source_unchanged")} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, required=True) + print(json.dumps(score(parser.parse_args().root), sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/test_network_operator.py b/tools/physical-workcell/test_network_operator.py new file mode 100644 index 0000000..f8a4558 --- /dev/null +++ b/tools/physical-workcell/test_network_operator.py @@ -0,0 +1,329 @@ +"""Deterministic real-socket workbench conformance; never model qualification.""" +import json +import threading +import time +import unittest +import uuid +from unittest import mock + +import body_client +import body_network +import network_operator_runtime as runtime +import order_protocol as protocol + + +def action(name="stop", x=None, y=None): + return {"action": name, "target_x": x, "target_y": y, "intent": "Declared deterministic network conformance"} + + +class NetworkOperatorTests(unittest.TestCase): + def setUp(self): + self.root = runtime.BASE / "output" / ("net-operator-test-" + uuid.uuid4().hex[:10]) + self.body_root = self.root / "body" + body_network.initialize(self.body_root, diagnostic_enabled=True) + self.service = body_network.BodyService(self.body_root).start() + self.host = self.root / "host" + self.patcher = mock.patch.object(runtime, "sources", return_value={"diagnostic_source": "fixed"}) + self.patcher.start() + runtime.initialize(self.host, self.service.origin) + self.op = None + + def tearDown(self): + if self.op: + self.op.close() + if self.service: + self.service.close() + failed = any(test is self for test, _ in (*self._outcome.result.failures, *self._outcome.result.errors)) + protocol.create_file(self.root / "conformance.json", protocol.encoded({"test_id": self.id(), "passed": not failed, + "policy": "explicitly_fake_diagnostic", "host_state": body_client.read_journal(self.host / "operator.json")})) + self.patcher.stop() + + def open(self, policy=None, worker=False): + self.op = runtime.Operator(self.host, policy or (lambda *_: (action(), {})), start_worker=worker) + return self.op + + def job(self, name="one", **changes): + return {"job_id": name, "label": "Network inspection", "target": "A", "disturbance_test": False, **changes} + + def wait(self, predicate, timeout=15): + until = time.monotonic() + timeout + while time.monotonic() < until and not predicate(): + time.sleep(.02) + self.assertTrue(predicate()) + + def test_pause_wins_while_resume_waits_for_actual_socket_status(self): + op = self.open() + op.pause() + entered, release = threading.Event(), threading.Event() + original = self.service.state + errors = [] + def delayed_status(): + entered.set() + release.wait(5) + return original() + def resume(): + try: + op.resume() + except protocol.Refusal as exc: + errors.append(str(exc)) + with mock.patch.object(self.service, "state", side_effect=delayed_status): + thread = threading.Thread(target=resume) + thread.start() + self.assertTrue(entered.wait(5)) + op.pause() + release.set() + thread.join(5) + self.assertFalse(thread.is_alive()) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertTrue(errors) + self.assertEqual(len(op._journal()["commands"]), 0) + self.assertEqual(self.service.body.status()["generation"], 0) + + def test_two_successive_jobs_and_disturbance_using_declared_replay(self): + audit = runtime.BASE.parent.parent / "jevdual/results/agent-visual-bench-20261011/AI-action-audit.json" + proposals = iter(json.loads(audit.read_text())["actions"]) + def policy(*_): + recorded = next(proposals)["proposal"] + return {k: recorded[k] for k in ("action", "target_x", "target_y", "intent")}, {} + op = self.open(policy) + op.enqueue(self.job()) + op.enqueue(self.job("two", target="B", disturbance_test=True)) + for _ in range(40): + if not op._step(): + break + self.assertEqual([j["status"] for j in op.state()["jobs"]], ["completed", "completed"]) + self.assertEqual(op.state()["usage"]["calls"], 29) + self.assertTrue(all(j["measurement"]["orange_pixel_count"] > 0 for j in op.state()["jobs"])) + self.assertTrue(all(j["reset"]["reset_contact_samples"] > 0 for j in op.state()["jobs"])) + self.assertEqual(len(self.service.body.status()["jobs"]), 2) + self.assertIsNone(op.m["stage"]) + self.assertLess(len(op._journal()["commands"]), runtime.MAX_COMMANDS) + + def test_lost_dispatch_disconnect_recovery_and_explicit_resume(self): + decisions = iter((action("move", -.25, 0), action())) + seen = [] + def policy(challenge, *_): + seen.append(challenge["observation"]["generation"]) + return next(decisions), {} + op = self.open(policy) + op.enqueue(self.job()) + op.fault({"mode": "drop_after", "delay_s": 0}) + self.assertFalse(op._step()) + token = op.state()["recovery"]["command_id"] + self.assertEqual(op.state()["recovery"]["state"], "uncertain") + self.assertEqual(self.service.body.status()["generation"], 1) + before = len(op._journal()["commands"]) + op.disconnect() + with self.assertRaises(protocol.Refusal): + op.reconcile() + op.reconnect() + self.assertEqual(len(op._journal()["commands"]), before) + op.reconcile() + self.assertEqual(op.state()["recovery"]["state"], "recovered") + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(op.m["applied_commands"].count(token), 1) + self.assertEqual(self.service.body.status()["generation"], 1) + with self.assertRaises(protocol.Refusal): + op.reconcile() + op.resume() + self.assertFalse(op._step()) + self.assertEqual(seen, [0, 1]) + self.assertEqual(op._journal()["commands"][token]["send_count"], 1) + + def test_unknown_start_observe_and_proposal_settle_without_replay_or_old_decision(self): + for index, operation in enumerate(("start_job", "observe", "propose")): + with self.subTest(operation=operation): + if index: + self.op.close() + self.op = None + self.service.close() + next_body = self.root / ("body-" + operation) + body_network.initialize(next_body, diagnostic_enabled=True) + self.service = body_network.BodyService(next_body).start() + self.host = self.root / ("host-" + operation) + runtime.initialize(self.host, self.service.origin) + op = self.open(lambda *_: (action("move", -.25, 0), {})) + op.enqueue(self.job(operation)) + op.link.arm("drop_after", operation=operation, delay_s=0) + self.assertFalse(op._step()) + self.assertEqual(op.state()["recovery"]["operation"], operation) + before = len(op._journal()["commands"]) + op.reconcile() + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(self.service.body.status()["generation"], 0) + self.assertEqual(len(op._journal()["commands"]), before) + self.assertIsNone(op.m["stage"]) + + def test_restart_recovers_exact_queue_stage_once_from_historical_receipt(self): + op = self.open(lambda *_: (action("move", -.25, 0), {})) + op.enqueue(self.job()) + op.fault({"mode": "drop_after", "delay_s": 0}) + self.assertFalse(op._step()) + token = op.m["stage"]["command_id"] + before = len(op._journal()["commands"]) + origin = op.link.origin + op.close() + self.op = None + op = self.open(lambda *_: self.fail("restart ran model"), worker=True) + self.assertEqual(op.link.origin, origin) + self.assertEqual(op.state()["runner_status"], "blocked") + op.reconcile() + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(len(op._journal()["commands"]), before) + self.assertEqual(op.m["applied_commands"].count(token), 1) + self.assertEqual(self.service.body.status()["generation"], 1) + + def test_pause_before_host_admission_suppresses_stage_and_socket_command(self): + op = self.open(lambda *_: self.fail("paused model")) + op.enqueue(self.job()) + op.pause() + self.assertFalse(op._step()) + self.assertIsNone(op.m["stage"]) + self.assertEqual(len(op._journal()["commands"]), 0) + self.assertIsNone(self.service.body.status()["active_job"]) + + def test_pause_after_host_admission_allows_exact_receipt_but_no_successor(self): + op = self.open(lambda *_: (action("move", -.25, 0), {})) + op.enqueue(self.job()) + entered, release = threading.Event(), threading.Event() + original = op.client.dispatch + def delayed_dispatch(proposal_id): + self.assertEqual(op.m["stage"]["operation"], "dispatch") + entered.set() + release.wait(5) + return original(proposal_id) + with mock.patch.object(op.client, "dispatch", side_effect=delayed_dispatch): + worker = threading.Thread(target=op._step) + worker.start() + self.assertTrue(entered.wait(10)) + op.pause() + release.set() + worker.join(10) + self.assertFalse(worker.is_alive()) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(self.service.body.status()["generation"], 1) + self.assertIsNone(op.m["stage"]) + before = len(op._journal()["commands"]) + self.assertFalse(op._step()) + self.assertEqual(len(op._journal()["commands"]), before) + + def test_pause_during_model_withholds_unadmitted_decision(self): + entered, release = threading.Event(), threading.Event() + def policy(*_): + entered.set() + release.wait(5) + return action("move", -.25, 0), {} + op = self.open(policy, worker=True) + op.enqueue(self.job()) + self.assertTrue(entered.wait(10)) + before = len(op._journal()["commands"]) + op.pause() + release.set() + self.wait(lambda: not op.in_model) + self.wait(lambda: any(e["kind"] == "decision_withheld" for e in op.m["activity"])) + self.assertEqual(len(op._journal()["commands"]), before) + self.assertEqual(self.service.body.status()["generation"], 0) + + def test_state_and_frame_are_responsive_while_transport_pending(self): + op = self.open() + op.enqueue(self.job()) + op._step() + op.resume() + entered, release = threading.Event(), threading.Event() + original = op.client.observe + def delayed_observe(): + entered.set() + release.wait(5) + return original() + with mock.patch.object(op.client, "observe", side_effect=delayed_observe): + worker = threading.Thread(target=op._step) + worker.start() + self.assertTrue(entered.wait(10)) + started = time.monotonic() + state = op.state() + self.assertTrue(state["transport_pending"]) + self.assertTrue(op.frame(state["current_frame"]["image_url"]).startswith(b"\x89PNG")) + self.assertLess(time.monotonic() - started, .2) + release.set() + worker.join(10) + self.assertFalse(worker.is_alive()) + + def test_changed_image_and_source_refuse_without_network_effect(self): + op = self.open() + op.enqueue(self.job()) + op._step() + before = len(op._journal()["commands"]) + with (mock.patch.object(runtime, "sources", return_value={"changed": True}), self.assertRaises(protocol.Refusal)): + op.state() + image = runtime.Path(op.m["frame"]["path"]) + image.write_bytes(b"changed cached image") + with self.assertRaises(protocol.Refusal): + op.frame() + self.assertEqual(len(op._journal()["commands"]), before) + + def test_invalid_body_identity_health_is_blocked_without_thread_crash(self): + op = self.open() + with mock.patch.object(self.service, "identity", side_effect=protocol.Refusal("diagnostic invalid identity")): + self.assertFalse(op._refresh_health()) + self.assertEqual(op.state()["connection"]["state"], "unavailable") + self.assertEqual(op.state()["runner_status"], "blocked") + self.assertTrue(op.health_worker.is_alive()) + self.assertEqual(len(op._journal()["commands"]), 0) + + def test_full_local_manifest_capacity_keeps_wire_limits(self): + op = self.open() + for i in range(6): + op.enqueue(self.job("job-" + str(i), label="L" * 120)) + for job in op.m["jobs"]: + job["history"] = [{"action": dict(action("move", -.25, 0), intent="I" * 500), "outcome": "executed", "reason": ""} for _ in range(6)] + ids = ["command-" + uuid.uuid4().hex for _ in range(240)] + op.m["applied_commands"] = ids + op.m["stage"] = {"before_commands": ids, "operation": "observe", "arguments": {}, "command_id": None, "context": {"job_id": "job-0"}, "control_epoch": 0} + op.m["activity"] = [{"seq": i, "time": 1, "kind": "diagnostic", "intent": "I" * 1000, "outcome": "O" * 1000} for i in range(24)] + op._save() + size = len(protocol.encoded(op.m)) + self.assertGreater(size, protocol.MAX_BYTES) + self.assertLessEqual(size, body_client.MAX_CLIENT_JOURNAL) + self.assertEqual(body_client.read_journal(self.host / "operator.json"), op.m) + self.assertLessEqual(len(protocol.encoded(op.state())), protocol.MAX_BYTES) + + def test_stale_health_timeout_after_known_socket_dispatch_does_not_pause(self): + op = self.open() + op.enqueue(self.job()) + op._step() + op.resume() + op.policy = lambda *_: (action("move", -.25, 0), {}) + op.health_stop.set() + op.health_worker.join(4) + entered, release = threading.Event(), threading.Event() + original = self.service.state + def delayed_health_state(): + entered.set() + release.wait(5) + return original() + with mock.patch.object(self.service, "state", side_effect=delayed_health_state): + health = threading.Thread(target=op._refresh_health) + health.start() + self.assertTrue(entered.wait(5)) + self.assertTrue(op._step()) + health.join(3) + release.set() + self.assertFalse(health.is_alive()) + self.assertEqual(self.service.body.status()["generation"], 1) + self.assertEqual(op.state()["connection"]["state"], "connected") + self.assertEqual(op.state()["runner_status"], "running") + self.assertIsNone(op.m["stage"]) + + def test_idle_body_outage_becomes_unavailable_without_effect_polling(self): + op = self.open() + before = len(op._journal()["commands"]) + self.service.close() + self.service = None + time.sleep(2.5) + self.assertEqual(op.state()["connection"]["state"], "unavailable") + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(len(op._journal()["commands"]), before) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/physical-workcell/test_network_operator_http.py b/tools/physical-workcell/test_network_operator_http.py new file mode 100644 index 0000000..1da5876 --- /dev/null +++ b/tools/physical-workcell/test_network_operator_http.py @@ -0,0 +1,137 @@ +"""Real HTTP boundary conformance; the operator is an explicitly labelled test double.""" +import json +import threading +import unittest +from http.client import HTTPConnection + +import network_bench_operator as product + + +class DiagnosticOperator: + """Records handler admission without starting a body or model.""" + + def __init__(self): + self.m = {"app_id": "http-conformance-app"} + self.calls = [] + + def _identity(self): + pass + + def state(self): + return {"app_id": self.m["app_id"], "simulation": True} + + def frame(self, path): + self.calls.append(("frame", path)) + return b"\x89PNG\r\n\x1a\n" + + def enqueue(self, request): + self.calls.append(("enqueue", request)) + return {"app_id": self.m["app_id"]} + + def fault(self, request): + self.calls.append(("fault", request)) + return {"app_id": self.m["app_id"]} + + def __getattr__(self, name): + if name not in ("pause", "resume", "disconnect", "reconnect", "reconcile"): + raise AttributeError(name) + def control(): + self.calls.append((name, None)) + return {"app_id": self.m["app_id"]} + return control + + +class NetworkHTTPTests(unittest.TestCase): + def setUp(self): + self.operator = DiagnosticOperator() + self.server = product.Server(("127.0.0.1", 0), self.operator) + self.thread = threading.Thread(target=self.server.serve_forever, kwargs={"poll_interval": .01}, daemon=True) + self.thread.start() + + def tearDown(self): + self.server.shutdown() + self.server.server_close() + self.thread.join(3) + self.assertFalse(self.thread.is_alive()) + + def request(self, method, path, payload=None, overrides=None, extra=()): + headers = {"Host": self.server.host} + body = json.dumps(payload).encode() if payload is not None else b"" + if method == "POST": + headers.update({"Origin": self.server.origin, + "X-Footwork-App-ID": self.operator.m["app_id"], + "Content-Type": "application/json", "Content-Length": str(len(body))}) + for name, value in (overrides or {}).items(): + if value is None: + headers.pop(name, None) + else: + headers[name] = value + connection = HTTPConnection("127.0.0.1", self.server.server_address[1], timeout=3) + try: + connection.putrequest(method, path, skip_host=True, skip_accept_encoding=True) + for name, value in headers.items(): + connection.putheader(name, value) + for name, value in extra: + connection.putheader(name, value) + connection.endheaders(body) + response = connection.getresponse() + return response.status, response.read(), response.getheader("Content-Type") + finally: + connection.close() + + def test_new_controls_admitted_only_with_exact_identity(self): + for route in ("disconnect", "reconnect", "reconcile", "pause", "resume"): + self.assertEqual(self.request("POST", "/api/" + route, {})[0], 200) + self.assertEqual([call[0] for call in self.operator.calls], + ["disconnect", "reconnect", "reconcile", "pause", "resume"]) + + def test_missing_foreign_or_duplicate_headers_never_mutate(self): + for name, foreign in (("Host", "localhost:9999"), ("Origin", "https://foreign.invalid"), + ("X-Footwork-App-ID", "foreign-app")): + for value in (None, foreign): + with self.subTest(header=name, value=value): + self.assertEqual(self.request("POST", "/api/reconnect", {}, {name: value})[0], 409) + valid = {"Host": self.server.host, "Origin": self.server.origin, + "X-Footwork-App-ID": self.operator.m["app_id"]}[name] + self.assertEqual(self.request("POST", "/api/reconcile", {}, extra=((name, valid),))[0], 409) + self.assertEqual(self.operator.calls, []) + + def test_controls_require_empty_exact_json_body(self): + for route in ("disconnect", "reconnect", "reconcile"): + for value in ({"replay": True}, [], {"command_id": "other"}): + self.assertEqual(self.request("POST", "/api/" + route, value)[0], 409) + self.assertEqual(self.operator.calls, []) + + def test_fault_schema_is_bounded_and_dispatch_only(self): + for mode in ("drop_after", "delay_after", "duplicate"): + for delay in (0, 2): + self.assertEqual(self.request("POST", "/api/fault", {"mode": mode, "delay_s": delay})[0], 200) + before = list(self.operator.calls) + for value in ({"mode": "other", "delay_s": 0}, {"mode": "duplicate", "delay_s": True}, + {"mode": "duplicate", "delay_s": -1}, {"mode": "duplicate", "delay_s": 3}, + {"mode": "duplicate", "delay_s": 0, "operation": "begin"}): + self.assertEqual(self.request("POST", "/api/fault", value)[0], 409) + self.assertEqual(self.operator.calls, before) + + def test_network_html_read_only_state_and_unknown_routes(self): + status, body, content_type = self.request("GET", "/") + self.assertEqual(status, 200) + self.assertIn("text/html", content_type) + for label in (b"Check receipt", b"Lose next reply", b"Duplicate next command"): + self.assertIn(label, body) + self.assertEqual(self.request("GET", "/api/state")[0], 200) + self.assertEqual(self.request("POST", "/api/reconcile?command=other", {})[0], 409) + self.assertEqual(self.request("GET", "/api/disconnect")[0], 404) + self.assertEqual(self.operator.calls, []) + + def test_http_body_framing_is_closed_before_mutation(self): + for overrides, extra in (({"Content-Type": "text/plain"}, ()), + ({"Content-Length": "4097"}, ()), + ({}, (("Content-Length", "2"),)), + ({}, (("Transfer-Encoding", "chunked"),))): + self.assertEqual(self.request("POST", "/api/reconnect", {}, overrides, extra)[0], 409) + self.assertEqual(self.operator.calls, []) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/physical-workcell/test_workbench_link.py b/tools/physical-workcell/test_workbench_link.py new file mode 100644 index 0000000..125ed17 --- /dev/null +++ b/tools/physical-workcell/test_workbench_link.py @@ -0,0 +1,223 @@ +"""Retained workbench-link checks with real TCP and unchanged native authority.""" +import socket +import time +import unittest +import uuid +from pathlib import Path + +import body_client +import body_network +import order_protocol as storage +import workbench_link + +BASE = Path(__file__).resolve().parent +ZONE = {"x_min": .04, "x_max": .10, "y_min": -.025, "y_max": .025} + + +class WorkbenchLinkTests(unittest.TestCase): + def setUp(self): + self.root = BASE / "output" / ("sim10-link-" + uuid.uuid4().hex[:12]) + self.root.mkdir(mode=0o700) + body_network.initialize(self.root / "body", diagnostic_enabled=True) + self.server = body_network.BodyService(self.root / "body").start() + self.link = workbench_link.WorkbenchLink(self.server.origin, self.root / "link").start() + self.client = body_client.BodyClient(self.root / "client", self.link.origin, timeout=2) + self.evidence = [] + + def tearDown(self): + self.client.close() + self.link.close() + self.server.close() + result = self._outcome.result + failed = any(test is self for test, _ in (*result.failures, *result.errors)) + storage.create_file(self.root / "conformance.json", storage.encoded({"test_id": self.id(), "passed": not failed, + "scenario_kind": "actual_tcp_retained_link_native_body", "evidence": self.evidence})) + + def events(self): + return [storage.decode(storage.read_bytes(path)) for path in sorted((self.root / "link" / "events").glob("*.json"))] + + def prepare(self): + self.client.acquire() + self.client.start_job("job", ZONE) + challenge = self.client.observe() + return self.client.propose(challenge["challenge_id"], "move", "bounded real native approach", -.19, 0) + + def command_id(self, proposal_id): + manifest = body_client.read_journal(self.root / "client" / "client.json") + matches = [] + for command_id in manifest["commands"]: + request = storage.decode(storage.read_bytes(self.root / "client" / "requests" / (command_id + ".json"))) + if request["operation"] == "dispatch" and request["arguments"]["proposal_id"] == proposal_id: + matches.append(command_id) + self.assertEqual(len(matches), 1) + return matches[0] + + def test_drop_after_effect_is_unknown_and_read_only_recovery_has_one_forward(self): + proposal = self.prepare() + self.link.arm("drop_after") + with self.assertRaises(body_client.Uncertain) as caught: + self.client.dispatch(proposal["proposal_id"]) + command_id = caught.exception.command_id + self.assertIsNone(self.link.state()["fault"]) + self.assertEqual(self.server.state()["bench"]["generation"], 1) + receipt = self.client.reconcile(command_id) + self.evidence.append(receipt) + self.assertEqual(receipt["state"], "completed") + self.assertEqual(receipt["result"]["outcome"], "executed") + forwards = [event for event in self.events() if event["kind"] == "forwarded" and event.get("command_id") == command_id] + self.assertEqual(len(forwards), 1) + self.assertEqual(self.server.state()["bench"]["generation"], 1) + + def test_duplicate_and_cached_terminal_requests_never_add_native_effects(self): + proposal = self.prepare() + self.link.arm("duplicate") + result = self.client.dispatch(proposal["proposal_id"]) + command_id = self.command_id(proposal["proposal_id"]) + manifest = body_client.read_journal(self.root / "client" / "client.json") + request = storage.read_bytes(self.root / "client" / "requests" / (command_id + ".json")) + status, content = body_client.http_call(self.link.origin, "POST", "/commands", + body_client.pinned_headers(manifest["identity"]), request) + cached = storage.decode(content) + self.evidence.append(cached) + self.assertEqual(status, 200) + self.assertEqual(cached["result"], result) + self.assertEqual(self.server.state()["bench"]["generation"], 1) + forwards = [event for event in self.events() if event["kind"] == "forwarded" and event.get("command_id") == command_id] + self.assertEqual(len(forwards), 3) + duplicate = [event for event in self.events() if event["kind"] == "duplicate_replies"] + self.assertEqual(len(duplicate), 1) + self.assertTrue(duplicate[0]["same_reply"]) + + def test_offline_and_reconnect_never_forward_the_saved_command(self): + self.client.acquire(duration_s=.1) + self.link.set_connected(False) + with self.assertRaises(body_client.Uncertain) as caught: + self.client.observe() + token = caught.exception.command_id + with self.assertRaises(body_client.Uncertain): + self.client.reconcile(token) + before = len([event for event in self.events() if event["kind"] == "forwarded"]) + self.link.set_connected(True) + self.assertEqual(len([event for event in self.events() if event["kind"] == "forwarded"]), before) + self.assertEqual(self.server.state()["bench"]["generation"], 0) + time.sleep(.15) + result = self.client.reconcile(token) + self.evidence.append(result) + self.assertEqual(result["state"], "not_accepted") + self.assertFalse([event for event in self.events() if event["kind"] == "forwarded" and event.get("command_id") == token]) + self.assertTrue(any(event["kind"] == "disconnected_request" and event["path"].startswith("/commands/") + for event in self.events())) + + def test_restart_retains_fixed_endpoint_offline_and_payload_history(self): + self.prepare() + self.link.set_connected(False) + origin = self.link.origin + before = {p.name: p.read_bytes() for p in (self.root / "link" / "requests").iterdir()} + self.link.close() + self.link = workbench_link.WorkbenchLink(self.server.origin, self.root / "link").start() + self.assertEqual(self.link.origin, origin) + self.assertFalse(self.link.state()["connected"]) + self.assertEqual({p.name: p.read_bytes() for p in (self.root / "link" / "requests").iterdir()}, before) + self.assertEqual(self.server.state()["bench"]["generation"], 0) + self.link.set_connected(True) + self.assertIn("challenge_id", self.client.observe()) + self.assertEqual(self.server.state()["bench"]["generation"], 0) + self.evidence.append(self.link.state()) + + def test_restart_cancels_armed_fault_without_forwarding(self): + self.link.arm("duplicate") + origin = self.link.origin + self.link.close() + self.link = workbench_link.WorkbenchLink(self.server.origin, self.root / "link").start() + self.assertEqual(self.link.origin, origin) + self.assertIsNone(self.link.state()["fault"]) + self.assertTrue(any(event["kind"] == "fault_cancelled_on_restart" for event in self.events())) + self.assertFalse([event for event in self.events() if event["kind"] == "forwarded"]) + self.assertEqual(self.server.state()["bench"]["generation"], 0) + + def test_delay_does_not_hold_state_or_disconnect_lock(self): + proposal = self.prepare() + self.link.arm("delay_after", delay_s=.2) + self.client.timeout = .05 + with self.assertRaises(body_client.Uncertain) as caught: + self.client.dispatch(proposal["proposal_id"]) + token = caught.exception.command_id + started = time.monotonic() + snapshot = self.link.state() + self.link.set_connected(False) + self.assertLess(time.monotonic() - started, .1) + self.assertTrue(snapshot["connected"]) + self.assertFalse(self.link.state()["connected"]) + self.link.set_connected(True) + self.client.timeout = 2 + result = self.client.reconcile(token) + self.evidence.append(result) + self.assertEqual(result["state"], "completed") + self.assertEqual(self.server.state()["bench"]["generation"], 1) + + def test_header_rejection_never_forwards_or_admits_dispatch(self): + proposal = self.prepare() + manifest = body_client.read_journal(self.root / "client" / "client.json") + pinned = manifest["identity"] + request = {"protocol": body_client.PROTOCOL, "adapter_id": pinned["adapter_id"], "body_id": pinned["body_id"], + "source_sha256": pinned["source_sha256"], "client_id": manifest["client_id"], + "lease_id": manifest["lease"]["lease_id"], "epoch": manifest["lease"]["epoch"], + "command_id": "command-invalid-" + uuid.uuid4().hex, "operation": "dispatch", + "arguments": {"proposal_id": proposal["proposal_id"]}} + payload = storage.encoded(request) + host, port = body_client.endpoint(self.link.origin) + good = [("Host", f"{host}:{port}"), ("Content-Type", "application/json"), + *body_client.pinned_headers(pinned).items(), ("Content-Length", str(len(payload)))] + attempts = [good + [(name, dict(good)[name])] for name in ("Host", "Content-Type", "X-Body-Id")] + attempts += [good + [("Origin", "http://foreign.invalid")], + [(k, "foreign.invalid" if k == "Host" else v) for k, v in good]] + before = {str(p.relative_to(self.root / "body" / "commands")): p.read_bytes() + for p in (self.root / "body" / "commands").rglob("*") if p.is_file()} + for headers in attempts: + wire = ("POST /commands HTTP/1.1\r\n" + "".join(f"{k}: {v}\r\n" for k, v in headers) + "\r\n").encode() + payload + with socket.create_connection((host, port), timeout=2) as connection: + connection.sendall(wire) + try: + reply = connection.recv(1024) + except ConnectionResetError: + reply = b"" + self.assertEqual(reply, b"") + self.assertEqual({str(p.relative_to(self.root / "body" / "commands")): p.read_bytes() + for p in (self.root / "body" / "commands").rglob("*") if p.is_file()}, before) + self.assertEqual(self.server.state()["bench"]["generation"], 0) + self.assertFalse([event for event in self.events() if event["kind"] == "forwarded" and + event.get("command_id") == request["command_id"]]) + self.evidence.append({"rejected_command": request, "invalid_headers": attempts}) + + def test_identity_endpoint_lock_and_state_copy_guards(self): + snapshot = self.link.state() + snapshot["connected"] = False + self.assertTrue(self.link.state()["connected"]) + with self.assertRaises(storage.Refusal): + workbench_link.WorkbenchLink(self.server.origin, self.root / "link").start() + origin = self.link.origin + self.link.close() + with self.assertRaises(storage.Refusal): + workbench_link.WorkbenchLink("http://127.0.0.1:1", self.root / "link").start() + with self.assertRaises(storage.Refusal): + workbench_link.WorkbenchLink(self.server.origin, self.root / "link", port=1).start() + self.link = workbench_link.WorkbenchLink(self.server.origin, self.root / "link").start() + self.assertEqual(self.link.origin, origin) + with self.assertRaises(storage.Refusal): + self.link.set_connected(1) + with self.assertRaises(storage.Refusal): + self.link.arm("drop_before") + with self.assertRaises(storage.Refusal): + self.link.arm("delay_after", delay_s=3) + + def test_idle_polling_does_not_exhaust_retained_command_journal(self): + self.client.acquire() + before = len(self.events()) + for _ in range(10): + self.client.status() + self.assertEqual(len(self.events()), before) + self.evidence.append({"ordinary_state_polls": 10, "additional_journal_events": 0}) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/physical-workcell/workbench_link.py b/tools/physical-workcell/workbench_link.py new file mode 100644 index 0000000..cb58b50 --- /dev/null +++ b/tools/physical-workcell/workbench_link.py @@ -0,0 +1,302 @@ +"""Retained loopback workbench link; reconnect and restart never replay requests. + +Command payload bytes and identity headers pass unchanged. One-shot faults are +local diagnostics. Ordinary read-only identity/state polling is not journaled. +""" +import concurrent.futures +import contextlib +import copy +import fcntl +import http.client +import os +import socket +import stat +import threading +import time +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import urlsplit + +import body_client +import order_protocol as protocol + +MODES = {"drop_after", "delay_after", "duplicate"} +MAX_EVENTS = 16384 + + +class WorkbenchLink: + def __init__(self, origin, root, port=0): + body_client.endpoint(origin) + if type(port) is not int or not 0 <= port <= 65535: + raise protocol.Refusal("link port must be a bounded integer") + self.upstream = origin + self.root = protocol.directory(root, create=True) + self.port = port + self.origin = None + self._mutex = threading.RLock() + self._manifest = None + self._server = self._thread = self._fd = None + + def _public(self, manifest=None): + m = self._manifest if manifest is None else manifest + return {key: copy.deepcopy(m[key]) for key in ("connected", "origin", "upstream", "fault")} + + def state(self): + with self._mutex: + if self._manifest is None: + raise protocol.Refusal("link has not started") + return self._public() + + def _event(self, kind, _changes=None, **data): + with self._mutex: + m = {**self._manifest, **(_changes or {})} + if m["sequence"] >= MAX_EVENTS: + raise protocol.Refusal("link event budget exhausted") + sequence = m["sequence"] + 1 + event = {"sequence": sequence, "kind": kind, "previous_sha256": m["event_sha256"], + "state_snapshot": self._public(m), **data} + content = protocol.encoded(event) + protocol.create_file(self.root / "events" / f"{sequence:06d}.json", content) + updated = {**m, "sequence": sequence, "event_sha256": protocol.sha(content)} + protocol.persist(self.root / "link.json", updated) + self._manifest = updated + return event + + def _restore(self): + m = protocol.decode(protocol.read_bytes(self.root / "link.json")) + protocol.fields(m, ("version", "origin", "upstream", "connected", "fault", "sequence", "event_sha256", "source_sha256"), + "retained link") + source_sha = protocol.sha(protocol.read_bytes(__file__)) + if (type(m["version"]) is not int or m["version"] != 1 or m["upstream"] != self.upstream or + m["source_sha256"] != source_sha or type(m["connected"]) is not bool or + type(m["sequence"]) is not int or not 1 <= m["sequence"] <= MAX_EVENTS): + raise protocol.Refusal("retained link identity, source or state changed") + _, port = body_client.endpoint(m["origin"]) + if self.port not in (0, port): + raise protocol.Refusal("retained link must use its exact original port") + previous, tail, payloads = None, None, set() + for sequence in range(1, m["sequence"] + 1): + content = protocol.read_bytes(self.root / "events" / f"{sequence:06d}.json") + event = protocol.decode(content) + if event.get("sequence") != sequence or event.get("previous_sha256") != previous: + raise protocol.Refusal("link event history changed") + if event["kind"] == "received": + payload_path = self.root / "requests" / f"{sequence:06d}.bin" + if protocol.sha(protocol.read_bytes(payload_path)) != event["payload_sha256"]: + raise protocol.Refusal("link request payload history changed") + payloads.add(payload_path.name) + previous, tail = protocol.sha(content), event + if (previous != m["event_sha256"] or tail["state_snapshot"] != {key: m[key] for key in + ("connected", "origin", "upstream", "fault")} or + len(list((self.root / "events").iterdir())) != m["sequence"] or + {path.name for path in (self.root / "requests").iterdir()} != payloads): + raise protocol.Refusal("retained link manifest or immutable journal changed") + if m["fault"] is not None: + self._validate_fault(**m["fault"]) + self._manifest, self.origin = m, m["origin"] + return port + + def start(self): + if self._server is not None: + raise protocol.Refusal("link already started") + fd = os.open(self.root / "link.lock", os.O_RDWR | os.O_CREAT | os.O_NOFOLLOW, 0o600) + server = None + try: + info = os.fstat(fd) + if not stat.S_ISREG(info.st_mode) or info.st_uid != os.getuid() or info.st_mode & 0o077: + raise protocol.Refusal("link lock must be an owned private regular file") + try: + fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except BlockingIOError as exc: + raise protocol.Refusal("another process owns this link") from exc + retained = (self.root / "link.json").exists() + if retained: + port = self._restore() + else: + if any(path.name != "link.lock" for path in self.root.iterdir()): + raise protocol.Refusal("new link requires an empty owned directory") + (self.root / "events").mkdir(mode=0o700) + (self.root / "requests").mkdir(mode=0o700) + port = self.port + owner = self + + class Handler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + + def log_message(self, *_): + pass + + def do_GET(self): + self.handle_request() + + def do_POST(self): + self.handle_request() + + def drop(self): + self.close_connection = True + with contextlib.suppress(OSError): + self.connection.shutdown(socket.SHUT_RDWR) + self.connection.close() + + def handle_request(self): + self.connection.settimeout(30) + try: + payload, operation, command_id, headers, audit = self.validate_request() + with owner._mutex: + if not owner._manifest["connected"]: + if audit: + owner._event("disconnected_request", method=self.command, path=self.path, + operation=operation, command_id=command_id, + payload_sha256=protocol.sha(payload)) + self.drop() + return + fault = owner._manifest["fault"] + fault = copy.deepcopy(fault) if fault and fault["operation"] == operation else None + if audit: + sequence = owner._manifest["sequence"] + 1 + protocol.create_file(owner.root / "requests" / f"{sequence:06d}.bin", payload) + owner._event("received", _changes={"fault": None} if fault else None, + operation=operation, command_id=command_id, method=self.command, path=self.path, payload_sha256=protocol.sha(payload), fault=fault) + mode = fault["mode"] if fault else None + + def forward(copy_index): + if audit: + owner._event("forwarded", command_id=command_id, copy_index=copy_index, + payload_sha256=protocol.sha(payload)) + status, content = body_client.http_call(owner.upstream, self.command, self.path, headers, + payload if self.command == "POST" else None, + timeout=30, maximum=body_client.MAX_IMAGE) + if audit: + owner._event("upstream_reply", command_id=command_id, copy_index=copy_index, + http_status=status, response_sha256=protocol.sha(content)) + return status, content + + if mode == "duplicate": + with concurrent.futures.ThreadPoolExecutor(max_workers=2) as pool: + replies = [pool.submit(forward, index) for index in (1, 2)] + responses = [reply.result() for reply in replies] + status, content = responses[0] + owner._event("duplicate_replies", command_id=command_id, same_reply=responses[0] == responses[1]) + else: + status, content = forward(1) + if mode == "delay_after": + owner._event("delay_after", command_id=command_id, delay_s=fault["delay_s"]) + time.sleep(fault["delay_s"]) + if mode == "drop_after": + owner._event("dropped_after", command_id=command_id) + self.drop() + return + self.send_response(status) + self.send_header("Content-Type", "image/png" if self.path.startswith("/images/") else "application/json") + self.send_header("Content-Length", str(len(content))) + self.send_header("Connection", "close") + self.close_connection = True + self.end_headers() + self.wfile.write(content) + if audit: + owner._event("reply_sent", command_id=command_id, http_status=status) + except (OSError, http.client.HTTPException, protocol.Refusal, KeyError, TypeError, ValueError) as exc: + with contextlib.suppress(Exception): + owner._event("transport_failure", reason=str(exc)) + self.drop() + + def validate_request(self): + parsed = urlsplit(self.path) + if (self.headers.get_all("Host") != [owner.origin.removeprefix("http://")] or + self.headers.get("Origin") is not None or self.headers.get("Transfer-Encoding") is not None or + parsed.scheme or parsed.netloc or parsed.fragment or not self.path.startswith("/")): + raise protocol.Refusal("link requires exact loopback Host and no browser Origin") + read_route = parsed.path in {"/identity", "/state"} or parsed.path.startswith(("/commands/", "/images/")) + if (self.command == "GET" and not read_route) or (self.command == "POST" and self.path not in {"/lease", "/commands"}): + raise protocol.Refusal("unsupported link route") + for name in ("X-Body-Id", "X-Adapter-Id", "X-Source-Sha256"): + values = self.headers.get_all(name, []) + if len(values) > 1 or (parsed.path != "/identity" and len(values) != 1): + raise protocol.Refusal("one exact body identity header is required") + lengths = self.headers.get_all("Content-Length", []) + if len(lengths) > 1 or (lengths and (not lengths[0].isascii() or not lengths[0].isdigit() or + int(lengths[0]) > protocol.MAX_BYTES)): + raise protocol.Refusal("link payload exceeds its bounded size") + length = int(lengths[0]) if lengths else 0 + if self.command == "POST" and (length < 1 or self.headers.get_all("Content-Type") != ["application/json"]): + raise protocol.Refusal("link requires one exact bounded JSON body") + if self.command == "GET" and length: + raise protocol.Refusal("link read requests cannot have a payload") + payload = self.rfile.read(length) + if len(payload) != length: + raise protocol.Refusal("link payload is truncated") + operation = command_id = None + if self.command == "POST": + decoded = protocol.decode(payload) + if not isinstance(decoded, dict): + raise protocol.Refusal("link command payload must be an object") + if self.path == "/commands": + operation, command_id = decoded.get("operation"), decoded.get("command_id") + protocol.identity(operation) + protocol.identity(command_id) + else: + operation = "lease" + headers = {key: value for key, value in self.headers.items() if key.lower() not in + {"host", "connection", "content-length", "transfer-encoding"}} + headers["Content-Length"] = str(length) + return payload, operation, command_id, headers, parsed.path not in {"/identity", "/state"} + + server = ThreadingHTTPServer(("127.0.0.1", port), Handler) + server.daemon_threads = False + if not retained: + self.origin = f"http://127.0.0.1:{server.server_port}" + self._manifest = {"version": 1, "origin": self.origin, "upstream": self.upstream, "connected": True, + "fault": None, "sequence": 0, "event_sha256": None, + "source_sha256": protocol.sha(protocol.read_bytes(__file__))} + elif self._manifest["fault"] is not None: + cancelled = self._manifest["fault"] + self._event("fault_cancelled_on_restart", _changes={"fault": None}, fault=cancelled) + self._event("started", origin=self.origin, upstream=self.upstream, restarted=retained) + self._server, self._fd = server, fd + self._thread = threading.Thread(target=server.serve_forever, kwargs={"poll_interval": .1}, daemon=True) + self._thread.start() + return self + except Exception: + if server is not None: + server.server_close() + os.close(fd) + raise + + def set_connected(self, connected): + if type(connected) is not bool: + raise protocol.Refusal("connected state must be boolean") + with self._mutex: + if self._server is None: + raise protocol.Refusal("link is not running") + previous = self._manifest["connected"] + self._event("connected" if connected else "disconnected", _changes={"connected": connected}, previous_connected=previous, + replayed_requests=0) + return self._public() + + @staticmethod + def _validate_fault(mode, operation="dispatch", delay_s=.2): + if mode not in MODES or operation not in {"start_job", "observe", "propose", "dispatch", "disturb", "lease"}: + raise protocol.Refusal("unsupported workbench link diagnostic fault") + delay = protocol.finite(delay_s) + if not 0 <= delay <= 2: + raise protocol.Refusal("link delay exceeds its two-second budget") + return {"mode": mode, "operation": operation, "delay_s": delay} + + def arm(self, mode, operation="dispatch", delay_s=.2): + fault = self._validate_fault(mode, operation, delay_s) + with self._mutex: + if self._server is None or self._manifest["fault"] is not None: + raise protocol.Refusal("link must be running with no outstanding fault") + self._event("armed", _changes={"fault": fault}, **fault) + return self._public() + + def close(self): + if self._server is not None: + self._server.shutdown() + try: + self._server.server_close() + self._thread.join(timeout=2) + self._event("closed") + finally: + self._server = None + os.close(self._fd) + self._fd = None From bd3425ab4d99fc3b45644bb27f491aa5159758a7 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Sun, 11 Oct 2026 17:45:48 -0400 Subject: [PATCH 131/216] Record qualified browser workbench recovery and persistent handoff --- .../experiments/SIM10-network-workbench.md | 4 + .../notebook/2026-10-11-network-workbench.md | 14 + .../attempt-ledger.json | 18 + .../conformance-summary.json | 22 + .../fault-observations.json | 36 + .../network-workbench-20261011/handoff.json | 37 + .../process-ledger.json | 25 + .../qualification-score.json | 707 ++++++++++++++++++ .../network-workbench-20261011/report.md | 22 + .../retained-development-attempts.json | 32 + .../source-freeze.json | 31 + .../network-workbench-20261011/ui-ledger.json | 680 +++++++++++++++++ .../ui/disconnected.jpg | Bin 0 -> 87983 bytes .../network-workbench-20261011/ui/handoff.jpg | Bin 0 -> 83379 bytes .../ui/uncertain.jpg | Bin 0 -> 86984 bytes 15 files changed, 1628 insertions(+) create mode 100644 jevdual/results/network-workbench-20261011/attempt-ledger.json create mode 100644 jevdual/results/network-workbench-20261011/conformance-summary.json create mode 100644 jevdual/results/network-workbench-20261011/fault-observations.json create mode 100644 jevdual/results/network-workbench-20261011/handoff.json create mode 100644 jevdual/results/network-workbench-20261011/process-ledger.json create mode 100644 jevdual/results/network-workbench-20261011/qualification-score.json create mode 100644 jevdual/results/network-workbench-20261011/report.md create mode 100644 jevdual/results/network-workbench-20261011/retained-development-attempts.json create mode 100644 jevdual/results/network-workbench-20261011/source-freeze.json create mode 100644 jevdual/results/network-workbench-20261011/ui-ledger.json create mode 100644 jevdual/results/network-workbench-20261011/ui/disconnected.jpg create mode 100644 jevdual/results/network-workbench-20261011/ui/handoff.jpg create mode 100644 jevdual/results/network-workbench-20261011/ui/uncertain.jpg diff --git a/jevdual/docs/experiments/SIM10-network-workbench.md b/jevdual/docs/experiments/SIM10-network-workbench.md index 9922b97..4593144 100644 --- a/jevdual/docs/experiments/SIM10-network-workbench.md +++ b/jevdual/docs/experiments/SIM10-network-workbench.md @@ -21,3 +21,7 @@ Scope: same-Mac loopback simulation; remote authentication, hardware and emergen ## Amendment · 2026-10-11 17:27 Host admission is the durable checked stage write, before handing the exact command to BodyClient. Pause/Disconnect prevent later host admissions; an admitted request may reach the body after the control returns. The body retains its separate lease/freshness/effect checks. Qualification must not claim that Pause interrupts this in-flight request. Add a control-boundary check: pause before admission yields no command; pause after admission permits only that command to settle and admits no successor. + +## Result · 2026-10-11 17:44 + +Held on the first frozen actual-model/browser attempt at source `d731ac8ea03f326edef18ea9c1b9cb2027421871`. Ninety-four conformance checks passed. The actual browser showed lost-reply uncertainty, disconnected receipt refusal, transport-only reconnect, exact receipt recovery and explicit Resume. Two successive jobs completed with native placement, one SQLite measurement each and contact resets independently checked after trial cleanup. All 26 model calls used exact TCP images and bound core receipts; the client sent each command once. Duplicate and 0.8-second delay controls also ran. Reload preserved completed history without a new command. Restart preserved both identities and left the host paused with no active or pending work. Evidence and retained earlier failures: [report](../../results/network-workbench-20261011/report.md), [score](../../results/network-workbench-20261011/qualification-score.json), [attempt ledger](../../results/network-workbench-20261011/attempt-ledger.json). Scope remains loopback simulation. diff --git a/jevdual/docs/notebook/2026-10-11-network-workbench.md b/jevdual/docs/notebook/2026-10-11-network-workbench.md index 4e11918..39caa3a 100644 --- a/jevdual/docs/notebook/2026-10-11-network-workbench.md +++ b/jevdual/docs/notebook/2026-10-11-network-workbench.md @@ -76,3 +76,17 @@ Refs: tools/physical-workcell/output/sim10-network-runtime-final.log Observed: the final eighty unchanged-core, adapter, link and HTTP checks passed; combined with the fourteen runtime checks this is 94 passing checks. Ruff, JavaScript syntax, notebook checks and CLI preflight pass. No existing body/core/local-product source changed. One regression launch used an incorrect relative interpreter path and exited before tests; the corrected launch is retained separately. Next: commit measured source and run the first actual browser/model trial without source edits. Refs: tools/physical-workcell/output/sim10-core-link-http-regression.log; tools/physical-workcell/output/sim10-core-link-http-regression-v2.log; tools/physical-workcell/output/sim10-network-runtime-final.log + +## SIM10-U8 · update · 2026-10-11 17:44 +Resolves: SIM10-P1 = held +Observed: the first frozen actual Codex browser trial passed independent scoring after both owned trial processes exited. Two successive thirteen-call jobs advanced one body from generation zero to twenty with continuous native time, one verified SQLite measurement each and contact resets. The first dispatch reply was lost; the browser blocked the queue. Disconnect, reconnect and exact receipt lookup retained four command records without another send, and recovery remained paused until explicit Resume. Duplicate and 0.8-second delay controls were consumed once. Reload preserved both completed jobs and eighty commands. Every model image, typed proposal and lower receipt was independently bound; no private pose was supplied. The same roots and ports restarted with unchanged identities and history, paused with no active job or pending model request. +Inferred: browser-visible uncertainty and explicit recovery compose with the retained body adapter for this loopback simulation. This does not qualify hardware or authenticated remote deployment. +Next: hand off the running paused product and its runbook; preserve finite budgets and admission semantics. +Refs: results/network-workbench-20261011/report.md; results/network-workbench-20261011/qualification-score.json; results/network-workbench-20261011/ui-ledger.json; results/network-workbench-20261011/fault-observations.json; results/network-workbench-20261011/handoff.json + +## SIM10-S1 · summary · 2026-10-11 17:44 +Established: the browser workbench now queues actual image-guided jobs through a separate persistent TCP body. Local identity, freshness, lease and effect guards remain authoritative. Disconnect, uncertain replies and exact receipt recovery are visible product states, with explicit Resume and no hidden retry. +Evidence: 94 conformance checks and the first frozen actual-model browser trial passed. Two completed jobs, native/SQLite/contact proof, receipt and image binding, reload and paused restart are retained in the result package. Development failures remain separately recorded. +Uncertain: physical actuation, cross-machine authentication and long-running budget renewal remain outside qualification. An admitted bounded action can settle after Pause or Disconnect. +Decision: adopt the qualified loopback network workbench and hand off the running paused product with completed history retained. +Refs: docs/experiments/SIM10-network-workbench.md; results/network-workbench-20261011/report.md; results/network-workbench-20261011/attempt-ledger.json; tools/physical-workcell/NETWORK_WORKBENCH.md diff --git a/jevdual/results/network-workbench-20261011/attempt-ledger.json b/jevdual/results/network-workbench-20261011/attempt-ledger.json new file mode 100644 index 0000000..9423b82 --- /dev/null +++ b/jevdual/results/network-workbench-20261011/attempt-ledger.json @@ -0,0 +1,18 @@ +{ + "actual_model_attempts": [ + { + "attempt": 1, + "completed_cycles": 2, + "faults": "fault-observations.json", + "model_calls": 26, + "outcome": "passed", + "owned_trial_processes_reaped": true, + "planner": "actual_codex_cli_images_over_TCP", + "run_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim10-browser-ai-v1", + "source_commit": "d731ac8ea03f326edef18ea9c1b9cb2027421871", + "transport_commands": 80 + } + ], + "development_attempts": "retained-development-attempts.json", + "handoff": "handoff.json" +} diff --git a/jevdual/results/network-workbench-20261011/conformance-summary.json b/jevdual/results/network-workbench-20261011/conformance-summary.json new file mode 100644 index 0000000..578a2b9 --- /dev/null +++ b/jevdual/results/network-workbench-20261011/conformance-summary.json @@ -0,0 +1,22 @@ +{ + "additional_checks": [ + "Ruff new Python", + "JavaScript syntax", + "notebook schema", + "Codex CLI authenticated preflight" + ], + "failed_final": 0, + "passed": 94, + "suites": [ + { + "cases": 14, + "log": "tools/physical-workcell/output/sim10-network-runtime-final.log", + "scope": "real-socket queue, unknown stages, restart, health and control races" + }, + { + "cases": 80, + "log": "tools/physical-workcell/output/sim10-core-link-http-regression-v2.log", + "scope": "unchanged core, adapter, network fault matrix, retained link and browser HTTP boundaries" + } + ] +} diff --git a/jevdual/results/network-workbench-20261011/fault-observations.json b/jevdual/results/network-workbench-20261011/fault-observations.json new file mode 100644 index 0000000..6fa586d --- /dev/null +++ b/jevdual/results/network-workbench-20261011/fault-observations.json @@ -0,0 +1,36 @@ +{ + "actual_browser_faults": [ + { + "client_POSTs": 1, + "client_send_count": 1, + "command_id": "command-85f915f500a54459b605d7bb546a8cba", + "delay_s": null, + "forwarded_count": 1, + "mode": "dropped_after", + "retained_command_state": "completed", + "same_reply": null + }, + { + "client_POSTs": 1, + "client_send_count": 1, + "command_id": "command-0b59b5fe6d674a12b1ba2d56b7c83833", + "delay_s": null, + "forwarded_count": 2, + "mode": "duplicate_replies", + "retained_command_state": "completed", + "same_reply": true + }, + { + "client_POSTs": 1, + "client_send_count": 1, + "command_id": "command-9e3ed3f1ec7c45acb5ed2ad4e17b640f", + "delay_s": 0.8, + "forwarded_count": 1, + "mode": "delay_after", + "retained_command_state": "completed", + "same_reply": null + } + ], + "native_receipt_binding": "qualification-score.json", + "recovery_ledger": "ui-ledger.json" +} diff --git a/jevdual/results/network-workbench-20261011/handoff.json b/jevdual/results/network-workbench-20261011/handoff.json new file mode 100644 index 0000000..5b06a76 --- /dev/null +++ b/jevdual/results/network-workbench-20261011/handoff.json @@ -0,0 +1,37 @@ +{ + "processes": [ + { + "role": "body", + "pid": 65719, + "arguments": [ + "body_network.py", + "--root", + "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim10-browser-ai-v1/body", + "--diagnostic", + "--port", + "51373" + ] + }, + { + "role": "workbench", + "pid": 65723, + "arguments": [ + "network_bench_operator.py", + "serve", + "--root", + "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim10-browser-ai-v1/operator", + "--port", + "51377", + "--backend", + "codex" + ] + } + ], + "browser_origin": "http://127.0.0.1:51377", + "body_id": "a649def6a17f4401b475acd602c151f5", + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "runner_status": "paused", + "completed_jobs": 2, + "client_commands": 80, + "model_request_pending": false +} \ No newline at end of file diff --git a/jevdual/results/network-workbench-20261011/process-ledger.json b/jevdual/results/network-workbench-20261011/process-ledger.json new file mode 100644 index 0000000..15c4df7 --- /dev/null +++ b/jevdual/results/network-workbench-20261011/process-ledger.json @@ -0,0 +1,25 @@ +{ + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "body_id": "a649def6a17f4401b475acd602c151f5", + "body_origin": "http://127.0.0.1:51373", + "browser_origin": "http://127.0.0.1:51377", + "owned_processes_exited": true, + "planner": "actual_codex_cli_images_over_TCP", + "processes": [ + { + "exit_observed": true, + "pid": 51543, + "returncode": 0, + "role": "body" + }, + { + "exit_observed": true, + "pid": 51546, + "returncode": 0, + "role": "workbench" + } + ], + "ready": true, + "simulation": true, + "source_commit": "d731ac8ea03f326edef18ea9c1b9cb2027421871" +} diff --git a/jevdual/results/network-workbench-20261011/qualification-score.json b/jevdual/results/network-workbench-20261011/qualification-score.json new file mode 100644 index 0000000..aa83971 --- /dev/null +++ b/jevdual/results/network-workbench-20261011/qualification-score.json @@ -0,0 +1,707 @@ +{ + "body_id": "a649def6a17f4401b475acd602c151f5", + "browser_transitions_passed": true, + "calls": [ + { + "action": "move", + "call": 1, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12606, + "output_tokens": 197 + }, + "withheld": false + }, + { + "action": "move", + "call": 2, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12682, + "output_tokens": 155 + }, + "withheld": false + }, + { + "action": "measure", + "call": 3, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10752, + "input_tokens": 13168, + "output_tokens": 123 + }, + "withheld": false + }, + { + "action": "begin_reset", + "call": 4, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12823, + "output_tokens": 38 + }, + "withheld": false + }, + { + "action": "move", + "call": 5, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12884, + "output_tokens": 221 + }, + "withheld": false + }, + { + "action": "move", + "call": 6, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12959, + "output_tokens": 166 + }, + "withheld": false + }, + { + "action": "move", + "call": 7, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13034, + "output_tokens": 167 + }, + "withheld": false + }, + { + "action": "move", + "call": 8, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13035, + "output_tokens": 178 + }, + "withheld": false + }, + { + "action": "move", + "call": 9, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13039, + "output_tokens": 172 + }, + "withheld": false + }, + { + "action": "move", + "call": 10, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13042, + "output_tokens": 179 + }, + "withheld": false + }, + { + "action": "move", + "call": 11, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13053, + "output_tokens": 178 + }, + "withheld": false + }, + { + "action": "move", + "call": 12, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13467, + "output_tokens": 107 + }, + "withheld": false + }, + { + "action": "finish_reset", + "call": 13, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13049, + "output_tokens": 97 + }, + "withheld": false + }, + { + "action": "move", + "call": 1, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12610, + "output_tokens": 170 + }, + "withheld": false + }, + { + "action": "move", + "call": 2, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10752, + "input_tokens": 13097, + "output_tokens": 177 + }, + "withheld": false + }, + { + "action": "measure", + "call": 3, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12750, + "output_tokens": 111 + }, + "withheld": false + }, + { + "action": "begin_reset", + "call": 4, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12817, + "output_tokens": 42 + }, + "withheld": false + }, + { + "action": "move", + "call": 5, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12882, + "output_tokens": 198 + }, + "withheld": false + }, + { + "action": "move", + "call": 6, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12957, + "output_tokens": 265 + }, + "withheld": false + }, + { + "action": "move", + "call": 7, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13028, + "output_tokens": 146 + }, + "withheld": false + }, + { + "action": "move", + "call": 8, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13032, + "output_tokens": 161 + }, + "withheld": false + }, + { + "action": "move", + "call": 9, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13036, + "output_tokens": 181 + }, + "withheld": false + }, + { + "action": "move", + "call": 10, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10752, + "input_tokens": 13459, + "output_tokens": 154 + }, + "withheld": false + }, + { + "action": "move", + "call": 11, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13053, + "output_tokens": 158 + }, + "withheld": false + }, + { + "action": "move", + "call": 12, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13055, + "output_tokens": 117 + }, + "withheld": false + }, + { + "action": "finish_reset", + "call": 13, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13060, + "output_tokens": 98 + }, + "withheld": false + } + ], + "completed_cycles": 2, + "lost_reply_reconciled_without_resend": true, + "model_boundaries_passed": true, + "owned_processes_exited": true, + "passed": true, + "scope": "browser UI and actual image policy over loopback TCP simulation", + "scores": [ + { + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "measurement_receipt": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "generation": 2, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.533999999999613, + "operation_id": "agent-995e1490e4144fee886050b9ac44e6b5", + "source_kind": "mujoco_simulation", + "state_sha256": "ebb7a34ed4811733325084e937c4752a7fe9349c170fff8a2f3d5243bae73cf3", + "version": 1, + "worker_pid": 53676 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06582868246696554, + -8.393868978677625e-11, + 0.034995730455369786 + ], + "external_force_cleared": true, + "generation": 2, + "native_time_s": 5.533999999999613, + "pusher_home": false, + "pusher_xyz": [ + -0.049999969408768885, + 8.057882667829012e-26, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "ebb7a34ed4811733325084e937c4752a7fe9349c170fff8a2f3d5243bae73cf3" + }, + "model_calls": 13, + "motion_count": 10, + "passed": true, + "reset_receipt": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "kind": "finish_reset", + "native_time_s": 21.81399999999879, + "operation_id": "agent-2d5b35e1c4ad4dc8a7756bb73b70b0fa", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8140, + "state_sha256": "ff7af086a1eea92c53736c30a05c8102da4417d39f0423b48573218144fcb713" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11582763630912812, + -2.3633644648884637e-09, + 0.03499573045536985 + ], + "external_force_cleared": true, + "generation": 10, + "native_time_s": 21.81399999999879, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "ff7af086a1eea92c53736c30a05c8102da4417d39f0423b48573218144fcb713" + } + }, + { + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "measurement_receipt": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "generation": 12, + "image_sha256": "abfdb72469ad6d232f3198aec14980db23bba6ddf167d8cebd3a06b297486b35", + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "measurement": { + "block_box": [ + 345, + 159, + 387, + 201 + ], + "block_center_xy": [ + 0.07666666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 365.085020242915, + 179.50722961249278 + ], + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 26.349999999996275, + "operation_id": "agent-a6f487c1961a478384394c551e62dfa6", + "source_kind": "mujoco_simulation", + "state_sha256": "b404922ffb5f889a67d58db1cd318adf36480402268a5324245f7b5aaf8dc4fa", + "version": 1, + "worker_pid": 60485 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.07578824921321287, + -2.363334835175414e-09, + 0.034995730455369856 + ], + "external_force_cleared": true, + "generation": 12, + "native_time_s": 26.349999999996275, + "pusher_home": false, + "pusher_xyz": [ + -0.029999969671445637, + -3.033819548242173e-26, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "b404922ffb5f889a67d58db1cd318adf36480402268a5324245f7b5aaf8dc4fa" + }, + "model_calls": 13, + "motion_count": 10, + "passed": true, + "reset_receipt": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "block_home_verified": true, + "generation": 20, + "image_sha256": "2d2c4fcec313d713e1865aba74ba4fb11a792380d7ce2b6b694b4ff968aac95b", + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "kind": "finish_reset", + "native_time_s": 42.56200000000605, + "operation_id": "agent-9bc164e1269d4eb3861b243de5629fff", + "pusher_home_verified": true, + "reset_contact_samples": 3254, + "reset_native_steps": 8106, + "state_sha256": "a50d85406807ec8e44cc67fbd34d34802fc7d6dda176fdceda92c4cae5af162d" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11584066223827265, + -6.772213335361033e-09, + 0.034995730455369876 + ], + "external_force_cleared": true, + "generation": 20, + "native_time_s": 42.56200000000605, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "a50d85406807ec8e44cc67fbd34d34802fc7d6dda176fdceda92c4cae5af162d" + } + } + ], + "source_commit": "d731ac8ea03f326edef18ea9c1b9cb2027421871", + "source_unchanged": true, + "sqlite": { + "count": 2, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "generation": 12, + "image_sha256": "abfdb72469ad6d232f3198aec14980db23bba6ddf167d8cebd3a06b297486b35", + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "operation_id": "agent-a6f487c1961a478384394c551e62dfa6", + "receipt": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "generation": 12, + "image_sha256": "abfdb72469ad6d232f3198aec14980db23bba6ddf167d8cebd3a06b297486b35", + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "measurement": { + "block_box": [ + 345, + 159, + 387, + 201 + ], + "block_center_xy": [ + 0.07666666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 365.085020242915, + 179.50722961249278 + ], + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 26.349999999996275, + "operation_id": "agent-a6f487c1961a478384394c551e62dfa6", + "source_kind": "mujoco_simulation", + "state_sha256": "b404922ffb5f889a67d58db1cd318adf36480402268a5324245f7b5aaf8dc4fa", + "version": 1, + "worker_pid": 60485 + }, + "state_sha256": "b404922ffb5f889a67d58db1cd318adf36480402268a5324245f7b5aaf8dc4fa" + }, + { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "generation": 2, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "operation_id": "agent-995e1490e4144fee886050b9ac44e6b5", + "receipt": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "generation": 2, + "image_sha256": "0036a91468be0843afde149e0b028384dc45405c715d049191b94fda59392463", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.533999999999613, + "operation_id": "agent-995e1490e4144fee886050b9ac44e6b5", + "source_kind": "mujoco_simulation", + "state_sha256": "ebb7a34ed4811733325084e937c4752a7fe9349c170fff8a2f3d5243bae73cf3", + "version": 1, + "worker_pid": 53676 + }, + "state_sha256": "ebb7a34ed4811733325084e937c4752a7fe9349c170fff8a2f3d5243bae73cf3" + } + ] + }, + "transport_command_count": 80, + "transport_journal_bound": true, + "ui_steps": [ + "completed", + "delay_armed", + "disconnected", + "offline_receipt", + "reconnected", + "recovered", + "reloaded", + "resumed", + "uncertain" + ] +} diff --git a/jevdual/results/network-workbench-20261011/report.md b/jevdual/results/network-workbench-20261011/report.md new file mode 100644 index 0000000..dffff9f --- /dev/null +++ b/jevdual/results/network-workbench-20261011/report.md @@ -0,0 +1,22 @@ +# Browser workbench on a persistent body + +The first frozen browser/model trial passed. Two successive actual Codex jobs used camera images downloaded over TCP, recorded one measurement each and reset by contact on the same simulated body. A lost motion reply visibly blocked the queue. Disconnect and reconnect sent no commands; receipt lookup recovered the original result without resending its action and left the agent paused until explicit Resume. + +Measured source: `d731ac8ea03f326edef18ea9c1b9cb2027421871`, unchanged throughout qualification. The preregistered experiment is [SIM10](../../docs/experiments/SIM10-network-workbench.md); the full independent result is [qualification-score.json](qualification-score.json). + +| Job | Model calls | Measurement generation | Reset generation | Native time at reset | Reset contact samples | +| --- | ---: | ---: | ---: | ---: | ---: | +| Network inspection 01 | 13 | 2 | 10 | 21.814 s | 3,174 | +| Network inspection 02 | 13 | 12 | 20 | 42.562 s | 3,254 | + +The independent scorer ran after both owned trial processes exited. It checked native placement and home snapshots, continuous native time and generation, exact SQLite measurement receipts, image digests, model process exit, typed proposals and core receipts, single client sends and the browser transition ledger. All passed. The planner and browser host had no native state access. Reload retained both completed jobs and all 80 client command records without another command. + +The browser also exercised an exact duplicate and a 0.8-second delayed dispatch reply. The duplicate produced two upstream forwards, equal retained replies and one client send; the body/core receipt bound the result to the original command. Each diagnostic fault was consumed once. See [fault observations](fault-observations.json). The recovery controls blocked receipt lookup while disconnected. The visible Resume snapshot was captured immediately after the click; its public-state ledger was recorded later while the successive jobs were still running. + +Conformance passed 94 checks: fourteen real-socket runtime checks and eighty core, adapter, fault-matrix, link and HTTP checks. Ruff, JavaScript syntax, notebook schema and authenticated CLI preflight passed. Earlier failures and fixture corrections remain in [retained development attempts](retained-development-attempts.json); the one actual-model attempt is in [attempt-ledger.json](attempt-ledger.json). + +After scoring, the same roots and ports were restarted for handoff. Body and application identities, completed history and the 80-command journal persisted. The host is paused with no active job or pending model request. The browser is at `http://127.0.0.1:51377/`; the body is at `http://127.0.0.1:51373`. Handoff process ownership is recorded in [handoff.json](handoff.json). Use New job or Repeat job, then Resume. Connection diagnostics remain visible. + +This qualifies same-Mac loopback simulation. Physical hardware and authenticated control across machines remain untested. Pause blocks later admissions; an already admitted bounded action may finish. Queue, model and command budgets are finite. Run and restart instructions are in [NETWORK_WORKBENCH.md](../../../tools/physical-workcell/NETWORK_WORKBENCH.md). + +![Completed jobs and connection controls](ui/handoff.jpg) diff --git a/jevdual/results/network-workbench-20261011/retained-development-attempts.json b/jevdual/results/network-workbench-20261011/retained-development-attempts.json new file mode 100644 index 0000000..95e9a6e --- /dev/null +++ b/jevdual/results/network-workbench-20261011/retained-development-attempts.json @@ -0,0 +1,32 @@ +{ + "attempts": [ + { + "artifact": "tools/physical-workcell/output/sim10-link-tests-v1/unittest.log", + "outcome": "Eight of nine passed; wrong lexical command selector corrected, retained link behavior unchanged" + }, + { + "artifact": "tools/physical-workcell/output/sim10-idle-health-before-fix.log", + "outcome": "Original idle upstream outage not detected; bounded health added" + }, + { + "artifact": "tools/physical-workcell/output/sim10-resume-before-fix.log", + "outcome": "Original stale Resume overrode Pause; control epoch bound" + }, + { + "artifact": "tools/physical-workcell/output/sim10-stale-health-before-fix.log", + "outcome": "Original old failed health response paused a known completed native dispatch; transport epoch bound" + }, + { + "artifact": "tools/physical-workcell/output/sim10-network-runtime-tests-first.log", + "outcome": "Eleven of thirteen passed; local manifest reader and duplicate fixture initialization errors corrected" + }, + { + "artifact": "tools/physical-workcell/output/sim10-network-runtime-tests-second.log", + "outcome": "Thirteen passed before the final fourteen-case suite" + }, + { + "artifact": "tools/physical-workcell/output/sim10-core-link-http-regression.log", + "outcome": "Wrong relative interpreter path exited before tests; corrected launch retained separately" + } + ] +} diff --git a/jevdual/results/network-workbench-20261011/source-freeze.json b/jevdual/results/network-workbench-20261011/source-freeze.json new file mode 100644 index 0000000..8a622f7 --- /dev/null +++ b/jevdual/results/network-workbench-20261011/source-freeze.json @@ -0,0 +1,31 @@ +{ + "commit": "d731ac8ea03f326edef18ea9c1b9cb2027421871", + "files": { + "tools/camera-capture-experiment/capture.py": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "tools/physical-workcell/agent_bench.py": "e120dbfc9a96ca07fedb15226f27282265203755866210b86d5f856f6e3f5e07", + "tools/physical-workcell/bench.py": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "tools/physical-workcell/body_client.py": "40388c238192d923888c9852b363314801dcf65c7266aadc8c377d3810aeb33d", + "tools/physical-workcell/body_network.py": "95fd21597bcdd9e982a698859cd1219ae4522062e332c50fea233629dbfb343c", + "tools/physical-workcell/body_protocol.py": "1d24066768105c28b5cf6f4d46458e4e1b9d86cbde45ed6ce466b30da7ff974f", + "tools/physical-workcell/codex-action.schema.json": "e57197e4e73aa4c78145814a460ca77b9c6dc5e49aaf4c91adc0b521b7c3d833", + "tools/physical-workcell/codex-policy.md": "ce947200b2a652e0766b422f3b404bd5095ceb398569341466b2c5f4dd9647bc", + "tools/physical-workcell/codex_policy.py": "40fe73e01d97ee1e5cfdb813650b11edadbea29534784ab10cc1ef4e7f4d5418", + "tools/physical-workcell/episode_cases.py": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "tools/physical-workcell/image_guided.py": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961", + "tools/physical-workcell/measurement.py": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "tools/physical-workcell/network_bench_operator.html": "2f9ffefc17fe25136cc3cd9582aef0add2d6f52361a2cc78d8261c231539eef5", + "tools/physical-workcell/network_bench_operator.py": "9079729ea4e8b56ccdf2a6d187b0c5d79a23a33688748fe55d92d10922500b40", + "tools/physical-workcell/network_fault_proxy.py": "44b0b52f7c213c0f5f93b8997ba72be4e750bc9f1a4f7f6d7b2a8c4f1233b595", + "tools/physical-workcell/network_operator_runtime.py": "65f7e939a0a09be788c3f618aa1570eb19740d04640caccbb80e1ae57860bf34", + "tools/physical-workcell/order_protocol.py": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "tools/physical-workcell/qualify_bench.py": "524c537c1b310a0f0ae493acee99a069966a5e7c4b0a783daadf347094db58ef", + "tools/physical-workcell/qualify_network_body.py": "2800cf38afd21b86f8b035c46e994b6f96d966db4ccba1bba703e9e1a22f7c2b", + "tools/physical-workcell/qualify_network_workbench.py": "e5c72acda2ea8fae3658faba907448765df2f1e34e05749fbe85faed28ef003b", + "tools/physical-workcell/record_network_workbench.py": "7604865caa309c7002c01a2384da84eb62d8b22dcd63ab256618c536bc5fedc4", + "tools/physical-workcell/scene.xml": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "tools/physical-workcell/score_network_body.py": "d1f7150a5ff23775664b5656fd21379502ba71175487fd7aadb2b51bffcdaf8c", + "tools/physical-workcell/score_network_workbench.py": "67a53586081fe425bd14b0a0fbbf3d7f0fc1e66daccda06765bb88f3d9d4d84c", + "tools/physical-workcell/workbench_link.py": "578d94684463bcb3d7f2d45d9ba68abcd27d8a27f7f39538323a269e251c330e", + "tools/physical-workcell/workcell.py": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2" + } +} diff --git a/jevdual/results/network-workbench-20261011/ui-ledger.json b/jevdual/results/network-workbench-20261011/ui-ledger.json new file mode 100644 index 0000000..e47f9da --- /dev/null +++ b/jevdual/results/network-workbench-20261011/ui-ledger.json @@ -0,0 +1,680 @@ +{ + "steps": [ + { + "browser_action": "Queued two jobs, armed Lose next reply, resumed, and observed Outcome uncertain in the browser", + "client_commands": 4, + "name": "uncertain", + "pending_command_ids": [ + "command-85f915f500a54459b605d7bb546a8cba" + ], + "screenshot": "ui/uncertain.jpg", + "state": { + "active_job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "connection": { + "adapter_id": "9e322142a34a41bf87ea1a23f6c4adb2", + "body_id": "a649def6a17f4401b475acd602c151f5", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 1, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "label": "Network inspection 01", + "last_intent": "Push the block right until its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "label": "Network inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-85f915f500a54459b605d7bb546a8cba", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791754738.6793149, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t74 checkbox Network inspection 01 Needs attention, Value: 0\n\t\t\t75 checkbox Network inspection 02 Queued, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t76 text Network inspection 02\n\t\t77 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t78 text reply is uncertain; reconcile exact command without resending\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t79 text Body connected\n\t\t\t80 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button Check receipt, ID: reconcile\n\t\t\t58 container\n\t\t\t\t59 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t60 text Test the simulated connection\n\t\t\t\t61 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t62 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t63 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t64 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t81 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t82 text Last observation \u00b7 Network inspection 01\n\t\t\t73 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t83 text Captured \u00b7 generation 0\n\t\t84 text OUTCOME UNCERTAIN\n\t\t85 text The command outcome is uncertain. Reconnect if needed, then check its receipt before continuing.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t86 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t87 text 14 events\n\t\t\t43 content list activity\n\t\t\t\t88 container\n\t\t\t\t\t89 text 05:38 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t90 container\n\t\t\t\t\t91 text 05:38 PM Sending a guarded action\n\t\t\t\t92 container\n\t\t\t\t\t93 text 05:38 PM Action proposal accepted Network inspection 01\n\t\t\t\t94 container\n\t\t\t\t\t95 text 05:38 PM Checking the planned action\n\t\t\t\t96 container\n\t\t\t\t\t97 text 05:38 PM AI planning requested Network inspection 01\n\t\t\t\t98 container\n\t\t\t\t\t99 text 05:38 PM Camera observation received Network inspection 01\n\t\t\t\t100 container\n\t\t\t\t\t101 text 05:38 PM Requesting camera observation\n\t\t\t\t102 container\n\t\t\t\t\t103 text 05:38 PM Inspection started Network inspection 01\n\t\t\t\t104 container\n\t\t\t\t\t105 text 05:38 PM Preparing inspection\n\t\t\t\t106 container\n\t\t\t\t\t107 text 05:38 PM Agent resumed\n\t\t\t\t108 container\n\t\t\t\t\t109 text 05:38 PM Reply fault armed The next command reply will be lost.\n\t\t\t\t110 container\n\t\t\t\t\t111 text 05:37 PM Job queued Network inspection 02\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t112 text 1 model requests \u00b7 Reported tokens: 12,610 input / 170 output\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Clicked Disconnect and observed Body disconnected with retained camera", + "client_commands": 4, + "name": "disconnected", + "pending_command_ids": [ + "command-85f915f500a54459b605d7bb546a8cba" + ], + "screenshot": "ui/disconnected.jpg", + "state": { + "active_job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "connection": { + "adapter_id": "9e322142a34a41bf87ea1a23f6c4adb2", + "body_id": "a649def6a17f4401b475acd602c151f5", + "epoch": 1, + "fault": null, + "reason": "Diagnostic link disconnected; cached observations are retained", + "state": "disconnected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 1, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "label": "Network inspection 01", + "last_intent": "Push the block right until its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "label": "Network inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-85f915f500a54459b605d7bb546a8cba", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791754751.266366, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t74 checkbox Network inspection 01 Needs attention, Value: 0\n\t\t\t75 checkbox Network inspection 02 Queued, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t76 text Network inspection 02\n\t\t77 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t78 text reply is uncertain; reconcile exact command without resending\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t79 text Body disconnected\n\t\t\t80 text Diagnostic link disconnected; cached observations are retained\n\t\t\t20 button Reconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t58 container\n\t\t\t\t59 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t60 text Test the simulated connection\n\t\t\t\t61 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t62 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t63 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t64 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t81 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t82 text Retained observation \u00b7 body offline\n\t\t\t73 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t83 text Retained \u00b7 offline \u00b7 generation 0\n\t\t84 text DISCONNECTED\n\t\t85 text The body connection is unavailable. The last camera observation is retained.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t86 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t87 text 15 events\n\t\t\t43 content list activity\n\t\t\t\t88 container\n\t\t\t\t\t89 text 05:39 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t90 container\n\t\t\t\t\t91 text 05:38 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t92 container\n\t\t\t\t\t93 text 05:38 PM Sending a guarded action\n\t\t\t\t94 container\n\t\t\t\t\t95 text 05:38 PM Action proposal accepted Network inspection 01\n\t\t\t\t96 container\n\t\t\t\t\t97 text 05:38 PM Checking the planned action\n\t\t\t\t98 container\n\t\t\t\t\t99 text 05:38 PM AI planning requested Network inspection 01\n\t\t\t\t100 container\n\t\t\t\t\t101 text 05:38 PM Camera observation received Network inspection 01\n\t\t\t\t102 container\n\t\t\t\t\t103 text 05:38 PM Requesting camera observation\n\t\t\t\t104 container\n\t\t\t\t\t105 text 05:38 PM Inspection started Network inspection 01\n\t\t\t\t106 container\n\t\t\t\t\t107 text 05:38 PM Preparing inspection\n\t\t\t\t108 container\n\t\t\t\t\t109 text 05:38 PM Agent resumed\n\t\t\t\t110 container\n\t\t\t\t\t111 text 05:38 PM Reply fault armed The next command reply will be lost.\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t112 text 1 model requests \u00b7 Reported tokens: 12,610 input / 170 output\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Observed and checked that Check receipt is disabled while offline; did not force the disabled control", + "client_commands": 4, + "name": "offline_receipt", + "pending_command_ids": [ + "command-85f915f500a54459b605d7bb546a8cba" + ], + "screenshot": null, + "state": { + "active_job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "connection": { + "adapter_id": "9e322142a34a41bf87ea1a23f6c4adb2", + "body_id": "a649def6a17f4401b475acd602c151f5", + "epoch": 1, + "fault": null, + "reason": "Diagnostic link disconnected; cached observations are retained", + "state": "disconnected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 1, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "label": "Network inspection 01", + "last_intent": "Push the block right until its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "label": "Network inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-85f915f500a54459b605d7bb546a8cba", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791754751.363982, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t74 checkbox Network inspection 01 Needs attention, Value: 0\n\t\t\t75 checkbox Network inspection 02 Queued, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t76 text Network inspection 02\n\t\t77 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t78 text reply is uncertain; reconcile exact command without resending\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t79 text Body disconnected\n\t\t\t80 text Diagnostic link disconnected; cached observations are retained\n\t\t\t20 button Reconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t58 container\n\t\t\t\t59 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t60 text Test the simulated connection\n\t\t\t\t61 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t62 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t63 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t64 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t81 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t82 text Retained observation \u00b7 body offline\n\t\t\t73 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t83 text Retained \u00b7 offline \u00b7 generation 0\n\t\t84 text DISCONNECTED\n\t\t85 text The body connection is unavailable. The last camera observation is retained.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t86 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t87 text 15 events\n\t\t\t43 content list activity\n\t\t\t\t88 container\n\t\t\t\t\t89 text 05:39 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t90 container\n\t\t\t\t\t91 text 05:38 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t92 container\n\t\t\t\t\t93 text 05:38 PM Sending a guarded action\n\t\t\t\t94 container\n\t\t\t\t\t95 text 05:38 PM Action proposal accepted Network inspection 01\n\t\t\t\t96 container\n\t\t\t\t\t97 text 05:38 PM Checking the planned action\n\t\t\t\t98 container\n\t\t\t\t\t99 text 05:38 PM AI planning requested Network inspection 01\n\t\t\t\t100 container\n\t\t\t\t\t101 text 05:38 PM Camera observation received Network inspection 01\n\t\t\t\t102 container\n\t\t\t\t\t103 text 05:38 PM Requesting camera observation\n\t\t\t\t104 container\n\t\t\t\t\t105 text 05:38 PM Inspection started Network inspection 01\n\t\t\t\t106 container\n\t\t\t\t\t107 text 05:38 PM Preparing inspection\n\t\t\t\t108 container\n\t\t\t\t\t109 text 05:38 PM Agent resumed\n\t\t\t\t110 container\n\t\t\t\t\t111 text 05:38 PM Reply fault armed The next command reply will be lost.\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t112 text 1 model requests \u00b7 Reported tokens: 12,610 input / 170 output\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Clicked Reconnect; observed Body connected with Outcome uncertain and effects still disabled", + "client_commands": 4, + "name": "reconnected", + "pending_command_ids": [ + "command-85f915f500a54459b605d7bb546a8cba" + ], + "screenshot": null, + "state": { + "active_job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "connection": { + "adapter_id": "9e322142a34a41bf87ea1a23f6c4adb2", + "body_id": "a649def6a17f4401b475acd602c151f5", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 1, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "label": "Network inspection 01", + "last_intent": "Push the block right until its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "label": "Network inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-85f915f500a54459b605d7bb546a8cba", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791754759.127721, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t74 checkbox Network inspection 01 Needs attention, Value: 0\n\t\t\t75 checkbox Network inspection 02 Queued, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t76 text Network inspection 02\n\t\t77 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t78 text reply is uncertain; reconcile exact command without resending\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t79 text Body connected\n\t\t\t80 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button Check receipt, ID: reconcile\n\t\t\t58 container\n\t\t\t\t59 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t60 text Test the simulated connection\n\t\t\t\t61 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t62 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t63 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t64 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t81 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t82 text Last observation \u00b7 Network inspection 01\n\t\t\t73 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t83 text Captured \u00b7 generation 0\n\t\t84 text OUTCOME UNCERTAIN\n\t\t85 text The command outcome is uncertain. Reconnect if needed, then check its receipt before continuing.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t86 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t87 text 16 events\n\t\t\t43 content list activity\n\t\t\t\t88 container\n\t\t\t\t\t89 text 05:39 PM Body reconnecting No command sent or replayed\n\t\t\t\t90 container\n\t\t\t\t\t91 text 05:39 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t92 container\n\t\t\t\t\t93 text 05:38 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t94 container\n\t\t\t\t\t95 text 05:38 PM Sending a guarded action\n\t\t\t\t96 container\n\t\t\t\t\t97 text 05:38 PM Action proposal accepted Network inspection 01\n\t\t\t\t98 container\n\t\t\t\t\t99 text 05:38 PM Checking the planned action\n\t\t\t\t100 container\n\t\t\t\t\t101 text 05:38 PM AI planning requested Network inspection 01\n\t\t\t\t102 container\n\t\t\t\t\t103 text 05:38 PM Camera observation received Network inspection 01\n\t\t\t\t104 container\n\t\t\t\t\t105 text 05:38 PM Requesting camera observation\n\t\t\t\t106 container\n\t\t\t\t\t107 text 05:38 PM Inspection started Network inspection 01\n\t\t\t\t108 container\n\t\t\t\t\t109 text 05:38 PM Preparing inspection\n\t\t\t\t110 container\n\t\t\t\t\t111 text 05:38 PM Agent resumed\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t112 text 1 model requests \u00b7 Reported tokens: 12,610 input / 170 output\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Clicked Check receipt; observed Receipt recovered, disabled receipt control, and explicit Resume", + "client_commands": 4, + "name": "recovered", + "pending_command_ids": [], + "screenshot": "ui/recovered.jpg", + "state": { + "active_job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "connection": { + "adapter_id": "9e322142a34a41bf87ea1a23f6c4adb2", + "body_id": "a649def6a17f4401b475acd602c151f5", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 1, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "label": "Network inspection 01", + "last_intent": "Push the block right until its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "label": "Network inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-85f915f500a54459b605d7bb546a8cba", + "operation": "dispatch", + "reason": "Exact historical stage recovered; explicit Resume observes fresh evidence", + "state": "recovered" + }, + "runner_status": "paused" + }, + "time": 1791754767.347348, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t74 checkbox Network inspection 01 Needs attention, Value: 0\n\t\t\t75 checkbox Network inspection 02 Queued, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t76 text Network inspection 02\n\t\t77 text Paused\n\t\t16 button Resume, ID: pause\n\t\t78 text Receipt recovered. The agent is paused; choose Resume to observe the bench again and continue.\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t79 text Body connected\n\t\t\t80 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t58 container\n\t\t\t\t59 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t60 text Test the simulated connection\n\t\t\t\t61 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t62 button Lose next reply, ID: fault-drop\n\t\t\t\t63 button Delay next reply, ID: fault-delay\n\t\t\t\t64 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t81 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t82 text Last observation \u00b7 Network inspection 01\n\t\t\t73 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t83 text Captured \u00b7 generation 0\n\t\t84 text RECEIPT RECOVERED\n\t\t85 text The exact command receipt was recovered. The agent is paused until you resume.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t86 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t87 text 18 events\n\t\t\t43 content list activity\n\t\t\t\t88 container\n\t\t\t\t\t89 text 05:39 PM Command receipt recovered The agent remains paused until you resume.\n\t\t\t\t90 container\n\t\t\t\t\t91 text 05:39 PM Action receipt checked Network inspection 01\n\t\t\t\t92 container\n\t\t\t\t\t93 text 05:39 PM Body reconnecting No command sent or replayed\n\t\t\t\t94 container\n\t\t\t\t\t95 text 05:39 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t96 container\n\t\t\t\t\t97 text 05:38 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t98 container\n\t\t\t\t\t99 text 05:38 PM Sending a guarded action\n\t\t\t\t100 container\n\t\t\t\t\t101 text 05:38 PM Action proposal accepted Network inspection 01\n\t\t\t\t102 container\n\t\t\t\t\t103 text 05:38 PM Checking the planned action\n\t\t\t\t104 container\n\t\t\t\t\t105 text 05:38 PM AI planning requested Network inspection 01\n\t\t\t\t106 container\n\t\t\t\t\t107 text 05:38 PM Camera observation received Network inspection 01\n\t\t\t\t108 container\n\t\t\t\t\t109 text 05:38 PM Requesting camera observation\n\t\t\t\t110 container\n\t\t\t\t\t111 text 05:38 PM Inspection started Network inspection 01\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t112 text 1 model requests \u00b7 Reported tokens: 12,610 input / 170 output\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Armed one exact duplicate, clicked Resume, and observed Running; next decision takes a fresh TCP image", + "client_commands": 52, + "name": "resumed", + "pending_command_ids": [], + "screenshot": null, + "state": { + "active_job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "connection": { + "adapter_id": "9e322142a34a41bf87ea1a23f6c4adb2", + "body_id": "a649def6a17f4401b475acd602c151f5", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 12, + "image_url": "/api/frame?generation=12&sha256=abfdb72469ad6d232f3198aec14980db23bba6ddf167d8cebd3a06b297486b35" + }, + "jobs": [ + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "label": "Network inspection 01", + "last_intent": "Finish reset now that the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "kind": "finish_reset", + "native_time_s": 21.81399999999879, + "operation_id": "agent-2d5b35e1c4ad4dc8a7756bb73b70b0fa", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8140, + "state_sha256": "ff7af086a1eea92c53736c30a05c8102da4417d39f0423b48573218144fcb713" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 4, + "disturbance_test": false, + "error": null, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "label": "Network inspection 02", + "last_intent": "Begin the reset sequence after the verified measurement.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "measured", + "reset": null, + "status": "running", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791754896.69149, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t74 checkbox Network inspection 01 Needs attention, Value: 0\n\t\t\t75 checkbox Network inspection 02 Queued, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t76 text Network inspection 02\n\t\t77 text Running\n\t\t16 button Pause, ID: pause\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t78 text Body connected\n\t\t\t79 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t58 container\n\t\t\t\t59 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t60 text Test the simulated connection\n\t\t\t\t61 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t62 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t63 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t64 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t80 text The next command will be duplicated with the same identity.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t81 text Last observation \u00b7 Network inspection 01\n\t\t\t73 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t82 text Captured \u00b7 generation 0\n\t\t83 text QUEUED\n\t\t84 text This job is queued. The agent will start when the bench is ready.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t85 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t86 text 20 events\n\t\t\t43 content list activity\n\t\t\t\t87 container\n\t\t\t\t\t88 text 05:39 PM Agent resumed\n\t\t\t\t89 container\n\t\t\t\t\t90 text 05:39 PM Reply fault armed The next command will be duplicated with the same identity.\n\t\t\t\t91 container\n\t\t\t\t\t92 text 05:39 PM Command receipt recovered The agent remains paused until you resume.\n\t\t\t\t93 container\n\t\t\t\t\t94 text 05:39 PM Action receipt checked Network inspection 01\n\t\t\t\t95 container\n\t\t\t\t\t96 text 05:39 PM Body reconnecting No command sent or replayed\n\t\t\t\t97 container\n\t\t\t\t\t98 text 05:39 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t99 container\n\t\t\t\t\t100 text 05:38 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t101 container\n\t\t\t\t\t102 text 05:38 PM Sending a guarded action\n\t\t\t\t103 container\n\t\t\t\t\t104 text 05:38 PM Action proposal accepted Network inspection 01\n\t\t\t\t105 container\n\t\t\t\t\t106 text 05:38 PM Checking the planned action\n\t\t\t\t107 container\n\t\t\t\t\t108 text 05:38 PM AI planning requested Network inspection 01\n\t\t\t\t109 container\n\t\t\t\t\t110 text 05:38 PM Camera observation received Network inspection 01\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t111 text 1 model requests \u00b7 Reported tokens: 12,610 input / 170 output\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Clicked Delay next reply while the second job was running; the UI confirmed the one-shot diagnostic fault", + "client_commands": 66, + "name": "delay_armed", + "pending_command_ids": [], + "screenshot": null, + "state": { + "active_job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "connection": { + "adapter_id": "9e322142a34a41bf87ea1a23f6c4adb2", + "body_id": "a649def6a17f4401b475acd602c151f5", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 16, + "image_url": "/api/frame?generation=16&sha256=3fbc15f387e7d6bdfcc7acc65497d1904707776869995ca60f37dde177934c2d" + }, + "jobs": [ + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "label": "Network inspection 01", + "last_intent": "Finish reset now that the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "kind": "finish_reset", + "native_time_s": 21.81399999999879, + "operation_id": "agent-2d5b35e1c4ad4dc8a7756bb73b70b0fa", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8140, + "state_sha256": "ff7af086a1eea92c53736c30a05c8102da4417d39f0423b48573218144fcb713" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 9, + "disturbance_test": false, + "error": null, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "label": "Network inspection 02", + "last_intent": "Push the block leftward from its right side until its center reaches the home zone.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "resetting", + "reset": null, + "status": "running", + "target": "B" + } + ], + "model_request_pending": true, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791754929.899638, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t94 checkbox Network inspection 01 Completed, Value: 0\n\t\t\t95 checkbox Network inspection 02 Working, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t96 text Network inspection 02\n\t\t97 text Running\n\t\t16 button Pause, ID: pause\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t98 text Body connected\n\t\t\t99 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t58 container\n\t\t\t\t59 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t60 text Test the simulated connection\n\t\t\t\t61 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t62 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t63 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t64 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t100 text The next command reply will be delayed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t101 text Last observation \u00b7 Network inspection 02\n\t\t\t73 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t102 text Captured \u00b7 generation 12\n\t\t103 text AI IS WORKING\n\t\t104 text Move the pusher into the upper bypass lane before crossing to the block's right side.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t105 text Recorded\n\t\t\t86 container measurement-result\n\t\t\t\t106 text 1,729\n\t\t\t\t88 text Orange pixels\n\t\t\t\t89 container\n\t\t\t\t\t107 text 4,802.8\n\t\t\t\t\t91 text mm\u00b2\n\t\t\t\t92 text Apparent footprint\n\t\t\t\t93 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t108 text 24 events\n\t\t\t43 content list activity\n\t\t\t\t109 container\n\t\t\t\t\t110 text 05:41 PM Reply fault armed The next command reply will be delayed.\n\t\t\t\t111 container\n\t\t\t\t\t112 text 05:41 PM Sending a guarded action\n\t\t\t\t113 container\n\t\t\t\t\t114 text 05:41 PM Action proposal accepted Network inspection 02\n\t\t\t\t115 container\n\t\t\t\t\t116 text 05:41 PM Checking the planned action\n\t\t\t\t117 container\n\t\t\t\t\t118 text 05:41 PM AI planning requested Network inspection 02\n\t\t\t\t119 container\n\t\t\t\t\t120 text 05:41 PM Camera observation received Network inspection 02\n\t\t\t\t121 container\n\t\t\t\t\t122 text 05:41 PM Requesting camera observation\n\t\t\t\t123 container\n\t\t\t\t\t124 text 05:41 PM Action receipt checked Network inspection 02\n\t\t\t\t125 container\n\t\t\t\t\t126 text 05:41 PM Sending a guarded action\n\t\t\t\t127 container\n\t\t\t\t\t128 text 05:41 PM Action proposal accepted Network inspection 02\n\t\t\t\t129 container\n\t\t\t\t\t130 text 05:41 PM Checking the planned action\n\t\t\t\t131 container\n\t\t\t\t\t132 text 05:41 PM AI planning requested Network inspection 02\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t133 text 18 model requests \u00b7 Reported tokens: 232,999 input / 2,712 output\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Observed both successive AI jobs Completed with recorded measurements and verified contact resets", + "client_commands": 80, + "name": "completed", + "pending_command_ids": [], + "screenshot": "tools/physical-workcell/output/sim10-browser-ai-v1/ui/completed.jpg", + "state": { + "active_job_id": null, + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "connection": { + "adapter_id": "9e322142a34a41bf87ea1a23f6c4adb2", + "body_id": "a649def6a17f4401b475acd602c151f5", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 20, + "image_url": "/api/frame?generation=20&sha256=2d2c4fcec313d713e1865aba74ba4fb11a792380d7ce2b6b694b4ff968aac95b" + }, + "jobs": [ + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "label": "Network inspection 01", + "last_intent": "Finish reset now that the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "kind": "finish_reset", + "native_time_s": 21.81399999999879, + "operation_id": "agent-2d5b35e1c4ad4dc8a7756bb73b70b0fa", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8140, + "state_sha256": "ff7af086a1eea92c53736c30a05c8102da4417d39f0423b48573218144fcb713" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "label": "Network inspection 02", + "last_intent": "Finish reset now that the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "block_home_verified": true, + "generation": 20, + "image_sha256": "2d2c4fcec313d713e1865aba74ba4fb11a792380d7ce2b6b694b4ff968aac95b", + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "kind": "finish_reset", + "native_time_s": 42.56200000000605, + "operation_id": "agent-9bc164e1269d4eb3861b243de5629fff", + "pusher_home_verified": true, + "reset_contact_samples": 3254, + "reset_native_steps": 8106, + "state_sha256": "a50d85406807ec8e44cc67fbd34d34802fc7d6dda176fdceda92c4cae5af162d" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791754971.431434, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t109 checkbox Network inspection 01 Completed, Value: 0\n\t\t\t110 checkbox Network inspection 02 Completed, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t111 text Network inspection 02\n\t\t112 text Running\n\t\t16 button Pause, ID: pause\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t113 text Body connected\n\t\t\t114 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t58 container\n\t\t\t\t59 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t60 text Test the simulated connection\n\t\t\t\t61 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t62 button Lose next reply, ID: fault-drop\n\t\t\t\t63 button Delay next reply, ID: fault-delay\n\t\t\t\t64 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t115 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t116 text Last camera observation\n\t\t\t73 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t117 text Captured \u00b7 generation 20\n\t\t118 text COMPLETED\n\t\t119 text Measurement recorded and reset verified. The bench is ready for another job.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t120 text Historical result\n\t\t\t86 container measurement-result\n\t\t\t\t121 text 1,729\n\t\t\t\t88 text Orange pixels\n\t\t\t\t89 container\n\t\t\t\t\t122 text 4,802.8\n\t\t\t\t\t91 text mm\u00b2\n\t\t\t\t92 text Apparent footprint\n\t\t\t\t93 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment.\n\t\t\t108 button Repeat job, ID: repeat\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t123 text 24 events\n\t\t\t43 content list activity\n\t\t\t\t124 container\n\t\t\t\t\t125 text 05:42 PM Action receipt checked Network inspection 02\n\t\t\t\t126 container\n\t\t\t\t\t127 text 05:42 PM Sending a guarded action\n\t\t\t\t128 container\n\t\t\t\t\t129 text 05:42 PM Action proposal accepted Network inspection 02\n\t\t\t\t130 container\n\t\t\t\t\t131 text 05:42 PM Checking the planned action\n\t\t\t\t132 container\n\t\t\t\t\t133 text 05:42 PM AI planning requested Network inspection 02\n\t\t\t\t134 container\n\t\t\t\t\t135 text 05:42 PM Camera observation received Network inspection 02\n\t\t\t\t136 container\n\t\t\t\t\t137 text 05:42 PM Requesting camera observation\n\t\t\t\t138 container\n\t\t\t\t\t139 text 05:42 PM Action receipt checked Network inspection 02\n\t\t\t\t140 container\n\t\t\t\t\t141 text 05:42 PM Sending a guarded action\n\t\t\t\t142 container\n\t\t\t\t\t143 text 05:42 PM Action proposal accepted Network inspection 02\n\t\t\t\t144 container\n\t\t\t\t\t145 text 05:42 PM Checking the planned action\n\t\t\t\t146 container\n\t\t\t\t\t147 text 05:42 PM AI planning requested Network inspection 02\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t148 text 26 model requests \u00b7 Reported tokens: 337,677 input / 3,956 output\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Reloaded the browser and observed both completed jobs, measurements, and the same body identity without command replay", + "client_commands": 80, + "name": "reloaded", + "pending_command_ids": [], + "screenshot": "tools/physical-workcell/output/sim10-browser-ai-v1/ui/reloaded.jpg", + "state": { + "active_job_id": null, + "app_id": "7560f614128c40c7b9d82a7a20f35435", + "connection": { + "adapter_id": "9e322142a34a41bf87ea1a23f6c4adb2", + "body_id": "a649def6a17f4401b475acd602c151f5", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 20, + "image_url": "/api/frame?generation=20&sha256=2d2c4fcec313d713e1865aba74ba4fb11a792380d7ce2b6b694b4ff968aac95b" + }, + "jobs": [ + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "label": "Network inspection 01", + "last_intent": "Finish reset now that the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "60cf7b32-5b88-40d7-8534-14d1e0497557", + "kind": "finish_reset", + "native_time_s": 21.81399999999879, + "operation_id": "agent-2d5b35e1c4ad4dc8a7756bb73b70b0fa", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8140, + "state_sha256": "ff7af086a1eea92c53736c30a05c8102da4417d39f0423b48573218144fcb713" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "label": "Network inspection 02", + "last_intent": "Finish reset now that the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "a649def6a17f4401b475acd602c151f5", + "block_home_verified": true, + "generation": 20, + "image_sha256": "2d2c4fcec313d713e1865aba74ba4fb11a792380d7ce2b6b694b4ff968aac95b", + "job_id": "134b0e3d-6428-4614-8c67-7a6912852790", + "kind": "finish_reset", + "native_time_s": 42.56200000000605, + "operation_id": "agent-9bc164e1269d4eb3861b243de5629fff", + "pusher_home_verified": true, + "reset_contact_samples": 3254, + "reset_native_steps": 8106, + "state_sha256": "a50d85406807ec8e44cc67fbd34d34802fc7d6dda176fdceda92c4cae5af162d" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791754981.420227, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t9 checkbox Network inspection 01 Completed, Value: 0\n\t\t\t10 checkbox Network inspection 02 Completed, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t14 text Network inspection 02\n\t\t15 text Running\n\t\t16 button Pause, ID: pause\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t18 text Body connected\n\t\t\t19 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t22 button (collapsed) Test the simulated connection, Secondary Actions: Expand\n\t\t\t\t23 text Test the simulated connection\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t26 text Last camera observation\n\t\t\t27 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t29 text Captured \u00b7 generation 20\n\t\t30 text COMPLETED\n\t\t31 text Measurement recorded and reset verified. The bench is ready for another job.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t37 text Historical result\n\t\t\t38 container measurement-result\n\t\t\t\t39 text 1,729\n\t\t\t\t40 text Orange pixels\n\t\t\t\t41 container\n\t\t\t\t\t42 text 4,802.8\n\t\t\t\t\t43 text mm\u00b2\n\t\t\t\t44 text Apparent footprint\n\t\t\t\t45 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment.\n\t\t\t46 button Repeat job, ID: repeat\n\t\t47 container Activity\n\t\t\t48 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t49 text Activity\n\t\t\t50 text 24 events\n\t\t\t51 content list activity\n\t\t\t\t52 container\n\t\t\t\t\t53 text 05:42 PM Action receipt checked Network inspection 02\n\t\t\t\t54 container\n\t\t\t\t\t55 text 05:42 PM Sending a guarded action\n\t\t\t\t56 container\n\t\t\t\t\t57 text 05:42 PM Action proposal accepted Network inspection 02\n\t\t\t\t58 container\n\t\t\t\t\t59 text 05:42 PM Checking the planned action\n\t\t\t\t60 container\n\t\t\t\t\t61 text 05:42 PM AI planning requested Network inspection 02\n\t\t\t\t62 container\n\t\t\t\t\t63 text 05:42 PM Camera observation received Network inspection 02\n\t\t\t\t64 container\n\t\t\t\t\t65 text 05:42 PM Requesting camera observation\n\t\t\t\t66 container\n\t\t\t\t\t67 text 05:42 PM Action receipt checked Network inspection 02\n\t\t\t\t68 container\n\t\t\t\t\t69 text 05:42 PM Sending a guarded action\n\t\t\t\t70 container\n\t\t\t\t\t71 text 05:42 PM Action proposal accepted Network inspection 02\n\t\t\t\t72 container\n\t\t\t\t\t73 text 05:42 PM Checking the planned action\n\t\t\t\t74 container\n\t\t\t\t\t75 text 05:42 PM AI planning requested Network inspection 02\n\t\t76 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t77 text Session details\n\t\t78 text 26 model requests \u00b7 Reported tokens: 337,677 input / 3,956 output\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + } + ] +} diff --git a/jevdual/results/network-workbench-20261011/ui/disconnected.jpg b/jevdual/results/network-workbench-20261011/ui/disconnected.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8a1fc3c2d5977bff63eb1ed0ec77d8737be77757 GIT binary patch literal 87983 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

    )U)AsQSW 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%0D< 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 bJ75SwzHW>FSy(sx3qbrYIQxH({U!YyoyZJ* literal 0 HcmV?d00001 diff --git a/jevdual/results/network-workbench-20261011/ui/uncertain.jpg b/jevdual/results/network-workbench-20261011/ui/uncertain.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6be6c5af9d4d916fd1fe55fd0a4288c409f748a0 GIT binary patch literal 86984 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ℜ4;B#(tvFnGH4a4l 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 JZdDq&Phq8&|N3Km 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 I>9?_e0G83}{r~^~ literal 0 HcmV?d00001 From 6ba67ea076d3d0719facc41d296e73800829270e Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 13:56:38 -0400 Subject: [PATCH 132/216] Preregister AX fixture cleanup and startup qualification for packet v4 --- .../2026-10-12-onboarding-fixture-v4.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md diff --git a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md new file mode 100644 index 0000000..8e8e0b6 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md @@ -0,0 +1,22 @@ +# Onboarding fixture v4 + +## UF1 · prediction · 2026-10-12 13:56 +Hypothesis: closing the unique fixture document by exact AXDocument identity and its AXCloseButton, with any discard button confined to its observed attached save sheet, removes the Automation grant while preserving unrelated documents. +Test: first reproduce the old cleanup limitation in boundary scenarios; cover exact-path duplicates, same-name other paths, changed identity, attached versus unrelated sheets, unsuccessful AX presses and verified window disappearance. Then run the frozen new helper on the disposable guest with Automation declined and an edited owned document; check its receipt and independent owned-resource absence. +Predicts: the exact owned window closes automatically with only existing Accessibility, no Apple Event/Automation route executes, and ambiguous/changed/unobservable targets refuse without closing another window. Cleanup remains independent of browser/listener shutdown. +Against: another window or app-level dialog is acted on, the helper claims closure without observed disappearance, leaks the owned browser/listener on AX failure, or needs an extra permission. +Refs: results/u2-independent-onboarding-20261011-v1; results/u2-independent-onboarding-20261011-v2-dev; local Arc CUA6b353039 benchmarks/workflows.py:533; Claude1791753660836044000 + +## UF2 · prediction · 2026-10-12 13:56 +Hypothesis: separately bounded owned-browser startup readiness followed by the unchanged unique-window identity deadline classifies slow first launch without weakening resource identity. +Test: first preserve a slow-start/ambiguous-identity failing scenario against the old helper. Exercise delayed readiness, browser exit, startup timeout, missing/ambiguous windows and successful unique identity; freeze packetv4 and run its installed public path after normal Chrome verification. Keep every failure in distinct fresh run directories. +Predicts: delayed startup gets its own phase and bounded typed receipt/exit, identity ambiguity still refuses after its own deadline, a stopped browser never emits ready, and setup failures run bounded owned cleanup without traceback-only reporting. +Against: a late or foreign browser/window is adopted, ambiguous identity becomes authorized, timeout remains unclassified, or launch failure bypasses cleanup. +Refs: scripts/capability_fixture.py; local Chrome DevTools MCPf08dbe152502d66e75fa07fb2588dc0feb42bc20 src/BrowserManager.ts; UO5 in docs/notebook/2026-10-10-independent-onboarding.md + +## UF3 · prediction · 2026-10-12 13:56 +Hypothesis: a source-frozen packetv4 with the unchanged reviewed wheel permits a separately recorded denied-to-granted guest Terminal journey and fully automatic owned cleanup. +Test: build twice and verify exact inventory/source binding, review the artifact with Claude, then run an independently recorded guest permission journey with denied doctor/refusal, captured authorized grant, host restart, installed append/replay/report and automatic cleanup. Use the existing disposable guest only after an approved supported per-host Accessibility reset; preserve its v1/v2 evidence and label this as fresh permission state on a previously provisioned guest, not a newly cold OS. +Predicts: packet hashes repeat, denied fixture creates no resources, captured same-host grant and post-restart strict doctor pass, native oracle holds one effect/row, and cleanup confirms the exact document/browser/listener/worker without operator close or Automation grant. +Against: packet depends on runtime source/Git, grant remains uncaptured, native effect duplicates, cleanup is manual or needs extra access, or earlier failed evidence is regraded. +Refs: docs/experiments/U2-independent-onboarding.md; docs/independent-onboarding.md; results/u2-independent-onboarding-20261011-v2-dev From 0ae6d2a80162580dce8c52aec0b75b538ec5984e Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 13:57:29 -0400 Subject: [PATCH 133/216] Preregister mid-job body and workbench restart qualification --- .../experiments/SIM11-workbench-restarts.md | 19 +++++++++++++++++++ .../notebook/2026-10-12-workbench-restarts.md | 8 ++++++++ 2 files changed, 27 insertions(+) create mode 100644 jevdual/docs/experiments/SIM11-workbench-restarts.md create mode 100644 jevdual/docs/notebook/2026-10-12-workbench-restarts.md diff --git a/jevdual/docs/experiments/SIM11-workbench-restarts.md b/jevdual/docs/experiments/SIM11-workbench-restarts.md new file mode 100644 index 0000000..3a6ee85 --- /dev/null +++ b/jevdual/docs/experiments/SIM11-workbench-restarts.md @@ -0,0 +1,19 @@ +# SIM11: Mid-job process restart and browser recovery + +Hypothesis: the retained queue, exact command journal and historical body receipts preserve a camera-guided job across process restarts, including after a dispatch reply is lost, without replaying actions. + +Predictions if true: restarting the workbench while planning cancels its owned model process and leaves the retained job paused. A visible body outage during planning pauses and cancels the host; reboot preserves body identity and motion state while revoking old leases. Restarting either process with an uncertain dispatch preserves the exact pending command, body and application identities and client send count. Receipt recovery reads the original result, requires explicit Resume and obtains a fresh TCP image before the next decision. + +Predictions if false: a restart silently resumes planning, repeats an uncertain command, resets the body or loses its identity, releases an unknown outcome without proof, leaves an orphan model process or completes a job without measurement and reset evidence. + +Design: preserve the current paused completed product. Add a separate owned restart harness and independent scorer around the unchanged TCP body, link and browser workbench. Use two new actual Codex jobs in a fresh trial root. On job one, stop/restart the workbench during model planning and later while a dispatch is uncertain. On job two, stop the body during model planning long enough to observe an outage, restart it, and later stop/restart it while a different dispatch is uncertain. All product recovery actions use the real browser. Harness process controls use exact owned PIDs, retained roots and ports, checked public-state predicates and independent journal snapshots. Graceful process termination is the tested interruption; process kill during native file persistence is outside this trial. + +Primary metric: all four interruptions recover visibly without another send of the interrupted command, followed by two independently verified continuous native placement/measurement/contact-reset cycles on one body. + +Secondary checks: stopped workbench model processes are reaped; body epochs advance and stale leases cannot dispatch; restart is paused or blocked until explicit recovery; retained camera frames cannot grant new authority; a fresh observation precedes the next decision. Reload retains final results. Existing restart conformance and affected guards remain passing. + +Guardrails: commit predictions before tests, freeze all measured source before model calls, preserve failing attempts, keep original body/core/client guard source unchanged unless a demonstrated defect requires a separately preregistered repair, use bounded owned process controls, never initialize a retained body again, never replay an uncertain request, no private pose in model inputs and no hidden automatic Resume. Independent native scoring runs only after all trial processes stop. No new remote access or hardware actuation. + +Decision rule: report restart recovery verified only if all four product interruptions and the independent scorer pass. If any boundary fails, retain its evidence and report the exact mismatch without promoting unaffected checks to a full pass. Hand off a paused connected product only after successful scoring; otherwise return to the preserved product. + +Scope: two actual-model jobs, graceful owned process restarts, same-Mac loopback simulation. Abrupt power loss and torn native writes remain untested. diff --git a/jevdual/docs/notebook/2026-10-12-workbench-restarts.md b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md new file mode 100644 index 0000000..d3f349d --- /dev/null +++ b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md @@ -0,0 +1,8 @@ +# Mid-job restart and explicit browser recovery + +## SIM11-P1 · prediction · 2026-10-12 13:56 +Hypothesis: a pending browser stage and single-send command journal survive independent workbench and body restarts without resending an uncertain action; historical body receipts can settle the same stage after its boot epoch changes. +Test: freeze a fresh owned process harness, interrupt two actual image-guided browser jobs at planning and uncertain-dispatch boundaries, recover through the UI and independently score native/SQLite/contact records after cleanup. +Predicts: all four stops/restarts preserve body/application identity and client send counts, planning interruption cancels and reaps its model process, uncertain commands remain blocked until exact receipt lookup, and explicit Resume uses a fresh TCP image before completing both jobs. +Against: a replay, lost pending command, silently resumed planning, orphan model process, body reset or independent verification failure. +Refs: docs/experiments/SIM11-workbench-restarts.md; tools/physical-workcell/qualify_workbench_restarts.py; tools/physical-workcell/score_workbench_restarts.py; results/workbench-restarts-20261012/ From 4f41dfabd113ffb39a7fc2d3ab178a74fbe43d7e Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 13:58:20 -0400 Subject: [PATCH 134/216] Predict fast body reboot invalidation before command admission --- jevdual/docs/experiments/SIM11-workbench-restarts.md | 4 ++++ jevdual/docs/notebook/2026-10-12-workbench-restarts.md | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/jevdual/docs/experiments/SIM11-workbench-restarts.md b/jevdual/docs/experiments/SIM11-workbench-restarts.md index 3a6ee85..8b38e06 100644 --- a/jevdual/docs/experiments/SIM11-workbench-restarts.md +++ b/jevdual/docs/experiments/SIM11-workbench-restarts.md @@ -17,3 +17,7 @@ Guardrails: commit predictions before tests, freeze all measured source before m Decision rule: report restart recovery verified only if all four product interruptions and the independent scorer pass. If any boundary fails, retain its evidence and report the exact mismatch without promoting unaffected checks to a full pass. Hand off a paused connected product only after successful scoring; otherwise return to the preserved product. Scope: two actual-model jobs, graceful owned process restarts, same-Mac loopback simulation. Abrupt power loss and torn native writes remain untested. + +## Amendment · 2026-10-12 13:58 + +Read-only review found that a fast body reboot can fall between health polls: unchanged body identity with a new epoch currently leaves the host running and permits lease refresh around an old model decision. Add a real-socket reproduction before repair. A changed known boot epoch must invalidate the model decision and pause before a new command admission, including when the lease-acquisition read sees it before the health worker does. Pending historical commands must remain recoverable across that epoch change without lease rotation or replay. The live body-planning restart will also challenge the fast path; retained body identity and motion state remain intact. diff --git a/jevdual/docs/notebook/2026-10-12-workbench-restarts.md b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md index d3f349d..b5d7569 100644 --- a/jevdual/docs/notebook/2026-10-12-workbench-restarts.md +++ b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md @@ -6,3 +6,10 @@ Test: freeze a fresh owned process harness, interrupt two actual image-guided br Predicts: all four stops/restarts preserve body/application identity and client send counts, planning interruption cancels and reaps its model process, uncertain commands remain blocked until exact receipt lookup, and explicit Resume uses a fresh TCP image before completing both jobs. Against: a replay, lost pending command, silently resumed planning, orphan model process, body reset or independent verification failure. Refs: docs/experiments/SIM11-workbench-restarts.md; tools/physical-workcell/qualify_workbench_restarts.py; tools/physical-workcell/score_workbench_restarts.py; results/workbench-restarts-20261012/ + +## SIM11-EPOCH · prediction · 2026-10-12 13:58 +Hypothesis: a changed body boot epoch can preserve running state when its outage is missed, because health and lease acquisition verify stable identity without invalidating the old decision. Binding epoch changes to Pause before command admission will cancel stale planning without disturbing historical receipt recovery. +Test: reproduce on real sockets by rebooting the same body while a model decision waits, avoiding an outage poll; release the old decision after the new epoch is read. Cover health-first and admission-read-first paths, then rerun with epoch invalidation. Separately retain uncertain historical dispatch recovery across reboot. +Predicts: the original fast-reboot path admits the old decision; the repaired path pauses with no successor command, requires explicit Resume and a fresh observation, and retains exact unknown command identity for read-only recovery. +Against: original code already pauses, repaired code sends the old decision, permanently blocks historical receipt lookup, or silently rotates authority while a command remains uncertain. +Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py; docs/experiments/SIM11-workbench-restarts.md From 96be8bb63db64cdfb24075e5e82bd2262b77e06b Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 13:58:51 -0400 Subject: [PATCH 135/216] Specify packet v4 startup phases and captured guest permission rerun --- .../U3-packet-v4-permission-journey.md | 31 +++++++++++++++++++ jevdual/docs/independent-onboarding.md | 10 +++--- 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 jevdual/docs/experiments/U3-packet-v4-permission-journey.md diff --git a/jevdual/docs/experiments/U3-packet-v4-permission-journey.md b/jevdual/docs/experiments/U3-packet-v4-permission-journey.md new file mode 100644 index 0000000..2902d0a --- /dev/null +++ b/jevdual/docs/experiments/U3-packet-v4-permission-journey.md @@ -0,0 +1,31 @@ +# U3: packet v4 permission-state qualification + +Registered2026-10-12 before packet freeze and guest execution. This is a development qualification after the original U2 failure, not a regrade of that measurement or a heldout retry. + +## Hypothesis + +Exact-document AX cleanup and separate bounded browser startup/identity phases permit the installed public path and fully automatic owned-resource cleanup with Accessibility alone, following a captured denied-to-granted transition. + +## Predictions + +If true: the frozen packet repeats byte-for-byte and matches its immutable source; strict denied doctor exits1, fixture refusal creates no directory; the approved same Terminal host transition is captured off-to-on; after restart the installed public trial confirms one native effect, one ledger row, same-token replay and an accepted completion report; automatic exact-document/browser/listener/worker cleanup is confirmed without Automation or operator close. + +If false: a required denial/transition/native gate is absent, another resource is acted on, launch health substitutes for identity, cleanup needs another permission/operator, or a source/development environment supplies the runtime. A required gate cannot be replaced by an assertion or generic success receipt. + +## Design + +Preserve original U2 v1 and v2. Freeze v4 from committed source with the already reviewed wheel unchanged. Record preparation checks, source/packet/wheel hashes and Claude review. Use the existing independently provisioned SIP-enabled disposable guest, after approved supported per-host Accessibility reset. Label the run as fresh permission state on a previously provisioned OS with browser prerequisites already installed; do not claim a new cold OS or first Chrome launch. Extract v4 into a new root, verify pristine members, and cold-install public dependencies into a new venv/private home/cache. No SSH, clipboard/host shares, pregranted seed, provider keys, TCC database edits or SIP changes. + +Run denied diagnostics/refusal from the guest interactive Terminal; retain and visibly hash baseline bytes before granting. Capture actual approval, switch actor/time and restart. Run the generated isolated installed MCP command and detached worker, then Ctrl-C fixture cleanup. Preserve raw receipts and the read-only journal. Export only after execution/cleanup via a bounded fixed-artifact VM-bridge transfer, with hash readback and receiver shutdown. If the guest locks or requests authentication, the human supplies credentials; never log them. + +## Primary metric and guardrails + +Primary metric: all required permission, installed native and automatic cleanup gates pass in this one frozen run. Any required miss marks the run failed or unverified according to observed evidence. Disk persistence is not_checked. No extra discovery, Automation or Screen Recording grant is supplied for this AX slice; decline unexpected prompts and preserve them. No repeated input to mask uncertainty; same-token replay uses the durable protocol. No unrelated process/window close or evidence deletion. + +## Decision rule + +Accept only this scoped permission-state journey when every required gate and independent Claude receipt review pass. Preparation checks alone do not qualify runtime. Preserve failures, create new development scenarios and a new frozen packet before testing revised behavior. A passed rerun does not change U2's original failed cold-start/uncaptured-transition record. + +## Evidence location + +Preparation: results/onboarding-fixture-v4-preparation-20261012. Guest run: results/u3-packet-v4-permission-20261012-v1. Raw archives remain under ignored output. Notebook: docs/notebook/2026-10-12-onboarding-fixture-v4.md. diff --git a/jevdual/docs/independent-onboarding.md b/jevdual/docs/independent-onboarding.md index 9b77765..66266fc 100644 --- a/jevdual/docs/independent-onboarding.md +++ b/jevdual/docs/independent-onboarding.md @@ -2,13 +2,13 @@ This packet prepares U2; it is not a passed first-use result. It contains the reviewed standalone wheel, MIT license and qualification helpers, with hashes in MANIFEST.json. No code runs automatically. Product processes load Python runtime files from the installed wheel; helper code supplies the fixture and independent oracle. A runtime source checkout, development environment, provider credentials and evaluation results are absent. -Use an independently provisioned Mac or a new SIP-enabled macOS guest with a visible logged-in session. A pregranted CI runner or cloned granted seed cannot establish the initial permission transition. Record the actual environment and launch host; do not reset this MacBook's permissions to simulate a fresh machine. +Use an independently provisioned Mac or a new SIP-enabled macOS guest with a visible logged-in session. A pregranted CI runner or cloned granted seed cannot establish the initial permission transition. Record the actual environment and launch host; do not reset this MacBook's permissions to simulate a fresh machine. A rerun on a previously provisioned disposable guest must be labeled a fresh permission-state run, not a new cold-OS installation. Only after explicit approval, the supported guest command `tccutil reset Accessibility com.apple.Terminal` can restore that host's denied state; never reset other hosts or edit the TCC database. Retain all earlier run directories. ## Verify and install Compare the archive SHA256 with its accompanying preparation report before extracting. The manifest identifies the source commit and hashes every payload member. Work inside the extracted footwork directory. Provision compatible Python and uv through their normal installers on the independent environment; the packet does not install them or macOS. -The guest also needs TextEdit and Google Chrome at /Applications/Google Chrome.app, the executable used by the frozen fixture helper. Record the browser version and provision it through its normal installer before fixture execution. Keep its test profile unsigned-in. Missing Chrome is a browser prerequisite failure, not a permission denial. +The guest also needs TextEdit and Google Chrome at /Applications/Google Chrome.app, the executable used by the frozen fixture helper. Record the browser version and provision it through its normal installer before fixture execution. Launch Chrome once through Finder, let normal macOS verification finish, then quit it. Record this prerequisite separately; do not bypass Gatekeeper or count launch readiness as resource identity. Keep the fixture test profile unsigned-in. Missing Chrome is a browser prerequisite failure, not a permission denial. Open an interactive guest Terminal and define the packet directory: @@ -45,7 +45,7 @@ Record macOS version/build with sw_vers, SIP status with csrutil status, and the Record each command's exit code. With missing Accessibility, strict doctor must exit1 and report its blocker. The fixture must refuse before creating its directory, browser or document. If Accessibility is already granted, preserve the installation result and mark this lane ineligible for first-use permission qualification. A locked display, missing dependency or failed probe is not an observed permission denial. -The human grants the required permission to the actual responsible host in the guest's System Settings. Record the prompt or settings transition and any required host restart. Do not grant arbitrary helper paths or change SIP/TCC databases. Run subsequent commands from the same host. Screen Recording status is advisory for this DOM/AX slice; capture needs its own evidence. Record any additional permission required by an actual route or fixture cleanup. +The human approves the required permission for the actual responsible host in the guest's System Settings. The human or explicitly authorized operator changes that exact host's switch. Capture its off state, approval, actor and time, then its on state; separated denied/granted diagnostics without the actual transition do not pass this gate. Record any required host restart. Do not grant arbitrary helper paths or change SIP/TCC databases. Run subsequent commands from the same host. Screen Recording status is advisory for this DOM/AX slice; capture needs its own evidence. Record any additional permission required by an actual route or fixture cleanup. Repeat isolated strict doctor into doctor-after.json. Met prerequisites alone do not prove resource access or execution. @@ -58,6 +58,8 @@ In one Terminal, start and retain the owned fixture: --run-dir "$PACKET_ROOT/output/fixture-v1" ~~~ +The helper waits up to180seconds for its owned browser to expose a working private-profile CDP endpoint, then starts a separate30second unique-window identity phase. Startup health confers no scope authority. A typed failure is retained in fixture-status.json; stop on a nonzero exit and use a fresh directory for a later attempt. + Only after its ready response identifies the owned scope, use another Terminal from the same responsible host: ~~~sh @@ -79,6 +81,6 @@ Use only the entry points listed here; the other bundled modules supply imported ## Close and retain -Stop the fixture with Ctrl-C. Confirm its browser process is absent, its exact document window is closed and no owned worker remains. A reported cleanup failure needs an independent check or manual close of that exact owned document; do not substitute killing all Chrome/TextEdit processes. +Stop the fixture with Ctrl-C. The helper uses Accessibility to close only the window with the exact fixture document path. It may press a unique discard button only in that window's observed attached save sheet. It requests no TextEdit Automation grant. Retain cleanup.json and the fixture exit code. Confirm the owned browser process and loopback listener are gone, the exact document window is closed and no owned worker remains. A refusal, unknown result or manual close is a failed automatic-cleanup gate; preserve it and independently inspect only the exact owned resource. Do not substitute killing all Chrome/TextEdit processes. Cleanup does not certify whether TextEdit saved the edit before closing. Retain installation receipts, before/after diagnostics and exit codes, host/OS/SIP identity, consent observations, native receipt/journal/runtime contexts and cleanup evidence. Sanitize observations before sharing. Mark U2 passed only when an observed denied baseline, explicit permission transition and every native/postcondition/cleanup gate pass. This proves the scoped historical append/recovery/report behavior; it does not prove saved-file persistence, arbitrary apps or the host's entire goal. From 4fc6d5d00290a35d978115e8566f8a71ee76e1fb Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:04:04 -0400 Subject: [PATCH 136/216] Retain fast reboot failures and restart status diagnosis --- jevdual/docs/notebook/2026-10-12-workbench-restarts.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-12-workbench-restarts.md b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md index b5d7569..9ee3921 100644 --- a/jevdual/docs/notebook/2026-10-12-workbench-restarts.md +++ b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md @@ -13,3 +13,9 @@ Test: reproduce on real sockets by rebooting the same body while a model decisio Predicts: the original fast-reboot path admits the old decision; the repaired path pauses with no successor command, requires explicit Resume and a fresh observation, and retains exact unknown command identity for read-only recovery. Against: original code already pauses, repaired code sends the old decision, permanently blocks historical receipt lookup, or silently rotates authority while a command remains uncertain. Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py; docs/experiments/SIM11-workbench-restarts.md + +## SIM11-U1 · update · 2026-10-12 14:03 +Observed: four new real-socket checks failed on the original runtime. Health-first reboot let the old waiting model decision advance generation to one; acquisition-first reboot also admitted that decision under boot two. Historical uncertain dispatch stayed single-send across body reboot, but its recovered job remained labelled unknown. Graceful workbench restart left an unfinished job labelled running while its host was paused. Before-fix output is retained. The original completed product roots and source snapshot were preserved before stopping its verified idle owned processes. +Inferred: boot identity alone does not invalidate a model decision, and runner recovery needs a consistent unfinished-job status. The original historical receipt mechanism remains useful. +Next: repair the runtime epoch boundaries and labels, rerun affected real-socket checks, then freeze the actual browser restart trial. +Refs: tools/physical-workcell/output/sim11-epoch-before-fix.log; tools/physical-workcell/output/sim11-preserved-baseline/preserved.json; tools/physical-workcell/test_network_operator.py From 1d72e51ef7c4c5a49dac6cfac44c95427fbeff01 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:08:39 -0400 Subject: [PATCH 137/216] Use exact AX fixture cleanup and separate owned browser startup readiness --- jevdual/docs/independent-onboarding.md | 2 +- jevdual/scripts/capability_fixture.py | 443 +++++++++++++---- jevdual/tests/test_capability_fixture.py | 591 ++++++++++++++++++++++- 3 files changed, 951 insertions(+), 85 deletions(-) diff --git a/jevdual/docs/independent-onboarding.md b/jevdual/docs/independent-onboarding.md index 66266fc..28216e4 100644 --- a/jevdual/docs/independent-onboarding.md +++ b/jevdual/docs/independent-onboarding.md @@ -81,6 +81,6 @@ Use only the entry points listed here; the other bundled modules supply imported ## Close and retain -Stop the fixture with Ctrl-C. The helper uses Accessibility to close only the window with the exact fixture document path. It may press a unique discard button only in that window's observed attached save sheet. It requests no TextEdit Automation grant. Retain cleanup.json and the fixture exit code. Confirm the owned browser process and loopback listener are gone, the exact document window is closed and no owned worker remains. A refusal, unknown result or manual close is a failed automatic-cleanup gate; preserve it and independently inspect only the exact owned resource. Do not substitute killing all Chrome/TextEdit processes. Cleanup does not certify whether TextEdit saved the edit before closing. +Stop the fixture with Ctrl-C. The helper uses Accessibility to close only the window with the exact fixture document path. It may press a unique discard button only in that window's observed attached save sheet. Only identified English save sheets are supported; other dialogs refuse. It requests no TextEdit Automation grant. Retain cleanup.json and the fixture exit code. Confirm the owned browser process and loopback listener are gone, the exact document window is closed and no owned worker remains. A refusal, unknown result or manual close is a failed automatic-cleanup gate; preserve it and independently inspect only the exact owned resource. Do not substitute killing all Chrome/TextEdit processes. Cleanup does not certify whether TextEdit saved the edit before closing. Retain installation receipts, before/after diagnostics and exit codes, host/OS/SIP identity, consent observations, native receipt/journal/runtime contexts and cleanup evidence. Sanitize observations before sharing. Mark U2 passed only when an observed denied baseline, explicit permission transition and every native/postcondition/cleanup gate pass. This proves the scoped historical append/recovery/report behavior; it does not prove saved-file persistence, arbitrary apps or the host's entire goal. diff --git a/jevdual/scripts/capability_fixture.py b/jevdual/scripts/capability_fixture.py index 5ad8ec6..b57b2d3 100644 --- a/jevdual/scripts/capability_fixture.py +++ b/jevdual/scripts/capability_fixture.py @@ -1,7 +1,7 @@ -"""Prepare and hold run-owned browser/TextEdit fixtures for capability trials. +"""Hold run-owned browser/TextEdit fixtures; Ctrl-C performs bounded owned cleanup. -Run in a terminal; Ctrl-C closes only this process's browser and named fixture -document. Scope and fixture files remain in the explicitly supplied directory. +Accessibility must already be granted. Closing the exact document uses AX only; +this helper never requests an Automation or Screen Recording grant. """ from __future__ import annotations @@ -14,11 +14,22 @@ import time from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path +from urllib.parse import unquote, urlsplit +from urllib.request import ProxyHandler, build_opener VALUE = "17.25 USD" PREFIX = "Invoice report\n" HTML = f"Footwork invoice fixture

    Invoice

    Invoice total: {VALUE}

    " CHROME = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" +BROWSER_STARTUP_SECONDS = 180 +IDENTITY_SECONDS = 30 +CLEANUP_SECONDS = 10 + + +class FixtureFailure(Exception): + def __init__(self, phase: str, reason: str, exit_code: int): + super().__init__(reason) + self.phase, self.reason, self.exit_code = phase, reason, exit_code class Page(BaseHTTPRequestHandler): @@ -34,54 +45,304 @@ def log_message(self, *args): pass -def script(source: str, *args: str) -> str: - return subprocess.run( - ["osascript", "-e", source, *args], check=True, capture_output=True, text=True, timeout=10 - ).stdout.strip() +def normalized_document(value) -> str | None: + if not value: + return None + parts = urlsplit(str(value)) + if parts.scheme != "file" or parts.netloc not in ("", "localhost") or parts.query or parts.fragment: + return None + return str(Path(unquote(parts.path)).resolve()) + + +def ax_deadline(element, deadline: float | None): + from ApplicationServices import AXUIElementSetMessagingTimeout + + if deadline is None: + return + remaining = deadline - time.monotonic() + if remaining <= 0: + raise FixtureFailure("document_cleanup", "cleanup_deadline", 6) + error = AXUIElementSetMessagingTimeout(element, min(1.0, remaining)) + if error: + raise FixtureFailure("document_cleanup", f"ax_timeout_refused:{error}", 6) + + +def ax_attribute(element, name: str, *, optional: bool = False, deadline: float | None = None): + from ApplicationServices import AXUIElementCopyAttributeValue + + ax_deadline(element, deadline) + error, value = AXUIElementCopyAttributeValue(element, name, None) + # AXErrorAttributeUnsupported / AXErrorNoValue are absence only for optional attributes. + if error in (-25205, -25212) and optional: + return None + if error: + raise FixtureFailure("document_cleanup", f"ax_attribute_refused:{name}:{error}", 6) + return value + + +def owned_window(app, document: Path, deadline: float | None = None): + expected = str(document.resolve()) + matches = [ + window + for window in ax_attribute(app, "AXWindows", deadline=deadline) or () + if normalized_document(ax_attribute(window, "AXDocument", optional=True, deadline=deadline)) + == expected + ] + if len(matches) > 1: + raise FixtureFailure("document_cleanup", "document_ambiguous", 6) + return matches[0] if matches else None + + +def press(element, deadline: float | None = None): + from ApplicationServices import AXUIElementPerformAction + + ax_deadline(element, deadline) + error = AXUIElementPerformAction(element, "AXPress") + if error: + raise FixtureFailure("document_cleanup", f"ax_press_refused:{error}", 6) + + +def discard_button(window, deadline: float | None = None): + sheets = list(ax_attribute(window, "AXSheets", optional=True, deadline=deadline) or ()) + # Some TextEdit versions expose attached sheets through AXChildren instead. + if not sheets: + sheets = [ + child + for child in ax_attribute(window, "AXChildren", optional=True, deadline=deadline) or () + if ax_attribute(child, "AXRole", optional=True, deadline=deadline) == "AXSheet" + ] + if not sheets: + return None + if len(sheets) != 1 or ax_attribute(sheets[0], "AXRole", deadline=deadline) != "AXSheet": + raise FixtureFailure("document_cleanup", "sheet_ambiguous", 6) + sheet = sheets[0] + # The sheet must be attached to this exact window, never app-global. + if ax_attribute(sheet, "AXParent", deadline=deadline) != window: + raise FixtureFailure("document_cleanup", "sheet_not_attached", 6) + stack, seen, matches, titles = [sheet], 0, [], set() + while stack: + node = stack.pop() + seen += 1 + if seen > 400: + raise FixtureFailure("document_cleanup", "sheet_tree_limit", 6) + if ax_attribute(node, "AXRole", optional=True, deadline=deadline) == "AXButton": + title = str(ax_attribute(node, "AXTitle", optional=True, deadline=deadline) or "") + titles.add(title) + if title in ("Don't Save", "Don’t Save", "Delete"): + matches.append(node) + stack.extend(ax_attribute(node, "AXChildren", optional=True, deadline=deadline) or ()) + if not {"Save", "Cancel"} <= titles: + raise FixtureFailure("document_cleanup", "sheet_not_save_prompt", 6) + if len(matches) != 1: + raise FixtureFailure("document_cleanup", "discard_button_ambiguous", 6) + return sheet, matches[0] + + +def close_owned_document(pid: int, document: Path) -> dict: + from ApplicationServices import AXUIElementCreateApplication + + try: + deadline = time.monotonic() + CLEANUP_SECONDS + app = AXUIElementCreateApplication(pid) + window = owned_window(app, document, deadline) + if window is None: + return {"status": "unknown", "reason": "document_not_observed", "pid": pid} + close = ax_attribute(window, "AXCloseButton", optional=True, deadline=deadline) + if close is None: + raise FixtureFailure("document_cleanup", "close_button_missing", 6) + if owned_window(app, document, deadline) != window: + raise FixtureFailure("document_cleanup", "document_identity_changed", 6) + if ax_attribute(window, "AXCloseButton", deadline=deadline) != close: + raise FixtureFailure("document_cleanup", "close_button_changed", 6) + press(close, deadline) + discarded = False + while time.monotonic() < deadline: + current = owned_window(app, document, deadline) + if current is None: + # Do not mistake a renamed/reused window for observed disappearance. + if window in (ax_attribute(app, "AXWindows", deadline=deadline) or ()): + raise FixtureFailure("document_cleanup", "document_identity_changed", 6) + return {"status": "confirmed", "reason": "window_disappeared", "pid": pid} + if current != window: + raise FixtureFailure("document_cleanup", "document_identity_changed", 6) + discard = discard_button(window, deadline) + if discard is not None and not discarded: + if ( + owned_window(app, document, deadline) != window + or discard_button(window, deadline) != discard + ): + raise FixtureFailure("document_cleanup", "sheet_identity_changed", 6) + press(discard[1], deadline) + discarded = True + time.sleep(0.1) + return {"status": "unknown", "reason": "window_still_present", "pid": pid} + except Exception as exc: # noqa: BLE001 - receipt boundary; independent cleanup must continue + return {"status": "error", "reason": getattr(exc, "reason", type(exc).__name__), "pid": pid} + + +def wait_browser_ready(browser, profile: Path) -> dict: + deadline = time.monotonic() + BROWSER_STARTUP_SECONDS + opener = build_opener(ProxyHandler({})) + while time.monotonic() < deadline: + if browser.poll() is not None: + raise FixtureFailure("browser_startup", "browser_exited", 3) + try: + lines = (profile / "DevToolsActivePort").read_text().splitlines() + port = int(lines[0]) + if not 1 <= port <= 65535 or len(lines) != 2 or not lines[1].startswith("/devtools/browser/"): + raise ValueError("invalid private-profile endpoint") + with opener.open(f"http://127.0.0.1:{port}/json/version", timeout=1) as response: + version = json.loads(response.read(65536)) + if version.get("webSocketDebuggerUrl") != f"ws://127.0.0.1:{port}{lines[1]}": + raise ValueError("endpoint mismatch") + if browser.poll() is not None: + raise FixtureFailure("browser_startup", "browser_exited", 3) + return {"status": "ready", "pid": browser.pid, "port": port} + except (OSError, ValueError, IndexError): + time.sleep(0.25) + raise FixtureFailure("browser_startup", "startup_timeout", 3) + + +async def bounded_call(awaitable, deadline: float, phase: str): + remaining = deadline - time.monotonic() + if remaining <= 0: + awaitable.close() + raise FixtureFailure(phase, "sdk_deadline", 4 if phase == "identity" else 6) + try: + return await asyncio.wait_for(awaitable, timeout=remaining) + except TimeoutError as exc: + raise FixtureFailure(phase, "sdk_timeout", 4 if phase == "identity" else 6) from exc -async def scope_for(chrome_pid: int, url: str, document: Path) -> dict: +async def shutdown_driver(driver, phase: str, deadline: float): + await bounded_call(driver.shutdown(), deadline, phase) + + +async def textedit_pid() -> int | None: + from cua_driver import CuaDriver, ListAppsInput + + driver = CuaDriver.create() + deadline = time.monotonic() + 3 + try: + apps = (await bounded_call(driver.list_apps(ListAppsInput()), deadline - 1, "document_cleanup")).apps + pids = {a.pid for a in apps if a.name == "TextEdit" and a.pid} + if len(pids) > 1: + raise FixtureFailure("document_cleanup", "textedit_process_ambiguous", 6) + return next(iter(pids), None) + finally: + await shutdown_driver(driver, "document_cleanup", deadline) + + +async def scope_for(chrome_pid: int, url: str, document: Path, browser=None) -> dict: from cua_driver import CuaDriver, ListAppsInput, ListWindowsInput from jevdual import ax driver = CuaDriver.create() try: - deadline = time.monotonic() + 30 + deadline = time.monotonic() + IDENTITY_SECONDS while time.monotonic() < deadline: - apps = (await driver.list_apps(ListAppsInput())).apps - textedit = next((a for a in apps if a.name == "TextEdit" and a.pid), None) + if browser is not None and browser.poll() is not None: + raise FixtureFailure("identity", "browser_exited", 4) + apps = (await bounded_call(driver.list_apps(ListAppsInput()), deadline, "identity")).apps + textedit_pids = {a.pid for a in apps if a.name == "TextEdit" and a.pid} + if len(textedit_pids) > 1: + raise FixtureFailure("identity", "textedit_process_ambiguous", 4) + textedit = next(iter(textedit_pids), None) browser_windows = ( - await driver.list_windows(ListWindowsInput(pid=chrome_pid, on_screen_only=True)) + await bounded_call( + driver.list_windows(ListWindowsInput(pid=chrome_pid, on_screen_only=True)), + deadline, + "identity", + ) ).windows native_windows = ( - (await driver.list_windows(ListWindowsInput(pid=textedit.pid, on_screen_only=True))).windows + ( + await bounded_call( + driver.list_windows(ListWindowsInput(pid=textedit, on_screen_only=True)), + deadline, + "identity", + ) + ).windows if textedit else [] ) matching = [] for window in native_windows: try: - if ax.document_path(textedit.pid, window.window_id) == str(document): + path = ax.document_path(textedit, window.window_id) + if path and str(Path(path).resolve()) == str(document.resolve()): matching.append(window) except ax.AXError as exc: - # WindowServer can publish an opening window before its AX - # surface exists. Retain the identity check and deadline. if exc.reason != "window_missing": raise if len(browser_windows) == 1 and len(matching) == 1: + if browser is not None and browser.poll() is not None: + raise FixtureFailure("identity", "browser_exited", 4) return { "task": document.parent.name, "source": {"pid": chrome_pid, "window_id": browser_windows[0].window_id, "url": url}, "destination": { - "pid": textedit.pid, + "pid": textedit, "window_id": matching[0].window_id, "document": str(document), }, } await asyncio.sleep(0.25) - raise RuntimeError("Owned browser/document windows could not be identified uniquely") + raise FixtureFailure("identity", "windows_not_unique", 4) finally: - await driver.shutdown() + await shutdown_driver(driver, "identity", time.monotonic() + 2) + + +def cleanup(browser, http, thread, logfile, document: Path, *, opened: bool, pid: int | None) -> dict: + result = { + "document": {"status": "not_started"}, + "browser": {"status": "not_started"}, + "listener": {"status": "not_started"}, + } + if opened: + try: + observed_pid = asyncio.run(textedit_pid()) + if pid is not None and observed_pid != pid: + raise FixtureFailure("document_cleanup", "textedit_process_changed", 6) + pid = observed_pid + result["document"] = ( + close_owned_document(pid, document) + if pid + else {"status": "unknown", "reason": "textedit_not_observed"} + ) + except Exception as exc: # noqa: BLE001 - receipt boundary; independent cleanup must continue + result["document"] = {"status": "error", "reason": getattr(exc, "reason", type(exc).__name__)} + if browser is not None: + try: + if browser.poll() is None: + browser.terminate() + try: + browser.wait(timeout=10) + except subprocess.TimeoutExpired: + browser.kill() + browser.wait(timeout=10) + result["browser"] = {"status": "confirmed", "pid": browser.pid, "returncode": browser.returncode} + except Exception as exc: # noqa: BLE001 - receipt boundary; independent cleanup must continue + result["browser"] = {"status": "error", "reason": type(exc).__name__, "pid": browser.pid} + if http is not None: + try: + if thread is not None and thread.is_alive(): + http.shutdown() + http.server_close() + if thread is not None: + thread.join(timeout=2) + if thread.is_alive(): + raise RuntimeError("listener_thread_alive") + result["listener"] = {"status": "confirmed"} + except Exception as exc: # noqa: BLE001 - receipt boundary; independent cleanup must continue + result["listener"] = {"status": "error", "reason": type(exc).__name__} + if logfile is not None: + logfile.close() + return result + + +def record(root: Path, name: str, value: dict): + (root / name).write_text(json.dumps(value, indent=2) + "\n") def main() -> None: @@ -98,75 +359,91 @@ def main() -> None: root = args.run_dir.resolve() root.mkdir(parents=True, exist_ok=False, mode=0o700) document = root / f"{root.name}-invoice.txt" - document.write_text(PREFIX) - (root / "fixture.html").write_text(HTML) - http = ThreadingHTTPServer(("127.0.0.1", 0), Page) - threading.Thread(target=http.serve_forever, daemon=True).start() - url = f"http://127.0.0.1:{http.server_port}/" - logfile = (root / "chrome.log").open("w") - browser = subprocess.Popen( - [ - CHROME, - f"--user-data-dir={root / 'chrome-profile'}", - "--remote-debugging-port=0", - "--no-first-run", - "--no-default-browser-check", - "--disable-background-networking", - "--disable-sync", - "--disable-component-update", - "--new-window", - url, - ], - stdout=logfile, - stderr=logfile, - start_new_session=True, - ) + browser = http = thread = logfile = pid = None + opened, exit_code, phase = False, 0, "setup" try: - # Launch Services supplies the selected-file sandbox extension; a raw - # AppleEvent open can be refused by sandboxed TextEdit. - subprocess.run(["open", "-a", "TextEdit", str(document)], check=True) - scope = asyncio.run(scope_for(browser.pid, url, document)) - (root / "scope.json").write_text(json.dumps(scope, indent=2) + "\n") - (root / "fixture.json").write_text( - json.dumps( - { - "url": url, - "document": str(document), - "value": VALUE, - "prefix": PREFIX, - "browser_pid": browser.pid, - }, - indent=2, - ) - + "\n" + document.write_text(PREFIX) + (root / "fixture.html").write_text(HTML) + http = ThreadingHTTPServer(("127.0.0.1", 0), Page) + thread = threading.Thread(target=http.serve_forever, daemon=True) + thread.start() + url = f"http://127.0.0.1:{http.server_port}/" + logfile = (root / "chrome.log").open("w") + phase = "browser_startup" + browser = subprocess.Popen( + [ + CHROME, + f"--user-data-dir={root / 'chrome-profile'}", + "--remote-debugging-port=0", + "--no-first-run", + "--no-default-browser-check", + "--disable-background-networking", + "--disable-sync", + "--disable-component-update", + "--new-window", + url, + ], + stdout=logfile, + stderr=logfile, + start_new_session=True, + ) + startup = wait_browser_ready(browser, root / "chrome-profile") + record(root, "startup.json", startup) + phase = "document_open" + # Mark attempted ownership before launch, so partial opens still get cleanup. + opened = True + subprocess.run(["open", "-a", "TextEdit", str(document)], check=True, timeout=10) + phase = "identity" + scope = asyncio.run(scope_for(browser.pid, url, document, browser)) + pid = scope["destination"]["pid"] + record(root, "scope.json", scope) + record( + root, + "fixture.json", + { + "url": url, + "document": str(document), + "value": VALUE, + "prefix": PREFIX, + "browser_pid": browser.pid, + }, ) - print(json.dumps({"ready": True, "scope": str(root / "scope.json")}), flush=True) - while True: + ready = {"ready": True, "phase": "hold", "scope": str(root / "scope.json")} + record(root, "fixture-status.json", ready) + print(json.dumps(ready), flush=True) + phase = "hold" + while browser.poll() is None: time.sleep(1) + raise FixtureFailure("hold", "browser_exited", 3) except KeyboardInterrupt: - pass + if phase != "hold": + exit_code = 130 + failure = {"ready": False, "phase": phase, "reason": "interrupted", "exit_code": exit_code} + record(root, "fixture-status.json", failure) + print(json.dumps(failure), flush=True) + except Exception as exc: # noqa: BLE001 - receipt boundary; independent cleanup must continue + exit_code = getattr( + exc, "exit_code", 3 if phase == "browser_startup" else 4 if phase == "identity" else 5 + ) + failure = { + "ready": False, + "phase": getattr(exc, "phase", phase), + "reason": getattr(exc, "reason", type(exc).__name__), + "exit_code": exit_code, + } + record(root, "fixture-status.json", failure) + print(json.dumps(failure), flush=True) finally: - # This exact file was created and opened by this fixture owner. - try: - script( - 'on run argv\ntell application "TextEdit"\n' - "set matches to every document whose name is (item 2 of argv)\n" - "if (count of matches) is 1 then\nset d to item 1 of matches\n" - "if path of d is (item 1 of argv) then close d saving no\n" - "end if\nend tell\nend run", - str(document), - document.name, - ) - except (subprocess.CalledProcessError, subprocess.TimeoutExpired): - print("Fixture document cleanup could not be confirmed; browser cleanup continues.", flush=True) - browser.terminate() - try: - browser.wait(timeout=10) - except subprocess.TimeoutExpired: - browser.kill() - browser.wait(timeout=10) - http.shutdown() - logfile.close() + shutdown = cleanup(browser, http, thread, logfile, document, opened=opened, pid=pid) + record(root, "cleanup.json", shutdown) + print(json.dumps({"shutdown": shutdown}), flush=True) + if ( + any(item["status"] not in ("confirmed", "not_started") for item in shutdown.values()) + and not exit_code + ): + exit_code = 6 + if exit_code: + raise SystemExit(exit_code) if __name__ == "__main__": diff --git a/jevdual/tests/test_capability_fixture.py b/jevdual/tests/test_capability_fixture.py index deebbf9..a1c2300 100644 --- a/jevdual/tests/test_capability_fixture.py +++ b/jevdual/tests/test_capability_fixture.py @@ -3,6 +3,8 @@ from __future__ import annotations import importlib.util +import json +import subprocess import sys from pathlib import Path from types import SimpleNamespace @@ -18,7 +20,9 @@ def fixture_module(): return module -@pytest.mark.skipif(sys.platform != "darwin", reason="macOS Accessibility readiness gate requires ApplicationServices") +@pytest.mark.skipif( + sys.platform != "darwin", reason="macOS Accessibility readiness gate requires ApplicationServices" +) def test_locked_fixture_refuses_before_creating_files(monkeypatch, tmp_path): import ApplicationServices from jevdual import posture @@ -92,3 +96,588 @@ def path(*_): with pytest.raises(ax.AXError, match="no access"): await module.scope_for(42, "http://127.0.0.1:1", tmp_path / "owned.txt") assert stopped == [True] + + +def test_cleanup_uses_ax_without_apple_events(monkeypatch, tmp_path): + module = fixture_module() + assert not hasattr(module, "script"), "fixture cleanup still invokes osascript/Automation" + assert callable(module.close_owned_document) + + +def test_browser_startup_has_separate_bounded_phase(): + module = fixture_module() + assert module.BROWSER_STARTUP_SECONDS == 180 + assert module.IDENTITY_SECONDS == 30 + assert callable(module.wait_browser_ready) + + +def test_missing_owned_document_is_unknown_not_closed(monkeypatch, tmp_path): + module = fixture_module() + import ApplicationServices + + monkeypatch.setattr(ApplicationServices, "AXUIElementSetMessagingTimeout", lambda *args: 0) + + monkeypatch.setattr(ApplicationServices, "AXUIElementCreateApplication", lambda pid: {}) + monkeypatch.setattr(ApplicationServices, "AXUIElementCopyAttributeValue", lambda el, key, _: (0, [])) + result = module.close_owned_document(43, tmp_path / "owned.txt") + assert result["status"] == "unknown" + assert result["reason"] == "document_not_observed" + + +def ax_world(monkeypatch, tmp_path, *, edited=False): + import ApplicationServices + + module = fixture_module() + monkeypatch.setattr(ApplicationServices, "AXUIElementSetMessagingTimeout", lambda *args: 0) + document = tmp_path / "owned.txt" + window = {"AXDocument": document.as_uri(), "AXRole": "AXWindow"} + other = {"AXDocument": (tmp_path / "elsewhere" / "owned.txt").as_uri(), "AXRole": "AXWindow"} + app = {"AXWindows": [window, other]} + close = {"AXRole": "AXButton"} + window["AXCloseButton"] = close + window["AXChildren"] = [] + sheet = {"AXRole": "AXSheet", "AXParent": window, "AXChildren": []} + discard = {"AXRole": "AXButton", "AXTitle": "Don't Save", "AXChildren": []} + sheet["AXChildren"].extend( + [ + discard, + {"AXRole": "AXButton", "AXTitle": "Save", "AXChildren": []}, + {"AXRole": "AXButton", "AXTitle": "Cancel", "AXChildren": []}, + ] + ) + pressed = [] + + def action(el, _): + pressed.append(el) + if el is close: + if edited: + window["AXSheets"] = [sheet] + else: + app["AXWindows"].remove(window) + elif el is discard: + app["AXWindows"].remove(window) + return 0 + + monkeypatch.setattr(ApplicationServices, "AXUIElementCreateApplication", lambda pid: app) + monkeypatch.setattr( + ApplicationServices, + "AXUIElementCopyAttributeValue", + lambda el, key, _: (0, el[key]) if key in el else (-25205, None), + ) + monkeypatch.setattr(ApplicationServices, "AXUIElementPerformAction", action) + return module, document, app, window, other, close, sheet, discard, pressed + + +@pytest.mark.parametrize("edited", [False, True]) +def test_exact_owned_ax_window_closes_and_preserves_same_name(monkeypatch, tmp_path, edited): + module, document, app, _window, other, close, _sheet, discard, pressed = ax_world( + monkeypatch, tmp_path, edited=edited + ) + result = module.close_owned_document(43, document) + assert result["status"] == "confirmed" + assert app["AXWindows"] == [other] + assert pressed == ([close, discard] if edited else [close]) + + +def test_duplicate_exact_document_refuses_any_action(monkeypatch, tmp_path): + module, document, app, window, *_ = ax_world(monkeypatch, tmp_path) + app["AXWindows"].append(dict(window)) + result = module.close_owned_document(43, document) + assert result["reason"] == "document_ambiguous" + assert result["status"] == "error" + + +def test_identity_changed_before_close_refuses(monkeypatch, tmp_path): + module, document, _app, window, other, _close, _sheet, _discard, pressed = ax_world(monkeypatch, tmp_path) + original = module.owned_window + calls = [] + + def changed(*args): + calls.append(True) + if len(calls) == 2: + window["AXDocument"] = other["AXDocument"] + return original(*args) + + monkeypatch.setattr(module, "owned_window", changed) + assert module.close_owned_document(43, document)["reason"] == "document_identity_changed" + assert pressed == [] + + +def test_ax_windows_unreadable_after_press_is_not_absence(monkeypatch, tmp_path): + import ApplicationServices + + module, document, _app, _window, _other, _close, _sheet, _discard, pressed = ax_world( + monkeypatch, tmp_path + ) + original = ApplicationServices.AXUIElementCopyAttributeValue + + def attribute(el, key, arg): + if key == "AXWindows" and pressed: + return -25211, None + return original(el, key, arg) + + monkeypatch.setattr(ApplicationServices, "AXUIElementCopyAttributeValue", attribute) + assert module.close_owned_document(43, document)["status"] == "error" + + +@pytest.mark.parametrize( + "problem", ["unattached", "two_sheets", "two_buttons", "foreign_sheet", "failed_press"] +) +def test_discard_refuses_unbound_or_ambiguous_targets(monkeypatch, tmp_path, problem): + import ApplicationServices + + module, document, app, window, other, _close, sheet, discard, pressed = ax_world( + monkeypatch, tmp_path, edited=True + ) + if problem == "unattached": + sheet["AXParent"] = other + elif problem == "two_sheets": + window["AXSheets"] = [sheet, dict(sheet)] + elif problem == "two_buttons": + sheet["AXChildren"].append(dict(discard)) + elif problem == "foreign_sheet": + window["AXSheets"] = [{"AXRole": "AXSheet", "AXParent": other, "AXChildren": [discard]}] + else: + monkeypatch.setattr(ApplicationServices, "AXUIElementPerformAction", lambda *args: -25211) + # Preserve pre-existing malicious AXSheets across the mocked close action. + if problem in ("two_sheets", "foreign_sheet"): + original_sheets = window["AXSheets"] + monkeypatch.setattr( + ApplicationServices, + "AXUIElementPerformAction", + lambda el, _: pressed.append(el) or window.update(AXSheets=original_sheets) or 0, + ) + result = module.close_owned_document(43, document) + assert result["status"] == "error" + assert discard not in pressed + assert other in app["AXWindows"] + + +def test_changed_document_remaining_window_is_not_confirmed_disappearance(monkeypatch, tmp_path): + import ApplicationServices + + module, document, _app, window, other, _close, _sheet, _discard, _pressed = ax_world( + monkeypatch, tmp_path + ) + monkeypatch.setattr( + ApplicationServices, + "AXUIElementPerformAction", + lambda *args: window.update(AXDocument=other["AXDocument"]) or 0, + ) + assert module.close_owned_document(43, document)["reason"] == "document_identity_changed" + + +def fake_clock(monkeypatch, module, *, step=1): + ticks = iter(range(10000)) + monkeypatch.setattr(module.time, "monotonic", lambda: next(ticks) * step) + monkeypatch.setattr(module.time, "sleep", lambda _: None) + + +def test_browser_readiness_waits_for_private_profile_endpoint(monkeypatch, tmp_path): + module = fixture_module() + fake_clock(monkeypatch, module) + profile = tmp_path / "chrome-profile" + profile.mkdir() + attempts = [] + browser = SimpleNamespace(pid=42, poll=lambda: None) + + def delay(_): + attempts.append(True) + if len(attempts) == 40: # Beyond the old thirty-second combined phase. + (profile / "DevToolsActivePort").write_text("1234\n/devtools/browser/owned\n") + + class Response: + def __enter__(self): + return self + + def __exit__(self, *args): + pass + + def read(self, limit): + return b'{"webSocketDebuggerUrl":"ws://127.0.0.1:1234/devtools/browser/owned"}' + + urls = [] + monkeypatch.setattr(module.time, "sleep", delay) + monkeypatch.setattr( + module, + "build_opener", + lambda _: SimpleNamespace(open=lambda url, timeout: urls.append(url) or Response()), + ) + assert module.wait_browser_ready(browser, profile)["pid"] == 42 + assert len(attempts) == 40 + assert urls == ["http://127.0.0.1:1234/json/version"] + + +@pytest.mark.parametrize("exited,reason", [(True, "browser_exited"), (False, "startup_timeout")]) +def test_browser_readiness_classifies_failure(monkeypatch, tmp_path, exited, reason): + module = fixture_module() + fake_clock(monkeypatch, module, step=60) + with pytest.raises(module.FixtureFailure) as failure: + module.wait_browser_ready(SimpleNamespace(pid=42, poll=lambda: 1 if exited else None), tmp_path) + assert failure.value.phase == "browser_startup" + assert failure.value.reason == reason + assert failure.value.exit_code == 3 + + +@pytest.mark.asyncio +async def test_identity_stays_strict_after_startup(monkeypatch, tmp_path): + import cua_driver + from jevdual import ax + + module = fixture_module() + elapsed = [0] + monkeypatch.setattr(module.time, "monotonic", lambda: elapsed[0]) + + async def advance(_): + elapsed[0] += 10 + + monkeypatch.setattr(module.asyncio, "sleep", advance) + + class Driver: + async def list_apps(self, _): + return SimpleNamespace(apps=[SimpleNamespace(name="TextEdit", pid=43)]) + + async def list_windows(self, args): + return SimpleNamespace(windows=[SimpleNamespace(window_id=7), SimpleNamespace(window_id=8)]) + + async def shutdown(self): + pass + + monkeypatch.setattr(cua_driver.CuaDriver, "create", lambda: Driver()) + monkeypatch.setattr(ax, "document_path", lambda *args: str(tmp_path / "owned.txt")) + with pytest.raises(module.FixtureFailure) as failure: + await module.scope_for(42, "http://127.0.0.1:1", tmp_path / "owned.txt") + assert failure.value.reason == "windows_not_unique" + assert failure.value.exit_code == 4 + + +def test_cleanup_ax_refusal_still_stops_owned_browser_listener(monkeypatch, tmp_path): + module = fixture_module() + calls = [] + + async def pid(): + return 43 + + monkeypatch.setattr(module, "textedit_pid", pid) + monkeypatch.setattr( + module, "close_owned_document", lambda *args: {"status": "error", "reason": "refused"} + ) + browser = SimpleNamespace( + pid=42, + returncode=0, + poll=lambda: None, + terminate=lambda: calls.append("terminate"), + wait=lambda timeout: calls.append("wait"), + ) + http = SimpleNamespace( + shutdown=lambda: calls.append("shutdown"), server_close=lambda: calls.append("close") + ) + alive = iter([True, False]) + thread = SimpleNamespace(is_alive=lambda: next(alive), join=lambda timeout: calls.append("join")) + logfile = SimpleNamespace(close=lambda: calls.append("log_close")) + result = module.cleanup(browser, http, thread, logfile, tmp_path / "owned.txt", opened=True, pid=43) + assert result["document"]["status"] == "error" + assert result["browser"]["status"] == result["listener"]["status"] == "confirmed" + assert calls == ["terminate", "wait", "shutdown", "close", "join", "log_close"] + + +def test_attached_delete_sheet_without_save_context_refuses(monkeypatch, tmp_path): + module, document, _app, _window, _other, close, sheet, discard, pressed = ax_world( + monkeypatch, tmp_path, edited=True + ) + discard["AXTitle"] = "Delete" + sheet["AXChildren"] = [discard] + result = module.close_owned_document(43, document) + assert result["reason"] == "sheet_not_save_prompt" + assert pressed == [close] + + +@pytest.mark.parametrize( + "stage,expected_code", + [("popen", 3), ("startup", 3), ("open", 5), ("identity", 4), ("identity_hang", 4), ("interrupt", 130)], +) +def test_setup_failures_always_stop_owned_resources(monkeypatch, tmp_path, stage, expected_code): + import ApplicationServices + from jevdual import posture + + module = fixture_module() + monkeypatch.setattr(posture, "screen_locked", lambda: False) + monkeypatch.setattr(ApplicationServices, "AXIsProcessTrusted", lambda: True) + root = tmp_path / "run" + monkeypatch.setattr(sys, "argv", ["fixture", "--run-dir", str(root)]) + calls = [] + alive = [False] + http = SimpleNamespace( + server_port=1234, + serve_forever=lambda: None, + shutdown=lambda: calls.append("listener_shutdown"), + server_close=lambda: calls.append("listener_close"), + ) + + class Thread: + def __init__(self, **kwargs): + pass + + def start(self): + alive[0] = True + + def is_alive(self): + return alive[0] + + def join(self, timeout): + alive[0] = False + + monkeypatch.setattr(module, "ThreadingHTTPServer", lambda *args: http) + monkeypatch.setattr(module.threading, "Thread", Thread) + browser = SimpleNamespace( + pid=42, + returncode=0, + poll=lambda: None, + terminate=lambda: calls.append("browser_terminate"), + wait=lambda timeout: calls.append("browser_wait"), + ) + + def popen(*args, **kwargs): + if stage == "popen": + raise OSError("launch refused") + return browser + + def ready(*args): + if stage == "startup": + raise module.FixtureFailure("browser_startup", "startup_timeout", 3) + if stage == "interrupt": + raise KeyboardInterrupt() + return {"status": "ready", "pid": 42, "port": 1234} + + def open_document(*args, **kwargs): + if stage == "open": + raise subprocess.CalledProcessError(1, "open") + + async def identity(*args): + raise module.FixtureFailure("identity", "windows_not_unique", 4) + + async def pid(): + return 43 + + monkeypatch.setattr(module.subprocess, "Popen", popen) + monkeypatch.setattr(module.subprocess, "run", open_document) + monkeypatch.setattr(module, "wait_browser_ready", ready) + cancelled = [] + if stage == "identity_hang": + import asyncio + + import cua_driver + + class Driver: + async def list_apps(self, _): + try: + await asyncio.Future() + finally: + cancelled.append(True) + + async def shutdown(self): + pass + + monkeypatch.setattr(cua_driver.CuaDriver, "create", lambda: Driver()) + monkeypatch.setattr(module, "IDENTITY_SECONDS", 0.02) + else: + monkeypatch.setattr(module, "scope_for", identity) + monkeypatch.setattr(module, "textedit_pid", pid) + monkeypatch.setattr( + module, "close_owned_document", lambda *args: {"status": "unknown", "reason": "not_observed"} + ) + with pytest.raises(SystemExit) as failure: + module.main() + assert failure.value.code == expected_code + status = json.loads((root / "fixture-status.json").read_text()) + cleanup = json.loads((root / "cleanup.json").read_text()) + assert status["exit_code"] == expected_code + if stage == "identity_hang": + assert status["reason"] == "sdk_timeout" + assert cancelled == [True] + assert not (root / "scope.json").exists() + assert "listener_shutdown" in calls and "listener_close" in calls + assert cleanup["listener"]["status"] == "confirmed" + if stage != "popen": + assert "browser_terminate" in calls and "browser_wait" in calls + assert cleanup["browser"]["status"] == "confirmed" + + +def test_changed_textedit_pid_refuses_document_cleanup_and_still_stops_browser(monkeypatch, tmp_path): + module = fixture_module() + touched = [] + + async def pid(): + return 99 + + monkeypatch.setattr(module, "textedit_pid", pid) + monkeypatch.setattr(module, "close_owned_document", lambda *args: touched.append(True)) + browser = SimpleNamespace(pid=42, returncode=0, poll=lambda: 0, wait=lambda timeout: None) + result = module.cleanup(browser, None, None, None, tmp_path / "owned.txt", opened=True, pid=43) + assert result["document"]["reason"] == "textedit_process_changed" + assert not touched + assert result["browser"]["status"] == "confirmed" + + +def test_unresponsive_ax_has_rpc_timeout_and_no_confirmed_cleanup(monkeypatch, tmp_path): + import ApplicationServices + + module, document, *_ = ax_world(monkeypatch, tmp_path) + timeouts = [] + monkeypatch.setattr( + ApplicationServices, + "AXUIElementSetMessagingTimeout", + lambda el, timeout: timeouts.append(timeout) or 0, + ) + monkeypatch.setattr(ApplicationServices, "AXUIElementCopyAttributeValue", lambda *args: (-25204, None)) + result = module.close_owned_document(43, document) + assert result["status"] == "error" + assert timeouts and all(0 < timeout <= 1 for timeout in timeouts) + + +def test_save_sheet_traversal_deadline_stops_before_discard(monkeypatch, tmp_path): + module, document, _app, _window, _other, _close, sheet, discard, pressed = ax_world( + monkeypatch, tmp_path, edited=True + ) + ticks = iter([0] + [0.1] * 22 + [11] * 100) + monkeypatch.setattr(module.time, "monotonic", lambda: next(ticks)) + sheet["AXChildren"] += [{"AXRole": "AXGroup", "AXChildren": []} for _ in range(100)] + result = module.close_owned_document(43, document) + assert result["status"] == "error" + assert result["reason"] == "cleanup_deadline" + assert discard not in pressed + + +def test_main_automatic_ax_cleanup_with_automation_denied(monkeypatch, tmp_path): + import ApplicationServices + from jevdual import posture + + root = tmp_path / "run" + module, _document, app, window, other, _close, _sheet, _discard, _pressed = ax_world(monkeypatch, root) + window["AXDocument"] = (root / "run-invoice.txt").as_uri() + monkeypatch.setattr(posture, "screen_locked", lambda: False) + monkeypatch.setattr(ApplicationServices, "AXIsProcessTrusted", lambda: True) + monkeypatch.setattr(sys, "argv", ["fixture", "--run-dir", str(root)]) + stopped = [] + alive = [False] + http = SimpleNamespace( + server_port=1234, + serve_forever=lambda: None, + shutdown=lambda: stopped.append("http_shutdown"), + server_close=lambda: stopped.append("http_close"), + ) + + class Thread: + def __init__(self, **kwargs): + pass + + def start(self): + alive[0] = True + + def is_alive(self): + return alive[0] + + def join(self, timeout): + alive[0] = False + + browser = SimpleNamespace( + pid=42, + returncode=0, + poll=lambda: None, + terminate=lambda: stopped.append("browser"), + wait=lambda timeout: None, + ) + + def run(command, **kwargs): + if command[0] == "osascript": + raise subprocess.CalledProcessError(1, command) # Automation explicitly denied. + return SimpleNamespace(stdout="") + + async def scope(*args): + return {"destination": {"pid": 43}, "source": {"pid": 42}} + + async def pid(): + return 43 + + def stop(_): + raise KeyboardInterrupt() + + monkeypatch.setattr(module, "ThreadingHTTPServer", lambda *args: http) + monkeypatch.setattr(module.threading, "Thread", Thread) + monkeypatch.setattr(module.subprocess, "Popen", lambda *args, **kwargs: browser) + monkeypatch.setattr(module.subprocess, "run", run) + monkeypatch.setattr(module, "scope_for", scope) + if hasattr(module, "wait_browser_ready"): + monkeypatch.setattr(module, "wait_browser_ready", lambda *args: {"status": "ready"}) + monkeypatch.setattr(module, "textedit_pid", pid) + monkeypatch.setattr(module.time, "sleep", stop) + module.main() + assert app["AXWindows"] == [other], "Automation-denied old cleanup leaves the owned AX window open" + assert "browser" in stopped and "http_shutdown" in stopped + assert json.loads((root / "cleanup.json").read_text())["document"]["status"] == "confirmed" + + +@pytest.mark.asyncio +async def test_indefinite_sdk_enumeration_is_cancelled_then_owned_cleanup_runs(monkeypatch, tmp_path): + import asyncio + + import cua_driver + + module = fixture_module() + monkeypatch.setattr(module, "IDENTITY_SECONDS", 0.02) + cancelled, shutdown = [], [] + + class Driver: + async def list_apps(self, _): + try: + await asyncio.Future() + finally: + cancelled.append(True) + + async def shutdown(self): + shutdown.append(True) + + monkeypatch.setattr(cua_driver.CuaDriver, "create", lambda: Driver()) + with pytest.raises(module.FixtureFailure) as failure: + await module.scope_for(42, "http://127.0.0.1:1", tmp_path / "owned.txt") + assert failure.value.reason == "sdk_timeout" + assert failure.value.exit_code == 4 + assert cancelled == [True] and shutdown == [True] + stopped = [] + browser = SimpleNamespace( + pid=42, + returncode=0, + poll=lambda: None, + terminate=lambda: stopped.append("browser"), + wait=lambda timeout: None, + ) + http = SimpleNamespace(server_close=lambda: stopped.append("listener")) + result = module.cleanup(browser, http, None, None, tmp_path / "owned.txt", opened=False, pid=None) + assert result["browser"]["status"] == result["listener"]["status"] == "confirmed" + assert stopped == ["browser", "listener"] + assert not [ + task for task in asyncio.all_tasks() if task is not asyncio.current_task() and not task.done() + ] + + +@pytest.mark.asyncio +async def test_indefinite_driver_shutdown_is_cancelled(monkeypatch): + import asyncio + + module = fixture_module() + cancelled = [] + + class Driver: + async def shutdown(self): + try: + await asyncio.Future() + finally: + cancelled.append(True) + + with pytest.raises(module.FixtureFailure) as failure: + await module.shutdown_driver(Driver(), "document_cleanup", module.time.monotonic() + 0.02) + assert failure.value.reason == "sdk_timeout" + assert cancelled == [True] + assert not [ + task for task in asyncio.all_tasks() if task is not asyncio.current_task() and not task.done() + ] From d7072107d576d7a09643229ae584a3864d2fe0f6 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:09:14 -0400 Subject: [PATCH 138/216] Pause stale body-boot decisions and qualify owned mid-job restarts --- .../notebook/2026-10-12-workbench-restarts.md | 7 + tools/physical-workcell/NETWORK_WORKBENCH.md | 4 + .../network_bench_operator.html | 2 +- .../network_operator_runtime.py | 35 +- .../qualify_workbench_restarts.py | 370 ++++++++++++++++++ .../score_workbench_restarts.py | 153 ++++++++ .../test_network_operator.py | 138 +++++++ .../test_workbench_restart_harness.py | 72 ++++ 8 files changed, 777 insertions(+), 4 deletions(-) create mode 100644 tools/physical-workcell/qualify_workbench_restarts.py create mode 100644 tools/physical-workcell/score_workbench_restarts.py create mode 100644 tools/physical-workcell/test_workbench_restart_harness.py diff --git a/jevdual/docs/notebook/2026-10-12-workbench-restarts.md b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md index 9ee3921..674934c 100644 --- a/jevdual/docs/notebook/2026-10-12-workbench-restarts.md +++ b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md @@ -19,3 +19,10 @@ Observed: four new real-socket checks failed on the original runtime. Health-fir Inferred: boot identity alone does not invalidate a model decision, and runner recovery needs a consistent unfinished-job status. The original historical receipt mechanism remains useful. Next: repair the runtime epoch boundaries and labels, rerun affected real-socket checks, then freeze the actual browser restart trial. Refs: tools/physical-workcell/output/sim11-epoch-before-fix.log; tools/physical-workcell/output/sim11-preserved-baseline/preserved.json; tools/physical-workcell/test_network_operator.py + +## SIM11-U2 · update · 2026-10-12 14:09 +Resolves: SIM11-EPOCH = held +Observed: all nineteen runtime socket checks passed after epoch invalidation and job-status corrections. The old decision is withheld on health-first and lease-read-first reboot paths, exact unknown history stays recoverable once, and a later outage preserves the last verified epoch. Eighty core/adapter/link/HTTP regressions and four restart-harness control/ownership checks also passed. Ruff, JavaScript syntax and diff checks passed. The harness now records exact roots, ports, stopped processes, boot epochs and command digests; its scorer requires actual browser recovery evidence and final native/SQLite/contact proof. No actual-model restart trial has run yet. +Inferred: the epoch diagnosis is supported by failing and resolving socket evidence. The 103 mechanical checks establish readiness for the frozen browser trial, not its result. +Next: commit all measured source, then interrupt two actual image-guided jobs at the four preregistered process boundaries. +Refs: tools/physical-workcell/output/sim11-epoch-after-fix-runtime.log; tools/physical-workcell/output/sim11-core-network-regression.log; tools/physical-workcell/output/sim11-harness-tests-v1/unittest.log; tools/physical-workcell/qualify_workbench_restarts.py; tools/physical-workcell/score_workbench_restarts.py diff --git a/tools/physical-workcell/NETWORK_WORKBENCH.md b/tools/physical-workcell/NETWORK_WORKBENCH.md index 5285093..eda41f6 100644 --- a/tools/physical-workcell/NETWORK_WORKBENCH.md +++ b/tools/physical-workcell/NETWORK_WORKBENCH.md @@ -26,6 +26,10 @@ Use **Disconnect** to close the diagnostic link. The last image and completed re Restart the body by omitting `--initialize`; restart the host with the same root and exact port. Both identities persist. Body restart revokes leases. Host restart pauses the queue, keeps uncertain commands, and never replays them. Reloading the browser does not restart planning or reset the bench. +A new body boot epoch also pauses planning when a fast restart escaped the outage poll. An earlier model decision cannot acquire authority to continue across that boundary. Pending historical commands keep their original epoch and identity: **Check receipt** reads their retained result, then **Resume** obtains a fresh observation. Workbench restart cancels its owned planner before releasing process ownership; its active unfinished job appears paused or uncertain as appropriate. + +For a repeatable mid-job restart trial, use `qualify_workbench_restarts.py run --root NEW_ROOT --source-commit COMMITTED_SOURCE_SHA`. The harness owns the body and workbench processes. Its `request` command checks the current planning or uncertain-command predicate before stopping a role, and restarts only that role at its retained root and port. Browser actions still perform receipt recovery and Resume. Run `score_workbench_restarts.py --root NEW_ROOT` after the harness finishes. These trials cover graceful process restarts; forced termination during native persistence needs a separate experiment. + The link, client, queue, model inputs and receipts live beneath the host root. Native state and measurement SQLite remain beneath the separate body root. An independent post-trial scorer reads the native records after the trial processes stop; they are not model inputs. The previous local workbench uses different source files and roots. Qualification uses committed source: diff --git a/tools/physical-workcell/network_bench_operator.html b/tools/physical-workcell/network_bench_operator.html index fbc88d4..5ab2774 100644 --- a/tools/physical-workcell/network_bench_operator.html +++ b/tools/physical-workcell/network_bench_operator.html @@ -44,7 +44,7 @@ const operation = typeof item.outcome === 'string' ? item.outcome.split(':',1)[0] : ''; const requested = {start_job:'Preparing inspection',observe:'Requesting camera observation',propose:'Checking the planned action',disturb:'Starting recovery trial',dispatch:'Sending a guarded action'}; const received = {start_job:'Inspection started',observe:'Camera observation received',propose:'Action proposal accepted',disturb:'Recovery disturbance applied',dispatch:'Action receipt checked'}; - const titles = {observe:'Observed the bench',measurement:'Recorded measurement',reset:'Verified reset',pause:'Pause requested',resume:'Agent resumed',queued:'Job queued',start_intent:'Starting job',inference:'AI planning requested',decision_withheld:'Earlier model reply withheld',disturbance_intent:'Recovery trial started',dispatch:'Action submitted',completed:'Job completed',halt:'Agent stopped for review',shutdown_model_exit:'Model process stopped',shutdown_work_exit:'In-flight work stopped',disconnect:'Body disconnected',reconnect:'Body reconnecting',reconciled:'Command receipt recovered',fault_armed:'Reply fault armed',health_unavailable:'Body unavailable',unavailable:'Body unavailable'}; + const titles = {observe:'Observed the bench',measurement:'Recorded measurement',reset:'Verified reset',pause:'Pause requested',resume:'Agent resumed',queued:'Job queued',start_intent:'Starting job',inference:'AI planning requested',decision_withheld:'Earlier model reply withheld',disturbance_intent:'Recovery trial started',dispatch:'Action submitted',completed:'Job completed',halt:'Agent stopped for review',shutdown_model_exit:'Model process stopped',shutdown_work_exit:'In-flight work stopped',disconnect:'Body disconnected',reconnect:'Body reconnecting',reconciled:'Command receipt recovered',fault_armed:'Reply fault armed',health_unavailable:'Body unavailable',unavailable:'Body unavailable',body_epoch_changed:'Body restarted'}; if (item.kind === 'rpc_intent') return {title:requested[operation] || 'Sending a body request',detail:''}; if (item.kind === 'rpc_applied') return {title:received[operation] || 'Body receipt checked',detail:typeof item.intent === 'string' ? item.intent : ''}; if (item.kind === 'reconciled') return {title:titles.reconciled,detail:'The agent remains paused until you resume.'}; diff --git a/tools/physical-workcell/network_operator_runtime.py b/tools/physical-workcell/network_operator_runtime.py index 5ae9c23..1ed9978 100644 --- a/tools/physical-workcell/network_operator_runtime.py +++ b/tools/physical-workcell/network_operator_runtime.py @@ -80,6 +80,9 @@ def __init__(self, root, policy, start_worker=True): self._client_pin() if self.m["opened"]: self.m.update(runner_status="paused", reason="Restarted; inspect the retained stage before explicit Resume") + active = self._job() + if active and active["status"] == "running": + active.update(status="paused", error=self.m["reason"]) self.m["opened"] = True if self.m["stage"]: self._associate() @@ -153,6 +156,7 @@ def _refresh_health(self): control_epoch = self.control_epoch transport_epoch = self.transport_epoch pinned = dict(self.m["body_identity"]) + pinned["epoch"] = self.m["connection"]["epoch"] remote_identity = pinned try: status, content = body_client.http_call(self.link.origin, "GET", "/identity", timeout=.8) @@ -178,6 +182,9 @@ def _refresh_health(self): if (self.closing or self.transport_pending or control_epoch != self.control_epoch or transport_epoch != self.transport_epoch or not self.link.state()["connected"]): return False + if connection == "connected" and remote_identity["epoch"] != self.m["connection"]["epoch"]: + self._body_epoch_changed(remote_identity["epoch"], ready, known_unknown=not ready) + return ready old = self.m["connection"]["state"] self.body_ready = ready self.m["connection"].update(state=connection, reason=error or "Body identity verified by read-only TCP health", epoch=remote_identity["epoch"]) @@ -206,6 +213,19 @@ def _halt(self, reason, blocked=False): job.update(status="unknown" if blocked else "paused", error=str(reason)) self._event("halt", outcome=reason) + def _body_epoch_changed(self, epoch, ready, known_unknown=False): + previous = self.m["connection"]["epoch"] + reason = f"Body restarted from boot {previous} to {epoch}; check pending receipts and explicitly Resume for a fresh image" + self.body_ready = ready + self.m["connection"].update(state="connected", epoch=epoch, reason=reason) + self.cancel.set() + if self.m["stage"]: + self._uncertain(reason) + else: + self.control_epoch += 1 + self._halt(reason, blocked=known_unknown) + self._event("body_epoch_changed", outcome=f"{previous} -> {epoch}") + def _uncertain(self, reason): stage = self.m["stage"] self.m["recovery"] = {"state": "uncertain" if stage and stage.get("command_id") else "blocked", @@ -357,6 +377,7 @@ def _rpc(self, operation, arguments, context): self._halt("Conservative network-command budget exhausted") return None epoch = self.control_epoch + known_body_epoch = self.m["connection"]["epoch"] self.transport_pending = True self.transport_epoch += 1 try: @@ -365,6 +386,9 @@ def _rpc(self, operation, arguments, context): if epoch != self.control_epoch or self.cancel.is_set() or self.closing: return None journal = self.client._load() + if journal["identity"]["epoch"] != known_body_epoch: + self._body_epoch_changed(journal["identity"]["epoch"], ready=False) + return None self.m["connection"]["epoch"] = journal["identity"]["epoch"] self.m["stage"] = {"operation": operation, "arguments": arguments, "context": context, "before_commands": list(journal["commands"]), "command_id": None, "control_epoch": epoch} @@ -405,7 +429,7 @@ def _rpc(self, operation, arguments, context): self.m["runner_status"] = "paused" self._save() - def _public_status(self): + def _public_status(self, include_identity=False): status = self.client.status() remote = status["server_state"] if remote.get("state") != "ready": @@ -413,7 +437,7 @@ def _public_status(self): pinned = self.m["body_identity"] if any(remote["identity"][k] != pinned[k] for k in body_client.IDENTITY_KEYS - {"epoch"}): raise protocol.Refusal("network status belongs to another pinned body") - return remote["bench"] + return (remote["bench"], remote["identity"]) if include_identity else remote["bench"] def _apply(self, envelope, result): with self.lock: @@ -523,6 +547,9 @@ def reconcile(self): self._apply(envelope, envelope["result"]) with self.lock: self.m.update(runner_status="paused", reason="Exact historical stage recovered; explicit Resume observes fresh evidence") + active = self._job() + if active and active["status"] != "completed": + active.update(status="paused", error=None) self.m["recovery"] = {"state": "recovered", "command_id": token, "operation": stage["operation"], "reason": self.m["reason"]} self._event("reconciled", outcome=token) except Exception as exc: # Untrusted/missing receipt cannot settle effects. @@ -545,13 +572,15 @@ def resume(self): self.transport_epoch += 1 resume_epoch = self.control_epoch try: - self._public_status() + _, remote_identity = self._public_status(include_identity=True) with self.lock: if (resume_epoch != self.control_epoch or self.closing or self.m["connection"]["state"] != "connected"): raise protocol.Refusal("control changed while Resume was reading body status") self.control_epoch += 1 self.cancel.clear() + self.body_ready = True + self.m["connection"].update(epoch=remote_identity["epoch"], reason="Current body boot verified for explicit Resume") self.m.update(runner_status="running", reason="Resumed; next decision receives a fresh TCP image") self.m["recovery"] = {"state": "none", "command_id": None, "operation": None, "reason": "No pending command"} self._event("resume") diff --git a/tools/physical-workcell/qualify_workbench_restarts.py b/tools/physical-workcell/qualify_workbench_restarts.py new file mode 100644 index 0000000..2e708d8 --- /dev/null +++ b/tools/physical-workcell/qualify_workbench_restarts.py @@ -0,0 +1,370 @@ +"""Frozen owned-process restart trial; all product actions come from the browser. + +run --root PATH --source-commit SHA +request --root PATH --action stop-role --role workbench --predicate planning --wait-s 40 +request --root PATH --action start-role --role workbench +request --root PATH --action finish +Numbered control requests capture fresh expectations; mismatches never signal a PID. +""" +import argparse +import json +import signal +import subprocess +import threading +import time +from pathlib import Path + +import body_client +import order_protocol as protocol +import qualify_network_workbench as previous + +BASE, REPO = previous.BASE, previous.REPO +SOURCES = list(dict.fromkeys(previous.SOURCES + [BASE / "qualify_workbench_restarts.py", BASE / "score_workbench_restarts.py"])) + + +def retain(path, value): + protocol.create_file(path, protocol.encoded(value)) + + +def read(path): + return body_client.read_journal(path) + + +def get(origin, path, pinned=None): + status, content = body_client.http_call(origin, "GET", path, body_client.pinned_headers(pinned) if pinned else {}, timeout=1) + if status != 200: + raise protocol.Refusal("public read refused") + return protocol.decode(content) + + +def expected(public): + return {"app_id": public["app_id"], "body_id": public["connection"]["body_id"], + "runner_status": public["runner_status"], "model_request_pending": public["model_request_pending"], + "active_job_id": public["active_job_id"], "usage_calls": public["usage"]["calls"], + "recovery_command_id": public["recovery"]["command_id"]} + + +def matches(public, predicate): + if predicate == "planning": + return public["model_request_pending"] is True and public["runner_status"] == "running" + if predicate == "uncertain": + return bool(public["recovery"]["command_id"] and public["runner_status"] == "blocked") + return predicate == "none" + + +def validate_control(command): + protocol.fields(command, ("sequence", "action", "role", "predicate", "expect", "requested_time"), "restart control") + if type(command["sequence"]) is not int or not 1 <= command["sequence"] <= 4096: + raise protocol.Refusal("control sequence must be a bounded positive integer") + action, role, predicate = command["action"], command["role"], command["predicate"] + if (not isinstance(action, str) or action not in {"stop-role", "start-role", "finish"} or + role is not None and (not isinstance(role, str) or role not in {"body", "workbench"}) or + not isinstance(predicate, str) or predicate not in {"planning", "uncertain", "none"} or + action != "finish" and role is None or action == "finish" and role is not None or + action == "stop-role" and (predicate == "none" or command["expect"] is None) or + action != "stop-role" and predicate != "none"): + raise protocol.Refusal("control action, role or predicate is invalid") + protocol.finite(command["requested_time"]) + if command["expect"] is not None: + protocol.fields(command["expect"], ("app_id", "body_id", "runner_status", "model_request_pending", + "active_job_id", "usage_calls", "recovery_command_id"), "public expectation") + for key in ("app_id", "body_id"): + protocol.identity(command["expect"][key]) + for key in ("active_job_id", "recovery_command_id"): + if command["expect"][key] is not None: + protocol.identity(command["expect"][key]) + if (type(command["expect"]["model_request_pending"]) is not bool or + type(command["expect"]["usage_calls"]) is not int or not 0 <= command["expect"]["usage_calls"] <= 96 or + not isinstance(command["expect"]["runner_status"], str)): + raise protocol.Refusal("public expectation has invalid types") + return command + + +def request(root, action, role=None, predicate="none", wait_s=0): + root = protocol.directory(root) + ready = read(root / "ready.json") + if action not in {"stop-role", "start-role", "finish"} or role not in {None, "body", "workbench"}: + raise protocol.Refusal("unsupported process control") + if action != "finish" and role is None or action == "stop-role" and predicate not in {"planning", "uncertain"}: + raise protocol.Refusal("stop requires an exact planning or uncertain predicate") + wait_s = protocol.finite(wait_s) + if not 0 <= wait_s <= 40: + raise protocol.Refusal("predicate wait exceeds forty seconds") + deadline = time.monotonic() + wait_s + while True: + public = None if action == "start-role" and role == "workbench" else get(ready["browser_origin"], "/api/state") + if public is None or matches(public, predicate): + break + if time.monotonic() >= deadline: + raise protocol.Refusal("public state does not match the requested interruption predicate") + time.sleep(.05) + paths = list((root / "control").glob("*.request.json")) + sequence = max((int(path.name.split(".")[0]) for path in paths), default=0) + 1 + value = {"sequence": sequence, "action": action, "role": role, "predicate": predicate, + "expect": expected(public) if public else None, "requested_time": time.time()} + validate_control(value) + retain(root / "control" / f"{sequence:06d}.request.json", value) + return value + + +def freeze(root, commit): + if subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=REPO, text=True).strip() != commit: + raise protocol.Refusal("trial requires its committed source head") + files = {} + for path in SOURCES: + name = str(path.relative_to(REPO)) + content = protocol.read_bytes(path) + if subprocess.check_output(["git", "show", f"{commit}:{name}"], cwd=REPO) != content: + raise protocol.Refusal("source is not frozen: " + name) + files[name] = protocol.sha(content) + retain(root / "source-freeze.json", {"commit": commit, "files": files}) + + +class Trial: + def __init__(self, root, commit, body_port=0, browser_port=0): + self.root, self.commit = protocol.directory(root, create=True), commit + self.body_port, self.browser_port = body_port, browser_port + self.action_performed = False + self.processes, self.logs, self.active, self.stops = [], [], {}, {} + self.ledger = {"source_commit": commit, "planner": "actual_codex_cli_images_over_TCP", "simulation": True, + "processes": [], "ready": False} + self.restart_ledger = {"boundaries": []} + + def launch(self, role, initialize=False): + boot = sum(record["role"] == role for record in self.ledger["processes"]) + 1 + if role == "body": + args = [str(BASE / "body_network.py"), "--root", str(self.root / "body"), "--port", str(self.body_port)] + if initialize: + args += ["--initialize", "--diagnostic"] + else: + args = [str(BASE / "network_bench_operator.py"), "serve", "--root", str(self.root / "operator"), + "--port", str(self.browser_port), "--backend", "codex"] + log_name = f"{role}-{boot:02d}.log" + log = (self.root / log_name).open("xb") + log_path = self.root / log_name + log_path.chmod(0o600) + process = subprocess.Popen([str(BASE / ".venv/bin/python"), *args], cwd=REPO, stdout=log, stderr=log, + start_new_session=True) + record = {"role": role, "boot": boot, "pid": process.pid, "root": str(self.root / ("body" if role == "body" else "operator")), + "port": self.body_port if role == "body" else self.browser_port, "initialized": initialize, "log": log_name} + self.processes.append((process, record)) + self.logs.append(log) + self.ledger["processes"].append(record) + self.active[role] = process + return process + + def stop(self, role): + process = self.active.get(role) + if process is None or process.poll() is not None: + raise protocol.Refusal("requested role has no live owned process") + record = next((record for proc, record in self.processes if proc is process), None) + if record is None or record["role"] != role or record["pid"] != process.pid: + raise protocol.Refusal("process handle is not registered to this trial role") + process.terminate() + try: + process.wait(timeout=40) + except subprocess.TimeoutExpired as exc: + process.kill() + process.wait(timeout=5) + self.ledger["error"] = "owned graceful stop exceeded forty seconds; forced cleanup is not qualification" + raise protocol.Refusal(self.ledger["error"]) from exc + self.active[role] = None + record.update(exit_observed=True, returncode=process.returncode, stopped_time=time.time()) + return dict(record) + + def wait_public(self, origin, path): + deadline = time.monotonic() + 30 + while time.monotonic() < deadline: + try: + return get(origin, path) + except (OSError, ValueError): + if any(p is not None and p.poll() is not None for p in self.active.values()): + raise protocol.Refusal("owned role exited during readiness") + time.sleep(.05) + raise protocol.Refusal("owned endpoint readiness timed out") + + def snapshot(self, sequence, label): + value = {"time": time.time(), "public": None, "body_identity": None, "body_state": None, + "processes": {role: p.pid if p is not None and p.poll() is None else None for role, p in self.active.items()}} + for key, origin, path, pinned in (("public", self.browser_origin, "/api/state", None), + ("body_identity", self.body_origin, "/identity", None), + ("body_state", self.body_origin, "/state", self.identity)): + try: + value[key] = get(origin, path, pinned) + except (OSError, ValueError) as exc: + value[key + "_error"] = str(exc) + host = read(self.root / "operator" / "operator.json") + client = read(self.root / "operator" / "client" / "client.json") + commands = {} + for token, index in client["commands"].items(): + content = protocol.read_bytes(self.root / "operator" / "client" / "requests" / (token + ".json")) + if protocol.sha(content) != index["request_sha256"]: + raise protocol.Refusal("client immutable request changed during snapshot") + commands[token] = {"request_sha256": index["request_sha256"], "send_count": index["send_count"], + "state": index["state"], "operation": protocol.decode(content)["operation"]} + value["client"] = {"commands": commands, "pending_command_ids": client["pending_command_ids"], + "lease": client["lease"], "identity": client["identity"]} + value["host"] = {key: host[key] for key in ("app_id", "body_identity", "stage", "frame", "runner_status", "sequence", "usage")} + value["posts"] = [] + for path in sorted((self.root / "operator" / "link" / "events").glob("*.json")): + event = read(path) + if event["kind"] == "received" and event.get("method") == "POST" and event.get("command_id"): + value["posts"].append({key: event[key] for key in ("sequence", "command_id", "payload_sha256")}) + name = f"{sequence:06d}-{label}.json" + retain(self.root / "snapshots" / name, value) + return name, value + + def control(self, command): + validate_control(command) + sequence, action, role = command["sequence"], command["action"], command["role"] + result = {"request": command, "passed": False} + before_name, before = self.snapshot(sequence, "before") + result["before"] = before_name + if command["expect"] is not None and (before["public"] is None or expected(before["public"]) != command["expect"]): + raise protocol.Refusal("public state changed since this exact interruption was requested") + if action == "stop-role": + if role not in {"body", "workbench"} or not matches(before["public"], command["predicate"]): + raise protocol.Refusal("interruption predicate no longer matches") + fresh = get(self.browser_origin, "/api/state") + if expected(fresh) != command["expect"] or not matches(fresh, command["predicate"]): + raise protocol.Refusal("predicate changed immediately before owned process signal") + self.action_performed = True + result["process"] = self.stop(role) + self.stops[role] = {"sequence": sequence, "predicate": command["predicate"]} + elif action == "start-role": + if role not in self.stops or self.active.get(role) is not None: + raise protocol.Refusal("restart requires this trial's stopped role") + self.action_performed = True + process = self.launch(role) + ready = self.wait_public(self.body_origin if role == "body" else self.browser_origin, + "/identity" if role == "body" else "/api/state") + result.update(stopped_sequence=self.stops[role]["sequence"], predicate=self.stops[role]["predicate"], pid=process.pid) + # Give real health/epoch handling a bounded opportunity; never mutate host state. + deadline = time.monotonic() + 10 + while time.monotonic() < deadline: + public = get(self.browser_origin, "/api/state") + epoch_seen = role != "body" or public["connection"]["epoch"] == ready["epoch"] + if public["runner_status"] != "running" and not public["model_request_pending"] and epoch_seen: + break + time.sleep(.05) + if public["runner_status"] == "running" or public["model_request_pending"] or not epoch_seen: + raise protocol.Refusal("restarted body or workbench did not pause its old planning") + self.stops.pop(role) + elif action != "finish": + raise protocol.Refusal("unsupported restart action") + after_name, after = self.snapshot(sequence, "after") + result.update(after=after_name, passed=True, action_performed=self.action_performed) + self.restart_ledger["boundaries"].append(result) + protocol.persist(self.root / "restart-ledger.json", self.restart_ledger) + retain(self.root / "control" / f"{sequence:06d}.result.json", result) + return action == "finish", after + + def run(self): + freeze(self.root, self.commit) + for name in ("control", "snapshots"): + (self.root / name).mkdir(mode=0o700) + self.body_port = self.body_port or previous.available_port() + self.browser_port = self.browser_port or previous.available_port() + if self.body_port == self.browser_port or any(type(port) is not int or not 1 <= port <= 65535 for port in (self.body_port, self.browser_port)): + raise protocol.Refusal("body and browser need distinct bounded owned ports") + self.body_origin, self.browser_origin = f"http://127.0.0.1:{self.body_port}", f"http://127.0.0.1:{self.browser_port}" + stopped = threading.Event() + signal.signal(signal.SIGTERM, lambda *_: stopped.set()) + signal.signal(signal.SIGINT, lambda *_: stopped.set()) + try: + self.launch("body", initialize=True) + self.identity = self.wait_public(self.body_origin, "/identity") + retain(self.root / "identity.json", self.identity) + initialization = subprocess.Popen([str(BASE / ".venv/bin/python"), str(BASE / "network_bench_operator.py"), "init", + "--root", str(self.root / "operator"), "--body-origin", self.body_origin], cwd=REPO, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + record = {"role": "initialization", "pid": initialization.pid} + self.processes.append((initialization, record)) + self.ledger["processes"].append(record) + try: + stdout, stderr = initialization.communicate(timeout=30) + except subprocess.TimeoutExpired: + initialization.kill() + stdout, stderr = initialization.communicate(timeout=5) + self.ledger["error"] = "initialization exceeded its bounded deadline" + protocol.create_file(self.root / "initialization.stdout", stdout) + protocol.create_file(self.root / "initialization.stderr", stderr) + if initialization.returncode: + raise protocol.Refusal("workbench initialization failed") + self.launch("workbench") + initial = self.wait_public(self.browser_origin, "/api/state") + retain(self.root / "initial-public.json", initial) + self.ledger.update(ready=True, body_origin=self.body_origin, browser_origin=self.browser_origin, + app_id=initial["app_id"], body_id=self.identity["body_id"]) + retain(self.root / "ready.json", self.ledger) + print(json.dumps(self.ledger), flush=True) + deadline, handled, finished = time.monotonic() + 3600, set(), False + while not stopped.is_set() and not finished: + if time.monotonic() >= deadline: + raise protocol.Refusal("restart qualification exceeded sixty minutes") + if any(p is not None and p.poll() is not None for p in self.active.values()): + raise protocol.Refusal("owned process exited without a matching control request") + for path in sorted((self.root / "control").glob("*.request.json")): + if path.name in handled: + continue + handled.add(path.name) + command = read(path) + if path.name != f"{command['sequence']:06d}.request.json": + raise protocol.Refusal("request file sequence disagrees with its exact payload") + self.action_performed = False + try: + finished, _ = self.control(command) + except protocol.Refusal as exc: + retain(self.root / "control" / path.name.replace("request", "result"), + {"request": command, "passed": False, "reason": str(exc), "action_performed": self.action_performed}) + if self.action_performed or self.ledger.get("error"): + raise + if finished: + break + stopped.wait(.05) + retain(self.root / "final-public.json", get(self.browser_origin, "/api/state")) + except Exception as exc: + self.ledger["error"] = type(exc).__name__ + ": " + str(exc) + raise + finally: + for role in ("workbench", "body"): + if self.active.get(role) is not None and self.active[role].poll() is None: + try: + self.stop(role) + except (OSError, protocol.Refusal, subprocess.SubprocessError) as exc: + self.ledger["cleanup_error"] = str(exc) + for process, record in self.processes: + record.update(exit_observed=process.poll() is not None, returncode=process.poll()) + for log in self.logs: + log.close() + self.ledger["owned_processes_exited"] = all(process.poll() is not None for process, _ in self.processes) + retain(self.root / "process-ledger.json", self.ledger) + return self.ledger + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + sub = parser.add_subparsers(dest="mode", required=True) + run_parser = sub.add_parser("run") + run_parser.add_argument("--root", required=True, type=Path) + run_parser.add_argument("--source-commit", required=True) + run_parser.add_argument("--browser-port", type=int, default=0) + run_parser.add_argument("--body-port", type=int, default=0) + control = sub.add_parser("request") + control.add_argument("--root", required=True, type=Path) + control.add_argument("--action", required=True, choices=("stop-role", "start-role", "finish")) + control.add_argument("--role", choices=("body", "workbench")) + control.add_argument("--predicate", default="none", choices=("none", "planning", "uncertain")) + control.add_argument("--wait-s", type=float, default=0) + args = parser.parse_args() + if args.mode == "run": + root = protocol.directory(args.root, create=True) + with protocol.locked(root): + result = Trial(root, args.source_commit, args.body_port, args.browser_port).run() + else: + result = request(args.root, args.action, args.role, args.predicate, args.wait_s) + print(json.dumps(result, sort_keys=True), flush=True) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/score_workbench_restarts.py b/tools/physical-workcell/score_workbench_restarts.py new file mode 100644 index 0000000..1233943 --- /dev/null +++ b/tools/physical-workcell/score_workbench_restarts.py @@ -0,0 +1,153 @@ +"""Independent post-stop restart proof plus the unchanged SIM10 native scorer.""" +import argparse +import json +from pathlib import Path + +import body_client +import order_protocol as protocol +import score_network_workbench as previous + + +def read(path): + content = protocol.read_bytes(path, maximum=1024 * 1024) + # Local aggregate ledgers may exceed the wire JSON limit. Reject duplicate keys. + def unique(pairs): + result = {} + for key, value in pairs: + if key in result: + raise protocol.Refusal("duplicate scorer ledger key") + result[key] = value + return result + return json.loads(content, object_pairs_hook=unique, + parse_constant=lambda _: (_ for _ in ()).throw(protocol.Refusal("nonfinite scorer ledger"))) + + +def command_identity(snapshot): + return {token: {key: record[key] for key in ("request_sha256", "send_count", "operation", "state")} + for token, record in snapshot["client"]["commands"].items()} + + +def score(root): + root = protocol.directory(root) + processes = read(root / "process-ledger.json") + if not processes.get("owned_processes_exited"): + raise protocol.Refusal("independent native scoring requires all owned trial processes stopped") + legacy = previous.score(root) + ledger = read(root / "restart-ledger.json") + identity, initial = read(root / "identity.json"), read(root / "initial-public.json") + host_events = [read(path) for path in sorted((root / "operator" / "events").glob("*.json"))] + link_events = [read(path) for path in sorted((root / "operator" / "link" / "events").glob("*.json"))] + ui = read(root / "ui-ledger.json") + visible = {} + for role in ("workbench", "body"): + for predicate in ("planning", "uncertain"): + for phase in ("offline", "restored"): + name = f"{role}-{predicate}-{phase}" + text = protocol.read_bytes(root / "ui" / (name + ".txt"), maximum=16000).decode("utf-8").casefold() + phrases = (["disconnected"] if role == "workbench" else ["body unavailable"]) if phase == "offline" else ( + ["paused"] if predicate == "planning" else ["uncertain", "check receipt"]) + visible[name] = all(phrase in text for phrase in phrases) + for name, phrase in (("body-uncertain-recovered", "receipt recovered"), ("body-uncertain-resumed", "running")): + visible[name] = phrase in protocol.read_bytes(root / "ui" / (name + ".txt"), maximum=16000).decode("utf-8").casefold() + client = body_client.read_journal(root / "operator" / "client" / "client.json") + requests = {token: read(root / "operator" / "client" / "requests" / (token + ".json")) for token in client["commands"]} + stops = {entry["request"]["sequence"]: entry for entry in ledger["boundaries"] + if entry["request"]["action"] == "stop-role"} + boundaries = [] + uncertain_tokens = [] + for start in ledger["boundaries"]: + if start["request"]["action"] != "start-role": + continue + stop = stops.get(start["stopped_sequence"]) + if stop is None: + raise protocol.Refusal("restart has no exact retained stop request") + role, predicate = stop["request"]["role"], stop["request"]["predicate"] + snapshots = [read(root / "snapshots" / entry[name]) for entry in (stop, start) for name in ("before", "after")] + before, stopped, restarting, after = snapshots + stable_ids = all(s["host"]["app_id"] == initial["app_id"] and + s["host"]["body_identity"]["body_id"] == identity["body_id"] and + s["host"]["body_identity"]["adapter_id"] == identity["adapter_id"] for s in snapshots) + stable_commands = all(command_identity(s) == command_identity(before) and s["posts"] == before["posts"] for s in snapshots) + public_before, public_after = before["public"], after["public"] + paused = bool(public_after and public_after["runner_status"] in {"paused", "blocked"} and + public_after["model_request_pending"] is False) + owned = bool(stop["process"]["exit_observed"] and stop["process"]["returncode"] == 0 and + stopped["processes"][role] is None and after["processes"][role] == start["pid"] and + stop["process"]["pid"] != start["pid"]) + epoch_before = before["body_identity"]["epoch"] + epoch_after = after["body_identity"]["epoch"] + epoch_ok = epoch_after == epoch_before + (1 if role == "body" else 0) + identities_ok = all(s["body_identity"] is None or all(s["body_identity"][key] == identity[key] + for key in body_client.IDENTITY_KEYS - {"epoch"}) for s in snapshots) + outage = True + if role == "body": + outage_public = restarting["public"] + outage = bool(stopped["body_identity"] is None and restarting["body_identity"] is None and + outage_public and outage_public["connection"]["state"] == "unavailable" and + outage_public["runner_status"] != "running" and not outage_public["model_request_pending"]) + pending_ok, model_reaped = True, True + token = public_before["recovery"]["command_id"] + if predicate == "uncertain": + uncertain_tokens.append(token) + pending_ok = bool(token and all(s["host"]["stage"] and s["host"]["stage"]["command_id"] == token and + token in s["client"]["pending_command_ids"] for s in snapshots) and + public_after["recovery"]["command_id"] == token and public_after["runner_status"] == "blocked" and + requests[token]["operation"] == "dispatch") + else: + pending_ok = public_before["model_request_pending"] is True and public_before["runner_status"] == "running" + job_id = public_before["active_job_id"] + job = next(job for job in public_before["jobs"] if job["job_id"] == job_id) + outcome = read(root / "operator" / "calls" / f"{job_id}-{job['call_count']:02d}" / "outcome.json") + model_reaped = outcome.get("outcome") == "cancelled" and outcome.get("process_exit_observed") is True + after_sequence = after["host"]["sequence"] + future_events = [event for event in host_events if event["seq"] > after_sequence] + resume = next((event for event in future_events if event["kind"] == "resume"), None) + reconcile = next((event for event in future_events if event["kind"] == "reconciled" and event.get("outcome") == token), None) + last_link = max((event["sequence"] for event in after["posts"]), default=0) + future_posts = [event for event in link_events if event["kind"] == "received" and event.get("method") == "POST" and + event.get("command_id") and event["sequence"] > last_link] + new_operations = [requests[event["command_id"]]["operation"] for event in future_posts] + first_decision = next((i for i, operation in enumerate(new_operations) if operation in {"propose", "dispatch"}), None) + fresh = bool(resume and first_decision is not None and "observe" in new_operations[:first_decision]) + receipt_ok = True + if predicate == "uncertain": + lookups = [event for event in link_events if event["kind"] == "received" and event.get("method") == "GET" and + event.get("path", "").startswith("/commands/" + token + "?") and event["sequence"] > last_link] + response_path = root / "operator" / "client" / "responses" / (token + "-" + client["commands"][token]["response_sha256"] + ".json") + receipt = read(response_path) + ui_recovered = [step for step in ui["steps"] if step["state"]["recovery"]["state"] == "recovered" and + step["state"]["recovery"]["command_id"] == token and + step["state"]["runner_status"] != "running" and + step["client_commands"] == len(after["client"]["commands"])] + receipt_ok = bool(ui_recovered and reconcile and resume and reconcile["seq"] < resume["seq"] and lookups and + receipt["state"] == "completed" and receipt["request_sha256"] == client["commands"][token]["request_sha256"] and + receipt["recorded_epoch"] == requests[token]["epoch"] and + len([event for event in link_events if event["kind"] == "received" and event.get("method") == "POST" and + event.get("command_id") == token]) == 1 and client["commands"][token]["send_count"] == 1) + ok = all((stop["passed"], start["passed"], stable_ids, stable_commands, paused, owned, epoch_ok, + identities_ok, outage, pending_ok, model_reaped, fresh, receipt_ok)) + boundaries.append({"role": role, "predicate": predicate, "passed": ok, "stop_sequence": stop["request"]["sequence"], + "start_sequence": start["request"]["sequence"], "command_id": token, + "stable_ids": stable_ids and identities_ok, "unchanged_sends": stable_commands, + "paused_after_restart": paused, "owned_process_reaped": owned, "epoch_bound": epoch_ok, + "outage_observed": outage, "pending_bound": pending_ok, "model_reaped": model_reaped, + "fresh_observation_after_explicit_resume": fresh, "historical_receipt_without_replay": receipt_ok}) + required = {("body", "planning"), ("body", "uncertain"), ("workbench", "planning"), ("workbench", "uncertain")} + passed = bool(legacy["passed"] and required == {(b["role"], b["predicate"]) for b in boundaries} and + len(boundaries) == 4 and all(b["passed"] for b in boundaries) and all(visible.values()) and + len(uncertain_tokens) == len(set(uncertain_tokens)) == 2 and not processes.get("cleanup_error")) + result = {"passed": passed, "legacy_qualification": legacy, "restart_boundaries": boundaries, + "scope": "four graceful owned mid-job restarts; actual Codex browser; loopback simulation", + "owned_processes_exited": processes["owned_processes_exited"], "visible_restart_states": visible} + protocol.create_file(root / "restart-score.json", protocol.encoded(result)) + return result + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", required=True, type=Path) + print(json.dumps(score(parser.parse_args().root), sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/test_network_operator.py b/tools/physical-workcell/test_network_operator.py index f8a4558..456b601 100644 --- a/tools/physical-workcell/test_network_operator.py +++ b/tools/physical-workcell/test_network_operator.py @@ -51,6 +51,144 @@ def wait(self, predicate, timeout=15): time.sleep(.02) self.assertTrue(predicate()) + def restart_same_body(self): + identity = self.service.identity() + port = self.service.http.server_address[1] + self.service.close() + self.service = body_network.BodyService(self.body_root, port=port).start() + current = self.service.identity() + self.assertEqual(current["body_id"], identity["body_id"]) + self.assertEqual(current["adapter_id"], identity["adapter_id"]) + self.assertGreater(current["epoch"], identity["epoch"]) + return current + + def test_health_first_fast_body_reboot_withholds_old_model_decision(self): + entered, release = threading.Event(), threading.Event() + decisions = iter((action("move", -.25, 0), action())) + def policy(*_): + entered.set() + release.wait(5) + return next(decisions), {} + op = self.open(policy, worker=True) + op.health_stop.set() + op.health_worker.join(4) + op.enqueue(self.job()) + self.assertTrue(entered.wait(10)) + before = len(op._journal()["commands"]) + current = self.restart_same_body() + try: + op._refresh_health() + finally: + release.set() + self.wait(lambda: not op.in_model and op.m["runner_status"] == "paused") + self.assertEqual(self.service.body.status()["generation"], 0) + self.assertEqual(len(op._journal()["commands"]), before) + self.assertEqual(op.state()["connection"]["epoch"], current["epoch"]) + self.assertTrue(any(e["kind"] == "decision_withheld" for e in op.m["activity"])) + self.assertEqual(op.state()["jobs"][0]["status"], "paused") + + def test_acquisition_first_reboot_cannot_authorize_old_decision_with_fresh_lease(self): + calls = [] + before = [] + old_challenges = [] + def policy(challenge, *_): + calls.append(challenge) + if len(calls) == 1: + old_challenges.append(challenge["challenge_id"]) + before.append(len(op._journal()["commands"])) + self.restart_same_body() + return action("move", -.25, 0), {} + return action(), {} + op = self.open(policy) + op.health_stop.set() + op.health_worker.join(4) + op.enqueue(self.job()) + self.assertFalse(op._step()) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(self.service.body.status()["generation"], 0) + self.assertEqual(len(op._journal()["commands"]), before[0]) + self.assertIsNone(op.m["stage"]) + self.assertEqual(op._journal()["lease"]["epoch"], self.service.epoch) + op.resume() + self.assertFalse(op._step()) + self.assertEqual(len(calls), 2) + self.assertNotEqual(calls[1]["challenge_id"], old_challenges[0]) + self.assertEqual(calls[1]["observation"]["generation"], 0) + self.assertEqual(self.service.body.status()["generation"], 0) + + def test_unknown_dispatch_survives_body_epoch_then_exact_recovery_and_resume(self): + decisions = iter((action("move", -.25, 0), action())) + op = self.open(lambda *_: (next(decisions), {})) + op.health_stop.set() + op.health_worker.join(4) + op.enqueue(self.job()) + op.fault({"mode": "drop_after", "delay_s": 0}) + self.assertFalse(op._step()) + token = op.m["stage"]["command_id"] + journal = op._journal() + lease = journal["lease"] + count = len(journal["commands"]) + current = self.restart_same_body() + op._refresh_health() + self.assertEqual(op.m["stage"]["command_id"], token) + self.assertEqual(op.state()["recovery"]["command_id"], token) + self.assertEqual(op.state()["runner_status"], "blocked") + self.assertEqual(op._journal()["lease"], lease) + self.assertEqual(op._journal()["pending_command_ids"], [token]) + with self.assertRaises(protocol.Refusal): + op.resume() + op.reconcile() + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(op.state()["jobs"][0]["status"], "paused") + self.assertEqual(op.state()["connection"]["epoch"], current["epoch"]) + self.assertEqual(op.m["applied_commands"].count(token), 1) + self.assertEqual(len(op._journal()["commands"]), count) + self.assertEqual(op._journal()["commands"][token]["send_count"], 1) + self.assertEqual(self.service.body.status()["generation"], 1) + with self.assertRaises(protocol.Refusal): + op.reconcile() + op.resume() + self.assertFalse(op._step()) + self.assertEqual(self.service.body.status()["generation"], 1) + self.assertEqual(op._journal()["identity"]["epoch"], current["epoch"]) + + def test_graceful_host_restart_labels_unfinished_planning_as_paused(self): + entered = threading.Event() + def policy(challenge, history, directory, cancel): + entered.set() + cancel.wait(5) + return action("move", -.25, 0), {} + op = self.open(policy, worker=True) + op.enqueue(self.job()) + self.assertTrue(entered.wait(10)) + count = len(op._journal()["commands"]) + op.close() + self.op = None + op = self.open(lambda *_: self.fail("restart automatically requested a model"), worker=True) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(op.state()["jobs"][0]["status"], "paused") + self.assertEqual(len(op._journal()["commands"]), count) + self.assertEqual(self.service.body.status()["generation"], 0) + self.assertIsNone(op.m["stage"]) + + def test_acknowledged_second_boot_survives_outage_without_epoch_regression(self): + op = self.open() + op.health_stop.set() + op.health_worker.join(4) + current = self.restart_same_body() + op._refresh_health() + self.assertEqual(op.state()["runner_status"], "paused") + op.resume() + self.assertEqual(op.state()["connection"]["epoch"], current["epoch"]) + self.assertEqual(op.state()["runner_status"], "running") + self.service.close() + self.service = None + op._refresh_health() + self.assertEqual(op.state()["connection"]["state"], "unavailable") + self.assertEqual(op.state()["connection"]["epoch"], current["epoch"]) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(len(op._journal()["commands"]), 0) + def test_pause_wins_while_resume_waits_for_actual_socket_status(self): op = self.open() op.pause() diff --git a/tools/physical-workcell/test_workbench_restart_harness.py b/tools/physical-workcell/test_workbench_restart_harness.py new file mode 100644 index 0000000..7259c45 --- /dev/null +++ b/tools/physical-workcell/test_workbench_restart_harness.py @@ -0,0 +1,72 @@ +"""Focused harness guards; disposable owned processes, no model or body launches.""" +import copy +import subprocess +import sys +import tempfile +import unittest +from pathlib import Path + +import order_protocol as protocol +import qualify_workbench_restarts as harness + +PUBLIC = {"app_id": "app", "connection": {"body_id": "body"}, "runner_status": "running", + "model_request_pending": True, "active_job_id": "job", "usage": {"calls": 1}, + "recovery": {"command_id": None}} + + +class RestartHarnessGuards(unittest.TestCase): + def test_exact_planning_and_uncertain_predicates(self): + self.assertTrue(harness.matches(PUBLIC, "planning")) + self.assertFalse(harness.matches(PUBLIC, "uncertain")) + uncertain = copy.deepcopy(PUBLIC) + uncertain.update(runner_status="blocked", model_request_pending=False) + uncertain["recovery"]["command_id"] = "command" + self.assertTrue(harness.matches(uncertain, "uncertain")) + self.assertFalse(harness.matches(uncertain, "planning")) + + def test_malformed_controls_refuse_before_snapshots_or_signals(self): + control = {"sequence": 1, "action": "stop-role", "role": "workbench", "predicate": "planning", + "expect": harness.expected(PUBLIC), "requested_time": 1} + self.assertEqual(harness.validate_control(control), control) + for key, value in (("sequence", True), ("sequence", -1), ("action", "kill"), ("role", "other"), + ("predicate", "none"), ("expect", None)): + malformed = {**control, key: value} + with self.assertRaises(protocol.Refusal): + harness.validate_control(malformed) + bad = copy.deepcopy(control) + bad["expect"]["model_request_pending"] = 1 + with self.assertRaises(protocol.Refusal): + harness.validate_control(bad) + + def test_stop_only_signals_registered_owned_handle_and_reaps_it(self): + process = subprocess.Popen([sys.executable, "-c", "import time; time.sleep(30)"]) + try: + trial = object.__new__(harness.Trial) + trial.active, trial.processes, trial.ledger = {"body": process}, [], {} + with self.assertRaises(protocol.Refusal): + trial.stop("body") + self.assertIsNone(process.poll()) + record = {"role": "body", "pid": process.pid} + trial.processes.append((process, record)) + stopped = trial.stop("body") + self.assertTrue(stopped["exit_observed"]) + self.assertIsNone(trial.active["body"]) + with self.assertRaises(protocol.Refusal): + trial.stop("body") + finally: + if process.poll() is None: + process.terminate() + process.wait(timeout=3) + + def test_snapshot_reader_keeps_128k_journal_and_wire_limit_separate(self): + with tempfile.TemporaryDirectory() as directory: + path = Path(directory) / "journal.json" + path.write_bytes(protocol.encoded({"payload": "x" * 70000})) + path.chmod(0o600) + self.assertEqual(len(harness.read(path)["payload"]), 70000) + with self.assertRaises(protocol.Refusal): + protocol.decode(path.read_bytes()) + + +if __name__ == "__main__": + unittest.main() From 3d0984dda6e4c1b67a2c4ca79d5adde4a275ae2a Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:17:36 -0400 Subject: [PATCH 139/216] Bound identity AX reads and retain cleanup file snapshots after review --- jevdual/docs/independent-onboarding.md | 2 +- jevdual/scripts/capability_fixture.py | 86 ++++++++++++-- jevdual/tests/test_capability_fixture.py | 140 +++++++++++++++++++++++ 3 files changed, 219 insertions(+), 9 deletions(-) diff --git a/jevdual/docs/independent-onboarding.md b/jevdual/docs/independent-onboarding.md index 28216e4..f4a31ad 100644 --- a/jevdual/docs/independent-onboarding.md +++ b/jevdual/docs/independent-onboarding.md @@ -81,6 +81,6 @@ Use only the entry points listed here; the other bundled modules supply imported ## Close and retain -Stop the fixture with Ctrl-C. The helper uses Accessibility to close only the window with the exact fixture document path. It may press a unique discard button only in that window's observed attached save sheet. Only identified English save sheets are supported; other dialogs refuse. It requests no TextEdit Automation grant. Retain cleanup.json and the fixture exit code. Confirm the owned browser process and loopback listener are gone, the exact document window is closed and no owned worker remains. A refusal, unknown result or manual close is a failed automatic-cleanup gate; preserve it and independently inspect only the exact owned resource. Do not substitute killing all Chrome/TextEdit processes. Cleanup does not certify whether TextEdit saved the edit before closing. +Press Ctrl-C once, then wait for the shutdown response. The helper uses Accessibility to close only the window with the exact fixture document path. It may press a unique discard button only in that window's observed attached save sheet. Only identified English save sheets are supported; other dialogs refuse. It requests no TextEdit Automation grant. Retain cleanup.json and the fixture exit code. Confirm the owned browser process and loopback listener are gone, the exact document window is closed and no owned worker remains. A refusal, unknown result or manual close is a failed automatic-cleanup gate; preserve it and independently inspect only the exact owned resource. Do not substitute killing all Chrome/TextEdit processes. cleanup.json retains bounded file size and SHA256 observations before and after close; these are file snapshots, not a persistence certificate. Record the guest close-confirmation preference without changing it. Cleanup does not certify whether TextEdit saved the edit before closing. Retain installation receipts, before/after diagnostics and exit codes, host/OS/SIP identity, consent observations, native receipt/journal/runtime contexts and cleanup evidence. Sanitize observations before sharing. Mark U2 passed only when an observed denied baseline, explicit permission transition and every native/postcondition/cleanup gate pass. This proves the scoped historical append/recovery/report behavior; it does not prove saved-file persistence, arbitrary apps or the host's entire goal. diff --git a/jevdual/scripts/capability_fixture.py b/jevdual/scripts/capability_fixture.py index b57b2d3..e7570aa 100644 --- a/jevdual/scripts/capability_fixture.py +++ b/jevdual/scripts/capability_fixture.py @@ -8,7 +8,11 @@ import argparse import asyncio +import hashlib import json +import os +import signal +import stat import subprocess import threading import time @@ -24,6 +28,7 @@ BROWSER_STARTUP_SECONDS = 180 IDENTITY_SECONDS = 30 CLEANUP_SECONDS = 10 +MAX_DOCUMENT_BYTES = 1024 * 1024 class FixtureFailure(Exception): @@ -267,7 +272,19 @@ async def scope_for(chrome_pid: int, url: str, document: Path, browser=None) -> else [] ) matching = [] + if textedit: + from ApplicationServices import AXUIElementCreateApplication, AXUIElementSetMessagingTimeout + + app = AXUIElementCreateApplication(textedit) for window in native_windows: + # The synchronous product lookup inherits this process timeout; + # recheck the phase budget for each window and refuse late results. + remaining = deadline - time.monotonic() + if remaining <= 0: + raise FixtureFailure("identity", "identity_deadline", 4) + error = AXUIElementSetMessagingTimeout(app, min(1.0, remaining)) + if error: + raise FixtureFailure("identity", f"ax_timeout_refused:{error}", 4) try: path = ax.document_path(textedit, window.window_id) if path and str(Path(path).resolve()) == str(document.resolve()): @@ -276,6 +293,8 @@ async def scope_for(chrome_pid: int, url: str, document: Path, browser=None) -> if exc.reason != "window_missing": raise if len(browser_windows) == 1 and len(matching) == 1: + if time.monotonic() >= deadline: + raise FixtureFailure("identity", "identity_deadline", 4) if browser is not None and browser.poll() is not None: raise FixtureFailure("identity", "browser_exited", 4) return { @@ -293,12 +312,57 @@ async def scope_for(chrome_pid: int, url: str, document: Path, browser=None) -> await shutdown_driver(driver, "identity", time.monotonic() + 2) +def document_snapshot(document: Path) -> dict: + """Hash bounded actual file bytes; this says nothing about unsaved AX text.""" + directory_fd = file_fd = None + try: + directory_fd = os.open(document.parent, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW) + file_fd = os.open(document.name, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK, dir_fd=directory_fd) + before = os.fstat(file_fd) + if not stat.S_ISREG(before.st_mode): + return {"status": "refused", "reason": "not_regular"} + if before.st_size > MAX_DOCUMENT_BYTES: + return {"status": "refused", "reason": "file_too_large"} + payload = bytearray() + while len(payload) <= MAX_DOCUMENT_BYTES: + chunk = os.read(file_fd, min(65536, MAX_DOCUMENT_BYTES + 1 - len(payload))) + if not chunk: + break + payload.extend(chunk) + if len(payload) > MAX_DOCUMENT_BYTES: + return {"status": "refused", "reason": "file_too_large"} + after = os.fstat(file_fd) + current = os.stat(document.name, dir_fd=directory_fd, follow_symlinks=False) + identity = lambda value: (value.st_dev, value.st_ino, value.st_size, value.st_mtime_ns) + if ( + identity(before) != identity(after) + or identity(after) != identity(current) + or len(payload) != after.st_size + ): + return {"status": "refused", "reason": "file_changed"} + return { + "status": "observed", + "size_bytes": len(payload), + "sha256": hashlib.sha256(payload).hexdigest(), + } + except FileNotFoundError: + return {"status": "absent", "reason": "file_missing"} + except OSError as exc: + return {"status": "error", "reason": type(exc).__name__, "errno": exc.errno} + finally: + if file_fd is not None: + os.close(file_fd) + if directory_fd is not None: + os.close(directory_fd) + + def cleanup(browser, http, thread, logfile, document: Path, *, opened: bool, pid: int | None) -> dict: result = { "document": {"status": "not_started"}, "browser": {"status": "not_started"}, "listener": {"status": "not_started"}, } + before = document_snapshot(document) if opened: try: observed_pid = asyncio.run(textedit_pid()) @@ -312,6 +376,8 @@ def cleanup(browser, http, thread, logfile, document: Path, *, opened: bool, pid ) except Exception as exc: # noqa: BLE001 - receipt boundary; independent cleanup must continue result["document"] = {"status": "error", "reason": getattr(exc, "reason", type(exc).__name__)} + result["document"]["file_before"] = before + result["document"]["file_after"] = document_snapshot(document) if browser is not None: try: if browser.poll() is None: @@ -434,14 +500,18 @@ def main() -> None: record(root, "fixture-status.json", failure) print(json.dumps(failure), flush=True) finally: - shutdown = cleanup(browser, http, thread, logfile, document, opened=opened, pid=pid) - record(root, "cleanup.json", shutdown) - print(json.dumps({"shutdown": shutdown}), flush=True) - if ( - any(item["status"] not in ("confirmed", "not_started") for item in shutdown.values()) - and not exit_code - ): - exit_code = 6 + previous_sigint = signal.signal(signal.SIGINT, signal.SIG_IGN) + try: + shutdown = cleanup(browser, http, thread, logfile, document, opened=opened, pid=pid) + record(root, "cleanup.json", shutdown) + print(json.dumps({"shutdown": shutdown}), flush=True) + if ( + any(item["status"] not in ("confirmed", "not_started") for item in shutdown.values()) + and not exit_code + ): + exit_code = 6 + finally: + signal.signal(signal.SIGINT, previous_sigint) if exit_code: raise SystemExit(exit_code) diff --git a/jevdual/tests/test_capability_fixture.py b/jevdual/tests/test_capability_fixture.py index a1c2300..51272c5 100644 --- a/jevdual/tests/test_capability_fixture.py +++ b/jevdual/tests/test_capability_fixture.py @@ -12,6 +12,17 @@ import pytest +@pytest.fixture(autouse=True) +def simulated_identity_timeout_api(monkeypatch): + # Scope tests use fake PIDs: never send an AX RPC to an unrelated real process. + import ApplicationServices + + monkeypatch.setattr( + ApplicationServices, "AXUIElementCreateApplication", lambda pid: SimpleNamespace(pid=pid) + ) + monkeypatch.setattr(ApplicationServices, "AXUIElementSetMessagingTimeout", lambda *args: 0) + + def fixture_module(): path = Path(__file__).resolve().parents[1] / "scripts/capability_fixture.py" spec = importlib.util.spec_from_file_location("fixture_helper", path) @@ -681,3 +692,132 @@ async def shutdown(self): assert not [ task for task in asyncio.all_tasks() if task is not asyncio.current_task() and not task.done() ] + + +@pytest.mark.asyncio +async def test_scope_sets_process_timeout_and_rejects_late_document_identity(monkeypatch, tmp_path): + import ApplicationServices + import cua_driver + from jevdual import ax + + module = fixture_module() + document = tmp_path / "owned.txt" + elapsed, timeouts = [0], [] + monkeypatch.setattr(module.time, "monotonic", lambda: elapsed[0]) + monkeypatch.setattr( + ApplicationServices, + "AXUIElementSetMessagingTimeout", + lambda app, timeout: timeouts.append((app.pid, timeout)) or 0, + ) + + class Driver: + async def list_apps(self, _): + return SimpleNamespace(apps=[SimpleNamespace(name="TextEdit", pid=43)]) + + async def list_windows(self, args): + return SimpleNamespace(windows=[SimpleNamespace(window_id=7)]) + + async def shutdown(self): + pass + + def path(*args): + elapsed[0] = 31 # Synchronous native call returned beyond identity deadline. + return str(document) + + monkeypatch.setattr(cua_driver.CuaDriver, "create", lambda: Driver()) + monkeypatch.setattr(ax, "document_path", path) + with pytest.raises(module.FixtureFailure) as failure: + await module.scope_for(42, "http://127.0.0.1:1", document) + assert failure.value.reason == "identity_deadline" + assert failure.value.exit_code == 4 + assert timeouts == [(43, 1.0)] + + +def test_cleanup_snapshots_actual_file_bytes_before_and_after_close(monkeypatch, tmp_path): + import hashlib + + module = fixture_module() + document = tmp_path / "owned.txt" + before, after = b"actual on disk\n", b"different actual bytes\n" + document.write_bytes(before) + + async def pid(): + return 43 + + def close(*args): + document.write_bytes(after) + return {"status": "confirmed", "reason": "window_disappeared"} + + monkeypatch.setattr(module, "textedit_pid", pid) + monkeypatch.setattr(module, "close_owned_document", close) + result = module.cleanup(None, None, None, None, document, opened=True, pid=43)["document"] + assert result["file_before"] == { + "status": "observed", + "size_bytes": len(before), + "sha256": hashlib.sha256(before).hexdigest(), + } + assert result["file_after"] == { + "status": "observed", + "size_bytes": len(after), + "sha256": hashlib.sha256(after).hexdigest(), + } + assert "text" not in result["file_before"] + + +@pytest.mark.parametrize("kind", ["missing", "symlink", "large", "fifo"]) +def test_snapshot_refuses_unowned_or_unbounded_file_types(tmp_path, kind): + import os + + module = fixture_module() + document = tmp_path / "owned.txt" + if kind == "symlink": + target = tmp_path / "other.txt" + target.write_text("unrelated") + document.symlink_to(target) + elif kind == "large": + document.write_bytes(b"x" * (module.MAX_DOCUMENT_BYTES + 1)) + elif kind == "fifo": + os.mkfifo(document) + snapshot = module.document_snapshot(document) + assert snapshot["status"] != "observed" + assert "sha256" not in snapshot + if kind == "missing": + assert snapshot["status"] == "absent" + elif kind in ("large", "fifo"): + assert snapshot["status"] == "refused" + + +@pytest.mark.parametrize("cleanup_fails", [False, True]) +def test_second_sigint_is_ignored_only_during_cleanup_and_handler_restored( + monkeypatch, tmp_path, cleanup_fails +): + import signal + + import ApplicationServices + from jevdual import posture + + module = fixture_module() + previous = signal.getsignal(signal.SIGINT) + monkeypatch.setattr(posture, "screen_locked", lambda: False) + monkeypatch.setattr(ApplicationServices, "AXIsProcessTrusted", lambda: True) + monkeypatch.setattr(sys, "argv", ["fixture", "--run-dir", str(tmp_path / "run")]) + # Fail before owning a server; only the final-cleanup SIGINT guard is exercised. + monkeypatch.setattr(module, "ThreadingHTTPServer", lambda *args: (_ for _ in ()).throw(OSError())) + observed = [] + + def cleanup(*args, **kwargs): + observed.append(signal.getsignal(signal.SIGINT)) + signal.raise_signal(signal.SIGINT) # Ignored: no second KeyboardInterrupt escapes. + if cleanup_fails: + raise RuntimeError("cleanup receipt fault") + return { + "document": {"status": "not_started"}, + "browser": {"status": "not_started"}, + "listener": {"status": "not_started"}, + } + + monkeypatch.setattr(module, "cleanup", cleanup) + with pytest.raises(RuntimeError if cleanup_fails else SystemExit): + module.main() + assert observed == [signal.SIG_IGN] + assert signal.getsignal(signal.SIGINT) == previous From dd009cd2e77d25e17bd13cacc29c945020962bb5 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:22:20 -0400 Subject: [PATCH 140/216] Record packet preparation evidence and corrected AX timeout diagnosis --- .../notebook/2026-10-12-onboarding-fixture-v4.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md index 8e8e0b6..4cee512 100644 --- a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md +++ b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md @@ -20,3 +20,15 @@ Test: build twice and verify exact inventory/source binding, review the artifact Predicts: packet hashes repeat, denied fixture creates no resources, captured same-host grant and post-restart strict doctor pass, native oracle holds one effect/row, and cleanup confirms the exact document/browser/listener/worker without operator close or Automation grant. Against: packet depends on runtime source/Git, grant remains uncaptured, native effect duplicates, cleanup is manual or needs extra access, or earlier failed evidence is regraded. Refs: docs/experiments/U2-independent-onboarding.md; docs/independent-onboarding.md; results/u2-independent-onboarding-20261011-v2-dev + +## UFU1 · update · 2026-10-12 14:19 +Observed: the old Automation-denied main-boundary scenario leaves the exact owned AX window open; the new helper closes that window and preserves a same-name other-path window. Root reviews the worker diff and69focused helper/onboarding/packaging checks pass, with Ruff and notebook valid. Source3d0984d includes review notes on synchronous AX read deadlines, second-SIGINT cleanup protection and bounded actual file snapshots. Both final packet builds match14members and03dc0079; installed3.12/3.14 help/import/member/provenance preparation smokes pass without Git, stopping at an intentional uv stub. Claude approves initial23e5e16f artifact; final03dc0079 confirmation is pending. Guest unlock, SIP/prerequisite provenance and bounded awake hold are observed; no v4 guest effect or permission reset has occurred. +Changes: initial developer validation used a stale editable environment, then a relative source path failed the subprocess CLI check; absolute worktree PYTHONPATH corrected the probe without product/test changes. Guest close-preference defaults key is absent and GUI search yields no result; effective preference remains unverified rather than inferred off. +Next: complete final Claude artifact confirmation, transfer pristine v4, cold-install new guest dependencies, obtain explicit guest Terminal-only reset approval, then capture denial/grant/restart and installed automatic-cleanup evidence. UF1/UF2/UF3 remain open pending their real guest boundary. +Refs: results/onboarding-fixture-v4-preparation-20261012; output/u2-fixture-v4-dev/baseline-automation-behavior.txt; output/u2-packet-v4-final; Claude1791828646123834000; U3-packet-v4-permission-journey.md + +## UFU2 · update · 2026-10-12 14:20 +Observed: Claude confirms exact03dc0079 artifact for U3 but identifies an N3 API semantic error: AXUIElementSetMessagingTimeout applies only to the supplied element, not new equal application references created by product lookup. Apple documentation independently confirms the system-wide element is required for this process's global AX timeout and setting0 resets its default. Current pre/post checks refuse late identities but the prior inferred one-second native RPC bound is not established. No v4 guest effect/reset has occurred. +Inferred: the process-local system-wide timeout, scoped to identity collection and reset to default during teardown, should cover those internal references without changing OS permissions; this remains under existing UF2 and needs corrected boundary verification before a new freeze. +Next: correct the setter scope and cleanup restoration, retain old artifacts and refreeze the reviewed qualification candidate. Do not claim restoring an unknown previous custom timeout. +Refs: Claude1791829172719781000; https://developer.apple.com/documentation/applicationservices/1459345-axuielementsetmessagingtimeout; source3d0984d; UF2 From 21599c641e4c54cad137b3c49e11142c5c14e596 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:24:10 -0400 Subject: [PATCH 141/216] Scope native identity timeout to the helper process global AX default --- jevdual/scripts/capability_fixture.py | 22 ++++++--- jevdual/tests/test_capability_fixture.py | 63 +++++++++++++++++++++++- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/jevdual/scripts/capability_fixture.py b/jevdual/scripts/capability_fixture.py index e7570aa..89ef749 100644 --- a/jevdual/scripts/capability_fixture.py +++ b/jevdual/scripts/capability_fixture.py @@ -239,10 +239,12 @@ async def textedit_pid() -> int | None: async def scope_for(chrome_pid: int, url: str, document: Path, browser=None) -> dict: + from ApplicationServices import AXUIElementCreateSystemWide, AXUIElementSetMessagingTimeout from cua_driver import CuaDriver, ListAppsInput, ListWindowsInput from jevdual import ax driver = CuaDriver.create() + global_ax = AXUIElementCreateSystemWide() try: deadline = time.monotonic() + IDENTITY_SECONDS while time.monotonic() < deadline: @@ -272,17 +274,14 @@ async def scope_for(chrome_pid: int, url: str, document: Path, browser=None) -> else [] ) matching = [] - if textedit: - from ApplicationServices import AXUIElementCreateApplication, AXUIElementSetMessagingTimeout - - app = AXUIElementCreateApplication(textedit) for window in native_windows: - # The synchronous product lookup inherits this process timeout; - # recheck the phase budget for each window and refuse late results. + # System-wide element timeout sets this helper process's global AX + # default, including references created inside the product lookup. + # Recheck the phase budget for each window and refuse late results. remaining = deadline - time.monotonic() if remaining <= 0: raise FixtureFailure("identity", "identity_deadline", 4) - error = AXUIElementSetMessagingTimeout(app, min(1.0, remaining)) + error = AXUIElementSetMessagingTimeout(global_ax, min(1.0, remaining)) if error: raise FixtureFailure("identity", f"ax_timeout_refused:{error}", 4) try: @@ -309,7 +308,14 @@ async def scope_for(chrome_pid: int, url: str, document: Path, browser=None) -> await asyncio.sleep(0.25) raise FixtureFailure("identity", "windows_not_unique", 4) finally: - await shutdown_driver(driver, "identity", time.monotonic() + 2) + try: + await shutdown_driver(driver, "identity", time.monotonic() + 2) + finally: + # This standalone helper owns the process default. Zero resets the + # global default; it does not restore an unknown previous timeout. + error = AXUIElementSetMessagingTimeout(global_ax, 0) + if error: + raise FixtureFailure("identity", f"ax_timeout_reset_refused:{error}", 4) def document_snapshot(document: Path) -> dict: diff --git a/jevdual/tests/test_capability_fixture.py b/jevdual/tests/test_capability_fixture.py index 51272c5..3dc9185 100644 --- a/jevdual/tests/test_capability_fixture.py +++ b/jevdual/tests/test_capability_fixture.py @@ -20,6 +20,9 @@ def simulated_identity_timeout_api(monkeypatch): monkeypatch.setattr( ApplicationServices, "AXUIElementCreateApplication", lambda pid: SimpleNamespace(pid=pid) ) + monkeypatch.setattr( + ApplicationServices, "AXUIElementCreateSystemWide", lambda: SimpleNamespace(systemwide=True) + ) monkeypatch.setattr(ApplicationServices, "AXUIElementSetMessagingTimeout", lambda *args: 0) @@ -707,7 +710,7 @@ async def test_scope_sets_process_timeout_and_rejects_late_document_identity(mon monkeypatch.setattr( ApplicationServices, "AXUIElementSetMessagingTimeout", - lambda app, timeout: timeouts.append((app.pid, timeout)) or 0, + lambda app, timeout: timeouts.append((app.systemwide, timeout)) or 0, ) class Driver: @@ -730,7 +733,7 @@ def path(*args): await module.scope_for(42, "http://127.0.0.1:1", document) assert failure.value.reason == "identity_deadline" assert failure.value.exit_code == 4 - assert timeouts == [(43, 1.0)] + assert timeouts == [(True, 1.0), (True, 0)] def test_cleanup_snapshots_actual_file_bytes_before_and_after_close(monkeypatch, tmp_path): @@ -821,3 +824,59 @@ def cleanup(*args, **kwargs): module.main() assert observed == [signal.SIG_IGN] assert signal.getsignal(signal.SIGINT) == previous + + +@pytest.mark.asyncio +@pytest.mark.parametrize("outcome", ["success", "identity_failure", "shutdown_failure", "setter_failure"]) +async def test_identity_uses_global_ax_reference_and_resets_default_even_on_shutdown_failure( + monkeypatch, tmp_path, outcome +): + import ApplicationServices + import cua_driver + from jevdual import ax + + module = fixture_module() + global_reference = object() + calls = [] + document = tmp_path / "owned.txt" + monkeypatch.setattr(ApplicationServices, "AXUIElementCreateSystemWide", lambda: global_reference) + + def timeout(element, seconds): + assert element is global_reference # An application-element timeout would not cover new references. + calls.append(seconds) + return -25202 if outcome == "setter_failure" and seconds else 0 + + monkeypatch.setattr(ApplicationServices, "AXUIElementSetMessagingTimeout", timeout) + + class Driver: + async def list_apps(self, _): + return SimpleNamespace(apps=[SimpleNamespace(name="TextEdit", pid=43)]) + + async def list_windows(self, args): + return SimpleNamespace(windows=[SimpleNamespace(window_id=7)]) + + async def shutdown(self): + if outcome == "shutdown_failure": + raise RuntimeError("SDK shutdown refused") + + def path(*args): + if outcome == "identity_failure": + raise ax.AXError("permission_denied", "AX lookup refused") + return str(document) + + monkeypatch.setattr(cua_driver.CuaDriver, "create", lambda: Driver()) + monkeypatch.setattr(ax, "document_path", path) + if outcome == "success": + result = await module.scope_for(42, "http://127.0.0.1:1", document) + assert result["destination"]["document"] == str(document) + else: + expected = ( + ax.AXError + if outcome == "identity_failure" + else RuntimeError + if outcome == "shutdown_failure" + else module.FixtureFailure + ) + with pytest.raises(expected): + await module.scope_for(42, "http://127.0.0.1:1", document) + assert calls == [1.0, 0] From a6df1ff7f5ac07b151be8ab98c6286a22b227fde Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:26:47 -0400 Subject: [PATCH 142/216] Retain independently reviewed final packet v4 preparation evidence --- .../final-smoke.json | 44 ++++++++++++++++++ .../qualified-smoke.json | 44 ++++++++++++++++++ .../report.md | 17 +++++++ .../smoke.json | 44 ++++++++++++++++++ .../summary.json | 45 +++++++++++++++++++ 5 files changed, 194 insertions(+) create mode 100644 jevdual/results/onboarding-fixture-v4-preparation-20261012/final-smoke.json create mode 100644 jevdual/results/onboarding-fixture-v4-preparation-20261012/qualified-smoke.json create mode 100644 jevdual/results/onboarding-fixture-v4-preparation-20261012/report.md create mode 100644 jevdual/results/onboarding-fixture-v4-preparation-20261012/smoke.json create mode 100644 jevdual/results/onboarding-fixture-v4-preparation-20261012/summary.json diff --git a/jevdual/results/onboarding-fixture-v4-preparation-20261012/final-smoke.json b/jevdual/results/onboarding-fixture-v4-preparation-20261012/final-smoke.json new file mode 100644 index 0000000..2c57da6 --- /dev/null +++ b/jevdual/results/onboarding-fixture-v4-preparation-20261012/final-smoke.json @@ -0,0 +1,44 @@ +{ + "artifact_sha256": "03dc007954a246f6f038a771e3c63afa7df8d44f5b7616b1409f8c1d0eff2fb7", + "profiles": { + "312": { + "member_verification": { + "verified": true, + "members": 14, + "source_commit": "3d0984dda6e4c1b67a2c4ca79d5adde4a275ae2a", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7" + }, + "help_exits": { + "capability_clean_install.py": 0, + "capability_fixture.py": 0, + "capability_fixture_config.py": 0, + "capability_installed_trial.py": 0 + }, + "helper_imports": 7, + "git_invoked": false, + "receipt_source_commit": "3d0984dda6e4c1b67a2c4ca79d5adde4a275ae2a", + "intentional_uv_boundary_exit": 17 + }, + "314": { + "member_verification": { + "verified": true, + "members": 14, + "source_commit": "3d0984dda6e4c1b67a2c4ca79d5adde4a275ae2a", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7" + }, + "help_exits": { + "capability_clean_install.py": 0, + "capability_fixture.py": 0, + "capability_fixture_config.py": 0, + "capability_installed_trial.py": 0 + }, + "helper_imports": 7, + "git_invoked": false, + "receipt_source_commit": "3d0984dda6e4c1b67a2c4ca79d5adde4a275ae2a", + "intentional_uv_boundary_exit": 17 + } + }, + "native_actions": "not_performed", + "installation": "stopped_at_external_uv_boundary", + "passed": true +} diff --git a/jevdual/results/onboarding-fixture-v4-preparation-20261012/qualified-smoke.json b/jevdual/results/onboarding-fixture-v4-preparation-20261012/qualified-smoke.json new file mode 100644 index 0000000..6cca057 --- /dev/null +++ b/jevdual/results/onboarding-fixture-v4-preparation-20261012/qualified-smoke.json @@ -0,0 +1,44 @@ +{ + "artifact_sha256": "eef3632506680d74b21b511cec905d73de2324f951e924b0716f2309490f590d", + "profiles": { + "312": { + "member_verification": { + "verified": true, + "members": 14, + "source_commit": "21599c641e4c54cad137b3c49e11142c5c14e596", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7" + }, + "help_exits": { + "capability_clean_install.py": 0, + "capability_fixture.py": 0, + "capability_fixture_config.py": 0, + "capability_installed_trial.py": 0 + }, + "helper_imports": 7, + "git_invoked": false, + "receipt_source_commit": "21599c641e4c54cad137b3c49e11142c5c14e596", + "intentional_uv_boundary_exit": 17 + }, + "314": { + "member_verification": { + "verified": true, + "members": 14, + "source_commit": "21599c641e4c54cad137b3c49e11142c5c14e596", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7" + }, + "help_exits": { + "capability_clean_install.py": 0, + "capability_fixture.py": 0, + "capability_fixture_config.py": 0, + "capability_installed_trial.py": 0 + }, + "helper_imports": 7, + "git_invoked": false, + "receipt_source_commit": "21599c641e4c54cad137b3c49e11142c5c14e596", + "intentional_uv_boundary_exit": 17 + } + }, + "native_actions": "not_performed", + "installation": "stopped_at_external_uv_boundary", + "passed": true +} diff --git a/jevdual/results/onboarding-fixture-v4-preparation-20261012/report.md b/jevdual/results/onboarding-fixture-v4-preparation-20261012/report.md new file mode 100644 index 0000000..0e121f8 --- /dev/null +++ b/jevdual/results/onboarding-fixture-v4-preparation-20261012/report.md @@ -0,0 +1,17 @@ +# Packet v4 preparation + +Source1d72e51 adds exact-document Accessibility cleanup and separate browser startup/window-identity phases to the fixture helper. The reviewed product wheel is unchanged. The packet repeats byte-for-byte at14members; see summary.json for source, archive and wheel hashes. + +The old main-boundary scenario leaves its owned AX window open when Automation is denied. The new helper closes the unique exact-path window and preserves the same-name other-path window. Tests challenge duplicate paths, changed window/close/sheet identity, unrelated or unrecognized dialogs, failed and unresponsive AX calls, and disappearance readback. Browser/setup/identity failure and hung SDK scenarios retain typed receipts and independently stop owned browser/listener resources. Runtime AX calls, SDK enumeration and shutdown have bounded phases; only identified English save sheets are supported. This is mocked OS-boundary evidence, not a live result. + +Root reviewed the worker diff and reran61focused fixture/onboarding/packaging tests; Ruff and notebook checks pass. An initial developer probe used a stale editable environment, then a relative source path failed a subprocess check. The corrected absolute worktree PYTHONPATH passes the full selection; no product or tests were changed to hide those probe failures. + +Both installed3.12/3.14 preparation profiles verify all frozen members, import seven helpers and pass four help entry points outside source with Git unavailable. The cold-installer provenance smoke stops at its deliberately stubbed uv boundary; it does not qualify dependency installation or native effects. See smoke.json. + +Independent Claude artifact review is requested in1791828568355220000. No v4 guest effect or permission reset has run. U3 will record fresh permission state on the previously provisioned SIP-enabled guest, with new packet root and dependencies. It will not regrade the original U2 cold-start failure or imply a new cold OS. + +Reference seams: Arc CUA6b353039 benchmarks/workflows.py:533 for AX close (Footwork retains stronger exact identity); browser-usec75e8476 browser_use/browser/watchdogs/local_browser_watchdog.py:407 for process-aware loopback CDP readiness; Chrome DevTools MCPf08dbe15 src/BrowserManager.ts:132 for abandoned launch lifetime and owned cleanup. Discovery feature changes remain outside v4. + +Claude approved the initial exact artifact23e5e16f at1d72e51 (1791828646123834000), with no blockers and review notes. Root incorporated N2/N3/N4 into frozen3d0984d: bounded synchronous identity AX reads with late-result refusal, SIGINT protection only during bounded cleanup with handler restoration, and bounded actual document file size/SHA256 snapshots before/after close. All69focused checks and Ruff pass; the final14member packet03dc0079 repeats and both installed preparation profiles pass again. Prior artifacts remain retained. Final exact-artifact confirmation is requested in1791829124898322000; no v4 guest execution or TCC reset yet. + +Final qualification candidate is21599c6,14members,312685bytes, SHA256eef3632506680d74b21b511cec905d73de2324f951e924b0716f2309490f590d, stored at output/u2-packet-v4-final-r2/footwork-onboarding-u2.zip. Repeat bytes match and both installed preparation profiles pass. The73focused checks and Ruff pass. N3 is corrected to the process-local system-wide AX default, with reset0 in nested teardown; four new boundary cases fail the prior setter scope and pass the correction. Apple documentation confirms these semantics. Claude independently verifies the exact artifact/helper Git blob and approves without blockers in1791829509202848000. Prior revisions are retained; only this candidate enters U3. No product wheel change. diff --git a/jevdual/results/onboarding-fixture-v4-preparation-20261012/smoke.json b/jevdual/results/onboarding-fixture-v4-preparation-20261012/smoke.json new file mode 100644 index 0000000..5d69d7a --- /dev/null +++ b/jevdual/results/onboarding-fixture-v4-preparation-20261012/smoke.json @@ -0,0 +1,44 @@ +{ + "artifact_sha256": "23e5e16fe5923c392b9d11e4601c390ff174234efd01af9a27653ed59b6a3d1e", + "profiles": { + "312": { + "member_verification": { + "verified": true, + "members": 14, + "source_commit": "1d72e51ef7c4c5a49dac6cfac44c95427fbeff01", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7" + }, + "help_exits": { + "capability_clean_install.py": 0, + "capability_fixture.py": 0, + "capability_fixture_config.py": 0, + "capability_installed_trial.py": 0 + }, + "helper_imports": 7, + "git_invoked": false, + "receipt_source_commit": "1d72e51ef7c4c5a49dac6cfac44c95427fbeff01", + "intentional_uv_boundary_exit": 17 + }, + "314": { + "member_verification": { + "verified": true, + "members": 14, + "source_commit": "1d72e51ef7c4c5a49dac6cfac44c95427fbeff01", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7" + }, + "help_exits": { + "capability_clean_install.py": 0, + "capability_fixture.py": 0, + "capability_fixture_config.py": 0, + "capability_installed_trial.py": 0 + }, + "helper_imports": 7, + "git_invoked": false, + "receipt_source_commit": "1d72e51ef7c4c5a49dac6cfac44c95427fbeff01", + "intentional_uv_boundary_exit": 17 + } + }, + "native_actions": "not_performed", + "installation": "stopped_at_external_uv_boundary", + "passed": true +} diff --git a/jevdual/results/onboarding-fixture-v4-preparation-20261012/summary.json b/jevdual/results/onboarding-fixture-v4-preparation-20261012/summary.json new file mode 100644 index 0000000..d7596ef --- /dev/null +++ b/jevdual/results/onboarding-fixture-v4-preparation-20261012/summary.json @@ -0,0 +1,45 @@ +{ + "source_commit": "21599c641e4c54cad137b3c49e11142c5c14e596", + "packet_sha256": "eef3632506680d74b21b511cec905d73de2324f951e924b0716f2309490f590d", + "packet_bytes": 312685, + "packet_members": 14, + "repeat_build_matches": true, + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7", + "checks": { + "focused_tests_passed": 73, + "fixture_boundary_tests": 47, + "ruff": "passed", + "notebook": "passed", + "profiles": [ + "3.12", + "3.14" + ], + "helper_imports_per_profile": 7, + "help_entries_per_profile": 4 + }, + "baseline_automation_denial": "old exact AX window remains open; new helper automatically closes it", + "claude_review": { + "approved": true, + "message": "1791829509202848000", + "blockers": 0 + }, + "guest_qualification": "not_performed", + "initial_build": { + "source_commit": "1d72e51ef7c4c5a49dac6cfac44c95427fbeff01", + "packet_sha256": "23e5e16fe5923c392b9d11e4601c390ff174234efd01af9a27653ed59b6a3d1e", + "claude_review": "approved1791828646123834000 with notesN2/N3/N4" + }, + "retained_revisions": [ + { + "source_commit": "1d72e51ef7c4c5a49dac6cfac44c95427fbeff01", + "packet_sha256": "23e5e16fe5923c392b9d11e4601c390ff174234efd01af9a27653ed59b6a3d1e", + "claude_review": "approved1791828646123834000 with notesN2/N3/N4" + }, + { + "source_commit": "3d0984dda6e4c1b67a2c4ca79d5adde4a275ae2a", + "packet_sha256": "03dc007954a246f6f038a771e3c63afa7df8d44f5b7616b1409f8c1d0eff2fb7", + "claude_review": "approved1791829172719781000 with N3 APIcorrection note" + } + ], + "packet_path": "output/u2-packet-v4-final-r2/footwork-onboarding-u2.zip" +} From cfbf3abaee3026ea712fdda5daef5debee99a255 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:29:01 -0400 Subject: [PATCH 143/216] Record four verified mid-job restarts and guarded recovery evidence --- .../experiments/SIM11-workbench-restarts.md | 4 + .../notebook/2026-10-12-workbench-restarts.md | 13 + .../attempt-ledger.json | 37 + .../conformance-summary.json | 27 + .../control/000001.request.json | 16 + .../control/000001.result.json | 34 + .../control/000002.request.json | 8 + .../control/000002.result.json | 17 + .../control/000003.request.json | 16 + .../control/000003.result.json | 34 + .../control/000004.request.json | 8 + .../control/000004.result.json | 17 + .../control/000005.request.json | 16 + .../control/000005.result.json | 34 + .../control/000006.request.json | 16 + .../control/000006.result.json | 25 + .../control/000007.request.json | 16 + .../control/000007.result.json | 34 + .../control/000008.request.json | 16 + .../control/000008.result.json | 25 + .../control/000009.request.json | 16 + .../control/000009.result.json | 22 + .../workbench-restarts-20261012/handoff.json | 38 + .../health-timeout-observation.json | 11 + .../process-ledger.json | 91 ++ .../qualification-score.json | 744 +++++++++ .../workbench-restarts-20261012/report.md | 29 + .../restart-ledger.json | 246 +++ .../restart-score.json | 99 ++ .../snapshots/000001-after.json | 140 ++ .../snapshots/000001-before.json | 270 ++++ .../snapshots/000002-after.json | 277 ++++ .../snapshots/000002-before.json | 140 ++ .../snapshots/000003-after.json | 199 +++ .../snapshots/000003-before.json | 399 +++++ .../snapshots/000004-after.json | 406 +++++ .../snapshots/000004-before.json | 199 +++ .../snapshots/000005-after.json | 784 ++++++++++ .../snapshots/000005-before.json | 892 +++++++++++ .../snapshots/000006-after.json | 887 +++++++++++ .../snapshots/000006-before.json | 784 ++++++++++ .../snapshots/000007-after.json | 884 +++++++++++ .../snapshots/000007-before.json | 992 ++++++++++++ .../snapshots/000008-after.json | 987 ++++++++++++ .../snapshots/000008-before.json | 884 +++++++++++ .../snapshots/000009-after.json | 1385 +++++++++++++++++ .../snapshots/000009-before.json | 1385 +++++++++++++++++ .../source-freeze.json | 33 + .../ui-ledger.json | 734 +++++++++ .../ui/body-planning-offline.jpg | Bin 0 -> 88282 bytes .../ui/body-planning-offline.txt | 80 + .../ui/body-planning-restored.txt | 80 + .../ui/body-planning-resumed.txt | 80 + .../ui/body-uncertain-before.txt | 80 + .../ui/body-uncertain-offline.txt | 80 + .../ui/body-uncertain-recovered.jpg | Bin 0 -> 91223 bytes .../ui/body-uncertain-recovered.ledger.txt | 47 + .../ui/body-uncertain-recovered.txt | 55 + .../ui/body-uncertain-restored.txt | 80 + .../ui/body-uncertain-resumed.ledger.txt | 46 + .../ui/body-uncertain-resumed.txt | 79 + .../ui/completed.ledger.txt | 54 + .../ui/completed.txt | 87 ++ .../ui/disconnected.txt | 80 + .../ui/handoff.jpg | Bin 0 -> 74170 bytes .../ui/handoff.txt | 81 + .../ui/reconnected.txt | 80 + .../ui/recovered.txt | 80 + .../ui/reloaded.ledger.txt | 48 + .../ui/reloaded.txt | 81 + .../ui/resumed.txt | 79 + .../ui/transient-health-pause.jpg | Bin 0 -> 87331 bytes .../ui/transient-health-pause.txt | 87 ++ .../ui/transient-health-resumed.txt | 87 ++ .../ui/uncertain.txt | 80 + .../ui/workbench-planning-offline.txt | 68 + .../ui/workbench-planning-restored.txt | 70 + .../ui/workbench-planning-resumed.txt | 80 + .../ui/workbench-uncertain-offline.txt | 80 + .../ui/workbench-uncertain-restored.jpg | Bin 0 -> 90006 bytes .../ui/workbench-uncertain-restored.txt | 80 + .../test_workbench_restart_harness.py | 17 +- 82 files changed, 16388 insertions(+), 8 deletions(-) create mode 100644 jevdual/results/workbench-restarts-20261012/attempt-ledger.json create mode 100644 jevdual/results/workbench-restarts-20261012/conformance-summary.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000001.request.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000001.result.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000002.request.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000002.result.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000003.request.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000003.result.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000004.request.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000004.result.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000005.request.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000005.result.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000006.request.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000006.result.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000007.request.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000007.result.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000008.request.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000008.result.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000009.request.json create mode 100644 jevdual/results/workbench-restarts-20261012/control/000009.result.json create mode 100644 jevdual/results/workbench-restarts-20261012/handoff.json create mode 100644 jevdual/results/workbench-restarts-20261012/health-timeout-observation.json create mode 100644 jevdual/results/workbench-restarts-20261012/process-ledger.json create mode 100644 jevdual/results/workbench-restarts-20261012/qualification-score.json create mode 100644 jevdual/results/workbench-restarts-20261012/report.md create mode 100644 jevdual/results/workbench-restarts-20261012/restart-ledger.json create mode 100644 jevdual/results/workbench-restarts-20261012/restart-score.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000001-after.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000001-before.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000002-after.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000002-before.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000003-after.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000003-before.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000004-after.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000004-before.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000005-after.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000005-before.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000006-after.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000006-before.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000007-after.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000007-before.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000008-after.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000008-before.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000009-after.json create mode 100644 jevdual/results/workbench-restarts-20261012/snapshots/000009-before.json create mode 100644 jevdual/results/workbench-restarts-20261012/source-freeze.json create mode 100644 jevdual/results/workbench-restarts-20261012/ui-ledger.json create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-planning-offline.jpg create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-planning-offline.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-planning-restored.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-planning-resumed.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-uncertain-before.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-uncertain-offline.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-uncertain-recovered.jpg create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-uncertain-recovered.ledger.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-uncertain-recovered.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-uncertain-restored.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-uncertain-resumed.ledger.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/body-uncertain-resumed.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/completed.ledger.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/completed.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/disconnected.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/handoff.jpg create mode 100644 jevdual/results/workbench-restarts-20261012/ui/handoff.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/reconnected.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/recovered.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/reloaded.ledger.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/reloaded.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/resumed.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/transient-health-pause.jpg create mode 100644 jevdual/results/workbench-restarts-20261012/ui/transient-health-pause.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/transient-health-resumed.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/uncertain.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/workbench-planning-offline.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/workbench-planning-restored.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/workbench-planning-resumed.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/workbench-uncertain-offline.txt create mode 100644 jevdual/results/workbench-restarts-20261012/ui/workbench-uncertain-restored.jpg create mode 100644 jevdual/results/workbench-restarts-20261012/ui/workbench-uncertain-restored.txt diff --git a/jevdual/docs/experiments/SIM11-workbench-restarts.md b/jevdual/docs/experiments/SIM11-workbench-restarts.md index 8b38e06..5ec4c7a 100644 --- a/jevdual/docs/experiments/SIM11-workbench-restarts.md +++ b/jevdual/docs/experiments/SIM11-workbench-restarts.md @@ -21,3 +21,7 @@ Scope: two actual-model jobs, graceful owned process restarts, same-Mac loopback ## Amendment · 2026-10-12 13:58 Read-only review found that a fast body reboot can fall between health polls: unchanged body identity with a new epoch currently leaves the host running and permits lease refresh around an old model decision. Add a real-socket reproduction before repair. A changed known boot epoch must invalidate the model decision and pause before a new command admission, including when the lease-acquisition read sees it before the health worker does. Pending historical commands must remain recoverable across that epoch change without lease rotation or replay. The live body-planning restart will also challenge the fast path; retained body identity and motion state remain intact. + +## Result · 2026-10-12 14:25 + +Held for all four graceful restart boundaries on the first frozen actual-model/browser trial at `d7072107d576d7a09643229ae584a3864d2fe0f6`. Workbench and body were each stopped/restarted during planning and with a different uncertain dispatch. Both identities, continuous native motion, exact pending commands and client sends survived; receipt recovery read historical proof without replay and explicit Resume preceded fresh observations. Two jobs completed with independent native, SQLite and contact-reset checks. All seven trial processes exited before scoring; reload and paused handoff preserved 83 commands. Conformance passed 103 checks. A separate fast-reboot regression failed before the epoch repair and passed afterwards. The actual body outage was visible; fast missed-poll behavior was covered by socket regressions. One additional health timeout cancelled a model call; explicit Resume completed the reset without replay. Its cause remains unresolved and its evidence is retained. An earlier abbreviated-SHA launch was refused before any process or model call. See [report](../../results/workbench-restarts-20261012/report.md), [restart score](../../results/workbench-restarts-20261012/restart-score.json), [attempt ledger](../../results/workbench-restarts-20261012/attempt-ledger.json). diff --git a/jevdual/docs/notebook/2026-10-12-workbench-restarts.md b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md index 674934c..726a760 100644 --- a/jevdual/docs/notebook/2026-10-12-workbench-restarts.md +++ b/jevdual/docs/notebook/2026-10-12-workbench-restarts.md @@ -26,3 +26,16 @@ Observed: all nineteen runtime socket checks passed after epoch invalidation and Inferred: the epoch diagnosis is supported by failing and resolving socket evidence. The 103 mechanical checks establish readiness for the frozen browser trial, not its result. Next: commit all measured source, then interrupt two actual image-guided jobs at the four preregistered process boundaries. Refs: tools/physical-workcell/output/sim11-epoch-after-fix-runtime.log; tools/physical-workcell/output/sim11-core-network-regression.log; tools/physical-workcell/output/sim11-harness-tests-v1/unittest.log; tools/physical-workcell/qualify_workbench_restarts.py; tools/physical-workcell/score_workbench_restarts.py + +## SIM11-U3 · update · 2026-10-12 14:25 +Resolves: SIM11-P1 = held +Observed: all four graceful process restart boundaries and ten visible recovery states passed the independent scorer on the first actual-model trial at frozen d707210. Two jobs completed with native/SQLite/contact proof, continuous generations zero through twenty and 83 single-send command records. Workbench and body each stopped during planning and with a distinct uncertain dispatch. The five-command and 46-command recovery intervals added no sends. All seven trial processes exited before scoring. Three cancelled model calls were reaped and withheld: two planned interruptions and one additional health-timeout pause during reset. That extra pause required explicit Resume and a fresh observation; its cause remains unresolved. Reload preserved results without a command. Paused handoff retained identities, history and 83 commands at body boot four. An abbreviated-SHA launch was refused before process creation; its corrected full-SHA launch started the one actual-model attempt. An unmeasured helper fixture moved into owned output without changing measured source hashes. +Inferred: exact historical receipt recovery composes with graceful body/workbench restarts in this loopback product. Fast epoch invalidation is supported separately by socket regressions. The observed health timeout limits reliability claims even though guarded recovery worked. +Next: hand off the paused connected product and retained recovery evidence; leave sudden power loss and health-timeout diagnosis to separate work. +Refs: results/workbench-restarts-20261012/report.md; results/workbench-restarts-20261012/restart-score.json; results/workbench-restarts-20261012/qualification-score.json; results/workbench-restarts-20261012/health-timeout-observation.json; results/workbench-restarts-20261012/attempt-ledger.json; results/workbench-restarts-20261012/handoff.json + +## SIM11-S1 · summary · 2026-10-12 14:25 +Established: graceful workbench/body restart during actual planning and uncertain dispatch preserves one body, retained queue and command identity. Recovery reads exact historical receipts once, stays paused until Resume, and uses fresh TCP images. Two independently verified jobs and all four visible restart cases passed with measured source unchanged. Fast boot changes now invalidate old decisions before successor admission. +Uncertain: an additional health timeout paused reset and cancelled a model call; its cause is unresolved. Sudden power loss, forced kill during native persistence, physical hardware and authenticated remote access remain untested. +Decision: adopt the qualified restart behavior, retain the previous product and failing development evidence, and leave the current product connected and paused with both completed jobs visible. +Refs: docs/experiments/SIM11-workbench-restarts.md; results/workbench-restarts-20261012/report.md; tools/physical-workcell/NETWORK_WORKBENCH.md diff --git a/jevdual/results/workbench-restarts-20261012/attempt-ledger.json b/jevdual/results/workbench-restarts-20261012/attempt-ledger.json new file mode 100644 index 0000000..ed8c3a3 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/attempt-ledger.json @@ -0,0 +1,37 @@ +{ + "actual_model_attempts": [ + { + "additional_health_timeout_pause": true, + "attempt": 1, + "cancelled_calls": 3, + "commands": 83, + "completed_jobs": 2, + "model_calls": 29, + "owned_trial_processes_reaped": true, + "passed": true, + "restart_pairs": 4, + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2", + "source_commit": "d7072107d576d7a09643229ae584a3864d2fe0f6" + } + ], + "preserved_previous_product": "tools/physical-workcell/output/sim11-preserved-baseline/preserved.json", + "retained_development_failures": [ + { + "diagnosis": "old decisions survived fast boot change; unfinished/recovered job labels were inconsistent", + "failed_checks": 4, + "log": "tools/physical-workcell/output/sim11-epoch-before-fix.log" + } + ], + "startup_attempts": [ + { + "attempt": 1, + "model_calls": 0, + "observed_exit_code": 1, + "outcome": "refused before source freeze or process launch; full source SHA required", + "provenance": "Codex exec result chunk 1cd3d5; derived record, not reconstructed stdout", + "root": "tools/physical-workcell/output/sim11-browser-restarts-v1", + "source_argument": "d707210" + } + ], + "unmeasured_test_fixture_change": "The helper reader fixture moved from a temporary system directory to owned project output; measured source hashes stayed unchanged." +} diff --git a/jevdual/results/workbench-restarts-20261012/conformance-summary.json b/jevdual/results/workbench-restarts-20261012/conformance-summary.json new file mode 100644 index 0000000..ae8f616 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/conformance-summary.json @@ -0,0 +1,27 @@ +{ + "additional_checks": [ + "Ruff", + "JavaScript syntax", + "notebook schema", + "diff check" + ], + "failed_final": 0, + "passed": 103, + "suites": [ + { + "checks": 19, + "log": "tools/physical-workcell/output/sim11-epoch-after-fix-runtime.log", + "scope": "real-socket runtime, fast reboot epoch paths, historical recovery and job status" + }, + { + "checks": 80, + "log": "tools/physical-workcell/output/sim11-core-network-regression.log", + "scope": "core/body/client/link/fault-matrix/HTTP regressions" + }, + { + "checks": 4, + "log": "tools/physical-workcell/output/sim11-harness-tests-v2/unittest.log", + "scope": "restart control predicates, ownership and bounded readers; synthetic controls" + } + ] +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000001.request.json b/jevdual/results/workbench-restarts-20261012/control/000001.request.json new file mode 100644 index 0000000..e9c3abf --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000001.request.json @@ -0,0 +1,16 @@ +{ + "action": "stop-role", + "expect": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": true, + "recovery_command_id": null, + "runner_status": "running", + "usage_calls": 1 + }, + "predicate": "planning", + "requested_time": 1791828631.2835982, + "role": "workbench", + "sequence": 1 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000001.result.json b/jevdual/results/workbench-restarts-20261012/control/000001.result.json new file mode 100644 index 0000000..94eae0f --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000001.result.json @@ -0,0 +1,34 @@ +{ + "action_performed": true, + "after": "000001-after.json", + "before": "000001-before.json", + "passed": true, + "process": { + "boot": 1, + "exit_observed": true, + "initialized": false, + "log": "workbench-01.log", + "pid": 25794, + "port": 51377, + "returncode": 0, + "role": "workbench", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator", + "stopped_time": 1791828631.66827 + }, + "request": { + "action": "stop-role", + "expect": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": true, + "recovery_command_id": null, + "runner_status": "running", + "usage_calls": 1 + }, + "predicate": "planning", + "requested_time": 1791828631.2835982, + "role": "workbench", + "sequence": 1 + } +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000002.request.json b/jevdual/results/workbench-restarts-20261012/control/000002.request.json new file mode 100644 index 0000000..aa9d2de --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000002.request.json @@ -0,0 +1,8 @@ +{ + "action": "start-role", + "expect": null, + "predicate": "none", + "requested_time": 1791828682.922372, + "role": "workbench", + "sequence": 2 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000002.result.json b/jevdual/results/workbench-restarts-20261012/control/000002.result.json new file mode 100644 index 0000000..919ea88 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000002.result.json @@ -0,0 +1,17 @@ +{ + "action_performed": true, + "after": "000002-after.json", + "before": "000002-before.json", + "passed": true, + "pid": 30888, + "predicate": "planning", + "request": { + "action": "start-role", + "expect": null, + "predicate": "none", + "requested_time": 1791828682.922372, + "role": "workbench", + "sequence": 2 + }, + "stopped_sequence": 1 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000003.request.json b/jevdual/results/workbench-restarts-20261012/control/000003.request.json new file mode 100644 index 0000000..512aa51 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000003.request.json @@ -0,0 +1,16 @@ +{ + "action": "stop-role", + "expect": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "runner_status": "blocked", + "usage_calls": 2 + }, + "predicate": "uncertain", + "requested_time": 1791828767.342037, + "role": "workbench", + "sequence": 3 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000003.result.json b/jevdual/results/workbench-restarts-20261012/control/000003.result.json new file mode 100644 index 0000000..03de9ad --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000003.result.json @@ -0,0 +1,34 @@ +{ + "action_performed": true, + "after": "000003-after.json", + "before": "000003-before.json", + "passed": true, + "process": { + "boot": 2, + "exit_observed": true, + "initialized": false, + "log": "workbench-02.log", + "pid": 30888, + "port": 51377, + "returncode": 0, + "role": "workbench", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator", + "stopped_time": 1791828768.2145522 + }, + "request": { + "action": "stop-role", + "expect": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "runner_status": "blocked", + "usage_calls": 2 + }, + "predicate": "uncertain", + "requested_time": 1791828767.342037, + "role": "workbench", + "sequence": 3 + } +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000004.request.json b/jevdual/results/workbench-restarts-20261012/control/000004.request.json new file mode 100644 index 0000000..9c51ca9 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000004.request.json @@ -0,0 +1,8 @@ +{ + "action": "start-role", + "expect": null, + "predicate": "none", + "requested_time": 1791828779.372716, + "role": "workbench", + "sequence": 4 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000004.result.json b/jevdual/results/workbench-restarts-20261012/control/000004.result.json new file mode 100644 index 0000000..f79ce05 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000004.result.json @@ -0,0 +1,17 @@ +{ + "action_performed": true, + "after": "000004-after.json", + "before": "000004-before.json", + "passed": true, + "pid": 39967, + "predicate": "uncertain", + "request": { + "action": "start-role", + "expect": null, + "predicate": "none", + "requested_time": 1791828779.372716, + "role": "workbench", + "sequence": 4 + }, + "stopped_sequence": 3 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000005.request.json b/jevdual/results/workbench-restarts-20261012/control/000005.request.json new file mode 100644 index 0000000..bd01e01 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000005.request.json @@ -0,0 +1,16 @@ +{ + "action": "stop-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": true, + "recovery_command_id": null, + "runner_status": "running", + "usage_calls": 15 + }, + "predicate": "planning", + "requested_time": 1791828952.679998, + "role": "body", + "sequence": 5 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000005.result.json b/jevdual/results/workbench-restarts-20261012/control/000005.result.json new file mode 100644 index 0000000..9c98fc8 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000005.result.json @@ -0,0 +1,34 @@ +{ + "action_performed": true, + "after": "000005-after.json", + "before": "000005-before.json", + "passed": true, + "process": { + "boot": 1, + "exit_observed": true, + "initialized": true, + "log": "body-01.log", + "pid": 25787, + "port": 51373, + "returncode": 0, + "role": "body", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/body", + "stopped_time": 1791828952.994875 + }, + "request": { + "action": "stop-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": true, + "recovery_command_id": null, + "runner_status": "running", + "usage_calls": 15 + }, + "predicate": "planning", + "requested_time": 1791828952.679998, + "role": "body", + "sequence": 5 + } +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000006.request.json b/jevdual/results/workbench-restarts-20261012/control/000006.request.json new file mode 100644 index 0000000..ed87819 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000006.request.json @@ -0,0 +1,16 @@ +{ + "action": "start-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": null, + "runner_status": "paused", + "usage_calls": 15 + }, + "predicate": "none", + "requested_time": 1791829008.869165, + "role": "body", + "sequence": 6 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000006.result.json b/jevdual/results/workbench-restarts-20261012/control/000006.result.json new file mode 100644 index 0000000..6ec2f26 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000006.result.json @@ -0,0 +1,25 @@ +{ + "action_performed": true, + "after": "000006-after.json", + "before": "000006-before.json", + "passed": true, + "pid": 71324, + "predicate": "planning", + "request": { + "action": "start-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": null, + "runner_status": "paused", + "usage_calls": 15 + }, + "predicate": "none", + "requested_time": 1791829008.869165, + "role": "body", + "sequence": 6 + }, + "stopped_sequence": 5 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000007.request.json b/jevdual/results/workbench-restarts-20261012/control/000007.request.json new file mode 100644 index 0000000..01912cf --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000007.request.json @@ -0,0 +1,16 @@ +{ + "action": "stop-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "runner_status": "blocked", + "usage_calls": 16 + }, + "predicate": "uncertain", + "requested_time": 1791829041.8267992, + "role": "body", + "sequence": 7 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000007.result.json b/jevdual/results/workbench-restarts-20261012/control/000007.result.json new file mode 100644 index 0000000..d8bbbab --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000007.result.json @@ -0,0 +1,34 @@ +{ + "action_performed": true, + "after": "000007-after.json", + "before": "000007-before.json", + "passed": true, + "process": { + "boot": 2, + "exit_observed": true, + "initialized": false, + "log": "body-02.log", + "pid": 71324, + "port": 51373, + "returncode": 0, + "role": "body", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/body", + "stopped_time": 1791829042.1212611 + }, + "request": { + "action": "stop-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "runner_status": "blocked", + "usage_calls": 16 + }, + "predicate": "uncertain", + "requested_time": 1791829041.8267992, + "role": "body", + "sequence": 7 + } +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000008.request.json b/jevdual/results/workbench-restarts-20261012/control/000008.request.json new file mode 100644 index 0000000..3b5d2da --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000008.request.json @@ -0,0 +1,16 @@ +{ + "action": "start-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "runner_status": "paused", + "usage_calls": 16 + }, + "predicate": "none", + "requested_time": 1791829079.469436, + "role": "body", + "sequence": 8 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000008.result.json b/jevdual/results/workbench-restarts-20261012/control/000008.result.json new file mode 100644 index 0000000..6c508e3 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000008.result.json @@ -0,0 +1,25 @@ +{ + "action_performed": true, + "after": "000008-after.json", + "before": "000008-before.json", + "passed": true, + "pid": 74921, + "predicate": "uncertain", + "request": { + "action": "start-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "runner_status": "paused", + "usage_calls": 16 + }, + "predicate": "none", + "requested_time": 1791829079.469436, + "role": "body", + "sequence": 8 + }, + "stopped_sequence": 7 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000009.request.json b/jevdual/results/workbench-restarts-20261012/control/000009.request.json new file mode 100644 index 0000000..c4c1813 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000009.request.json @@ -0,0 +1,16 @@ +{ + "action": "finish", + "expect": { + "active_job_id": null, + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": null, + "runner_status": "running", + "usage_calls": 29 + }, + "predicate": "none", + "requested_time": 1791829364.559857, + "role": null, + "sequence": 9 +} diff --git a/jevdual/results/workbench-restarts-20261012/control/000009.result.json b/jevdual/results/workbench-restarts-20261012/control/000009.result.json new file mode 100644 index 0000000..97785a0 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/control/000009.result.json @@ -0,0 +1,22 @@ +{ + "action_performed": false, + "after": "000009-after.json", + "before": "000009-before.json", + "passed": true, + "request": { + "action": "finish", + "expect": { + "active_job_id": null, + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": null, + "runner_status": "running", + "usage_calls": 29 + }, + "predicate": "none", + "requested_time": 1791829364.559857, + "role": null, + "sequence": 9 + } +} diff --git a/jevdual/results/workbench-restarts-20261012/handoff.json b/jevdual/results/workbench-restarts-20261012/handoff.json new file mode 100644 index 0000000..7b0fac7 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/handoff.json @@ -0,0 +1,38 @@ +{ + "processes": [ + { + "role": "body", + "pid": 8139, + "arguments": [ + "body_network.py", + "--root", + "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/body", + "--port", + "51373" + ] + }, + { + "role": "workbench", + "pid": 8145, + "arguments": [ + "network_bench_operator.py", + "serve", + "--root", + "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator", + "--port", + "51377", + "--backend", + "codex" + ] + } + ], + "browser_origin": "http://127.0.0.1:51377", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "epoch": 4, + "runner_status": "paused", + "client_commands": 83, + "completed_jobs": 2, + "model_request_pending": false, + "source_commit": "d7072107d576d7a09643229ae584a3864d2fe0f6" +} \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/health-timeout-observation.json b/jevdual/results/workbench-restarts-20261012/health-timeout-observation.json new file mode 100644 index 0000000..4530889 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/health-timeout-observation.json @@ -0,0 +1,11 @@ +{ + "cause": "unresolved; do not infer a specific network or scheduler cause", + "evidence": [ + "ui/transient-health-pause.txt", + "ui/transient-health-resumed.txt", + "qualification-score.json" + ], + "observed": "Health reads timed out during second-job reset and cancelled one additional model call; later read-only identity returned in 0.023494 seconds and connection was connected. Explicit Resume took a fresh observation and the job completed.", + "replayed_commands": 0, + "source_edited_during_trial": false +} diff --git a/jevdual/results/workbench-restarts-20261012/process-ledger.json b/jevdual/results/workbench-restarts-20261012/process-ledger.json new file mode 100644 index 0000000..cda8183 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/process-ledger.json @@ -0,0 +1,91 @@ +{ + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "body_origin": "http://127.0.0.1:51373", + "browser_origin": "http://127.0.0.1:51377", + "owned_processes_exited": true, + "planner": "actual_codex_cli_images_over_TCP", + "processes": [ + { + "boot": 1, + "exit_observed": true, + "initialized": true, + "log": "body-01.log", + "pid": 25787, + "port": 51373, + "returncode": 0, + "role": "body", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/body", + "stopped_time": 1791828952.994875 + }, + { + "exit_observed": true, + "pid": 25789, + "returncode": 0, + "role": "initialization" + }, + { + "boot": 1, + "exit_observed": true, + "initialized": false, + "log": "workbench-01.log", + "pid": 25794, + "port": 51377, + "returncode": 0, + "role": "workbench", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator", + "stopped_time": 1791828631.66827 + }, + { + "boot": 2, + "exit_observed": true, + "initialized": false, + "log": "workbench-02.log", + "pid": 30888, + "port": 51377, + "returncode": 0, + "role": "workbench", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator", + "stopped_time": 1791828768.2145522 + }, + { + "boot": 3, + "exit_observed": true, + "initialized": false, + "log": "workbench-03.log", + "pid": 39967, + "port": 51377, + "returncode": 0, + "role": "workbench", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator", + "stopped_time": 1791829365.605063 + }, + { + "boot": 2, + "exit_observed": true, + "initialized": false, + "log": "body-02.log", + "pid": 71324, + "port": 51373, + "returncode": 0, + "role": "body", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/body", + "stopped_time": 1791829042.1212611 + }, + { + "boot": 3, + "exit_observed": true, + "initialized": false, + "log": "body-03.log", + "pid": 74921, + "port": 51373, + "returncode": 0, + "role": "body", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/body", + "stopped_time": 1791829365.6788201 + } + ], + "ready": true, + "simulation": true, + "source_commit": "d7072107d576d7a09643229ae584a3864d2fe0f6" +} diff --git a/jevdual/results/workbench-restarts-20261012/qualification-score.json b/jevdual/results/workbench-restarts-20261012/qualification-score.json new file mode 100644 index 0000000..0f12bed --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/qualification-score.json @@ -0,0 +1,744 @@ +{ + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "browser_transitions_passed": true, + "calls": [ + { + "action": null, + "call": 1, + "core_receipt_bound": false, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": false, + "usage": null, + "withheld": true + }, + { + "action": "move", + "call": 2, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13063, + "output_tokens": 199 + }, + "withheld": false + }, + { + "action": "move", + "call": 3, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13123, + "output_tokens": 131 + }, + "withheld": false + }, + { + "action": "measure", + "call": 4, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13192, + "output_tokens": 136 + }, + "withheld": false + }, + { + "action": "begin_reset", + "call": 5, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13262, + "output_tokens": 38 + }, + "withheld": false + }, + { + "action": "move", + "call": 6, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13323, + "output_tokens": 191 + }, + "withheld": false + }, + { + "action": "move", + "call": 7, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13406, + "output_tokens": 152 + }, + "withheld": false + }, + { + "action": "move", + "call": 8, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13466, + "output_tokens": 246 + }, + "withheld": false + }, + { + "action": "move", + "call": 9, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13017, + "output_tokens": 165 + }, + "withheld": false + }, + { + "action": "move", + "call": 10, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13017, + "output_tokens": 193 + }, + "withheld": false + }, + { + "action": "move", + "call": 11, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13018, + "output_tokens": 195 + }, + "withheld": false + }, + { + "action": "move", + "call": 12, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13495, + "output_tokens": 138 + }, + "withheld": false + }, + { + "action": "move", + "call": 13, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13494, + "output_tokens": 105 + }, + "withheld": false + }, + { + "action": "finish_reset", + "call": 14, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13496, + "output_tokens": 119 + }, + "withheld": false + }, + { + "action": null, + "call": 1, + "core_receipt_bound": false, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": false, + "usage": null, + "withheld": true + }, + { + "action": "move", + "call": 2, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13084, + "output_tokens": 214 + }, + "withheld": false + }, + { + "action": "move", + "call": 3, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13144, + "output_tokens": 147 + }, + "withheld": false + }, + { + "action": "measure", + "call": 4, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 12758, + "output_tokens": 127 + }, + "withheld": false + }, + { + "action": "begin_reset", + "call": 5, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13294, + "output_tokens": 42 + }, + "withheld": false + }, + { + "action": "move", + "call": 6, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12893, + "output_tokens": 146 + }, + "withheld": false + }, + { + "action": "move", + "call": 7, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12968, + "output_tokens": 189 + }, + "withheld": false + }, + { + "action": "move", + "call": 8, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13041, + "output_tokens": 161 + }, + "withheld": false + }, + { + "action": "move", + "call": 9, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13049, + "output_tokens": 166 + }, + "withheld": false + }, + { + "action": "move", + "call": 10, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13519, + "output_tokens": 165 + }, + "withheld": false + }, + { + "action": "move", + "call": 11, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13057, + "output_tokens": 202 + }, + "withheld": false + }, + { + "action": "move", + "call": 12, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13065, + "output_tokens": 164 + }, + "withheld": false + }, + { + "action": "move", + "call": 13, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13530, + "output_tokens": 120 + }, + "withheld": false + }, + { + "action": null, + "call": 14, + "core_receipt_bound": false, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": false, + "usage": null, + "withheld": true + }, + { + "action": "finish_reset", + "call": 15, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13536, + "output_tokens": 112 + }, + "withheld": false + } + ], + "completed_cycles": 2, + "lost_reply_reconciled_without_resend": true, + "model_boundaries_passed": true, + "owned_processes_exited": true, + "passed": true, + "scope": "browser UI and actual image policy over loopback TCP simulation", + "scores": [ + { + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 2, + "image_sha256": "bdee3bf2ea5af18d557cb6560b766242a409cd25ac852273ce2724825f12decb", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.46799999999962, + "operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "source_kind": "mujoco_simulation", + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9", + "version": 1, + "worker_pid": 51928 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06582870900153087, + -8.38971234022521e-11, + 0.03499573045536974 + ], + "external_force_cleared": true, + "generation": 2, + "native_time_s": 5.46799999999962, + "pusher_home": false, + "pusher_xyz": [ + -0.03999996967021979, + 1.8297702229966647e-25, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9" + }, + "model_calls": 14, + "motion_count": 10, + "passed": true, + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11582763630839087, + -2.3619261859293773e-09, + 0.03499573045536983 + ], + "external_force_cleared": true, + "generation": 10, + "native_time_s": 21.679999999998863, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + } + }, + { + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 12, + "image_sha256": "60d8074b8c92a02b009c072c57bc1340098311df51c08f9d9d02d41f596c342e", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "measurement": { + "block_box": [ + 345, + 159, + 387, + 201 + ], + "block_center_xy": [ + 0.07666666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 365.085020242915, + 179.50722961249278 + ], + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 26.349999999996275, + "operation_id": "agent-12d303b3be23401d9cdd1b1296f3c87a", + "source_kind": "mujoco_simulation", + "state_sha256": "7ced546541611d509086f34fc585c77771e272c65f3bbb518c94fb1942dbcd16", + "version": 1, + "worker_pid": 77998 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.07578825420376317, + -2.361855509899145e-09, + 0.03499573045536977 + ], + "external_force_cleared": true, + "generation": 12, + "native_time_s": 26.349999999996275, + "pusher_home": false, + "pusher_xyz": [ + -0.049999969400252586, + 1.975335742467142e-26, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "7ced546541611d509086f34fc585c77771e272c65f3bbb518c94fb1942dbcd16" + }, + "model_calls": 15, + "motion_count": 10, + "passed": true, + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 20, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "kind": "finish_reset", + "native_time_s": 42.630000000006135, + "operation_id": "agent-7acee30a3cb442d9a3a2b3a9bfec10ed", + "pusher_home_verified": true, + "reset_contact_samples": 3314, + "reset_native_steps": 8140, + "state_sha256": "02c49f9f03f16f8de552b4b4ce57b6d78c85e291fc3dbf1b6acb0ce4b7cd638b" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11582731939863683, + -9.491113827050927e-09, + 0.03499573045536984 + ], + "external_force_cleared": true, + "generation": 20, + "native_time_s": 42.630000000006135, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "02c49f9f03f16f8de552b4b4ce57b6d78c85e291fc3dbf1b6acb0ce4b7cd638b" + } + } + ], + "source_commit": "d7072107d576d7a09643229ae584a3864d2fe0f6", + "source_unchanged": true, + "sqlite": { + "count": 2, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 2, + "image_sha256": "bdee3bf2ea5af18d557cb6560b766242a409cd25ac852273ce2724825f12decb", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 2, + "image_sha256": "bdee3bf2ea5af18d557cb6560b766242a409cd25ac852273ce2724825f12decb", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.46799999999962, + "operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "source_kind": "mujoco_simulation", + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9", + "version": 1, + "worker_pid": 51928 + }, + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9" + }, + { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 12, + "image_sha256": "60d8074b8c92a02b009c072c57bc1340098311df51c08f9d9d02d41f596c342e", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "operation_id": "agent-12d303b3be23401d9cdd1b1296f3c87a", + "receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 12, + "image_sha256": "60d8074b8c92a02b009c072c57bc1340098311df51c08f9d9d02d41f596c342e", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "measurement": { + "block_box": [ + 345, + 159, + 387, + 201 + ], + "block_center_xy": [ + 0.07666666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 365.085020242915, + 179.50722961249278 + ], + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 26.349999999996275, + "operation_id": "agent-12d303b3be23401d9cdd1b1296f3c87a", + "source_kind": "mujoco_simulation", + "state_sha256": "7ced546541611d509086f34fc585c77771e272c65f3bbb518c94fb1942dbcd16", + "version": 1, + "worker_pid": 77998 + }, + "state_sha256": "7ced546541611d509086f34fc585c77771e272c65f3bbb518c94fb1942dbcd16" + } + ] + }, + "transport_command_count": 83, + "transport_journal_bound": true, + "ui_steps": [ + "body_uncertain_recovered", + "body_uncertain_resumed", + "completed", + "disconnected", + "offline_receipt", + "reconnected", + "recovered", + "reloaded", + "resumed", + "uncertain" + ] +} diff --git a/jevdual/results/workbench-restarts-20261012/report.md b/jevdual/results/workbench-restarts-20261012/report.md new file mode 100644 index 0000000..a79ebb7 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/report.md @@ -0,0 +1,29 @@ +# Mid-job restart recovery + +All four graceful process restart cases passed in the actual browser with actual Codex planning. The first model trial ran on frozen source `d7072107d576d7a09643229ae584a3864d2fe0f6`; measured source stayed unchanged. Two jobs completed on one continuous simulated body, with independently checked placement, one SQLite measurement each and contact resets. No uncertain action was resent. + +| Interruption | Observed recovery | Independent check | +| --- | --- | --- | +| Workbench while planning | Browser disconnected; owned planner exited; retained job returned paused | Same identity and command records; explicit Resume preceded fresh observation | +| Workbench with uncertain dispatch | Same pending command returned blocked; Check receipt recovered it and left the job paused | Five commands throughout restart, disconnect, reconnect and receipt recovery; one send of the lost command | +| Body while planning | Browser showed Body unavailable; planner cancelled; reboot returned paused | Body identity and motion state retained; epoch advanced from one to two; fresh planning followed Resume | +| Body with uncertain dispatch | Same command stayed unresolved through outage and reboot; historical receipt recovered while paused | Boot-two command recovered during boot three with 46 command records unchanged; one send; fresh observation after Resume | + +The [restart score](restart-score.json) passed every boundary and all ten required visible states. The [native/model score](qualification-score.json) bound each exact TCP image to its model input, every applied decision to its typed proposal and lower receipt, and each command to one client send. It ran after all seven owned trial processes had exited. Two cancelled planning calls and a later health cancellation were reaped and withheld; none supplied an action. + +| Job | Model requests | Reset generation | Native time at reset | Contact samples | +| --- | ---: | ---: | ---: | ---: | +| Restart inspection 01 | 14 | 10 | 21.680 s | 3,174 | +| Restart inspection 02 | 15 | 20 | 42.630 s | 3,314 | + +The run retained 83 command records and 29 model requests, including three cancellations. Browser reload preserved both completed jobs and sent no command. After scoring, both services restarted at the same roots and ports for handoff: [workbench](http://127.0.0.1:51377/), body port 51373. The host is paused, body boot four is verified, both results remain visible, and no job, model request or uncertain command is pending. Owned handoff PIDs and identities are in [handoff.json](handoff.json). + +Testing first reproduced a fast-reboot defect: an old decision could acquire a new boot's lease when its outage escaped polling. The runtime now invalidates that decision at either health readback or command admission, requiring explicit Resume and a fresh observation. Restarted and recovered unfinished jobs show Paused. Body/core/client freshness, identity, lease and effect guards were not edited. + +Conformance passed 103 checks: nineteen runtime socket cases, eighty core/network/HTTP regressions and four synthetic harness control/ownership checks. Ruff, JavaScript syntax, notebook and diff checks passed. Before-fix failures, an abbreviated-SHA startup refusal before any process or model launch, and the preserved previous product are recorded in [attempt-ledger.json](attempt-ledger.json). + +One additional health timeout during reset cancelled a model call and paused the second job. Later read-only health succeeded; explicit Resume used a fresh image and completed the job. Its cause remains unresolved. This is a product reliability limitation retained in [health-timeout-observation.json](health-timeout-observation.json), rather than an excluded attempt. No source changed during that recovery. + +Scope is graceful process restarts in same-Mac loopback simulation. Sudden power loss, process kill during native persistence, hardware and authenticated remote access remain untested. Full browser captures and snapshots accompany the compact UI ledger; later ledger entries use main-panel excerpts to stay within its existing 64 KiB bound. Private model prompts and process output remain in ignored trial storage. Reproduce with the [runbook](../../../tools/physical-workcell/NETWORK_WORKBENCH.md) and [preregistered experiment](../../docs/experiments/SIM11-workbench-restarts.md). + +![Historical command recovered after body reboot; agent remains paused](ui/body-uncertain-recovered.jpg) diff --git a/jevdual/results/workbench-restarts-20261012/restart-ledger.json b/jevdual/results/workbench-restarts-20261012/restart-ledger.json new file mode 100644 index 0000000..a35e0e9 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/restart-ledger.json @@ -0,0 +1,246 @@ +{ + "boundaries": [ + { + "action_performed": true, + "after": "000001-after.json", + "before": "000001-before.json", + "passed": true, + "process": { + "boot": 1, + "exit_observed": true, + "initialized": false, + "log": "workbench-01.log", + "pid": 25794, + "port": 51377, + "returncode": 0, + "role": "workbench", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator", + "stopped_time": 1791828631.66827 + }, + "request": { + "action": "stop-role", + "expect": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": true, + "recovery_command_id": null, + "runner_status": "running", + "usage_calls": 1 + }, + "predicate": "planning", + "requested_time": 1791828631.2835982, + "role": "workbench", + "sequence": 1 + } + }, + { + "action_performed": true, + "after": "000002-after.json", + "before": "000002-before.json", + "passed": true, + "pid": 30888, + "predicate": "planning", + "request": { + "action": "start-role", + "expect": null, + "predicate": "none", + "requested_time": 1791828682.922372, + "role": "workbench", + "sequence": 2 + }, + "stopped_sequence": 1 + }, + { + "action_performed": true, + "after": "000003-after.json", + "before": "000003-before.json", + "passed": true, + "process": { + "boot": 2, + "exit_observed": true, + "initialized": false, + "log": "workbench-02.log", + "pid": 30888, + "port": 51377, + "returncode": 0, + "role": "workbench", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator", + "stopped_time": 1791828768.2145522 + }, + "request": { + "action": "stop-role", + "expect": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "runner_status": "blocked", + "usage_calls": 2 + }, + "predicate": "uncertain", + "requested_time": 1791828767.342037, + "role": "workbench", + "sequence": 3 + } + }, + { + "action_performed": true, + "after": "000004-after.json", + "before": "000004-before.json", + "passed": true, + "pid": 39967, + "predicate": "uncertain", + "request": { + "action": "start-role", + "expect": null, + "predicate": "none", + "requested_time": 1791828779.372716, + "role": "workbench", + "sequence": 4 + }, + "stopped_sequence": 3 + }, + { + "action_performed": true, + "after": "000005-after.json", + "before": "000005-before.json", + "passed": true, + "process": { + "boot": 1, + "exit_observed": true, + "initialized": true, + "log": "body-01.log", + "pid": 25787, + "port": 51373, + "returncode": 0, + "role": "body", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/body", + "stopped_time": 1791828952.994875 + }, + "request": { + "action": "stop-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": true, + "recovery_command_id": null, + "runner_status": "running", + "usage_calls": 15 + }, + "predicate": "planning", + "requested_time": 1791828952.679998, + "role": "body", + "sequence": 5 + } + }, + { + "action_performed": true, + "after": "000006-after.json", + "before": "000006-before.json", + "passed": true, + "pid": 71324, + "predicate": "planning", + "request": { + "action": "start-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": null, + "runner_status": "paused", + "usage_calls": 15 + }, + "predicate": "none", + "requested_time": 1791829008.869165, + "role": "body", + "sequence": 6 + }, + "stopped_sequence": 5 + }, + { + "action_performed": true, + "after": "000007-after.json", + "before": "000007-before.json", + "passed": true, + "process": { + "boot": 2, + "exit_observed": true, + "initialized": false, + "log": "body-02.log", + "pid": 71324, + "port": 51373, + "returncode": 0, + "role": "body", + "root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/body", + "stopped_time": 1791829042.1212611 + }, + "request": { + "action": "stop-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "runner_status": "blocked", + "usage_calls": 16 + }, + "predicate": "uncertain", + "requested_time": 1791829041.8267992, + "role": "body", + "sequence": 7 + } + }, + { + "action_performed": true, + "after": "000008-after.json", + "before": "000008-before.json", + "passed": true, + "pid": 74921, + "predicate": "uncertain", + "request": { + "action": "start-role", + "expect": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "runner_status": "paused", + "usage_calls": 16 + }, + "predicate": "none", + "requested_time": 1791829079.469436, + "role": "body", + "sequence": 8 + }, + "stopped_sequence": 7 + }, + { + "action_performed": false, + "after": "000009-after.json", + "before": "000009-before.json", + "passed": true, + "request": { + "action": "finish", + "expect": { + "active_job_id": null, + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "model_request_pending": false, + "recovery_command_id": null, + "runner_status": "running", + "usage_calls": 29 + }, + "predicate": "none", + "requested_time": 1791829364.559857, + "role": null, + "sequence": 9 + } + } + ] +} diff --git a/jevdual/results/workbench-restarts-20261012/restart-score.json b/jevdual/results/workbench-restarts-20261012/restart-score.json new file mode 100644 index 0000000..d5756f7 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/restart-score.json @@ -0,0 +1,99 @@ +{ + "legacy_qualification": { + "browser_transitions_passed": true, + "completed_cycles": 2, + "lost_reply_reconciled_without_resend": true, + "model_boundaries_passed": true, + "passed": true, + "source_unchanged": true + }, + "owned_processes_exited": true, + "passed": true, + "restart_boundaries": [ + { + "command_id": null, + "epoch_bound": true, + "fresh_observation_after_explicit_resume": true, + "historical_receipt_without_replay": true, + "model_reaped": true, + "outage_observed": true, + "owned_process_reaped": true, + "passed": true, + "paused_after_restart": true, + "pending_bound": true, + "predicate": "planning", + "role": "workbench", + "stable_ids": true, + "start_sequence": 2, + "stop_sequence": 1, + "unchanged_sends": true + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "epoch_bound": true, + "fresh_observation_after_explicit_resume": true, + "historical_receipt_without_replay": true, + "model_reaped": true, + "outage_observed": true, + "owned_process_reaped": true, + "passed": true, + "paused_after_restart": true, + "pending_bound": true, + "predicate": "uncertain", + "role": "workbench", + "stable_ids": true, + "start_sequence": 4, + "stop_sequence": 3, + "unchanged_sends": true + }, + { + "command_id": null, + "epoch_bound": true, + "fresh_observation_after_explicit_resume": true, + "historical_receipt_without_replay": true, + "model_reaped": true, + "outage_observed": true, + "owned_process_reaped": true, + "passed": true, + "paused_after_restart": true, + "pending_bound": true, + "predicate": "planning", + "role": "body", + "stable_ids": true, + "start_sequence": 6, + "stop_sequence": 5, + "unchanged_sends": true + }, + { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "epoch_bound": true, + "fresh_observation_after_explicit_resume": true, + "historical_receipt_without_replay": true, + "model_reaped": true, + "outage_observed": true, + "owned_process_reaped": true, + "passed": true, + "paused_after_restart": true, + "pending_bound": true, + "predicate": "uncertain", + "role": "body", + "stable_ids": true, + "start_sequence": 8, + "stop_sequence": 7, + "unchanged_sends": true + } + ], + "scope": "four graceful owned mid-job restarts; actual Codex browser; loopback simulation", + "visible_restart_states": { + "body-planning-offline": true, + "body-planning-restored": true, + "body-uncertain-offline": true, + "body-uncertain-recovered": true, + "body-uncertain-restored": true, + "body-uncertain-resumed": true, + "workbench-planning-offline": true, + "workbench-planning-restored": true, + "workbench-uncertain-offline": true, + "workbench-uncertain-restored": true + } +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000001-after.json b/jevdual/results/workbench-restarts-20261012/snapshots/000001-after.json new file mode 100644 index 0000000..c812945 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000001-after.json @@ -0,0 +1,140 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "moves": 0, + "phase": "prepare", + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 0, + "jobs": {}, + "native_time_s": 1.0000000000000007, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 1, + "expires_in_s": 24.078790416941047, + "lease_id": "08011306c044435da2272672ebbe5ba5" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "08011306c044435da2272672ebbe5ba5" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 0, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-134e7f48aa154ee1843c5a5d9250af9b-4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7.png", + "sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "runner_status": "stopped", + "sequence": 10, + "stage": null, + "usage": { + "calls": 1, + "input_tokens": 0, + "output_tokens": 0, + "reported_calls": 0 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + } + ], + "processes": { + "body": 25787, + "workbench": null + }, + "public": null, + "public_error": "[Errno 61] Connection refused", + "time": 1791828631.668277 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000001-before.json b/jevdual/results/workbench-restarts-20261012/snapshots/000001-before.json new file mode 100644 index 0000000..ecfcc66 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000001-before.json @@ -0,0 +1,270 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "moves": 0, + "phase": "prepare", + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 0, + "jobs": {}, + "native_time_s": 1.0000000000000007, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 1, + "expires_in_s": 24.430517291883007, + "lease_id": "08011306c044435da2272672ebbe5ba5" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "08011306c044435da2272672ebbe5ba5" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 0, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-134e7f48aa154ee1843c5a5d9250af9b-4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7.png", + "sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "runner_status": "running", + "sequence": 9, + "stage": null, + "usage": { + "calls": 1, + "input_tokens": 0, + "output_tokens": 0, + "reported_calls": 0 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + } + ], + "processes": { + "body": 25787, + "workbench": 25794 + }, + "public": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "activity": [ + { + "intent": "", + "kind": "pause", + "outcome": "Pause requested; a command already admitted by this host may finish within body bounds", + "seq": 1, + "time": 1791828609.2092621 + }, + { + "intent": "Restart inspection 01", + "kind": "queued", + "outcome": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "seq": 2, + "time": 1791828615.833963 + }, + { + "intent": "Restart inspection 02", + "kind": "queued", + "outcome": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "seq": 3, + "time": 1791828616.64305 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 4, + "time": 1791828625.7236679 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 5, + "time": 1791828625.734359 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "start_job: command-36da4220dfcd4e85b9a4cee555ccd7aa", + "seq": 6, + "time": 1791828625.7491488 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 7, + "time": 1791828625.759552 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-e897a3cba83b4d83b460a556be5e459b", + "seq": 8, + "time": 1791828625.8979042 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "1", + "seq": 9, + "time": 1791828625.8994381 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 1, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "running", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": true, + "pending_operation": null, + "readiness": { + "ready": true, + "reason": "Resumed; next decision receives a fresh TCP image" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 1, + "input_tokens": 0, + "output_tokens": 0, + "reported_calls": 0, + "token_usage_complete": false + } + }, + "time": 1791828631.315989 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000002-after.json b/jevdual/results/workbench-restarts-20261012/snapshots/000002-after.json new file mode 100644 index 0000000..1c2b672 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000002-after.json @@ -0,0 +1,277 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "moves": 0, + "phase": "prepare", + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 0, + "jobs": {}, + "native_time_s": 1.0000000000000007, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 1, + "expires_in_s": 0, + "lease_id": "08011306c044435da2272672ebbe5ba5" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "08011306c044435da2272672ebbe5ba5" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 0, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-134e7f48aa154ee1843c5a5d9250af9b-4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7.png", + "sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "runner_status": "paused", + "sequence": 10, + "stage": null, + "usage": { + "calls": 1, + "input_tokens": 0, + "output_tokens": 0, + "reported_calls": 0 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + } + ], + "processes": { + "body": 25787, + "workbench": 30888 + }, + "public": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "activity": [ + { + "intent": "", + "kind": "pause", + "outcome": "Pause requested; a command already admitted by this host may finish within body bounds", + "seq": 1, + "time": 1791828609.2092621 + }, + { + "intent": "Restart inspection 01", + "kind": "queued", + "outcome": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "seq": 2, + "time": 1791828615.833963 + }, + { + "intent": "Restart inspection 02", + "kind": "queued", + "outcome": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "seq": 3, + "time": 1791828616.64305 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 4, + "time": 1791828625.7236679 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 5, + "time": 1791828625.734359 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "start_job: command-36da4220dfcd4e85b9a4cee555ccd7aa", + "seq": 6, + "time": 1791828625.7491488 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 7, + "time": 1791828625.759552 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-e897a3cba83b4d83b460a556be5e459b", + "seq": 8, + "time": 1791828625.8979042 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "1", + "seq": 9, + "time": 1791828625.8994381 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 10, + "time": 1791828631.352569 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 1, + "disturbance_test": false, + "error": "operator_pause_requested", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "paused", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": null, + "readiness": { + "ready": false, + "reason": "Restarted; inspect the retained stage before explicit Resume" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "paused", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 1, + "input_tokens": 0, + "output_tokens": 0, + "reported_calls": 0, + "token_usage_complete": false + } + }, + "time": 1791828683.136389 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000002-before.json b/jevdual/results/workbench-restarts-20261012/snapshots/000002-before.json new file mode 100644 index 0000000..25d0091 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000002-before.json @@ -0,0 +1,140 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "moves": 0, + "phase": "prepare", + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 0, + "jobs": {}, + "native_time_s": 1.0000000000000007, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 1, + "expires_in_s": 0, + "lease_id": "08011306c044435da2272672ebbe5ba5" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "08011306c044435da2272672ebbe5ba5" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 0, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-134e7f48aa154ee1843c5a5d9250af9b-4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7.png", + "sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "runner_status": "stopped", + "sequence": 10, + "stage": null, + "usage": { + "calls": 1, + "input_tokens": 0, + "output_tokens": 0, + "reported_calls": 0 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + } + ], + "processes": { + "body": 25787, + "workbench": null + }, + "public": null, + "public_error": "[Errno 61] Connection refused", + "time": 1791828682.949166 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000003-after.json b/jevdual/results/workbench-restarts-20261012/snapshots/000003-after.json new file mode 100644 index 0000000..a9d0a26 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000003-after.json @@ -0,0 +1,199 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "moves": 1, + "phase": "prepare", + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 1, + "jobs": {}, + "native_time_s": 4.0999999999997705, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 1, + "expires_in_s": 11.691162209026515, + "lease_id": "e7dc313216964cb388797a7054076bb8" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "unknown" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "e7dc313216964cb388797a7054076bb8" + }, + "pending_command_ids": [ + "command-24230a0f96bc4e84a84f720b1c974054" + ] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 0, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-8f4e7c93a38f43518d06e8ca79652ee1-4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7.png", + "sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "runner_status": "stopped", + "sequence": 19, + "stage": { + "arguments": { + "proposal_id": "proposal-7638971758c9474484d815accb5fd532" + }, + "before_commands": [ + "command-1e2386315d6c4c7692405dac7dfa7bd1", + "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "command-933c11248d6a48079ead24676a2df7fb", + "command-e897a3cba83b4d83b460a556be5e459b" + ], + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "context": { + "action": { + "action": "move", + "intent": "Push the block right so its center enters the measurement zone.", + "target_x": 0.015, + "target_y": 0.0 + }, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/calls/20eb6586-e73a-4db4-aaac-db3e5d537329-02", + "decision_epoch": 1, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329" + }, + "control_epoch": 1, + "operation": "dispatch" + }, + "usage": { + "calls": 2, + "input_tokens": 13063, + "output_tokens": 199, + "reported_calls": 1 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + } + ], + "processes": { + "body": 25787, + "workbench": null + }, + "public": null, + "public_error": "[Errno 61] Connection refused", + "time": 1791828768.214575 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000003-before.json b/jevdual/results/workbench-restarts-20261012/snapshots/000003-before.json new file mode 100644 index 0000000..b85a59e --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000003-before.json @@ -0,0 +1,399 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "moves": 1, + "phase": "prepare", + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 1, + "jobs": {}, + "native_time_s": 4.0999999999997705, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 1, + "expires_in_s": 12.518944750074297, + "lease_id": "e7dc313216964cb388797a7054076bb8" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "unknown" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "e7dc313216964cb388797a7054076bb8" + }, + "pending_command_ids": [ + "command-24230a0f96bc4e84a84f720b1c974054" + ] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 0, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-8f4e7c93a38f43518d06e8ca79652ee1-4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7.png", + "sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "runner_status": "blocked", + "sequence": 19, + "stage": { + "arguments": { + "proposal_id": "proposal-7638971758c9474484d815accb5fd532" + }, + "before_commands": [ + "command-1e2386315d6c4c7692405dac7dfa7bd1", + "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "command-933c11248d6a48079ead24676a2df7fb", + "command-e897a3cba83b4d83b460a556be5e459b" + ], + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "context": { + "action": { + "action": "move", + "intent": "Push the block right so its center enters the measurement zone.", + "target_x": 0.015, + "target_y": 0.0 + }, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/calls/20eb6586-e73a-4db4-aaac-db3e5d537329-02", + "decision_epoch": 1, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329" + }, + "control_epoch": 1, + "operation": "dispatch" + }, + "usage": { + "calls": 2, + "input_tokens": 13063, + "output_tokens": 199, + "reported_calls": 1 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + } + ], + "processes": { + "body": 25787, + "workbench": 30888 + }, + "public": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "activity": [ + { + "intent": "", + "kind": "pause", + "outcome": "Pause requested; a command already admitted by this host may finish within body bounds", + "seq": 1, + "time": 1791828609.2092621 + }, + { + "intent": "Restart inspection 01", + "kind": "queued", + "outcome": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "seq": 2, + "time": 1791828615.833963 + }, + { + "intent": "Restart inspection 02", + "kind": "queued", + "outcome": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "seq": 3, + "time": 1791828616.64305 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 4, + "time": 1791828625.7236679 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 5, + "time": 1791828625.734359 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "start_job: command-36da4220dfcd4e85b9a4cee555ccd7aa", + "seq": 6, + "time": 1791828625.7491488 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 7, + "time": 1791828625.759552 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-e897a3cba83b4d83b460a556be5e459b", + "seq": 8, + "time": 1791828625.8979042 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "1", + "seq": 9, + "time": 1791828625.8994381 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 10, + "time": 1791828631.352569 + }, + { + "intent": "", + "kind": "fault_armed", + "outcome": "drop_after", + "seq": 11, + "time": 1791828738.0263119 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 12, + "time": 1791828738.312355 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 13, + "time": 1791828738.326447 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-933c11248d6a48079ead24676a2df7fb", + "seq": 14, + "time": 1791828738.4128268 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "2", + "seq": 15, + "time": 1791828738.414289 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 16, + "time": 1791828749.914588 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-1e2386315d6c4c7692405dac7dfa7bd1", + "seq": 17, + "time": 1791828749.932271 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 18, + "time": 1791828749.944431 + }, + { + "intent": "", + "kind": "halt", + "outcome": "reply is uncertain; reconcile exact command without resending", + "seq": 19, + "time": 1791828750.08527 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 2, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Push the block right so its center enters the measurement zone.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": "dispatch", + "readiness": { + "ready": false, + "reason": "reply is uncertain; reconcile exact command without resending" + }, + "recovery": { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 2, + "input_tokens": 13063, + "output_tokens": 199, + "reported_calls": 1, + "token_usage_complete": false + } + }, + "time": 1791828767.3916018 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000004-after.json b/jevdual/results/workbench-restarts-20261012/snapshots/000004-after.json new file mode 100644 index 0000000..5840704 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000004-after.json @@ -0,0 +1,406 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "moves": 1, + "phase": "prepare", + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 1, + "jobs": {}, + "native_time_s": 4.0999999999997705, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 1, + "expires_in_s": 0.25754929217509925, + "lease_id": "e7dc313216964cb388797a7054076bb8" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "unknown" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "e7dc313216964cb388797a7054076bb8" + }, + "pending_command_ids": [ + "command-24230a0f96bc4e84a84f720b1c974054" + ] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 0, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-8f4e7c93a38f43518d06e8ca79652ee1-4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7.png", + "sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "runner_status": "blocked", + "sequence": 20, + "stage": { + "arguments": { + "proposal_id": "proposal-7638971758c9474484d815accb5fd532" + }, + "before_commands": [ + "command-1e2386315d6c4c7692405dac7dfa7bd1", + "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "command-933c11248d6a48079ead24676a2df7fb", + "command-e897a3cba83b4d83b460a556be5e459b" + ], + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "context": { + "action": { + "action": "move", + "intent": "Push the block right so its center enters the measurement zone.", + "target_x": 0.015, + "target_y": 0.0 + }, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/calls/20eb6586-e73a-4db4-aaac-db3e5d537329-02", + "decision_epoch": 1, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329" + }, + "control_epoch": 1, + "operation": "dispatch" + }, + "usage": { + "calls": 2, + "input_tokens": 13063, + "output_tokens": 199, + "reported_calls": 1 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + } + ], + "processes": { + "body": 25787, + "workbench": 39967 + }, + "public": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "activity": [ + { + "intent": "", + "kind": "pause", + "outcome": "Pause requested; a command already admitted by this host may finish within body bounds", + "seq": 1, + "time": 1791828609.2092621 + }, + { + "intent": "Restart inspection 01", + "kind": "queued", + "outcome": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "seq": 2, + "time": 1791828615.833963 + }, + { + "intent": "Restart inspection 02", + "kind": "queued", + "outcome": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "seq": 3, + "time": 1791828616.64305 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 4, + "time": 1791828625.7236679 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 5, + "time": 1791828625.734359 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "start_job: command-36da4220dfcd4e85b9a4cee555ccd7aa", + "seq": 6, + "time": 1791828625.7491488 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 7, + "time": 1791828625.759552 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-e897a3cba83b4d83b460a556be5e459b", + "seq": 8, + "time": 1791828625.8979042 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "1", + "seq": 9, + "time": 1791828625.8994381 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 10, + "time": 1791828631.352569 + }, + { + "intent": "", + "kind": "fault_armed", + "outcome": "drop_after", + "seq": 11, + "time": 1791828738.0263119 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 12, + "time": 1791828738.312355 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 13, + "time": 1791828738.326447 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-933c11248d6a48079ead24676a2df7fb", + "seq": 14, + "time": 1791828738.4128268 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "2", + "seq": 15, + "time": 1791828738.414289 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 16, + "time": 1791828749.914588 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-1e2386315d6c4c7692405dac7dfa7bd1", + "seq": 17, + "time": 1791828749.932271 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 18, + "time": 1791828749.944431 + }, + { + "intent": "", + "kind": "halt", + "outcome": "reply is uncertain; reconcile exact command without resending", + "seq": 19, + "time": 1791828750.08527 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Restarted with a retained command stage; check its exact receipt", + "seq": 20, + "time": 1791828779.589948 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 2, + "disturbance_test": false, + "error": "Restarted with a retained command stage; check its exact receipt", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Push the block right so its center enters the measurement zone.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": "dispatch", + "readiness": { + "ready": false, + "reason": "Restarted with a retained command stage; check its exact receipt" + }, + "recovery": { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "operation": "dispatch", + "reason": "Restarted with a retained command stage; check its exact receipt", + "state": "uncertain" + }, + "runner_status": "blocked", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 2, + "input_tokens": 13063, + "output_tokens": 199, + "reported_calls": 1, + "token_usage_complete": false + } + }, + "time": 1791828779.6568692 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000004-before.json b/jevdual/results/workbench-restarts-20261012/snapshots/000004-before.json new file mode 100644 index 0000000..5516de1 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000004-before.json @@ -0,0 +1,199 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "moves": 1, + "phase": "prepare", + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 1, + "jobs": {}, + "native_time_s": 4.0999999999997705, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 1, + "expires_in_s": 0.5128371671307832, + "lease_id": "e7dc313216964cb388797a7054076bb8" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "unknown" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "e7dc313216964cb388797a7054076bb8" + }, + "pending_command_ids": [ + "command-24230a0f96bc4e84a84f720b1c974054" + ] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 0, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-8f4e7c93a38f43518d06e8ca79652ee1-4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7.png", + "sha256": "4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "runner_status": "stopped", + "sequence": 19, + "stage": { + "arguments": { + "proposal_id": "proposal-7638971758c9474484d815accb5fd532" + }, + "before_commands": [ + "command-1e2386315d6c4c7692405dac7dfa7bd1", + "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "command-933c11248d6a48079ead24676a2df7fb", + "command-e897a3cba83b4d83b460a556be5e459b" + ], + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "context": { + "action": { + "action": "move", + "intent": "Push the block right so its center enters the measurement zone.", + "target_x": 0.015, + "target_y": 0.0 + }, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/calls/20eb6586-e73a-4db4-aaac-db3e5d537329-02", + "decision_epoch": 1, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329" + }, + "control_epoch": 1, + "operation": "dispatch" + }, + "usage": { + "calls": 2, + "input_tokens": 13063, + "output_tokens": 199, + "reported_calls": 1 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + } + ], + "processes": { + "body": 25787, + "workbench": null + }, + "public": null, + "public_error": "[Errno 61] Connection refused", + "time": 1791828779.410984 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000005-after.json b/jevdual/results/workbench-restarts-20261012/snapshots/000005-after.json new file mode 100644 index 0000000..b72ccf6 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000005-after.json @@ -0,0 +1,784 @@ +{ + "body_identity": null, + "body_identity_error": "[Errno 61] Connection refused", + "body_state": null, + "body_state_error": "[Errno 61] Connection refused", + "client": { + "commands": { + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "f816c68447d947988c70c3362c619003" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 10, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-71f5f95d2a1f4b91ab54de93a921a68c-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "running", + "sequence": 114, + "stage": null, + "usage": { + "calls": 15, + "input_tokens": 172372, + "output_tokens": 2008, + "reported_calls": 13 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + } + ], + "processes": { + "body": null, + "workbench": 39967 + }, + "public": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "activity": [ + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "12", + "seq": 91, + "time": 1791828921.078729 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 92, + "time": 1791828929.681102 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-553be6e82b274944b5e6ea9e2cd3902e", + "seq": 93, + "time": 1791828929.76928 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 94, + "time": 1791828929.815944 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-d9922eefd392420b96bf0a62d7eea982", + "seq": 95, + "time": 1791828930.0683122 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 96, + "time": 1791828930.114275 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-f7b8d8e5cddb47ecbac988938ccee2a0", + "seq": 97, + "time": 1791828930.315923 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "13", + "seq": 98, + "time": 1791828930.318308 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 99, + "time": 1791828937.617022 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-7661dbdae1c34bd797ca17b3b5321a5e", + "seq": 100, + "time": 1791828937.772455 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 101, + "time": 1791828937.839915 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-c80c18cc647b45fe8e9faf2fa890283c", + "seq": 102, + "time": 1791828938.114055 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 103, + "time": 1791828938.266146 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-248b9798493e4a43a51259929e135e29", + "seq": 104, + "time": 1791828938.604191 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "14", + "seq": 105, + "time": 1791828938.608861 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 106, + "time": 1791828950.833822 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-015d5d03d0624f14ba43d889871c45ee", + "seq": 107, + "time": 1791828950.9307368 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 108, + "time": 1791828950.97887 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-210150e3ac9f45adae24e89f22a66286", + "seq": 109, + "time": 1791828951.468124 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 110, + "time": 1791828951.5941691 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "start_job: command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "seq": 111, + "time": 1791828951.745876 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 112, + "time": 1791828951.8522959 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-ab4679dd21e14ce08f70b1ef63bd5868", + "seq": 113, + "time": 1791828952.1878028 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "1", + "seq": 114, + "time": 1791828952.191465 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 10, + "image_url": "/api/frame?generation=10&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 1, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "running", + "target": "B" + } + ], + "model_request_pending": true, + "pending_operation": null, + "readiness": { + "ready": true, + "reason": "Resumed; next decision receives a fresh TCP image" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 15, + "input_tokens": 172372, + "output_tokens": 2008, + "reported_calls": 13, + "token_usage_complete": false + } + }, + "time": 1791828952.994922 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000005-before.json b/jevdual/results/workbench-restarts-20261012/snapshots/000005-before.json new file mode 100644 index 0000000..049cc57 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000005-before.json @@ -0,0 +1,892 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "moves": 0, + "phase": "prepare", + "started_generation": 10, + "started_native_time_s": 21.679999999998863, + "target_zone": { + "x_max": 0.115, + "x_min": 0.045, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 10, + "jobs": { + "20eb6586-e73a-4db4-aaac-db3e5d537329": { + "completed_generation": 10, + "completed_native_time_s": 21.679999999998863, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement_operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 2, + "image_sha256": "bdee3bf2ea5af18d557cb6560b766242a409cd25ac852273ce2724825f12decb", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.46799999999962, + "operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "source_kind": "mujoco_simulation", + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9", + "version": 1, + "worker_pid": 51928 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "reset_started_generation": 2, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 21.679999999998863, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 1, + "expires_in_s": 29.00711249979213, + "lease_id": "f816c68447d947988c70c3362c619003" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "f816c68447d947988c70c3362c619003" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 10, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-71f5f95d2a1f4b91ab54de93a921a68c-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "running", + "sequence": 114, + "stage": null, + "usage": { + "calls": 15, + "input_tokens": 172372, + "output_tokens": 2008, + "reported_calls": 13 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + } + ], + "processes": { + "body": 25787, + "workbench": 39967 + }, + "public": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "activity": [ + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "12", + "seq": 91, + "time": 1791828921.078729 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 92, + "time": 1791828929.681102 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-553be6e82b274944b5e6ea9e2cd3902e", + "seq": 93, + "time": 1791828929.76928 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 94, + "time": 1791828929.815944 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-d9922eefd392420b96bf0a62d7eea982", + "seq": 95, + "time": 1791828930.0683122 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 96, + "time": 1791828930.114275 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-f7b8d8e5cddb47ecbac988938ccee2a0", + "seq": 97, + "time": 1791828930.315923 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "13", + "seq": 98, + "time": 1791828930.318308 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 99, + "time": 1791828937.617022 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-7661dbdae1c34bd797ca17b3b5321a5e", + "seq": 100, + "time": 1791828937.772455 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 101, + "time": 1791828937.839915 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-c80c18cc647b45fe8e9faf2fa890283c", + "seq": 102, + "time": 1791828938.114055 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 103, + "time": 1791828938.266146 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-248b9798493e4a43a51259929e135e29", + "seq": 104, + "time": 1791828938.604191 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "14", + "seq": 105, + "time": 1791828938.608861 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 106, + "time": 1791828950.833822 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-015d5d03d0624f14ba43d889871c45ee", + "seq": 107, + "time": 1791828950.9307368 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 108, + "time": 1791828950.97887 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-210150e3ac9f45adae24e89f22a66286", + "seq": 109, + "time": 1791828951.468124 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 110, + "time": 1791828951.5941691 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "start_job: command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "seq": 111, + "time": 1791828951.745876 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 112, + "time": 1791828951.8522959 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-ab4679dd21e14ce08f70b1ef63bd5868", + "seq": 113, + "time": 1791828952.1878028 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "1", + "seq": 114, + "time": 1791828952.191465 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 10, + "image_url": "/api/frame?generation=10&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 1, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "running", + "target": "B" + } + ], + "model_request_pending": true, + "pending_operation": null, + "readiness": { + "ready": true, + "reason": "Resumed; next decision receives a fresh TCP image" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 15, + "input_tokens": 172372, + "output_tokens": 2008, + "reported_calls": 13, + "token_usage_complete": false + } + }, + "time": 1791828952.71952 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000006-after.json b/jevdual/results/workbench-restarts-20261012/snapshots/000006-after.json new file mode 100644 index 0000000..5ed24d1 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000006-after.json @@ -0,0 +1,887 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "moves": 0, + "phase": "prepare", + "started_generation": 10, + "started_native_time_s": 21.679999999998863, + "target_zone": { + "x_max": 0.115, + "x_min": 0.045, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 10, + "jobs": { + "20eb6586-e73a-4db4-aaac-db3e5d537329": { + "completed_generation": 10, + "completed_native_time_s": 21.679999999998863, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement_operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 2, + "image_sha256": "bdee3bf2ea5af18d557cb6560b766242a409cd25ac852273ce2724825f12decb", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.46799999999962, + "operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "source_kind": "mujoco_simulation", + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9", + "version": 1, + "worker_pid": 51928 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "reset_started_generation": 2, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 21.679999999998863, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": null, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "f816c68447d947988c70c3362c619003" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 10, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-71f5f95d2a1f4b91ab54de93a921a68c-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "paused", + "sequence": 118, + "stage": null, + "usage": { + "calls": 15, + "input_tokens": 172372, + "output_tokens": 2008, + "reported_calls": 13 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + } + ], + "processes": { + "body": 71324, + "workbench": 39967 + }, + "public": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "activity": [ + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-d9922eefd392420b96bf0a62d7eea982", + "seq": 95, + "time": 1791828930.0683122 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 96, + "time": 1791828930.114275 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-f7b8d8e5cddb47ecbac988938ccee2a0", + "seq": 97, + "time": 1791828930.315923 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "13", + "seq": 98, + "time": 1791828930.318308 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 99, + "time": 1791828937.617022 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-7661dbdae1c34bd797ca17b3b5321a5e", + "seq": 100, + "time": 1791828937.772455 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 101, + "time": 1791828937.839915 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-c80c18cc647b45fe8e9faf2fa890283c", + "seq": 102, + "time": 1791828938.114055 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 103, + "time": 1791828938.266146 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-248b9798493e4a43a51259929e135e29", + "seq": 104, + "time": 1791828938.604191 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "14", + "seq": 105, + "time": 1791828938.608861 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 106, + "time": 1791828950.833822 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-015d5d03d0624f14ba43d889871c45ee", + "seq": 107, + "time": 1791828950.9307368 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 108, + "time": 1791828950.97887 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-210150e3ac9f45adae24e89f22a66286", + "seq": 109, + "time": 1791828951.468124 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 110, + "time": 1791828951.5941691 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "start_job: command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "seq": 111, + "time": 1791828951.745876 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 112, + "time": 1791828951.8522959 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-ab4679dd21e14ce08f70b1ef63bd5868", + "seq": 113, + "time": 1791828952.1878028 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "1", + "seq": 114, + "time": 1791828952.191465 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Remote end closed connection without response", + "seq": 115, + "time": 1791828953.570592 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 116, + "time": 1791828953.590626 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image", + "seq": 117, + "time": 1791829010.0203352 + }, + { + "intent": "", + "kind": "body_epoch_changed", + "outcome": "1 -> 2", + "seq": 118, + "time": 1791829010.021775 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "fault": null, + "reason": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 10, + "image_url": "/api/frame?generation=10&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 1, + "disturbance_test": false, + "error": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "paused", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": null, + "readiness": { + "ready": false, + "reason": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "paused", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 15, + "input_tokens": 172372, + "output_tokens": 2008, + "reported_calls": 13, + "token_usage_complete": false + } + }, + "time": 1791829010.038528 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000006-before.json b/jevdual/results/workbench-restarts-20261012/snapshots/000006-before.json new file mode 100644 index 0000000..6371a56 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000006-before.json @@ -0,0 +1,784 @@ +{ + "body_identity": null, + "body_identity_error": "[Errno 61] Connection refused", + "body_state": null, + "body_state_error": "[Errno 61] Connection refused", + "client": { + "commands": { + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 1, + "lease_id": "f816c68447d947988c70c3362c619003" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 10, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-71f5f95d2a1f4b91ab54de93a921a68c-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "paused", + "sequence": 116, + "stage": null, + "usage": { + "calls": 15, + "input_tokens": 172372, + "output_tokens": 2008, + "reported_calls": 13 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + } + ], + "processes": { + "body": null, + "workbench": 39967 + }, + "public": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "activity": [ + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-553be6e82b274944b5e6ea9e2cd3902e", + "seq": 93, + "time": 1791828929.76928 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 94, + "time": 1791828929.815944 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-d9922eefd392420b96bf0a62d7eea982", + "seq": 95, + "time": 1791828930.0683122 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 96, + "time": 1791828930.114275 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-f7b8d8e5cddb47ecbac988938ccee2a0", + "seq": 97, + "time": 1791828930.315923 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "13", + "seq": 98, + "time": 1791828930.318308 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 99, + "time": 1791828937.617022 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-7661dbdae1c34bd797ca17b3b5321a5e", + "seq": 100, + "time": 1791828937.772455 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 101, + "time": 1791828937.839915 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-c80c18cc647b45fe8e9faf2fa890283c", + "seq": 102, + "time": 1791828938.114055 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 103, + "time": 1791828938.266146 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-248b9798493e4a43a51259929e135e29", + "seq": 104, + "time": 1791828938.604191 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "14", + "seq": 105, + "time": 1791828938.608861 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 106, + "time": 1791828950.833822 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-015d5d03d0624f14ba43d889871c45ee", + "seq": 107, + "time": 1791828950.9307368 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 108, + "time": 1791828950.97887 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-210150e3ac9f45adae24e89f22a66286", + "seq": 109, + "time": 1791828951.468124 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 110, + "time": 1791828951.5941691 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "start_job: command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "seq": 111, + "time": 1791828951.745876 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 112, + "time": 1791828951.8522959 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-ab4679dd21e14ce08f70b1ef63bd5868", + "seq": 113, + "time": 1791828952.1878028 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "1", + "seq": 114, + "time": 1791828952.191465 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Remote end closed connection without response", + "seq": 115, + "time": 1791828953.570592 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 116, + "time": 1791828953.590626 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Remote end closed connection without response", + "state": "unavailable" + }, + "current_frame": { + "available": true, + "generation": 10, + "image_url": "/api/frame?generation=10&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 1, + "disturbance_test": false, + "error": "operator_pause_requested", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "paused", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": null, + "readiness": { + "ready": false, + "reason": "operator_pause_requested" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "paused", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 15, + "input_tokens": 172372, + "output_tokens": 2008, + "reported_calls": 13, + "token_usage_complete": false + } + }, + "time": 1791829008.8750951 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000007-after.json b/jevdual/results/workbench-restarts-20261012/snapshots/000007-after.json new file mode 100644 index 0000000..af93ddf --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000007-after.json @@ -0,0 +1,884 @@ +{ + "body_identity": null, + "body_identity_error": "[Errno 61] Connection refused", + "body_state": null, + "body_state_error": "[Errno 61] Connection refused", + "client": { + "commands": { + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-40c6a8a1f1a04ea7bec902767b57387a": { + "operation": "observe", + "request_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-9f8d9402f1d74504b579f39b9c793576": { + "operation": "propose", + "request_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-cf898dd6e56a4d8bb0a5894371f9ba81": { + "operation": "dispatch", + "request_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "send_count": 1, + "state": "unknown" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 2, + "lease_id": "8acd97f5a9dc48b583d6d3097f60b1ba" + }, + "pending_command_ids": [ + "command-cf898dd6e56a4d8bb0a5894371f9ba81" + ] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 10, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-28dc527b5ab349cab70e9bea9dbea92a-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "blocked", + "sequence": 127, + "stage": { + "arguments": { + "proposal_id": "proposal-2fc20beaf42745488b7a16af3afeaf6d" + }, + "before_commands": [ + "command-015d5d03d0624f14ba43d889871c45ee", + "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "command-0e35d66b16a64168b11d255a1d871e71", + "command-1936c404000d4b55a094c49a2fd9eeb3", + "command-1e2386315d6c4c7692405dac7dfa7bd1", + "command-210150e3ac9f45adae24e89f22a66286", + "command-24230a0f96bc4e84a84f720b1c974054", + "command-248b9798493e4a43a51259929e135e29", + "command-2a6e74bdbe424b3caa700dc047365a1c", + "command-2d0b436b61124502a9d8558816bda68d", + "command-3083d955014b4e5282809a47046c53db", + "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "command-38a300b989a649fd9ee243704cdc65a9", + "command-40c6a8a1f1a04ea7bec902767b57387a", + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "command-553be6e82b274944b5e6ea9e2cd3902e", + "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "command-5ced22700795486fa68a50fcda4767b8", + "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "command-7661dbdae1c34bd797ca17b3b5321a5e", + "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "command-84c016d3c2564ecea6025edaea7d23e7", + "command-8c948c9df6074ee5969ef8b19a3eaddb", + "command-933c11248d6a48079ead24676a2df7fb", + "command-9dd2a0c9603f4667956ec976e822b74a", + "command-9f8d9402f1d74504b579f39b9c793576", + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "command-ab4679dd21e14ce08f70b1ef63bd5868", + "command-b17181d5918a492a916e0e3c5a2f3a11", + "command-b182534626d34766a52d5e11d48239e7", + "command-bdc662ab7f4645d79c02f84921f3c9f6", + "command-c80c18cc647b45fe8e9faf2fa890283c", + "command-c8be0caf76504410a68a595296d56bd3", + "command-d9922eefd392420b96bf0a62d7eea982", + "command-df199bef22b442168d0a42242c00c5c4", + "command-e19f5d23dd944e40b806e930f7d44b35", + "command-e1af2fbe5a254692bf212769ddfea045", + "command-e897a3cba83b4d83b460a556be5e459b", + "command-ede04073e3654f4fa17f0a0056db9004", + "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "command-f008b852a29348218bc57e931887b963", + "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "command-f4c202be91064d3e8f4c929f1175450e", + "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "command-fda8dcacccc940c493511804050cc0ec" + ], + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "context": { + "action": { + "action": "move", + "intent": "Push the block right so its center reaches the measurement region.", + "target_x": 0.025, + "target_y": 0.0 + }, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/calls/c922a26d-9121-4d7e-82e1-7b61b0e42161-02", + "decision_epoch": 7, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161" + }, + "control_epoch": 7, + "operation": "dispatch" + }, + "usage": { + "calls": 16, + "input_tokens": 185456, + "output_tokens": 2222, + "reported_calls": 14 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + }, + { + "command_id": "command-40c6a8a1f1a04ea7bec902767b57387a", + "payload_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "sequence": 480 + }, + { + "command_id": "command-9f8d9402f1d74504b579f39b9c793576", + "payload_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "sequence": 492 + }, + { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "payload_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "sequence": 500 + } + ], + "processes": { + "body": null, + "workbench": 39967 + }, + "public": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "activity": [ + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-248b9798493e4a43a51259929e135e29", + "seq": 104, + "time": 1791828938.604191 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "14", + "seq": 105, + "time": 1791828938.608861 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 106, + "time": 1791828950.833822 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-015d5d03d0624f14ba43d889871c45ee", + "seq": 107, + "time": 1791828950.9307368 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 108, + "time": 1791828950.97887 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-210150e3ac9f45adae24e89f22a66286", + "seq": 109, + "time": 1791828951.468124 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 110, + "time": 1791828951.5941691 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "start_job: command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "seq": 111, + "time": 1791828951.745876 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 112, + "time": 1791828951.8522959 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-ab4679dd21e14ce08f70b1ef63bd5868", + "seq": 113, + "time": 1791828952.1878028 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "1", + "seq": 114, + "time": 1791828952.191465 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Remote end closed connection without response", + "seq": 115, + "time": 1791828953.570592 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 116, + "time": 1791828953.590626 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image", + "seq": 117, + "time": 1791829010.0203352 + }, + { + "intent": "", + "kind": "body_epoch_changed", + "outcome": "1 -> 2", + "seq": 118, + "time": 1791829010.021775 + }, + { + "intent": "", + "kind": "fault_armed", + "outcome": "drop_after", + "seq": 119, + "time": 1791829019.593674 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 120, + "time": 1791829019.920613 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 121, + "time": 1791829019.99926 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-40c6a8a1f1a04ea7bec902767b57387a", + "seq": 122, + "time": 1791829020.389618 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "2", + "seq": 123, + "time": 1791829020.392122 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 124, + "time": 1791829028.703949 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-9f8d9402f1d74504b579f39b9c793576", + "seq": 125, + "time": 1791829028.798069 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 126, + "time": 1791829028.864546 + }, + { + "intent": "", + "kind": "halt", + "outcome": "reply is uncertain; reconcile exact command without resending", + "seq": 127, + "time": 1791829029.1331468 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 10, + "image_url": "/api/frame?generation=10&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 2, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Push the block right so its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": "dispatch", + "readiness": { + "ready": false, + "reason": "reply is uncertain; reconcile exact command without resending" + }, + "recovery": { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 16, + "input_tokens": 185456, + "output_tokens": 2222, + "reported_calls": 14, + "token_usage_complete": false + } + }, + "time": 1791829042.121286 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000007-before.json b/jevdual/results/workbench-restarts-20261012/snapshots/000007-before.json new file mode 100644 index 0000000..f95297e --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000007-before.json @@ -0,0 +1,992 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "moves": 1, + "phase": "prepare", + "started_generation": 10, + "started_native_time_s": 21.679999999998863, + "target_zone": { + "x_max": 0.115, + "x_min": 0.045, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 11, + "jobs": { + "20eb6586-e73a-4db4-aaac-db3e5d537329": { + "completed_generation": 10, + "completed_native_time_s": 21.679999999998863, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement_operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 2, + "image_sha256": "bdee3bf2ea5af18d557cb6560b766242a409cd25ac852273ce2724825f12decb", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.46799999999962, + "operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "source_kind": "mujoco_simulation", + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9", + "version": 1, + "worker_pid": 51928 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "reset_started_generation": 2, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 24.847999999997107, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 2, + "expires_in_s": 16.92054991587065, + "lease_id": "8acd97f5a9dc48b583d6d3097f60b1ba" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-40c6a8a1f1a04ea7bec902767b57387a": { + "operation": "observe", + "request_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-9f8d9402f1d74504b579f39b9c793576": { + "operation": "propose", + "request_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-cf898dd6e56a4d8bb0a5894371f9ba81": { + "operation": "dispatch", + "request_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "send_count": 1, + "state": "unknown" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 2, + "lease_id": "8acd97f5a9dc48b583d6d3097f60b1ba" + }, + "pending_command_ids": [ + "command-cf898dd6e56a4d8bb0a5894371f9ba81" + ] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 10, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-28dc527b5ab349cab70e9bea9dbea92a-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "blocked", + "sequence": 127, + "stage": { + "arguments": { + "proposal_id": "proposal-2fc20beaf42745488b7a16af3afeaf6d" + }, + "before_commands": [ + "command-015d5d03d0624f14ba43d889871c45ee", + "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "command-0e35d66b16a64168b11d255a1d871e71", + "command-1936c404000d4b55a094c49a2fd9eeb3", + "command-1e2386315d6c4c7692405dac7dfa7bd1", + "command-210150e3ac9f45adae24e89f22a66286", + "command-24230a0f96bc4e84a84f720b1c974054", + "command-248b9798493e4a43a51259929e135e29", + "command-2a6e74bdbe424b3caa700dc047365a1c", + "command-2d0b436b61124502a9d8558816bda68d", + "command-3083d955014b4e5282809a47046c53db", + "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "command-38a300b989a649fd9ee243704cdc65a9", + "command-40c6a8a1f1a04ea7bec902767b57387a", + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "command-553be6e82b274944b5e6ea9e2cd3902e", + "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "command-5ced22700795486fa68a50fcda4767b8", + "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "command-7661dbdae1c34bd797ca17b3b5321a5e", + "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "command-84c016d3c2564ecea6025edaea7d23e7", + "command-8c948c9df6074ee5969ef8b19a3eaddb", + "command-933c11248d6a48079ead24676a2df7fb", + "command-9dd2a0c9603f4667956ec976e822b74a", + "command-9f8d9402f1d74504b579f39b9c793576", + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "command-ab4679dd21e14ce08f70b1ef63bd5868", + "command-b17181d5918a492a916e0e3c5a2f3a11", + "command-b182534626d34766a52d5e11d48239e7", + "command-bdc662ab7f4645d79c02f84921f3c9f6", + "command-c80c18cc647b45fe8e9faf2fa890283c", + "command-c8be0caf76504410a68a595296d56bd3", + "command-d9922eefd392420b96bf0a62d7eea982", + "command-df199bef22b442168d0a42242c00c5c4", + "command-e19f5d23dd944e40b806e930f7d44b35", + "command-e1af2fbe5a254692bf212769ddfea045", + "command-e897a3cba83b4d83b460a556be5e459b", + "command-ede04073e3654f4fa17f0a0056db9004", + "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "command-f008b852a29348218bc57e931887b963", + "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "command-f4c202be91064d3e8f4c929f1175450e", + "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "command-fda8dcacccc940c493511804050cc0ec" + ], + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "context": { + "action": { + "action": "move", + "intent": "Push the block right so its center reaches the measurement region.", + "target_x": 0.025, + "target_y": 0.0 + }, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/calls/c922a26d-9121-4d7e-82e1-7b61b0e42161-02", + "decision_epoch": 7, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161" + }, + "control_epoch": 7, + "operation": "dispatch" + }, + "usage": { + "calls": 16, + "input_tokens": 185456, + "output_tokens": 2222, + "reported_calls": 14 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + }, + { + "command_id": "command-40c6a8a1f1a04ea7bec902767b57387a", + "payload_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "sequence": 480 + }, + { + "command_id": "command-9f8d9402f1d74504b579f39b9c793576", + "payload_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "sequence": 492 + }, + { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "payload_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "sequence": 500 + } + ], + "processes": { + "body": 71324, + "workbench": 39967 + }, + "public": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "activity": [ + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "observe: command-248b9798493e4a43a51259929e135e29", + "seq": 104, + "time": 1791828938.604191 + }, + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "14", + "seq": 105, + "time": 1791828938.608861 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 106, + "time": 1791828950.833822 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-015d5d03d0624f14ba43d889871c45ee", + "seq": 107, + "time": 1791828950.9307368 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 108, + "time": 1791828950.97887 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-210150e3ac9f45adae24e89f22a66286", + "seq": 109, + "time": 1791828951.468124 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 110, + "time": 1791828951.5941691 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "start_job: command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "seq": 111, + "time": 1791828951.745876 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 112, + "time": 1791828951.8522959 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-ab4679dd21e14ce08f70b1ef63bd5868", + "seq": 113, + "time": 1791828952.1878028 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "1", + "seq": 114, + "time": 1791828952.191465 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Remote end closed connection without response", + "seq": 115, + "time": 1791828953.570592 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 116, + "time": 1791828953.590626 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image", + "seq": 117, + "time": 1791829010.0203352 + }, + { + "intent": "", + "kind": "body_epoch_changed", + "outcome": "1 -> 2", + "seq": 118, + "time": 1791829010.021775 + }, + { + "intent": "", + "kind": "fault_armed", + "outcome": "drop_after", + "seq": 119, + "time": 1791829019.593674 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 120, + "time": 1791829019.920613 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 121, + "time": 1791829019.99926 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-40c6a8a1f1a04ea7bec902767b57387a", + "seq": 122, + "time": 1791829020.389618 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "2", + "seq": 123, + "time": 1791829020.392122 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 124, + "time": 1791829028.703949 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-9f8d9402f1d74504b579f39b9c793576", + "seq": 125, + "time": 1791829028.798069 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 126, + "time": 1791829028.864546 + }, + { + "intent": "", + "kind": "halt", + "outcome": "reply is uncertain; reconcile exact command without resending", + "seq": 127, + "time": 1791829029.1331468 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 10, + "image_url": "/api/frame?generation=10&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 2, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Push the block right so its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": "dispatch", + "readiness": { + "ready": false, + "reason": "reply is uncertain; reconcile exact command without resending" + }, + "recovery": { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 16, + "input_tokens": 185456, + "output_tokens": 2222, + "reported_calls": 14, + "token_usage_complete": false + } + }, + "time": 1791829041.853085 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000008-after.json b/jevdual/results/workbench-restarts-20261012/snapshots/000008-after.json new file mode 100644 index 0000000..b5499ec --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000008-after.json @@ -0,0 +1,987 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": { + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "moves": 1, + "phase": "prepare", + "started_generation": 10, + "started_native_time_s": 21.679999999998863, + "target_zone": { + "x_max": 0.115, + "x_min": 0.045, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 11, + "jobs": { + "20eb6586-e73a-4db4-aaac-db3e5d537329": { + "completed_generation": 10, + "completed_native_time_s": 21.679999999998863, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement_operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 2, + "image_sha256": "bdee3bf2ea5af18d557cb6560b766242a409cd25ac852273ce2724825f12decb", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.46799999999962, + "operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "source_kind": "mujoco_simulation", + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9", + "version": 1, + "worker_pid": 51928 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "reset_started_generation": 2, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 24.847999999997107, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": null, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-40c6a8a1f1a04ea7bec902767b57387a": { + "operation": "observe", + "request_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-9f8d9402f1d74504b579f39b9c793576": { + "operation": "propose", + "request_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-cf898dd6e56a4d8bb0a5894371f9ba81": { + "operation": "dispatch", + "request_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "send_count": 1, + "state": "unknown" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 2, + "lease_id": "8acd97f5a9dc48b583d6d3097f60b1ba" + }, + "pending_command_ids": [ + "command-cf898dd6e56a4d8bb0a5894371f9ba81" + ] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 10, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-28dc527b5ab349cab70e9bea9dbea92a-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "blocked", + "sequence": 130, + "stage": { + "arguments": { + "proposal_id": "proposal-2fc20beaf42745488b7a16af3afeaf6d" + }, + "before_commands": [ + "command-015d5d03d0624f14ba43d889871c45ee", + "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "command-0e35d66b16a64168b11d255a1d871e71", + "command-1936c404000d4b55a094c49a2fd9eeb3", + "command-1e2386315d6c4c7692405dac7dfa7bd1", + "command-210150e3ac9f45adae24e89f22a66286", + "command-24230a0f96bc4e84a84f720b1c974054", + "command-248b9798493e4a43a51259929e135e29", + "command-2a6e74bdbe424b3caa700dc047365a1c", + "command-2d0b436b61124502a9d8558816bda68d", + "command-3083d955014b4e5282809a47046c53db", + "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "command-38a300b989a649fd9ee243704cdc65a9", + "command-40c6a8a1f1a04ea7bec902767b57387a", + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "command-553be6e82b274944b5e6ea9e2cd3902e", + "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "command-5ced22700795486fa68a50fcda4767b8", + "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "command-7661dbdae1c34bd797ca17b3b5321a5e", + "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "command-84c016d3c2564ecea6025edaea7d23e7", + "command-8c948c9df6074ee5969ef8b19a3eaddb", + "command-933c11248d6a48079ead24676a2df7fb", + "command-9dd2a0c9603f4667956ec976e822b74a", + "command-9f8d9402f1d74504b579f39b9c793576", + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "command-ab4679dd21e14ce08f70b1ef63bd5868", + "command-b17181d5918a492a916e0e3c5a2f3a11", + "command-b182534626d34766a52d5e11d48239e7", + "command-bdc662ab7f4645d79c02f84921f3c9f6", + "command-c80c18cc647b45fe8e9faf2fa890283c", + "command-c8be0caf76504410a68a595296d56bd3", + "command-d9922eefd392420b96bf0a62d7eea982", + "command-df199bef22b442168d0a42242c00c5c4", + "command-e19f5d23dd944e40b806e930f7d44b35", + "command-e1af2fbe5a254692bf212769ddfea045", + "command-e897a3cba83b4d83b460a556be5e459b", + "command-ede04073e3654f4fa17f0a0056db9004", + "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "command-f008b852a29348218bc57e931887b963", + "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "command-f4c202be91064d3e8f4c929f1175450e", + "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "command-fda8dcacccc940c493511804050cc0ec" + ], + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "context": { + "action": { + "action": "move", + "intent": "Push the block right so its center reaches the measurement region.", + "target_x": 0.025, + "target_y": 0.0 + }, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/calls/c922a26d-9121-4d7e-82e1-7b61b0e42161-02", + "decision_epoch": 7, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161" + }, + "control_epoch": 7, + "operation": "dispatch" + }, + "usage": { + "calls": 16, + "input_tokens": 185456, + "output_tokens": 2222, + "reported_calls": 14 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + }, + { + "command_id": "command-40c6a8a1f1a04ea7bec902767b57387a", + "payload_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "sequence": 480 + }, + { + "command_id": "command-9f8d9402f1d74504b579f39b9c793576", + "payload_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "sequence": 492 + }, + { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "payload_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "sequence": 500 + } + ], + "processes": { + "body": 74921, + "workbench": 39967 + }, + "public": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "activity": [ + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-015d5d03d0624f14ba43d889871c45ee", + "seq": 107, + "time": 1791828950.9307368 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 108, + "time": 1791828950.97887 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-210150e3ac9f45adae24e89f22a66286", + "seq": 109, + "time": 1791828951.468124 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 110, + "time": 1791828951.5941691 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "start_job: command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "seq": 111, + "time": 1791828951.745876 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 112, + "time": 1791828951.8522959 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-ab4679dd21e14ce08f70b1ef63bd5868", + "seq": 113, + "time": 1791828952.1878028 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "1", + "seq": 114, + "time": 1791828952.191465 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Remote end closed connection without response", + "seq": 115, + "time": 1791828953.570592 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 116, + "time": 1791828953.590626 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image", + "seq": 117, + "time": 1791829010.0203352 + }, + { + "intent": "", + "kind": "body_epoch_changed", + "outcome": "1 -> 2", + "seq": 118, + "time": 1791829010.021775 + }, + { + "intent": "", + "kind": "fault_armed", + "outcome": "drop_after", + "seq": 119, + "time": 1791829019.593674 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 120, + "time": 1791829019.920613 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 121, + "time": 1791829019.99926 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-40c6a8a1f1a04ea7bec902767b57387a", + "seq": 122, + "time": 1791829020.389618 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "2", + "seq": 123, + "time": 1791829020.392122 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 124, + "time": 1791829028.703949 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-9f8d9402f1d74504b579f39b9c793576", + "seq": 125, + "time": 1791829028.798069 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 126, + "time": 1791829028.864546 + }, + { + "intent": "", + "kind": "halt", + "outcome": "reply is uncertain; reconcile exact command without resending", + "seq": 127, + "time": 1791829029.1331468 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Remote end closed connection without response", + "seq": 128, + "time": 1791829042.14413 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Body restarted from boot 2 to 3; check pending receipts and explicitly Resume for a fresh image", + "seq": 129, + "time": 1791829080.500874 + }, + { + "intent": "", + "kind": "body_epoch_changed", + "outcome": "2 -> 3", + "seq": 130, + "time": 1791829080.502091 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "fault": null, + "reason": "Body restarted from boot 2 to 3; check pending receipts and explicitly Resume for a fresh image", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 10, + "image_url": "/api/frame?generation=10&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 2, + "disturbance_test": false, + "error": "Body restarted from boot 2 to 3; check pending receipts and explicitly Resume for a fresh image", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Push the block right so its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": "dispatch", + "readiness": { + "ready": false, + "reason": "Body restarted from boot 2 to 3; check pending receipts and explicitly Resume for a fresh image" + }, + "recovery": { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "operation": "dispatch", + "reason": "Body restarted from boot 2 to 3; check pending receipts and explicitly Resume for a fresh image", + "state": "uncertain" + }, + "runner_status": "blocked", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 16, + "input_tokens": 185456, + "output_tokens": 2222, + "reported_calls": 14, + "token_usage_complete": false + } + }, + "time": 1791829080.5281138 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000008-before.json b/jevdual/results/workbench-restarts-20261012/snapshots/000008-before.json new file mode 100644 index 0000000..bf6647c --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000008-before.json @@ -0,0 +1,884 @@ +{ + "body_identity": null, + "body_identity_error": "[Errno 61] Connection refused", + "body_state": null, + "body_state_error": "[Errno 61] Connection refused", + "client": { + "commands": { + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-40c6a8a1f1a04ea7bec902767b57387a": { + "operation": "observe", + "request_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-9f8d9402f1d74504b579f39b9c793576": { + "operation": "propose", + "request_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-cf898dd6e56a4d8bb0a5894371f9ba81": { + "operation": "dispatch", + "request_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "send_count": 1, + "state": "unknown" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 2, + "lease_id": "8acd97f5a9dc48b583d6d3097f60b1ba" + }, + "pending_command_ids": [ + "command-cf898dd6e56a4d8bb0a5894371f9ba81" + ] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 10, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-28dc527b5ab349cab70e9bea9dbea92a-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "paused", + "sequence": 128, + "stage": { + "arguments": { + "proposal_id": "proposal-2fc20beaf42745488b7a16af3afeaf6d" + }, + "before_commands": [ + "command-015d5d03d0624f14ba43d889871c45ee", + "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "command-0e35d66b16a64168b11d255a1d871e71", + "command-1936c404000d4b55a094c49a2fd9eeb3", + "command-1e2386315d6c4c7692405dac7dfa7bd1", + "command-210150e3ac9f45adae24e89f22a66286", + "command-24230a0f96bc4e84a84f720b1c974054", + "command-248b9798493e4a43a51259929e135e29", + "command-2a6e74bdbe424b3caa700dc047365a1c", + "command-2d0b436b61124502a9d8558816bda68d", + "command-3083d955014b4e5282809a47046c53db", + "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "command-38a300b989a649fd9ee243704cdc65a9", + "command-40c6a8a1f1a04ea7bec902767b57387a", + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "command-553be6e82b274944b5e6ea9e2cd3902e", + "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "command-5ced22700795486fa68a50fcda4767b8", + "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "command-7661dbdae1c34bd797ca17b3b5321a5e", + "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "command-84c016d3c2564ecea6025edaea7d23e7", + "command-8c948c9df6074ee5969ef8b19a3eaddb", + "command-933c11248d6a48079ead24676a2df7fb", + "command-9dd2a0c9603f4667956ec976e822b74a", + "command-9f8d9402f1d74504b579f39b9c793576", + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "command-ab4679dd21e14ce08f70b1ef63bd5868", + "command-b17181d5918a492a916e0e3c5a2f3a11", + "command-b182534626d34766a52d5e11d48239e7", + "command-bdc662ab7f4645d79c02f84921f3c9f6", + "command-c80c18cc647b45fe8e9faf2fa890283c", + "command-c8be0caf76504410a68a595296d56bd3", + "command-d9922eefd392420b96bf0a62d7eea982", + "command-df199bef22b442168d0a42242c00c5c4", + "command-e19f5d23dd944e40b806e930f7d44b35", + "command-e1af2fbe5a254692bf212769ddfea045", + "command-e897a3cba83b4d83b460a556be5e459b", + "command-ede04073e3654f4fa17f0a0056db9004", + "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "command-f008b852a29348218bc57e931887b963", + "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "command-f4c202be91064d3e8f4c929f1175450e", + "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "command-fda8dcacccc940c493511804050cc0ec" + ], + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "context": { + "action": { + "action": "move", + "intent": "Push the block right so its center reaches the measurement region.", + "target_x": 0.025, + "target_y": 0.0 + }, + "call_dir": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/calls/c922a26d-9121-4d7e-82e1-7b61b0e42161-02", + "decision_epoch": 7, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161" + }, + "control_epoch": 7, + "operation": "dispatch" + }, + "usage": { + "calls": 16, + "input_tokens": 185456, + "output_tokens": 2222, + "reported_calls": 14 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + }, + { + "command_id": "command-40c6a8a1f1a04ea7bec902767b57387a", + "payload_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "sequence": 480 + }, + { + "command_id": "command-9f8d9402f1d74504b579f39b9c793576", + "payload_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "sequence": 492 + }, + { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "payload_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "sequence": 500 + } + ], + "processes": { + "body": null, + "workbench": 39967 + }, + "public": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "activity": [ + { + "intent": "Restart inspection 01", + "kind": "inference", + "outcome": "14", + "seq": 105, + "time": 1791828938.608861 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 106, + "time": 1791828950.833822 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "propose: command-015d5d03d0624f14ba43d889871c45ee", + "seq": 107, + "time": 1791828950.9307368 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 108, + "time": 1791828950.97887 + }, + { + "intent": "Restart inspection 01", + "kind": "rpc_applied", + "outcome": "dispatch: command-210150e3ac9f45adae24e89f22a66286", + "seq": 109, + "time": 1791828951.468124 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "start_job", + "seq": 110, + "time": 1791828951.5941691 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "start_job: command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "seq": 111, + "time": 1791828951.745876 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 112, + "time": 1791828951.8522959 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-ab4679dd21e14ce08f70b1ef63bd5868", + "seq": 113, + "time": 1791828952.1878028 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "1", + "seq": 114, + "time": 1791828952.191465 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Remote end closed connection without response", + "seq": 115, + "time": 1791828953.570592 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 116, + "time": 1791828953.590626 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image", + "seq": 117, + "time": 1791829010.0203352 + }, + { + "intent": "", + "kind": "body_epoch_changed", + "outcome": "1 -> 2", + "seq": 118, + "time": 1791829010.021775 + }, + { + "intent": "", + "kind": "fault_armed", + "outcome": "drop_after", + "seq": 119, + "time": 1791829019.593674 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 120, + "time": 1791829019.920613 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 121, + "time": 1791829019.99926 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-40c6a8a1f1a04ea7bec902767b57387a", + "seq": 122, + "time": 1791829020.389618 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "2", + "seq": 123, + "time": 1791829020.392122 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 124, + "time": 1791829028.703949 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-9f8d9402f1d74504b579f39b9c793576", + "seq": 125, + "time": 1791829028.798069 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 126, + "time": 1791829028.864546 + }, + { + "intent": "", + "kind": "halt", + "outcome": "reply is uncertain; reconcile exact command without resending", + "seq": 127, + "time": 1791829029.1331468 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Remote end closed connection without response", + "seq": 128, + "time": 1791829042.14413 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 2, + "fault": null, + "reason": "Remote end closed connection without response", + "state": "unavailable" + }, + "current_frame": { + "available": true, + "generation": 10, + "image_url": "/api/frame?generation=10&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 2, + "disturbance_test": false, + "error": "Remote end closed connection without response", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Push the block right so its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "paused", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": "dispatch", + "readiness": { + "ready": false, + "reason": "Remote end closed connection without response" + }, + "recovery": { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "paused", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 16, + "input_tokens": 185456, + "output_tokens": 2222, + "reported_calls": 14, + "token_usage_complete": false + } + }, + "time": 1791829079.486072 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000009-after.json b/jevdual/results/workbench-restarts-20261012/snapshots/000009-after.json new file mode 100644 index 0000000..b549285 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000009-after.json @@ -0,0 +1,1385 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": null, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 20, + "jobs": { + "20eb6586-e73a-4db4-aaac-db3e5d537329": { + "completed_generation": 10, + "completed_native_time_s": 21.679999999998863, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement_operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 2, + "image_sha256": "bdee3bf2ea5af18d557cb6560b766242a409cd25ac852273ce2724825f12decb", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.46799999999962, + "operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "source_kind": "mujoco_simulation", + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9", + "version": 1, + "worker_pid": 51928 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "reset_started_generation": 2, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "c922a26d-9121-4d7e-82e1-7b61b0e42161": { + "completed_generation": 20, + "completed_native_time_s": 42.630000000006135, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "measurement_operation_id": "agent-12d303b3be23401d9cdd1b1296f3c87a", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 12, + "image_sha256": "60d8074b8c92a02b009c072c57bc1340098311df51c08f9d9d02d41f596c342e", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 26.349999999996275, + "operation_id": "agent-12d303b3be23401d9cdd1b1296f3c87a", + "source_kind": "mujoco_simulation", + "state_sha256": "7ced546541611d509086f34fc585c77771e272c65f3bbb518c94fb1942dbcd16", + "version": 1, + "worker_pid": 77998 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 20, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "kind": "finish_reset", + "native_time_s": 42.630000000006135, + "operation_id": "agent-7acee30a3cb442d9a3a2b3a9bfec10ed", + "pusher_home_verified": true, + "reset_contact_samples": 3314, + "reset_native_steps": 8140, + "state_sha256": "02c49f9f03f16f8de552b4b4ce57b6d78c85e291fc3dbf1b6acb0ce4b7cd638b" + }, + "reset_started_generation": 12, + "started_generation": 10, + "started_native_time_s": 21.679999999998863, + "target_zone": { + "x_max": 0.115, + "x_min": 0.045, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 42.630000000006135, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 3, + "expires_in_s": 0, + "lease_id": "64fd21cec5f8404abdfe09dbbecfe4f8" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-009165e2aa1d4b6d8c000766c3967914": { + "operation": "propose", + "request_sha256": "1206f95b1d06e80eae8ca4baf0ce26951be111339dc3e2f4d9ebfa1dbe410eab", + "send_count": 1, + "state": "completed" + }, + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-01793f114b2c4d3a8f23b17ebc2b8f1f": { + "operation": "propose", + "request_sha256": "6bf2d4795f61435907607137db5beb6f2607768011e90fb1b8b00082d8c62274", + "send_count": 1, + "state": "completed" + }, + "command-07d3f286ef6846ba90c196ad79a88bff": { + "operation": "dispatch", + "request_sha256": "956cc6d0e3e864da997877f551aa587cb8c18ef23887fa852f68d322858a1934", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0c04ca9d775443a9b69a78f25f183e7d": { + "operation": "dispatch", + "request_sha256": "e9dce120ea68457626fe8f895b8003547049335bf71398de3a7d45d50475ff93", + "send_count": 1, + "state": "completed" + }, + "command-0d1afb96c11546759d80d26095199c48": { + "operation": "observe", + "request_sha256": "df0a0ddfda89951587e1c2bbae4062b35d48d528b9ff565aad1ae070312bdae2", + "send_count": 1, + "state": "completed" + }, + "command-0d48c82d84d340c6b1d28b76f670dd29": { + "operation": "propose", + "request_sha256": "4335b774435a6b013d28c8327d5fc7e208576eed4d6796b3b671fd41dbf58ba3", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-0ee1728417374a16938ab09aa59e64c0": { + "operation": "propose", + "request_sha256": "32bfef5a823099dab6fc5291582f6faaa0ac10a840ac9e94c38946dab92ae0ab", + "send_count": 1, + "state": "completed" + }, + "command-12c51cb647bc4d01badb3bebf7cb0446": { + "operation": "observe", + "request_sha256": "45dee3c4b5394ccc300f72ba73630f476ddcd992912bb5a1da838e264bf53343", + "send_count": 1, + "state": "completed" + }, + "command-16ac2d834cc949e980dbdc7b3bf60af7": { + "operation": "propose", + "request_sha256": "e750a765511c25e30bf1a54400fae352577c98a13af91dc2bbded25a2b60e0b6", + "send_count": 1, + "state": "completed" + }, + "command-16c006b2256a4000b45fc63cd2d334ff": { + "operation": "dispatch", + "request_sha256": "8f291e7bbe50782c675defef8bc2c5636c22ce4c9e383802274acca154c03a31", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1af4c5bd1341495093201a5821d1dec9": { + "operation": "observe", + "request_sha256": "217b8ec12db8b35fbe968b343144566338207ce3b7d07e9ea8ad8fbf766845a9", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-382a79f756314a4ea88e1836344549d2": { + "operation": "dispatch", + "request_sha256": "3dda2ab314e9003e2f4f2126c449a2e634fdb05cc99050e52a101481650ae9a2", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-38b6786c82b04b3d92ecde7200a19450": { + "operation": "propose", + "request_sha256": "0eedff7111f86a7c96f02b76328e26f9252832fcd0b32fdcfab09fd639cf62ac", + "send_count": 1, + "state": "completed" + }, + "command-40c6a8a1f1a04ea7bec902767b57387a": { + "operation": "observe", + "request_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-4c3705f8d7cc48a4b45029d078357250": { + "operation": "observe", + "request_sha256": "6670065bd1fd29ab4a84a51cb0a31a497929cb54d24b94909462d946768c2d6d", + "send_count": 1, + "state": "completed" + }, + "command-51f66bfa90ab421bb24242caa6d054fd": { + "operation": "observe", + "request_sha256": "327a292c61ede952cf37c3157827e4fa1d919d5e90b244f18010ef464b558f42", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-604436650640419d9ce6c551ac3e3407": { + "operation": "observe", + "request_sha256": "98c01becbe239e62be2fe587554aa3ea29f2273a052c5359e1e5a85fb476362f", + "send_count": 1, + "state": "completed" + }, + "command-69a56ced2e8c49ce9e9f214c57023381": { + "operation": "propose", + "request_sha256": "9cfc65fc7994db66a7ebebdd994fba2dad0a4d54475862539cd87586f2779dfa", + "send_count": 1, + "state": "completed" + }, + "command-6e6b99559d5749eab04cbf8f42b46ae2": { + "operation": "observe", + "request_sha256": "3a2970680dd2675a75e8bbf91affd223084373d5789d6b873b4fe8bdab7dd5aa", + "send_count": 1, + "state": "completed" + }, + "command-74dc57912fda4c3e96f6845cdffbb045": { + "operation": "observe", + "request_sha256": "aed94b91da1d8ac4b41ac1ad21b488bc9c43e6db4066e352dc6bbacceee6b907", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7b94f03fcd7449ec97ca592813c20693": { + "operation": "observe", + "request_sha256": "e9adecd7c66f60c892d0bf60a14266e115b7948b8cbac2a26aff6e4fb526e615", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-90b2509eee524747a3397627f2c51643": { + "operation": "propose", + "request_sha256": "ba39f43b6c1947a04304c95045272d8cff2c0f70c14831e48ef8b77ce03d585b", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-93b6bfdc895349d2a07cfed89231411d": { + "operation": "propose", + "request_sha256": "a1e20276d19935994fb87711dc6ad10ef2a0f5423e274a3c9ca189348e861573", + "send_count": 1, + "state": "completed" + }, + "command-95a7bae7c4f8479b81bae1ea55e7597f": { + "operation": "observe", + "request_sha256": "acc6a031281992af1b58960f9038dc6cab3e67e435b497bfdaaea926b4c47620", + "send_count": 1, + "state": "completed" + }, + "command-96ff5828100a40b9945b5960aeb7e5dd": { + "operation": "dispatch", + "request_sha256": "80aa2ffe12f32c32c279d78eb3775b4311d8b83677f816849f91ae636fec87d0", + "send_count": 1, + "state": "completed" + }, + "command-9841ade4a0ea46a2b43353bf2b951a7c": { + "operation": "propose", + "request_sha256": "7b732e90c18d4e428c43c95403e2afeca93754f75cc963d94ba01cdec8224561", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-9f8d9402f1d74504b579f39b9c793576": { + "operation": "propose", + "request_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-acd7ec8de3eb4a548e2e070898a0318f": { + "operation": "dispatch", + "request_sha256": "e963b00f5df17ccc10c5a050cac94cd1515f23b7c9e38ebfd7b97285aa6fb0cf", + "send_count": 1, + "state": "completed" + }, + "command-ad464b677e044b43ae8f9dd725331fce": { + "operation": "observe", + "request_sha256": "2a139a6cd850620070ff777a29a2acbfb326b69d260036bb5847aefd6a5c4c18", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c5861bc07c0d4b6a992850fe1ab3c769": { + "operation": "dispatch", + "request_sha256": "2747a5c1d597b72581a2ffef5303fd6f137acdae3c6243750c87309aedb74de2", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-cd90dd204ff74139880f3846418a41b7": { + "operation": "dispatch", + "request_sha256": "dc58e74652094316cd08bb4ed5a2b9e9ba9a1793326b9918539c6365f1537e3b", + "send_count": 1, + "state": "completed" + }, + "command-cf898dd6e56a4d8bb0a5894371f9ba81": { + "operation": "dispatch", + "request_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "send_count": 1, + "state": "completed" + }, + "command-cf90ff6221c640f9ac99b5ceb8a91754": { + "operation": "dispatch", + "request_sha256": "9109f545b48718b5291c081e098f1f815b521fae16217993ee9985e898ffc043", + "send_count": 1, + "state": "completed" + }, + "command-cfead433cabe4303b15fd2ca83ee8899": { + "operation": "propose", + "request_sha256": "504d2c9975111bb32e985cc71034239f5d62d10929273eb2ec94d6b5b59534dd", + "send_count": 1, + "state": "completed" + }, + "command-d3e05b3b869542a085afeba4414811ba": { + "operation": "dispatch", + "request_sha256": "cb0758e27127d99fbc0a75c6dc7cfc2d61c2bdf92925e51129e916f3637fee40", + "send_count": 1, + "state": "completed" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e7a47417ff124ebc915329783ad7c5bb": { + "operation": "dispatch", + "request_sha256": "07cb08a35c3378b556b2d9fb19d575ea53e577e4dca56624bf3e5e49e868fe68", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-eb16ab3154eb40f78f021869ebb485b3": { + "operation": "propose", + "request_sha256": "bbd21b24923ad60e0ba472125e2544efe9ab758d7887e2444bd293bd0f5e25b6", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fb77cbd4d30f4827bdef78ff67cabe2b": { + "operation": "dispatch", + "request_sha256": "286b425e934eb0fa16526805b7ef5fe3431d0d172fdcf02fd4cc9ccb9d89ef5f", + "send_count": 1, + "state": "completed" + }, + "command-fca0d0500040494396aabdb153197133": { + "operation": "observe", + "request_sha256": "36f0a50bf16631b346b7669d99fb49c44bf15ade5d62d3a84e9bfaf016fd1d1f", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + }, + "command-fe049e3ca1ce489e9e7cc0e25188a245": { + "operation": "observe", + "request_sha256": "20563be149da9ea5513d1f967925a42fb19aef1a112f38923e15d34a79907c68", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 3, + "lease_id": "64fd21cec5f8404abdfe09dbbecfe4f8" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 20, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-021548ca7f144b57a98d5dfa7df72f15-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "running", + "sequence": 227, + "stage": null, + "usage": { + "calls": 29, + "input_tokens": 343310, + "output_tokens": 3963, + "reported_calls": 26 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + }, + { + "command_id": "command-40c6a8a1f1a04ea7bec902767b57387a", + "payload_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "sequence": 480 + }, + { + "command_id": "command-9f8d9402f1d74504b579f39b9c793576", + "payload_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "sequence": 492 + }, + { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "payload_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "sequence": 500 + }, + { + "command_id": "command-604436650640419d9ce6c551ac3e3407", + "payload_sha256": "98c01becbe239e62be2fe587554aa3ea29f2273a052c5359e1e5a85fb476362f", + "sequence": 550 + }, + { + "command_id": "command-01793f114b2c4d3a8f23b17ebc2b8f1f", + "payload_sha256": "6bf2d4795f61435907607137db5beb6f2607768011e90fb1b8b00082d8c62274", + "sequence": 562 + }, + { + "command_id": "command-d3e05b3b869542a085afeba4414811ba", + "payload_sha256": "cb0758e27127d99fbc0a75c6dc7cfc2d61c2bdf92925e51129e916f3637fee40", + "sequence": 570 + }, + { + "command_id": "command-6e6b99559d5749eab04cbf8f42b46ae2", + "payload_sha256": "3a2970680dd2675a75e8bbf91affd223084373d5789d6b873b4fe8bdab7dd5aa", + "sequence": 578 + }, + { + "command_id": "command-90b2509eee524747a3397627f2c51643", + "payload_sha256": "ba39f43b6c1947a04304c95045272d8cff2c0f70c14831e48ef8b77ce03d585b", + "sequence": 590 + }, + { + "command_id": "command-0c04ca9d775443a9b69a78f25f183e7d", + "payload_sha256": "e9dce120ea68457626fe8f895b8003547049335bf71398de3a7d45d50475ff93", + "sequence": 598 + }, + { + "command_id": "command-7b94f03fcd7449ec97ca592813c20693", + "payload_sha256": "e9adecd7c66f60c892d0bf60a14266e115b7948b8cbac2a26aff6e4fb526e615", + "sequence": 606 + }, + { + "command_id": "command-eb16ab3154eb40f78f021869ebb485b3", + "payload_sha256": "bbd21b24923ad60e0ba472125e2544efe9ab758d7887e2444bd293bd0f5e25b6", + "sequence": 618 + }, + { + "command_id": "command-acd7ec8de3eb4a548e2e070898a0318f", + "payload_sha256": "e963b00f5df17ccc10c5a050cac94cd1515f23b7c9e38ebfd7b97285aa6fb0cf", + "sequence": 626 + }, + { + "command_id": "command-4c3705f8d7cc48a4b45029d078357250", + "payload_sha256": "6670065bd1fd29ab4a84a51cb0a31a497929cb54d24b94909462d946768c2d6d", + "sequence": 634 + }, + { + "command_id": "command-0ee1728417374a16938ab09aa59e64c0", + "payload_sha256": "32bfef5a823099dab6fc5291582f6faaa0ac10a840ac9e94c38946dab92ae0ab", + "sequence": 646 + }, + { + "command_id": "command-07d3f286ef6846ba90c196ad79a88bff", + "payload_sha256": "956cc6d0e3e864da997877f551aa587cb8c18ef23887fa852f68d322858a1934", + "sequence": 654 + }, + { + "command_id": "command-74dc57912fda4c3e96f6845cdffbb045", + "payload_sha256": "aed94b91da1d8ac4b41ac1ad21b488bc9c43e6db4066e352dc6bbacceee6b907", + "sequence": 662 + }, + { + "command_id": "command-009165e2aa1d4b6d8c000766c3967914", + "payload_sha256": "1206f95b1d06e80eae8ca4baf0ce26951be111339dc3e2f4d9ebfa1dbe410eab", + "sequence": 674 + }, + { + "command_id": "command-382a79f756314a4ea88e1836344549d2", + "payload_sha256": "3dda2ab314e9003e2f4f2126c449a2e634fdb05cc99050e52a101481650ae9a2", + "sequence": 682 + }, + { + "command_id": "command-0d1afb96c11546759d80d26095199c48", + "payload_sha256": "df0a0ddfda89951587e1c2bbae4062b35d48d528b9ff565aad1ae070312bdae2", + "sequence": 690 + }, + { + "command_id": "command-0d48c82d84d340c6b1d28b76f670dd29", + "payload_sha256": "4335b774435a6b013d28c8327d5fc7e208576eed4d6796b3b671fd41dbf58ba3", + "sequence": 702 + }, + { + "command_id": "command-16c006b2256a4000b45fc63cd2d334ff", + "payload_sha256": "8f291e7bbe50782c675defef8bc2c5636c22ce4c9e383802274acca154c03a31", + "sequence": 710 + }, + { + "command_id": "command-ad464b677e044b43ae8f9dd725331fce", + "payload_sha256": "2a139a6cd850620070ff777a29a2acbfb326b69d260036bb5847aefd6a5c4c18", + "sequence": 718 + }, + { + "command_id": "command-16ac2d834cc949e980dbdc7b3bf60af7", + "payload_sha256": "e750a765511c25e30bf1a54400fae352577c98a13af91dc2bbded25a2b60e0b6", + "sequence": 730 + }, + { + "command_id": "command-fb77cbd4d30f4827bdef78ff67cabe2b", + "payload_sha256": "286b425e934eb0fa16526805b7ef5fe3431d0d172fdcf02fd4cc9ccb9d89ef5f", + "sequence": 738 + }, + { + "command_id": "command-1af4c5bd1341495093201a5821d1dec9", + "payload_sha256": "217b8ec12db8b35fbe968b343144566338207ce3b7d07e9ea8ad8fbf766845a9", + "sequence": 746 + }, + { + "command_id": "command-93b6bfdc895349d2a07cfed89231411d", + "payload_sha256": "a1e20276d19935994fb87711dc6ad10ef2a0f5423e274a3c9ca189348e861573", + "sequence": 758 + }, + { + "command_id": "command-96ff5828100a40b9945b5960aeb7e5dd", + "payload_sha256": "80aa2ffe12f32c32c279d78eb3775b4311d8b83677f816849f91ae636fec87d0", + "sequence": 766 + }, + { + "command_id": "command-fca0d0500040494396aabdb153197133", + "payload_sha256": "36f0a50bf16631b346b7669d99fb49c44bf15ade5d62d3a84e9bfaf016fd1d1f", + "sequence": 774 + }, + { + "command_id": "command-69a56ced2e8c49ce9e9f214c57023381", + "payload_sha256": "9cfc65fc7994db66a7ebebdd994fba2dad0a4d54475862539cd87586f2779dfa", + "sequence": 786 + }, + { + "command_id": "command-cf90ff6221c640f9ac99b5ceb8a91754", + "payload_sha256": "9109f545b48718b5291c081e098f1f815b521fae16217993ee9985e898ffc043", + "sequence": 794 + }, + { + "command_id": "command-51f66bfa90ab421bb24242caa6d054fd", + "payload_sha256": "327a292c61ede952cf37c3157827e4fa1d919d5e90b244f18010ef464b558f42", + "sequence": 802 + }, + { + "command_id": "command-38b6786c82b04b3d92ecde7200a19450", + "payload_sha256": "0eedff7111f86a7c96f02b76328e26f9252832fcd0b32fdcfab09fd639cf62ac", + "sequence": 814 + }, + { + "command_id": "command-c5861bc07c0d4b6a992850fe1ab3c769", + "payload_sha256": "2747a5c1d597b72581a2ffef5303fd6f137acdae3c6243750c87309aedb74de2", + "sequence": 822 + }, + { + "command_id": "command-fe049e3ca1ce489e9e7cc0e25188a245", + "payload_sha256": "20563be149da9ea5513d1f967925a42fb19aef1a112f38923e15d34a79907c68", + "sequence": 830 + }, + { + "command_id": "command-cfead433cabe4303b15fd2ca83ee8899", + "payload_sha256": "504d2c9975111bb32e985cc71034239f5d62d10929273eb2ec94d6b5b59534dd", + "sequence": 842 + }, + { + "command_id": "command-cd90dd204ff74139880f3846418a41b7", + "payload_sha256": "dc58e74652094316cd08bb4ed5a2b9e9ba9a1793326b9918539c6365f1537e3b", + "sequence": 850 + }, + { + "command_id": "command-95a7bae7c4f8479b81bae1ea55e7597f", + "payload_sha256": "acc6a031281992af1b58960f9038dc6cab3e67e435b497bfdaaea926b4c47620", + "sequence": 858 + }, + { + "command_id": "command-12c51cb647bc4d01badb3bebf7cb0446", + "payload_sha256": "45dee3c4b5394ccc300f72ba73630f476ddcd992912bb5a1da838e264bf53343", + "sequence": 871 + }, + { + "command_id": "command-9841ade4a0ea46a2b43353bf2b951a7c", + "payload_sha256": "7b732e90c18d4e428c43c95403e2afeca93754f75cc963d94ba01cdec8224561", + "sequence": 883 + }, + { + "command_id": "command-e7a47417ff124ebc915329783ad7c5bb", + "payload_sha256": "07cb08a35c3378b556b2d9fb19d575ea53e577e4dca56624bf3e5e49e868fe68", + "sequence": 891 + } + ], + "processes": { + "body": 74921, + "workbench": 39967 + }, + "public": { + "active_job_id": null, + "activity": [ + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 204, + "time": 1791829189.127323 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-fe049e3ca1ce489e9e7cc0e25188a245", + "seq": 205, + "time": 1791829189.480195 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "13", + "seq": 206, + "time": 1791829189.4844081 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 207, + "time": 1791829196.4102259 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-cfead433cabe4303b15fd2ca83ee8899", + "seq": 208, + "time": 1791829196.602696 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 209, + "time": 1791829196.697315 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "dispatch: command-cd90dd204ff74139880f3846418a41b7", + "seq": 210, + "time": 1791829197.11283 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 211, + "time": 1791829197.23605 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-95a7bae7c4f8479b81bae1ea55e7597f", + "seq": 212, + "time": 1791829197.9852512 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "14", + "seq": 213, + "time": 1791829197.991858 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 214, + "time": 1791829202.567657 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 215, + "time": 1791829202.618878 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 216, + "time": 1791829224.8969312 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 217, + "time": 1791829230.2752252 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 218, + "time": 1791829234.4515479 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 219, + "time": 1791829242.3595982 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 220, + "time": 1791829285.4561422 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 221, + "time": 1791829285.550546 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-12c51cb647bc4d01badb3bebf7cb0446", + "seq": 222, + "time": 1791829286.054108 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "15", + "seq": 223, + "time": 1791829286.056795 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 224, + "time": 1791829296.4025989 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-9841ade4a0ea46a2b43353bf2b951a7c", + "seq": 225, + "time": 1791829296.548447 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 226, + "time": 1791829296.6237051 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "dispatch: command-e7a47417ff124ebc915329783ad7c5bb", + "seq": 227, + "time": 1791829297.049696 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 20, + "image_url": "/api/frame?generation=20&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 15, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Finish reset with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 20, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "kind": "finish_reset", + "native_time_s": 42.630000000006135, + "operation_id": "agent-7acee30a3cb442d9a3a2b3a9bfec10ed", + "pusher_home_verified": true, + "reset_contact_samples": 3314, + "reset_native_steps": 8140, + "state_sha256": "02c49f9f03f16f8de552b4b4ce57b6d78c85e291fc3dbf1b6acb0ce4b7cd638b" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": null, + "readiness": { + "ready": true, + "reason": "Resumed; next decision receives a fresh TCP image" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 29, + "input_tokens": 343310, + "output_tokens": 3963, + "reported_calls": 26, + "token_usage_complete": false + } + }, + "time": 1791829365.090233 +} diff --git a/jevdual/results/workbench-restarts-20261012/snapshots/000009-before.json b/jevdual/results/workbench-restarts-20261012/snapshots/000009-before.json new file mode 100644 index 0000000..6ff4761 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/snapshots/000009-before.json @@ -0,0 +1,1385 @@ +{ + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "body_state": { + "bench": { + "active_job": null, + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "diagnostic_enabled": true, + "generation": 20, + "jobs": { + "20eb6586-e73a-4db4-aaac-db3e5d537329": { + "completed_generation": 10, + "completed_native_time_s": 21.679999999998863, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement_operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 2, + "image_sha256": "bdee3bf2ea5af18d557cb6560b766242a409cd25ac852273ce2724825f12decb", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 5.46799999999962, + "operation_id": "agent-8831a976a3b7434db04d4fbcbe36a532", + "source_kind": "mujoco_simulation", + "state_sha256": "7ed25a4cf203dc0ebbb58dc4acdaec8b9dd83be0ccd7d6be0d34c6c74ff8cdd9", + "version": 1, + "worker_pid": 51928 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "reset_started_generation": 2, + "started_generation": 0, + "started_native_time_s": 1.0000000000000007, + "target_zone": { + "x_max": 0.105, + "x_min": 0.035, + "y_max": 0.025, + "y_min": -0.025 + } + }, + "c922a26d-9121-4d7e-82e1-7b61b0e42161": { + "completed_generation": 20, + "completed_native_time_s": 42.630000000006135, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "measurement_operation_id": "agent-12d303b3be23401d9cdd1b1296f3c87a", + "measurement_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "generation": 12, + "image_sha256": "60d8074b8c92a02b009c072c57bc1340098311df51c08f9d9d02d41f596c342e", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 26.349999999996275, + "operation_id": "agent-12d303b3be23401d9cdd1b1296f3c87a", + "source_kind": "mujoco_simulation", + "state_sha256": "7ced546541611d509086f34fc585c77771e272c65f3bbb518c94fb1942dbcd16", + "version": 1, + "worker_pid": 77998 + }, + "moves": 10, + "phase": "completed", + "reset_receipt": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 20, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "kind": "finish_reset", + "native_time_s": 42.630000000006135, + "operation_id": "agent-7acee30a3cb442d9a3a2b3a9bfec10ed", + "pusher_home_verified": true, + "reset_contact_samples": 3314, + "reset_native_steps": 8140, + "state_sha256": "02c49f9f03f16f8de552b4b4ce57b6d78c85e291fc3dbf1b6acb0ce4b7cd638b" + }, + "reset_started_generation": 12, + "started_generation": 10, + "started_native_time_s": 21.679999999998863, + "target_zone": { + "x_max": 0.115, + "x_min": 0.045, + "y_max": 0.025, + "y_min": -0.025 + } + } + }, + "native_time_s": 42.630000000006135, + "source_fingerprints": { + "bench_sha256": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "capture_utility_sha256": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "case_validator_sha256": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "controller_sha256": "4b0c7f3e5f069111e7282b85f073ddc2bcd3efba8aaf47d228aad9a3213edd7f", + "implementation_sha256": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2", + "measurement_sha256": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "model_sha256": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "mujoco_version": "3.15.0", + "protocol_sha256": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "state_spec": 16383, + "vision_sha256": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961" + }, + "source_kind": "mujoco_simulation", + "state": "ready", + "unresolved_effect": null, + "version": 1 + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "epoch": 3, + "expires_in_s": 0, + "lease_id": "64fd21cec5f8404abdfe09dbbecfe4f8" + }, + "state": "ready", + "unresolved_commands": [] + }, + "client": { + "commands": { + "command-009165e2aa1d4b6d8c000766c3967914": { + "operation": "propose", + "request_sha256": "1206f95b1d06e80eae8ca4baf0ce26951be111339dc3e2f4d9ebfa1dbe410eab", + "send_count": 1, + "state": "completed" + }, + "command-015d5d03d0624f14ba43d889871c45ee": { + "operation": "propose", + "request_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "send_count": 1, + "state": "completed" + }, + "command-01793f114b2c4d3a8f23b17ebc2b8f1f": { + "operation": "propose", + "request_sha256": "6bf2d4795f61435907607137db5beb6f2607768011e90fb1b8b00082d8c62274", + "send_count": 1, + "state": "completed" + }, + "command-07d3f286ef6846ba90c196ad79a88bff": { + "operation": "dispatch", + "request_sha256": "956cc6d0e3e864da997877f551aa587cb8c18ef23887fa852f68d322858a1934", + "send_count": 1, + "state": "completed" + }, + "command-097e6bec1ce24ef2bc8f37c40f80d98f": { + "operation": "dispatch", + "request_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "send_count": 1, + "state": "completed" + }, + "command-0c04ca9d775443a9b69a78f25f183e7d": { + "operation": "dispatch", + "request_sha256": "e9dce120ea68457626fe8f895b8003547049335bf71398de3a7d45d50475ff93", + "send_count": 1, + "state": "completed" + }, + "command-0d1afb96c11546759d80d26095199c48": { + "operation": "observe", + "request_sha256": "df0a0ddfda89951587e1c2bbae4062b35d48d528b9ff565aad1ae070312bdae2", + "send_count": 1, + "state": "completed" + }, + "command-0d48c82d84d340c6b1d28b76f670dd29": { + "operation": "propose", + "request_sha256": "4335b774435a6b013d28c8327d5fc7e208576eed4d6796b3b671fd41dbf58ba3", + "send_count": 1, + "state": "completed" + }, + "command-0e35d66b16a64168b11d255a1d871e71": { + "operation": "observe", + "request_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "send_count": 1, + "state": "completed" + }, + "command-0ee1728417374a16938ab09aa59e64c0": { + "operation": "propose", + "request_sha256": "32bfef5a823099dab6fc5291582f6faaa0ac10a840ac9e94c38946dab92ae0ab", + "send_count": 1, + "state": "completed" + }, + "command-12c51cb647bc4d01badb3bebf7cb0446": { + "operation": "observe", + "request_sha256": "45dee3c4b5394ccc300f72ba73630f476ddcd992912bb5a1da838e264bf53343", + "send_count": 1, + "state": "completed" + }, + "command-16ac2d834cc949e980dbdc7b3bf60af7": { + "operation": "propose", + "request_sha256": "e750a765511c25e30bf1a54400fae352577c98a13af91dc2bbded25a2b60e0b6", + "send_count": 1, + "state": "completed" + }, + "command-16c006b2256a4000b45fc63cd2d334ff": { + "operation": "dispatch", + "request_sha256": "8f291e7bbe50782c675defef8bc2c5636c22ce4c9e383802274acca154c03a31", + "send_count": 1, + "state": "completed" + }, + "command-1936c404000d4b55a094c49a2fd9eeb3": { + "operation": "observe", + "request_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "send_count": 1, + "state": "completed" + }, + "command-1af4c5bd1341495093201a5821d1dec9": { + "operation": "observe", + "request_sha256": "217b8ec12db8b35fbe968b343144566338207ce3b7d07e9ea8ad8fbf766845a9", + "send_count": 1, + "state": "completed" + }, + "command-1e2386315d6c4c7692405dac7dfa7bd1": { + "operation": "propose", + "request_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "send_count": 1, + "state": "completed" + }, + "command-210150e3ac9f45adae24e89f22a66286": { + "operation": "dispatch", + "request_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "send_count": 1, + "state": "completed" + }, + "command-24230a0f96bc4e84a84f720b1c974054": { + "operation": "dispatch", + "request_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "send_count": 1, + "state": "completed" + }, + "command-248b9798493e4a43a51259929e135e29": { + "operation": "observe", + "request_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "send_count": 1, + "state": "completed" + }, + "command-2a6e74bdbe424b3caa700dc047365a1c": { + "operation": "dispatch", + "request_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "send_count": 1, + "state": "completed" + }, + "command-2d0b436b61124502a9d8558816bda68d": { + "operation": "observe", + "request_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "send_count": 1, + "state": "completed" + }, + "command-3083d955014b4e5282809a47046c53db": { + "operation": "propose", + "request_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "send_count": 1, + "state": "completed" + }, + "command-36da4220dfcd4e85b9a4cee555ccd7aa": { + "operation": "start_job", + "request_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "send_count": 1, + "state": "completed" + }, + "command-382a79f756314a4ea88e1836344549d2": { + "operation": "dispatch", + "request_sha256": "3dda2ab314e9003e2f4f2126c449a2e634fdb05cc99050e52a101481650ae9a2", + "send_count": 1, + "state": "completed" + }, + "command-38a300b989a649fd9ee243704cdc65a9": { + "operation": "observe", + "request_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "send_count": 1, + "state": "completed" + }, + "command-38b6786c82b04b3d92ecde7200a19450": { + "operation": "propose", + "request_sha256": "0eedff7111f86a7c96f02b76328e26f9252832fcd0b32fdcfab09fd639cf62ac", + "send_count": 1, + "state": "completed" + }, + "command-40c6a8a1f1a04ea7bec902767b57387a": { + "operation": "observe", + "request_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "send_count": 1, + "state": "completed" + }, + "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e": { + "operation": "propose", + "request_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "send_count": 1, + "state": "completed" + }, + "command-4c3705f8d7cc48a4b45029d078357250": { + "operation": "observe", + "request_sha256": "6670065bd1fd29ab4a84a51cb0a31a497929cb54d24b94909462d946768c2d6d", + "send_count": 1, + "state": "completed" + }, + "command-51f66bfa90ab421bb24242caa6d054fd": { + "operation": "observe", + "request_sha256": "327a292c61ede952cf37c3157827e4fa1d919d5e90b244f18010ef464b558f42", + "send_count": 1, + "state": "completed" + }, + "command-553be6e82b274944b5e6ea9e2cd3902e": { + "operation": "propose", + "request_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "send_count": 1, + "state": "completed" + }, + "command-5ca0b6a7e99f4263b2239a95b02ca7e7": { + "operation": "propose", + "request_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "send_count": 1, + "state": "completed" + }, + "command-5ced22700795486fa68a50fcda4767b8": { + "operation": "propose", + "request_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "send_count": 1, + "state": "completed" + }, + "command-5e27abcb6c914c5ca0ae77ddee974bbc": { + "operation": "dispatch", + "request_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "send_count": 1, + "state": "completed" + }, + "command-604436650640419d9ce6c551ac3e3407": { + "operation": "observe", + "request_sha256": "98c01becbe239e62be2fe587554aa3ea29f2273a052c5359e1e5a85fb476362f", + "send_count": 1, + "state": "completed" + }, + "command-69a56ced2e8c49ce9e9f214c57023381": { + "operation": "propose", + "request_sha256": "9cfc65fc7994db66a7ebebdd994fba2dad0a4d54475862539cd87586f2779dfa", + "send_count": 1, + "state": "completed" + }, + "command-6e6b99559d5749eab04cbf8f42b46ae2": { + "operation": "observe", + "request_sha256": "3a2970680dd2675a75e8bbf91affd223084373d5789d6b873b4fe8bdab7dd5aa", + "send_count": 1, + "state": "completed" + }, + "command-74dc57912fda4c3e96f6845cdffbb045": { + "operation": "observe", + "request_sha256": "aed94b91da1d8ac4b41ac1ad21b488bc9c43e6db4066e352dc6bbacceee6b907", + "send_count": 1, + "state": "completed" + }, + "command-7661dbdae1c34bd797ca17b3b5321a5e": { + "operation": "propose", + "request_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "send_count": 1, + "state": "completed" + }, + "command-7b94f03fcd7449ec97ca592813c20693": { + "operation": "observe", + "request_sha256": "e9adecd7c66f60c892d0bf60a14266e115b7948b8cbac2a26aff6e4fb526e615", + "send_count": 1, + "state": "completed" + }, + "command-7ce7b5eb9b5b4b1d953e624d2312327b": { + "operation": "dispatch", + "request_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "send_count": 1, + "state": "completed" + }, + "command-84c016d3c2564ecea6025edaea7d23e7": { + "operation": "propose", + "request_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "send_count": 1, + "state": "completed" + }, + "command-8c948c9df6074ee5969ef8b19a3eaddb": { + "operation": "propose", + "request_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "send_count": 1, + "state": "completed" + }, + "command-90b2509eee524747a3397627f2c51643": { + "operation": "propose", + "request_sha256": "ba39f43b6c1947a04304c95045272d8cff2c0f70c14831e48ef8b77ce03d585b", + "send_count": 1, + "state": "completed" + }, + "command-933c11248d6a48079ead24676a2df7fb": { + "operation": "observe", + "request_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "send_count": 1, + "state": "completed" + }, + "command-93b6bfdc895349d2a07cfed89231411d": { + "operation": "propose", + "request_sha256": "a1e20276d19935994fb87711dc6ad10ef2a0f5423e274a3c9ca189348e861573", + "send_count": 1, + "state": "completed" + }, + "command-95a7bae7c4f8479b81bae1ea55e7597f": { + "operation": "observe", + "request_sha256": "acc6a031281992af1b58960f9038dc6cab3e67e435b497bfdaaea926b4c47620", + "send_count": 1, + "state": "completed" + }, + "command-96ff5828100a40b9945b5960aeb7e5dd": { + "operation": "dispatch", + "request_sha256": "80aa2ffe12f32c32c279d78eb3775b4311d8b83677f816849f91ae636fec87d0", + "send_count": 1, + "state": "completed" + }, + "command-9841ade4a0ea46a2b43353bf2b951a7c": { + "operation": "propose", + "request_sha256": "7b732e90c18d4e428c43c95403e2afeca93754f75cc963d94ba01cdec8224561", + "send_count": 1, + "state": "completed" + }, + "command-9dd2a0c9603f4667956ec976e822b74a": { + "operation": "observe", + "request_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "send_count": 1, + "state": "completed" + }, + "command-9f8d9402f1d74504b579f39b9c793576": { + "operation": "propose", + "request_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "send_count": 1, + "state": "completed" + }, + "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee": { + "operation": "dispatch", + "request_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "send_count": 1, + "state": "completed" + }, + "command-ab4679dd21e14ce08f70b1ef63bd5868": { + "operation": "observe", + "request_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "send_count": 1, + "state": "completed" + }, + "command-acd7ec8de3eb4a548e2e070898a0318f": { + "operation": "dispatch", + "request_sha256": "e963b00f5df17ccc10c5a050cac94cd1515f23b7c9e38ebfd7b97285aa6fb0cf", + "send_count": 1, + "state": "completed" + }, + "command-ad464b677e044b43ae8f9dd725331fce": { + "operation": "observe", + "request_sha256": "2a139a6cd850620070ff777a29a2acbfb326b69d260036bb5847aefd6a5c4c18", + "send_count": 1, + "state": "completed" + }, + "command-b17181d5918a492a916e0e3c5a2f3a11": { + "operation": "propose", + "request_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "send_count": 1, + "state": "completed" + }, + "command-b182534626d34766a52d5e11d48239e7": { + "operation": "observe", + "request_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "send_count": 1, + "state": "completed" + }, + "command-bdc662ab7f4645d79c02f84921f3c9f6": { + "operation": "dispatch", + "request_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "send_count": 1, + "state": "completed" + }, + "command-c5861bc07c0d4b6a992850fe1ab3c769": { + "operation": "dispatch", + "request_sha256": "2747a5c1d597b72581a2ffef5303fd6f137acdae3c6243750c87309aedb74de2", + "send_count": 1, + "state": "completed" + }, + "command-c80c18cc647b45fe8e9faf2fa890283c": { + "operation": "dispatch", + "request_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "send_count": 1, + "state": "completed" + }, + "command-c8be0caf76504410a68a595296d56bd3": { + "operation": "observe", + "request_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "send_count": 1, + "state": "completed" + }, + "command-cd90dd204ff74139880f3846418a41b7": { + "operation": "dispatch", + "request_sha256": "dc58e74652094316cd08bb4ed5a2b9e9ba9a1793326b9918539c6365f1537e3b", + "send_count": 1, + "state": "completed" + }, + "command-cf898dd6e56a4d8bb0a5894371f9ba81": { + "operation": "dispatch", + "request_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "send_count": 1, + "state": "completed" + }, + "command-cf90ff6221c640f9ac99b5ceb8a91754": { + "operation": "dispatch", + "request_sha256": "9109f545b48718b5291c081e098f1f815b521fae16217993ee9985e898ffc043", + "send_count": 1, + "state": "completed" + }, + "command-cfead433cabe4303b15fd2ca83ee8899": { + "operation": "propose", + "request_sha256": "504d2c9975111bb32e985cc71034239f5d62d10929273eb2ec94d6b5b59534dd", + "send_count": 1, + "state": "completed" + }, + "command-d3e05b3b869542a085afeba4414811ba": { + "operation": "dispatch", + "request_sha256": "cb0758e27127d99fbc0a75c6dc7cfc2d61c2bdf92925e51129e916f3637fee40", + "send_count": 1, + "state": "completed" + }, + "command-d9922eefd392420b96bf0a62d7eea982": { + "operation": "dispatch", + "request_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "send_count": 1, + "state": "completed" + }, + "command-df199bef22b442168d0a42242c00c5c4": { + "operation": "observe", + "request_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "send_count": 1, + "state": "completed" + }, + "command-e19f5d23dd944e40b806e930f7d44b35": { + "operation": "dispatch", + "request_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "send_count": 1, + "state": "completed" + }, + "command-e1af2fbe5a254692bf212769ddfea045": { + "operation": "observe", + "request_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "send_count": 1, + "state": "completed" + }, + "command-e7a47417ff124ebc915329783ad7c5bb": { + "operation": "dispatch", + "request_sha256": "07cb08a35c3378b556b2d9fb19d575ea53e577e4dca56624bf3e5e49e868fe68", + "send_count": 1, + "state": "completed" + }, + "command-e897a3cba83b4d83b460a556be5e459b": { + "operation": "observe", + "request_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "send_count": 1, + "state": "completed" + }, + "command-eb16ab3154eb40f78f021869ebb485b3": { + "operation": "propose", + "request_sha256": "bbd21b24923ad60e0ba472125e2544efe9ab758d7887e2444bd293bd0f5e25b6", + "send_count": 1, + "state": "completed" + }, + "command-ede04073e3654f4fa17f0a0056db9004": { + "operation": "dispatch", + "request_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "send_count": 1, + "state": "completed" + }, + "command-ef48ba673c2b4ae08b09fbbc4c56fca8": { + "operation": "start_job", + "request_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "send_count": 1, + "state": "completed" + }, + "command-f008b852a29348218bc57e931887b963": { + "operation": "dispatch", + "request_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "send_count": 1, + "state": "completed" + }, + "command-f0d26ac5d6914f1bb038a57ee515b7f0": { + "operation": "observe", + "request_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "send_count": 1, + "state": "completed" + }, + "command-f4c202be91064d3e8f4c929f1175450e": { + "operation": "propose", + "request_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "send_count": 1, + "state": "completed" + }, + "command-f7b8d8e5cddb47ecbac988938ccee2a0": { + "operation": "observe", + "request_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "send_count": 1, + "state": "completed" + }, + "command-fb77cbd4d30f4827bdef78ff67cabe2b": { + "operation": "dispatch", + "request_sha256": "286b425e934eb0fa16526805b7ef5fe3431d0d172fdcf02fd4cc9ccb9d89ef5f", + "send_count": 1, + "state": "completed" + }, + "command-fca0d0500040494396aabdb153197133": { + "operation": "observe", + "request_sha256": "36f0a50bf16631b346b7669d99fb49c44bf15ade5d62d3a84e9bfaf016fd1d1f", + "send_count": 1, + "state": "completed" + }, + "command-fda8dcacccc940c493511804050cc0ec": { + "operation": "propose", + "request_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "send_count": 1, + "state": "completed" + }, + "command-fe049e3ca1ce489e9e7cc0e25188a245": { + "operation": "observe", + "request_sha256": "20563be149da9ea5513d1f967925a42fb19aef1a112f38923e15d34a79907c68", + "send_count": 1, + "state": "completed" + } + }, + "identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "lease": { + "client_id": "client-6c734bbe900342329bb34c0d4dcc485b", + "duration_s": 30.0, + "epoch": 3, + "lease_id": "64fd21cec5f8404abdfe09dbbecfe4f8" + }, + "pending_command_ids": [] + }, + "host": { + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "body_identity": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "frame": { + "generation": 20, + "path": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2/operator/client/images/challenge-021548ca7f144b57a98d5dfa7df72f15-118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa.png", + "sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "runner_status": "running", + "sequence": 227, + "stage": null, + "usage": { + "calls": 29, + "input_tokens": 343310, + "output_tokens": 3963, + "reported_calls": 26 + } + }, + "posts": [ + { + "command_id": "command-36da4220dfcd4e85b9a4cee555ccd7aa", + "payload_sha256": "7ea11721570fb77e340b4f2e0d66e64ab5b136d5478b26c44a967be1d86256eb", + "sequence": 8 + }, + { + "command_id": "command-e897a3cba83b4d83b460a556be5e459b", + "payload_sha256": "0b35d9142df3fc25df922ec8c0812e7ad7460346f7389fb80bace9904ec147bb", + "sequence": 16 + }, + { + "command_id": "command-933c11248d6a48079ead24676a2df7fb", + "payload_sha256": "8e249e904c29f91de3ef73aa9fa15d6517e2d6983edfdc0a097e8eda8fc67f59", + "sequence": 31 + }, + { + "command_id": "command-1e2386315d6c4c7692405dac7dfa7bd1", + "payload_sha256": "29daaf4dd4f38db1720d0a28f833caa5084b170118c8cd781a1aba9ce7d1746b", + "sequence": 43 + }, + { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "payload_sha256": "4725aa167fe57d46a1c6674fa63a1f97413421451a44826ee954952e11c63158", + "sequence": 51 + }, + { + "command_id": "command-0e35d66b16a64168b11d255a1d871e71", + "payload_sha256": "ac2992d20493bd10b8fbebea63151c6d075a4704088b321b909ce4a44388b331", + "sequence": 67 + }, + { + "command_id": "command-fda8dcacccc940c493511804050cc0ec", + "payload_sha256": "db632f120ae418bddfaca319ffc50e98d0d206def22a9d0c3655c39423aa1717", + "sequence": 79 + }, + { + "command_id": "command-5e27abcb6c914c5ca0ae77ddee974bbc", + "payload_sha256": "b150863371975909061c5c284297745de818973ef9bb4483fe276d83230c4974", + "sequence": 87 + }, + { + "command_id": "command-c8be0caf76504410a68a595296d56bd3", + "payload_sha256": "d5867b3b7dab8738fe2bcc2e878c120a9651fe09dc13d102dacf63d5e6e3b564", + "sequence": 95 + }, + { + "command_id": "command-f4c202be91064d3e8f4c929f1175450e", + "payload_sha256": "425fe924fe46c38097155ffde315f426490bb4d8ee43f16cd7454fe52af7bf3d", + "sequence": 107 + }, + { + "command_id": "command-e19f5d23dd944e40b806e930f7d44b35", + "payload_sha256": "788dac06d5863a4a6363c4e9b6c16f38bea0eb4bdea7658fd4f83f732a59583a", + "sequence": 115 + }, + { + "command_id": "command-1936c404000d4b55a094c49a2fd9eeb3", + "payload_sha256": "7eda001e48f71d8279c5770cf2633237f092c1b0bb35aa15e19f3667c6116eb2", + "sequence": 123 + }, + { + "command_id": "command-8c948c9df6074ee5969ef8b19a3eaddb", + "payload_sha256": "658c7671a0d062cc75c20b2112e39826075affea6d5d60a183135b399050218d", + "sequence": 135 + }, + { + "command_id": "command-bdc662ab7f4645d79c02f84921f3c9f6", + "payload_sha256": "0ccb54ee47fa858a87eb10bcfb069c345b29db8fad61669c1e58751549e43dc0", + "sequence": 143 + }, + { + "command_id": "command-e1af2fbe5a254692bf212769ddfea045", + "payload_sha256": "9efbed5e6627632a03212e000b633a1ab1e8692aaa81c4340c7b76536a2af8a3", + "sequence": 151 + }, + { + "command_id": "command-b17181d5918a492a916e0e3c5a2f3a11", + "payload_sha256": "56ce449d1a0416dc5e7f1830c50887e493606e6f935dd72cfb0fff054a2b7042", + "sequence": 163 + }, + { + "command_id": "command-2a6e74bdbe424b3caa700dc047365a1c", + "payload_sha256": "c8c822c9fba17ecf981cb86e65485f2678e917c7266fda736ef3d0b0635b5f9c", + "sequence": 171 + }, + { + "command_id": "command-df199bef22b442168d0a42242c00c5c4", + "payload_sha256": "14d1cb1ec52d8e8d520981b293408d72ff6fb592324b6a3da695f0254f04c636", + "sequence": 179 + }, + { + "command_id": "command-5ca0b6a7e99f4263b2239a95b02ca7e7", + "payload_sha256": "8110ae8d9f624a89419f3229a1f13a47f9f17249df601237cfd4cae5224a07ee", + "sequence": 191 + }, + { + "command_id": "command-f008b852a29348218bc57e931887b963", + "payload_sha256": "46b71d8afc3b366718a29d00919e73d3d7bc8199558f2c6345c38d602084c454", + "sequence": 199 + }, + { + "command_id": "command-2d0b436b61124502a9d8558816bda68d", + "payload_sha256": "d565247b59ff983b0e8056739a7312553ff11a86e0c2ade2e57ae03e2794e389", + "sequence": 207 + }, + { + "command_id": "command-40dfcee9c7d24d5b88eacf3ad4ef9a4e", + "payload_sha256": "22fd8eae4d69f51771a01dd11df73ca52f7ab75a37cf657e5ce13d4231112a6c", + "sequence": 219 + }, + { + "command_id": "command-aa19aa0c97ee4d8bb8ab6ab1c175e8ee", + "payload_sha256": "21d9f088823463acf90956ee026ac32de41b84cd1f3bfc9f7473836ec6d08a97", + "sequence": 227 + }, + { + "command_id": "command-b182534626d34766a52d5e11d48239e7", + "payload_sha256": "5ad3e108bbf0076da2cd4442bc2cb513b7a3b03a3eb9e6ebcb9365da6617d48a", + "sequence": 235 + }, + { + "command_id": "command-84c016d3c2564ecea6025edaea7d23e7", + "payload_sha256": "e7af49a829ed12157954efd8c9a4d13b89e2cd991bd0254fa3377a8ea20b2aff", + "sequence": 247 + }, + { + "command_id": "command-ede04073e3654f4fa17f0a0056db9004", + "payload_sha256": "8d4f2e531917f1b2ebb0b3ac9e9c7bc8640874a5709a1dbf0cf755db56cd6a28", + "sequence": 255 + }, + { + "command_id": "command-f0d26ac5d6914f1bb038a57ee515b7f0", + "payload_sha256": "6f52c77b4617240c34fa8b76ec854925153b81d241bdf354519ee685ea333e05", + "sequence": 263 + }, + { + "command_id": "command-5ced22700795486fa68a50fcda4767b8", + "payload_sha256": "9ee7328d2661197fbca4b2fb342317a403245d5db32515b19b398e1b10ba27e9", + "sequence": 275 + }, + { + "command_id": "command-7ce7b5eb9b5b4b1d953e624d2312327b", + "payload_sha256": "b6b3bf3339bf5881e47f71f7eb5f514f3e287587f62fe505bbd2d9950828acc4", + "sequence": 283 + }, + { + "command_id": "command-9dd2a0c9603f4667956ec976e822b74a", + "payload_sha256": "3652535d33974b64aba2aba0d5df03b66c1c9075c9069c7b673874f332e0bbcb", + "sequence": 291 + }, + { + "command_id": "command-3083d955014b4e5282809a47046c53db", + "payload_sha256": "f4ffd63b2254e4e91e23fdfb9eb6e1ac0e5f0701d7ba7617f575083cbc2fffec", + "sequence": 303 + }, + { + "command_id": "command-097e6bec1ce24ef2bc8f37c40f80d98f", + "payload_sha256": "3df0298afc1f4e44d60b2b3f7d3cf13c0277600682f0f0d6359cf0ae1cfb9488", + "sequence": 311 + }, + { + "command_id": "command-38a300b989a649fd9ee243704cdc65a9", + "payload_sha256": "97c7881b3b3eac3f20e327de6d1e0a23e94b8b06415bc43b0b2d00a298a1778f", + "sequence": 319 + }, + { + "command_id": "command-553be6e82b274944b5e6ea9e2cd3902e", + "payload_sha256": "1e1cc0fede8a9f595d8146da49dce6138da32f9261916b1613f46392318f3a1e", + "sequence": 331 + }, + { + "command_id": "command-d9922eefd392420b96bf0a62d7eea982", + "payload_sha256": "7440f248c466bc7ce206c2354a5852ad1cdf7f9372457b367879d24984766480", + "sequence": 339 + }, + { + "command_id": "command-f7b8d8e5cddb47ecbac988938ccee2a0", + "payload_sha256": "bf279c09f19252bbda950361945a6b143fb96c87ce278b567860295e4a263f7c", + "sequence": 347 + }, + { + "command_id": "command-7661dbdae1c34bd797ca17b3b5321a5e", + "payload_sha256": "c1470e90804d516b6bd51b0dc825b1d06f699223e0b0d117e66da0ce8d97f463", + "sequence": 359 + }, + { + "command_id": "command-c80c18cc647b45fe8e9faf2fa890283c", + "payload_sha256": "0bf907eb26ef2015935816cf5887a6e465a729aecc183a4fa10cca5ad47334cd", + "sequence": 367 + }, + { + "command_id": "command-248b9798493e4a43a51259929e135e29", + "payload_sha256": "bed21822b73961a780adf48cc0912e8038574b180a5f0ad976f2a01ebe37703a", + "sequence": 375 + }, + { + "command_id": "command-015d5d03d0624f14ba43d889871c45ee", + "payload_sha256": "072a32a019c848228f49953e695f6a220d0db7743fdda906011df8ed8f71c3a0", + "sequence": 387 + }, + { + "command_id": "command-210150e3ac9f45adae24e89f22a66286", + "payload_sha256": "674d3fa1ea7146ddb31fb4e1dccd69d009a30437e56cafc56ae48019202f991d", + "sequence": 395 + }, + { + "command_id": "command-ef48ba673c2b4ae08b09fbbc4c56fca8", + "payload_sha256": "6a500fe4198f0aadde08c1859e8020d7833ca1fa0529fbdbac4c8f17aa957a60", + "sequence": 403 + }, + { + "command_id": "command-ab4679dd21e14ce08f70b1ef63bd5868", + "payload_sha256": "c7cfb9cf1ffa949ed60ad3b3aef61884cfd959107a56129d23c7758714a971d8", + "sequence": 411 + }, + { + "command_id": "command-40c6a8a1f1a04ea7bec902767b57387a", + "payload_sha256": "7bb39849a52b98bf039deebb6371d28ece55c04faed9809c9866c6babae4ef26", + "sequence": 480 + }, + { + "command_id": "command-9f8d9402f1d74504b579f39b9c793576", + "payload_sha256": "1c6f1885adbe13c8b3ab749812e10139310fcbadf478b3debaa8bc025bda45b0", + "sequence": 492 + }, + { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "payload_sha256": "bd591cd9646fb80860bc791d8b9d02fd3695a496ead456ceb7f903185883edc9", + "sequence": 500 + }, + { + "command_id": "command-604436650640419d9ce6c551ac3e3407", + "payload_sha256": "98c01becbe239e62be2fe587554aa3ea29f2273a052c5359e1e5a85fb476362f", + "sequence": 550 + }, + { + "command_id": "command-01793f114b2c4d3a8f23b17ebc2b8f1f", + "payload_sha256": "6bf2d4795f61435907607137db5beb6f2607768011e90fb1b8b00082d8c62274", + "sequence": 562 + }, + { + "command_id": "command-d3e05b3b869542a085afeba4414811ba", + "payload_sha256": "cb0758e27127d99fbc0a75c6dc7cfc2d61c2bdf92925e51129e916f3637fee40", + "sequence": 570 + }, + { + "command_id": "command-6e6b99559d5749eab04cbf8f42b46ae2", + "payload_sha256": "3a2970680dd2675a75e8bbf91affd223084373d5789d6b873b4fe8bdab7dd5aa", + "sequence": 578 + }, + { + "command_id": "command-90b2509eee524747a3397627f2c51643", + "payload_sha256": "ba39f43b6c1947a04304c95045272d8cff2c0f70c14831e48ef8b77ce03d585b", + "sequence": 590 + }, + { + "command_id": "command-0c04ca9d775443a9b69a78f25f183e7d", + "payload_sha256": "e9dce120ea68457626fe8f895b8003547049335bf71398de3a7d45d50475ff93", + "sequence": 598 + }, + { + "command_id": "command-7b94f03fcd7449ec97ca592813c20693", + "payload_sha256": "e9adecd7c66f60c892d0bf60a14266e115b7948b8cbac2a26aff6e4fb526e615", + "sequence": 606 + }, + { + "command_id": "command-eb16ab3154eb40f78f021869ebb485b3", + "payload_sha256": "bbd21b24923ad60e0ba472125e2544efe9ab758d7887e2444bd293bd0f5e25b6", + "sequence": 618 + }, + { + "command_id": "command-acd7ec8de3eb4a548e2e070898a0318f", + "payload_sha256": "e963b00f5df17ccc10c5a050cac94cd1515f23b7c9e38ebfd7b97285aa6fb0cf", + "sequence": 626 + }, + { + "command_id": "command-4c3705f8d7cc48a4b45029d078357250", + "payload_sha256": "6670065bd1fd29ab4a84a51cb0a31a497929cb54d24b94909462d946768c2d6d", + "sequence": 634 + }, + { + "command_id": "command-0ee1728417374a16938ab09aa59e64c0", + "payload_sha256": "32bfef5a823099dab6fc5291582f6faaa0ac10a840ac9e94c38946dab92ae0ab", + "sequence": 646 + }, + { + "command_id": "command-07d3f286ef6846ba90c196ad79a88bff", + "payload_sha256": "956cc6d0e3e864da997877f551aa587cb8c18ef23887fa852f68d322858a1934", + "sequence": 654 + }, + { + "command_id": "command-74dc57912fda4c3e96f6845cdffbb045", + "payload_sha256": "aed94b91da1d8ac4b41ac1ad21b488bc9c43e6db4066e352dc6bbacceee6b907", + "sequence": 662 + }, + { + "command_id": "command-009165e2aa1d4b6d8c000766c3967914", + "payload_sha256": "1206f95b1d06e80eae8ca4baf0ce26951be111339dc3e2f4d9ebfa1dbe410eab", + "sequence": 674 + }, + { + "command_id": "command-382a79f756314a4ea88e1836344549d2", + "payload_sha256": "3dda2ab314e9003e2f4f2126c449a2e634fdb05cc99050e52a101481650ae9a2", + "sequence": 682 + }, + { + "command_id": "command-0d1afb96c11546759d80d26095199c48", + "payload_sha256": "df0a0ddfda89951587e1c2bbae4062b35d48d528b9ff565aad1ae070312bdae2", + "sequence": 690 + }, + { + "command_id": "command-0d48c82d84d340c6b1d28b76f670dd29", + "payload_sha256": "4335b774435a6b013d28c8327d5fc7e208576eed4d6796b3b671fd41dbf58ba3", + "sequence": 702 + }, + { + "command_id": "command-16c006b2256a4000b45fc63cd2d334ff", + "payload_sha256": "8f291e7bbe50782c675defef8bc2c5636c22ce4c9e383802274acca154c03a31", + "sequence": 710 + }, + { + "command_id": "command-ad464b677e044b43ae8f9dd725331fce", + "payload_sha256": "2a139a6cd850620070ff777a29a2acbfb326b69d260036bb5847aefd6a5c4c18", + "sequence": 718 + }, + { + "command_id": "command-16ac2d834cc949e980dbdc7b3bf60af7", + "payload_sha256": "e750a765511c25e30bf1a54400fae352577c98a13af91dc2bbded25a2b60e0b6", + "sequence": 730 + }, + { + "command_id": "command-fb77cbd4d30f4827bdef78ff67cabe2b", + "payload_sha256": "286b425e934eb0fa16526805b7ef5fe3431d0d172fdcf02fd4cc9ccb9d89ef5f", + "sequence": 738 + }, + { + "command_id": "command-1af4c5bd1341495093201a5821d1dec9", + "payload_sha256": "217b8ec12db8b35fbe968b343144566338207ce3b7d07e9ea8ad8fbf766845a9", + "sequence": 746 + }, + { + "command_id": "command-93b6bfdc895349d2a07cfed89231411d", + "payload_sha256": "a1e20276d19935994fb87711dc6ad10ef2a0f5423e274a3c9ca189348e861573", + "sequence": 758 + }, + { + "command_id": "command-96ff5828100a40b9945b5960aeb7e5dd", + "payload_sha256": "80aa2ffe12f32c32c279d78eb3775b4311d8b83677f816849f91ae636fec87d0", + "sequence": 766 + }, + { + "command_id": "command-fca0d0500040494396aabdb153197133", + "payload_sha256": "36f0a50bf16631b346b7669d99fb49c44bf15ade5d62d3a84e9bfaf016fd1d1f", + "sequence": 774 + }, + { + "command_id": "command-69a56ced2e8c49ce9e9f214c57023381", + "payload_sha256": "9cfc65fc7994db66a7ebebdd994fba2dad0a4d54475862539cd87586f2779dfa", + "sequence": 786 + }, + { + "command_id": "command-cf90ff6221c640f9ac99b5ceb8a91754", + "payload_sha256": "9109f545b48718b5291c081e098f1f815b521fae16217993ee9985e898ffc043", + "sequence": 794 + }, + { + "command_id": "command-51f66bfa90ab421bb24242caa6d054fd", + "payload_sha256": "327a292c61ede952cf37c3157827e4fa1d919d5e90b244f18010ef464b558f42", + "sequence": 802 + }, + { + "command_id": "command-38b6786c82b04b3d92ecde7200a19450", + "payload_sha256": "0eedff7111f86a7c96f02b76328e26f9252832fcd0b32fdcfab09fd639cf62ac", + "sequence": 814 + }, + { + "command_id": "command-c5861bc07c0d4b6a992850fe1ab3c769", + "payload_sha256": "2747a5c1d597b72581a2ffef5303fd6f137acdae3c6243750c87309aedb74de2", + "sequence": 822 + }, + { + "command_id": "command-fe049e3ca1ce489e9e7cc0e25188a245", + "payload_sha256": "20563be149da9ea5513d1f967925a42fb19aef1a112f38923e15d34a79907c68", + "sequence": 830 + }, + { + "command_id": "command-cfead433cabe4303b15fd2ca83ee8899", + "payload_sha256": "504d2c9975111bb32e985cc71034239f5d62d10929273eb2ec94d6b5b59534dd", + "sequence": 842 + }, + { + "command_id": "command-cd90dd204ff74139880f3846418a41b7", + "payload_sha256": "dc58e74652094316cd08bb4ed5a2b9e9ba9a1793326b9918539c6365f1537e3b", + "sequence": 850 + }, + { + "command_id": "command-95a7bae7c4f8479b81bae1ea55e7597f", + "payload_sha256": "acc6a031281992af1b58960f9038dc6cab3e67e435b497bfdaaea926b4c47620", + "sequence": 858 + }, + { + "command_id": "command-12c51cb647bc4d01badb3bebf7cb0446", + "payload_sha256": "45dee3c4b5394ccc300f72ba73630f476ddcd992912bb5a1da838e264bf53343", + "sequence": 871 + }, + { + "command_id": "command-9841ade4a0ea46a2b43353bf2b951a7c", + "payload_sha256": "7b732e90c18d4e428c43c95403e2afeca93754f75cc963d94ba01cdec8224561", + "sequence": 883 + }, + { + "command_id": "command-e7a47417ff124ebc915329783ad7c5bb", + "payload_sha256": "07cb08a35c3378b556b2d9fb19d575ea53e577e4dca56624bf3e5e49e868fe68", + "sequence": 891 + } + ], + "processes": { + "body": 74921, + "workbench": 39967 + }, + "public": { + "active_job_id": null, + "activity": [ + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 204, + "time": 1791829189.127323 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-fe049e3ca1ce489e9e7cc0e25188a245", + "seq": 205, + "time": 1791829189.480195 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "13", + "seq": 206, + "time": 1791829189.4844081 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 207, + "time": 1791829196.4102259 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-cfead433cabe4303b15fd2ca83ee8899", + "seq": 208, + "time": 1791829196.602696 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 209, + "time": 1791829196.697315 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "dispatch: command-cd90dd204ff74139880f3846418a41b7", + "seq": 210, + "time": 1791829197.11283 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 211, + "time": 1791829197.23605 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-95a7bae7c4f8479b81bae1ea55e7597f", + "seq": 212, + "time": 1791829197.9852512 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "14", + "seq": 213, + "time": 1791829197.991858 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 214, + "time": 1791829202.567657 + }, + { + "intent": "", + "kind": "halt", + "outcome": "operator_pause_requested", + "seq": 215, + "time": 1791829202.618878 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 216, + "time": 1791829224.8969312 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 217, + "time": 1791829230.2752252 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 218, + "time": 1791829234.4515479 + }, + { + "intent": "", + "kind": "halt", + "outcome": "timed out", + "seq": 219, + "time": 1791829242.3595982 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 220, + "time": 1791829285.4561422 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 221, + "time": 1791829285.550546 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-12c51cb647bc4d01badb3bebf7cb0446", + "seq": 222, + "time": 1791829286.054108 + }, + { + "intent": "Restart inspection 02", + "kind": "inference", + "outcome": "15", + "seq": 223, + "time": 1791829286.056795 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 224, + "time": 1791829296.4025989 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-9841ade4a0ea46a2b43353bf2b951a7c", + "seq": 225, + "time": 1791829296.548447 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 226, + "time": 1791829296.6237051 + }, + { + "intent": "Restart inspection 02", + "kind": "rpc_applied", + "outcome": "dispatch: command-e7a47417ff124ebc915329783ad7c5bb", + "seq": 227, + "time": 1791829297.049696 + } + ], + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 20, + "image_url": "/api/frame?generation=20&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 15, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Finish reset with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 20, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "kind": "finish_reset", + "native_time_s": 42.630000000006135, + "operation_id": "agent-7acee30a3cb442d9a3a2b3a9bfec10ed", + "pusher_home_verified": true, + "reset_contact_samples": 3314, + "reset_native_steps": 8140, + "state_sha256": "02c49f9f03f16f8de552b4b4ce57b6d78c85e291fc3dbf1b6acb0ce4b7cd638b" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": null, + "readiness": { + "ready": true, + "reason": "Resumed; next decision receives a fresh TCP image" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 29, + "input_tokens": 343310, + "output_tokens": 3963, + "reported_calls": 26, + "token_usage_complete": false + } + }, + "time": 1791829364.5815492 +} diff --git a/jevdual/results/workbench-restarts-20261012/source-freeze.json b/jevdual/results/workbench-restarts-20261012/source-freeze.json new file mode 100644 index 0000000..1c1115e --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/source-freeze.json @@ -0,0 +1,33 @@ +{ + "commit": "d7072107d576d7a09643229ae584a3864d2fe0f6", + "files": { + "tools/camera-capture-experiment/capture.py": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "tools/physical-workcell/agent_bench.py": "e120dbfc9a96ca07fedb15226f27282265203755866210b86d5f856f6e3f5e07", + "tools/physical-workcell/bench.py": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "tools/physical-workcell/body_client.py": "40388c238192d923888c9852b363314801dcf65c7266aadc8c377d3810aeb33d", + "tools/physical-workcell/body_network.py": "95fd21597bcdd9e982a698859cd1219ae4522062e332c50fea233629dbfb343c", + "tools/physical-workcell/body_protocol.py": "1d24066768105c28b5cf6f4d46458e4e1b9d86cbde45ed6ce466b30da7ff974f", + "tools/physical-workcell/codex-action.schema.json": "e57197e4e73aa4c78145814a460ca77b9c6dc5e49aaf4c91adc0b521b7c3d833", + "tools/physical-workcell/codex-policy.md": "ce947200b2a652e0766b422f3b404bd5095ceb398569341466b2c5f4dd9647bc", + "tools/physical-workcell/codex_policy.py": "40fe73e01d97ee1e5cfdb813650b11edadbea29534784ab10cc1ef4e7f4d5418", + "tools/physical-workcell/episode_cases.py": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "tools/physical-workcell/image_guided.py": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961", + "tools/physical-workcell/measurement.py": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "tools/physical-workcell/network_bench_operator.html": "a4164134b418929476b7e69946b9e42b6804e2836bb57e606630763704d9becb", + "tools/physical-workcell/network_bench_operator.py": "9079729ea4e8b56ccdf2a6d187b0c5d79a23a33688748fe55d92d10922500b40", + "tools/physical-workcell/network_fault_proxy.py": "44b0b52f7c213c0f5f93b8997ba72be4e750bc9f1a4f7f6d7b2a8c4f1233b595", + "tools/physical-workcell/network_operator_runtime.py": "706e0165da8173e501f8d689bcb161f480ae052a283e5e72f01bd26dca1be73b", + "tools/physical-workcell/order_protocol.py": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "tools/physical-workcell/qualify_bench.py": "524c537c1b310a0f0ae493acee99a069966a5e7c4b0a783daadf347094db58ef", + "tools/physical-workcell/qualify_network_body.py": "2800cf38afd21b86f8b035c46e994b6f96d966db4ccba1bba703e9e1a22f7c2b", + "tools/physical-workcell/qualify_network_workbench.py": "e5c72acda2ea8fae3658faba907448765df2f1e34e05749fbe85faed28ef003b", + "tools/physical-workcell/qualify_workbench_restarts.py": "2bc3edc5ea39b69f3372d4274b757f06472409407a22cd3149dfa52fbf314dcb", + "tools/physical-workcell/record_network_workbench.py": "7604865caa309c7002c01a2384da84eb62d8b22dcd63ab256618c536bc5fedc4", + "tools/physical-workcell/scene.xml": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "tools/physical-workcell/score_network_body.py": "d1f7150a5ff23775664b5656fd21379502ba71175487fd7aadb2b51bffcdaf8c", + "tools/physical-workcell/score_network_workbench.py": "67a53586081fe425bd14b0a0fbbf3d7f0fc1e66daccda06765bb88f3d9d4d84c", + "tools/physical-workcell/score_workbench_restarts.py": "181cbf4ee1bbd5483f38edc4a84244fc3efa98dfd21b5c9751d43edfe8f9f5a5", + "tools/physical-workcell/workbench_link.py": "578d94684463bcb3d7f2d45d9ba68abcd27d8a27f7f39538323a269e251c330e", + "tools/physical-workcell/workcell.py": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2" + } +} diff --git a/jevdual/results/workbench-restarts-20261012/ui-ledger.json b/jevdual/results/workbench-restarts-20261012/ui-ledger.json new file mode 100644 index 0000000..ca4659d --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui-ledger.json @@ -0,0 +1,734 @@ +{ + "steps": [ + { + "browser_action": "Observed the first lost dispatch reply as Outcome uncertain before any process restart or receipt lookup", + "client_commands": 5, + "name": "uncertain", + "pending_command_ids": [ + "command-24230a0f96bc4e84a84f720b1c974054" + ], + "screenshot": "tools/physical-workcell/output/sim11-browser-restarts-v2/ui/uncertain.jpg", + "state": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 2, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Push the block right so its center enters the measurement zone.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791828766.590297, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t75 checkbox Restart inspection 01 Needs attention, Value: 1\n\t\t\t76 checkbox Restart inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t77 text Restart inspection 01\n\t\t78 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t79 text reply is uncertain; reconcile exact command without resending\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t80 text Body connected\n\t\t\t81 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button Check receipt, ID: reconcile\n\t\t\t68 container\n\t\t\t\t69 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t70 text Test the simulated connection\n\t\t\t\t71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t72 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t73 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t74 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t82 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t83 text Last observation \u00b7 Restart inspection 01\n\t\t\t60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t84 text Captured \u00b7 generation 0\n\t\t85 text OUTCOME UNCERTAIN\n\t\t86 text The command outcome is uncertain. Reconnect if needed, then check its receipt before continuing.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t87 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t88 text 19 events\n\t\t\t43 content list activity\n\t\t\t\t89 container\n\t\t\t\t\t90 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t91 container\n\t\t\t\t\t92 text 02:12 PM Sending a guarded action\n\t\t\t\t93 container\n\t\t\t\t\t94 text 02:12 PM Action proposal accepted Restart inspection 01\n\t\t\t\t95 container\n\t\t\t\t\t96 text 02:12 PM Checking the planned action\n\t\t\t\t97 container\n\t\t\t\t\t98 text 02:12 PM AI planning requested Restart inspection 01\n\t\t\t\t99 container\n\t\t\t\t\t100 text 02:12 PM Camera observation received Restart inspection 01\n\t\t\t\t101 container\n\t\t\t\t\t102 text 02:12 PM Requesting camera observation\n\t\t\t\t103 container\n\t\t\t\t\t104 text 02:12 PM Agent resumed\n\t\t\t\t105 container\n\t\t\t\t\t106 text 02:12 PM Reply fault armed The next command reply will be lost.\n\t\t\t\t107 container\n\t\t\t\t\t108 text 02:10 PM Agent stopped for review operator_pause_requested\n\t\t\t\t109 container\n\t\t\t\t\t110 text 02:10 PM AI planning requested Restart inspection 01\n\t\t\t\t111 container\n\t\t\t\t\t112 text 02:10 PM Camera observation received Restart inspection 01\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t113 text 2 model requests \u00b7 Reported tokens: 13,063 input / 199 output \u00b7 Reporting incomplete (1 of 2 requests)\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Clicked Disconnect after workbench restart while preserving the same uncertain command", + "client_commands": 5, + "name": "disconnected", + "pending_command_ids": [ + "command-24230a0f96bc4e84a84f720b1c974054" + ], + "screenshot": null, + "state": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Diagnostic link disconnected; cached observations are retained", + "state": "disconnected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 2, + "disturbance_test": false, + "error": "Restarted with a retained command stage; check its exact receipt", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Push the block right so its center enters the measurement zone.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "operation": "dispatch", + "reason": "Restarted with a retained command stage; check its exact receipt", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791828795.696644, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t75 checkbox Restart inspection 01 Needs attention, Value: 1\n\t\t\t76 checkbox Restart inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t77 text Restart inspection 01\n\t\t78 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t79 text Restarted with a retained command stage; check its exact receipt\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t80 text Body disconnected\n\t\t\t81 text Diagnostic link disconnected; cached observations are retained\n\t\t\t20 button Reconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t68 container\n\t\t\t\t69 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t70 text Test the simulated connection\n\t\t\t\t71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t72 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t73 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t74 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t82 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t83 text Retained observation \u00b7 body offline\n\t\t\t60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t84 text Retained \u00b7 offline \u00b7 generation 0\n\t\t85 text DISCONNECTED\n\t\t86 text The body connection is unavailable. The last camera observation is retained.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t87 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t88 text 21 events\n\t\t\t43 content list activity\n\t\t\t\t89 container\n\t\t\t\t\t90 text 02:13 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t91 container\n\t\t\t\t\t92 text 02:12 PM Agent stopped for review Restarted with a retained command stage; check its exact receipt\n\t\t\t\t93 container\n\t\t\t\t\t94 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t95 container\n\t\t\t\t\t96 text 02:12 PM Sending a guarded action\n\t\t\t\t97 container\n\t\t\t\t\t98 text 02:12 PM Action proposal accepted Restart inspection 01\n\t\t\t\t99 container\n\t\t\t\t\t100 text 02:12 PM Checking the planned action\n\t\t\t\t101 container\n\t\t\t\t\t102 text 02:12 PM AI planning requested Restart inspection 01\n\t\t\t\t103 container\n\t\t\t\t\t104 text 02:12 PM Camera observation received Restart inspection 01\n\t\t\t\t105 container\n\t\t\t\t\t106 text 02:12 PM Requesting camera observation\n\t\t\t\t107 container\n\t\t\t\t\t108 text 02:12 PM Agent resumed\n\t\t\t\t109 container\n\t\t\t\t\t110 text 02:12 PM Reply fault armed The next command reply will be lost.\n\t\t\t\t111 container\n\t\t\t\t\t112 text 02:10 PM Agent stopped for review operator_pause_requested\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t113 text 2 model requests \u00b7 Reported tokens: 13,063 input / 199 output \u00b7 Reporting incomplete (1 of 2 requests)\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Observed Check receipt disabled while the retained command remained uncertain and the link was disconnected", + "client_commands": 5, + "name": "offline_receipt", + "pending_command_ids": [ + "command-24230a0f96bc4e84a84f720b1c974054" + ], + "screenshot": null, + "state": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Diagnostic link disconnected; cached observations are retained", + "state": "disconnected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 2, + "disturbance_test": false, + "error": "Restarted with a retained command stage; check its exact receipt", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Push the block right so its center enters the measurement zone.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "operation": "dispatch", + "reason": "Restarted with a retained command stage; check its exact receipt", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791828795.808469, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t75 checkbox Restart inspection 01 Needs attention, Value: 1\n\t\t\t76 checkbox Restart inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t77 text Restart inspection 01\n\t\t78 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t79 text Restarted with a retained command stage; check its exact receipt\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t80 text Body disconnected\n\t\t\t81 text Diagnostic link disconnected; cached observations are retained\n\t\t\t20 button Reconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t68 container\n\t\t\t\t69 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t70 text Test the simulated connection\n\t\t\t\t71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t72 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t73 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t74 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t82 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t83 text Retained observation \u00b7 body offline\n\t\t\t60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t84 text Retained \u00b7 offline \u00b7 generation 0\n\t\t85 text DISCONNECTED\n\t\t86 text The body connection is unavailable. The last camera observation is retained.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t87 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t88 text 21 events\n\t\t\t43 content list activity\n\t\t\t\t89 container\n\t\t\t\t\t90 text 02:13 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t91 container\n\t\t\t\t\t92 text 02:12 PM Agent stopped for review Restarted with a retained command stage; check its exact receipt\n\t\t\t\t93 container\n\t\t\t\t\t94 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t95 container\n\t\t\t\t\t96 text 02:12 PM Sending a guarded action\n\t\t\t\t97 container\n\t\t\t\t\t98 text 02:12 PM Action proposal accepted Restart inspection 01\n\t\t\t\t99 container\n\t\t\t\t\t100 text 02:12 PM Checking the planned action\n\t\t\t\t101 container\n\t\t\t\t\t102 text 02:12 PM AI planning requested Restart inspection 01\n\t\t\t\t103 container\n\t\t\t\t\t104 text 02:12 PM Camera observation received Restart inspection 01\n\t\t\t\t105 container\n\t\t\t\t\t106 text 02:12 PM Requesting camera observation\n\t\t\t\t107 container\n\t\t\t\t\t108 text 02:12 PM Agent resumed\n\t\t\t\t109 container\n\t\t\t\t\t110 text 02:12 PM Reply fault armed The next command reply will be lost.\n\t\t\t\t111 container\n\t\t\t\t\t112 text 02:10 PM Agent stopped for review operator_pause_requested\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t113 text 2 model requests \u00b7 Reported tokens: 13,063 input / 199 output \u00b7 Reporting incomplete (1 of 2 requests)\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Clicked Reconnect; the same unknown command remained blocked and no command was sent", + "client_commands": 5, + "name": "reconnected", + "pending_command_ids": [ + "command-24230a0f96bc4e84a84f720b1c974054" + ], + "screenshot": null, + "state": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 2, + "disturbance_test": false, + "error": "Restarted with a retained command stage; check its exact receipt", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Push the block right so its center enters the measurement zone.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "operation": "dispatch", + "reason": "Restarted with a retained command stage; check its exact receipt", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791828811.400429, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t75 checkbox Restart inspection 01 Needs attention, Value: 1\n\t\t\t76 checkbox Restart inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t77 text Restart inspection 01\n\t\t78 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t79 text Restarted with a retained command stage; check its exact receipt\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t80 text Body connected\n\t\t\t81 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button Check receipt, ID: reconcile\n\t\t\t68 container\n\t\t\t\t69 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t70 text Test the simulated connection\n\t\t\t\t71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t72 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t73 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t74 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t82 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t83 text Last observation \u00b7 Restart inspection 01\n\t\t\t60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t84 text Captured \u00b7 generation 0\n\t\t85 text OUTCOME UNCERTAIN\n\t\t86 text The command outcome is uncertain. Reconnect if needed, then check its receipt before continuing.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t87 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t88 text 22 events\n\t\t\t43 content list activity\n\t\t\t\t89 container\n\t\t\t\t\t90 text 02:13 PM Body reconnecting No command sent or replayed\n\t\t\t\t91 container\n\t\t\t\t\t92 text 02:13 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t93 container\n\t\t\t\t\t94 text 02:12 PM Agent stopped for review Restarted with a retained command stage; check its exact receipt\n\t\t\t\t95 container\n\t\t\t\t\t96 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t97 container\n\t\t\t\t\t98 text 02:12 PM Sending a guarded action\n\t\t\t\t99 container\n\t\t\t\t\t100 text 02:12 PM Action proposal accepted Restart inspection 01\n\t\t\t\t101 container\n\t\t\t\t\t102 text 02:12 PM Checking the planned action\n\t\t\t\t103 container\n\t\t\t\t\t104 text 02:12 PM AI planning requested Restart inspection 01\n\t\t\t\t105 container\n\t\t\t\t\t106 text 02:12 PM Camera observation received Restart inspection 01\n\t\t\t\t107 container\n\t\t\t\t\t108 text 02:12 PM Requesting camera observation\n\t\t\t\t109 container\n\t\t\t\t\t110 text 02:12 PM Agent resumed\n\t\t\t\t111 container\n\t\t\t\t\t112 text 02:12 PM Reply fault armed The next command reply will be lost.\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t113 text 2 model requests \u00b7 Reported tokens: 13,063 input / 199 output \u00b7 Reporting incomplete (1 of 2 requests)\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Clicked Check receipt after workbench restart; the exact historical command settled and remained paused without a new command", + "client_commands": 5, + "name": "recovered", + "pending_command_ids": [], + "screenshot": "tools/physical-workcell/output/sim11-browser-restarts-v2/ui/recovered.jpg", + "state": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 0, + "image_url": "/api/frame?generation=0&sha256=4fe3b2c26529a4b05ed8a8f0d72bfe586ceea6567dab4713011a550f6f12cbe7" + }, + "jobs": [ + { + "call_count": 2, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Push the block right so its center enters the measurement zone.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "paused", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-24230a0f96bc4e84a84f720b1c974054", + "operation": "dispatch", + "reason": "Exact historical stage recovered; explicit Resume observes fresh evidence", + "state": "recovered" + }, + "runner_status": "paused" + }, + "time": 1791828827.093657, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t75 checkbox Restart inspection 01 Paused, Value: 1\n\t\t\t76 checkbox Restart inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t77 text Restart inspection 01\n\t\t78 text Paused\n\t\t16 button Resume, ID: pause\n\t\t79 text Receipt recovered. The agent is paused; choose Resume to observe the bench again and continue.\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t80 text Body connected\n\t\t\t81 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t68 container\n\t\t\t\t69 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t70 text Test the simulated connection\n\t\t\t\t71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t72 button Lose next reply, ID: fault-drop\n\t\t\t\t73 button Delay next reply, ID: fault-delay\n\t\t\t\t74 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t82 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t83 text Last observation \u00b7 Restart inspection 01\n\t\t\t60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t84 text Captured \u00b7 generation 0\n\t\t85 text RECEIPT RECOVERED\n\t\t86 text The exact command receipt was recovered. The agent is paused until you resume.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t87 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t88 text 24 events\n\t\t\t90 content list activity\n\t\t\t\t91 container\n\t\t\t\t\t92 text 02:13 PM Command receipt recovered The agent remains paused until you resume.\n\t\t\t\t93 container\n\t\t\t\t\t94 text 02:13 PM Action receipt checked Restart inspection 01\n\t\t\t\t95 container\n\t\t\t\t\t96 text 02:13 PM Body reconnecting No command sent or replayed\n\t\t\t\t97 container\n\t\t\t\t\t98 text 02:13 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t99 container\n\t\t\t\t\t100 text 02:12 PM Agent stopped for review Restarted with a retained command stage; check its exact receipt\n\t\t\t\t101 container\n\t\t\t\t\t102 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t103 container\n\t\t\t\t\t104 text 02:12 PM Sending a guarded action\n\t\t\t\t105 container\n\t\t\t\t\t106 text 02:12 PM Action proposal accepted Restart inspection 01\n\t\t\t\t107 container\n\t\t\t\t\t108 text 02:12 PM Checking the planned action\n\t\t\t\t109 container\n\t\t\t\t\t110 text 02:12 PM AI planning requested Restart inspection 01\n\t\t\t\t111 container\n\t\t\t\t\t112 text 02:12 PM Camera observation received Restart inspection 01\n\t\t\t\t113 container\n\t\t\t\t\t114 text 02:12 PM Requesting camera observation\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t89 text 2 model requests \u00b7 Reported tokens: 13,063 input / 199 output \u00b7 Reporting incomplete (1 of 2 requests)\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Clicked Resume explicitly after receipt recovery; next step takes a fresh TCP camera observation", + "client_commands": 6, + "name": "resumed", + "pending_command_ids": [], + "screenshot": null, + "state": { + "active_job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 1, + "image_url": "/api/frame?generation=1&sha256=cb4221e600bbb24aec549f49924fc9224876a1ad8d04159fe0cc3798658d8357" + }, + "jobs": [ + { + "call_count": 3, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Push the block right so its center enters the measurement zone.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "running", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": true, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791828841.224544, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t91 checkbox Restart inspection 01 Paused, Value: 1\n\t\t\t92 checkbox Restart inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t93 text Restart inspection 01\n\t\t94 text Running\n\t\t16 button Pause, ID: pause\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t95 text Body connected\n\t\t\t96 text Current body boot verified for explicit Resume\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t68 container\n\t\t\t\t69 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t70 text Test the simulated connection\n\t\t\t\t71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t72 button Lose next reply, ID: fault-drop\n\t\t\t\t73 button Delay next reply, ID: fault-delay\n\t\t\t\t74 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t97 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t98 text Last observation \u00b7 Restart inspection 01\n\t\t\t60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t99 text Captured \u00b7 generation 0\n\t\t100 text AGENT\n\t\t101 text Push the block right so its center enters the measurement zone.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t102 text Pending\n\t\t\t38 text The part\u2019s visible footprint will be measured after its placement is verified.\n\t\t39 container Activity\n\t\t\t40 heading Activity, Value: 2, ID: activity-heading\n\t\t\t\t41 text Activity\n\t\t\t103 text 24 events\n\t\t\t90 content list activity\n\t\t\t\t104 container\n\t\t\t\t\t105 text 02:13 PM Requesting camera observation\n\t\t\t\t106 container\n\t\t\t\t\t107 text 02:13 PM Agent resumed\n\t\t\t\t108 container\n\t\t\t\t\t109 text 02:13 PM Command receipt recovered The agent remains paused until you resume.\n\t\t\t\t110 container\n\t\t\t\t\t111 text 02:13 PM Action receipt checked Restart inspection 01\n\t\t\t\t112 container\n\t\t\t\t\t113 text 02:13 PM Body reconnecting No command sent or replayed\n\t\t\t\t114 container\n\t\t\t\t\t115 text 02:13 PM Body disconnected Transport only; no body reset or replay\n\t\t\t\t116 container\n\t\t\t\t\t117 text 02:12 PM Agent stopped for review Restarted with a retained command stage; check its exact receipt\n\t\t\t\t118 container\n\t\t\t\t\t119 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending\n\t\t\t\t120 container\n\t\t\t\t\t121 text 02:12 PM Sending a guarded action\n\t\t\t\t122 container\n\t\t\t\t\t123 text 02:12 PM Action proposal accepted Restart inspection 01\n\t\t\t\t124 container\n\t\t\t\t\t125 text 02:12 PM Checking the planned action\n\t\t\t\t126 container\n\t\t\t\t\t127 text 02:12 PM AI planning requested Restart inspection 01\n\t\t50 button (collapsed) Session details, Secondary Actions: Expand\n\t\t\t51 text Session details\n\t\t128 text 2 model requests \u00b7 Reported tokens: 13,063 input / 199 output \u00b7 Reporting incomplete (1 of 2 requests)\n\nThe focused UI element is 1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/" + }, + { + "browser_action": "Clicked Check receipt after body reboot; historical boot-two command recovered while boot three remained paused; full UI capture retained separately", + "client_commands": 46, + "name": "body_uncertain_recovered", + "pending_command_ids": [], + "screenshot": "tools/physical-workcell/output/sim11-browser-restarts-v2/ui/body-uncertain-recovered.jpg", + "state": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 10, + "image_url": "/api/frame?generation=10&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 2, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Push the block right so its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "paused", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-cf898dd6e56a4d8bb0a5894371f9ba81", + "operation": "dispatch", + "reason": "Exact historical stage recovered; explicit Resume observes fresh evidence", + "state": "recovered" + }, + "runner_status": "paused" + }, + "time": 1791829096.6301959, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t105 checkbox Restart inspection 01 Completed, Value: 0\n\t\t\t106 checkbox Restart inspection 02 Paused, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t107 text Restart inspection 02\n\t\t108 text Paused\n\t\t16 button Resume, ID: pause\n\t\t109 text Receipt recovered. The agent is paused; choose Resume to observe the bench again and continue.\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t110 text Body connected\n\t\t\t111 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t68 container\n\t\t\t\t69 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t70 text Test the simulated connection\n\t\t\t\t71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t72 button Lose next reply, ID: fault-drop\n\t\t\t\t73 button Delay next reply, ID: fault-delay\n\t\t\t\t74 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t112 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t113 text Last observation \u00b7 Restart inspection 02\n\t\t\t60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t114 text Captured \u00b7 generation 10\n\t\t115 text RECEIPT RECOVERED\n\t\t116 text The exact command receipt was recovered. The agent is paused until you resume.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t117 text Pending\n\t\t\t104 text The part\u2019s visible footprint will be measured after its placement is verified.\n[Main-panel excerpt; full browser capture is body-uncertain-recovered.txt]\n" + }, + { + "browser_action": "Clicked Resume explicitly after boot-two receipt recovery; the next decision receives a fresh boot-three TCP image; full UI capture retained separately", + "client_commands": 47, + "name": "body_uncertain_resumed", + "pending_command_ids": [], + "screenshot": null, + "state": { + "active_job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 11, + "image_url": "/api/frame?generation=11&sha256=0d42c93fef97b6bf1ded19965b65518e43b873916c9e8bc1d8300debf130f9fa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 3, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Push the block right so its center reaches the measurement region.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "running", + "target": "B" + } + ], + "model_request_pending": true, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791829107.8461351, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t105 checkbox Restart inspection 01 Completed, Value: 0\n\t\t\t106 checkbox Restart inspection 02 Paused, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t107 text Restart inspection 02\n\t\t108 text Running\n\t\t16 button Pause, ID: pause\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t109 text Body connected\n\t\t\t110 text Current body boot verified for explicit Resume\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t68 container\n\t\t\t\t69 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t70 text Test the simulated connection\n\t\t\t\t71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t72 button Lose next reply, ID: fault-drop\n\t\t\t\t73 button Delay next reply, ID: fault-delay\n\t\t\t\t74 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t111 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t112 text Last observation \u00b7 Restart inspection 02\n\t\t\t60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t113 text Captured \u00b7 generation 10\n\t\t114 text AGENT\n\t\t115 text Push the block right so its center reaches the measurement region.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t116 text Pending\n\t\t\t104 text The part\u2019s visible footprint will be measured after its placement is verified.\n[Main-panel excerpt; full browser capture is body-uncertain-resumed.txt]\n" + }, + { + "browser_action": "Observed both jobs completed after all four restart recoveries and one explicit health-timeout resume; full browser capture retained separately", + "client_commands": 83, + "name": "completed", + "pending_command_ids": [], + "screenshot": "tools/physical-workcell/output/sim11-browser-restarts-v2/ui/completed.jpg", + "state": { + "active_job_id": null, + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 20, + "image_url": "/api/frame?generation=20&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 15, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Finish reset with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 20, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "kind": "finish_reset", + "native_time_s": 42.630000000006135, + "operation_id": "agent-7acee30a3cb442d9a3a2b3a9bfec10ed", + "pusher_home_verified": true, + "reset_contact_samples": 3314, + "reset_native_steps": 8140, + "state_sha256": "02c49f9f03f16f8de552b4b4ce57b6d78c85e291fc3dbf1b6acb0ce4b7cd638b" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791829354.9904199, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t140 checkbox Restart inspection 01 Completed, Value: 0\n\t\t\t141 checkbox Restart inspection 02 Completed, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t142 text Restart inspection 02\n\t\t143 text Running\n\t\t16 button Pause, ID: pause\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t144 text Body connected\n\t\t\t145 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t68 container\n\t\t\t\t69 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t70 text Test the simulated connection\n\t\t\t\t71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t72 button Lose next reply, ID: fault-drop\n\t\t\t\t73 button Delay next reply, ID: fault-delay\n\t\t\t\t74 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t146 text No reply fault armed.\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t147 text Last camera observation\n\t\t\t60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t148 text Captured \u00b7 generation 20\n\t\t149 text COMPLETED\n\t\t150 text Measurement recorded and reset verified. The bench is ready for another job.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t151 text Historical result\n\t\t\t132 container measurement-result\n\t\t\t\t152 text 1,729\n\t\t\t\t134 text Orange pixels\n\t\t\t\t135 container\n\t\t\t\t\t153 text 4,802.8\n\t\t\t\t\t137 text mm\u00b2\n\t\t\t\t138 text Apparent footprint\n\t\t\t\t139 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment.\n\t\t\t154 button Repeat job, ID: repeat\n[Main-panel excerpt; full browser capture is completed.txt]\n" + }, + { + "browser_action": "Reloaded the browser; completed job records and the 83-command journal remained identical with no replay; full capture retained separately", + "client_commands": 83, + "name": "reloaded", + "pending_command_ids": [], + "screenshot": null, + "state": { + "active_job_id": null, + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "connection": { + "adapter_id": "96943574039142dda13cb620decfddf0", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "epoch": 3, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 20, + "image_url": "/api/frame?generation=20&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "label": "Restart inspection 01", + "last_intent": "Request verification with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 10, + "image_sha256": "b404f8a09f6ccd21c78edfec024e7e3e940c21146aeeaa3f58975e6aee8a7e87", + "job_id": "20eb6586-e73a-4db4-aaac-db3e5d537329", + "kind": "finish_reset", + "native_time_s": 21.679999999998863, + "operation_id": "agent-e8227a121d794919a11b4e108dff63f6", + "pusher_home_verified": true, + "reset_contact_samples": 3174, + "reset_native_steps": 8106, + "state_sha256": "f403fd1d61afe7bb83d4a4ff3dd9aa56936c5dbe9d0a709af793549130097d0e" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 15, + "disturbance_test": false, + "error": null, + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "label": "Restart inspection 02", + "last_intent": "Finish reset with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "a26eb04332df4e1e9f3f0f307db47644", + "block_home_verified": true, + "generation": 20, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "c922a26d-9121-4d7e-82e1-7b61b0e42161", + "kind": "finish_reset", + "native_time_s": 42.630000000006135, + "operation_id": "agent-7acee30a3cb442d9a3a2b3a9bfec10ed", + "pusher_home_verified": true, + "reset_contact_samples": 3314, + "reset_native_steps": 8140, + "state_sha256": "02c49f9f03f16f8de552b4b4ce57b6d78c85e291fc3dbf1b6acb0ce4b7cd638b" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791829364.1247208, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t9 checkbox Restart inspection 01 Completed, Value: 0\n\t\t\t10 checkbox Restart inspection 02 Completed, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t14 text Restart inspection 02\n\t\t15 text Running\n\t\t16 button Pause, ID: pause\n\t\t17 container Description: Body connection, ID: network-card\n\t\t\t18 text Body connected\n\t\t\t19 text Body identity verified by read-only TCP health\n\t\t\t20 button Disconnect, ID: disconnect\n\t\t\t21 button (disabled) Check receipt, ID: reconcile\n\t\t\t22 button (collapsed) Test the simulated connection, Secondary Actions: Expand\n\t\t\t\t23 text Test the simulated connection\n\t\t24 container Camera observation\n\t\t\t25 text OVERHEAD CAMERA\n\t\t\t26 text Last camera observation\n\t\t\t27 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t28 text Orange part Blue pusher Green task region\n\t\t\t29 text Captured \u00b7 generation 20\n\t\t30 text COMPLETED\n\t\t31 text Measurement recorded and reset verified. The bench is ready for another job.\n\t\t32 container Job progress\n\t\t\t33 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t34 container Measurement\n\t\t\t35 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t36 text Measurement\n\t\t\t37 text Historical result\n\t\t\t38 container measurement-result\n\t\t\t\t39 text 1,729\n\t\t\t\t40 text Orange pixels\n\t\t\t\t41 container\n\t\t\t\t\t42 text 4,802.8\n\t\t\t\t\t43 text mm\u00b2\n\t\t\t\t44 text Apparent footprint\n\t\t\t\t45 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment.\n\t\t\t46 button Repeat job, ID: repeat\n[Main-panel excerpt; full browser capture is reloaded.txt]\n" + } + ] +} diff --git a/jevdual/results/workbench-restarts-20261012/ui/body-planning-offline.jpg b/jevdual/results/workbench-restarts-20261012/ui/body-planning-offline.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a415cba640c1375d9f70c8242c54a74f0dc37362 GIT binary patch literal 88282 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 literal 0 HcmV?d00001 diff --git a/jevdual/results/workbench-restarts-20261012/ui/body-planning-offline.txt b/jevdual/results/workbench-restarts-20261012/ui/body-planning-offline.txt new file mode 100644 index 0000000..0681d30 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/body-planning-offline.txt @@ -0,0 +1,80 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button (disabled) + New job, ID: new-job + 8 container queue + 105 checkbox Restart inspection 01 Completed, Value: 0 + 106 checkbox Restart inspection 02 Paused, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 107 text Restart inspection 02 + 108 text Paused + 16 button (disabled) Resume, ID: pause + 109 text Remote end closed connection without response + 17 container Description: Body connection, ID: network-card + 110 text Body unavailable + 111 text Remote end closed connection without response + 20 button Reconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button (disabled) Lose next reply, ID: fault-drop + 73 button (disabled) Delay next reply, ID: fault-delay + 74 button (disabled) Duplicate next command, ID: fault-duplicate + 112 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 113 text Retained observation · body offline + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 114 text Retained · offline · generation 10 + 115 text DISCONNECTED + 116 text The body connection is unavailable. The last camera observation is retained. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 117 text Pending + 104 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 118 text 24 events + 90 content list activity + 119 container + 120 text 02:15 PM Agent stopped for review operator_pause_requested + 121 container + 122 text 02:15 PM Agent stopped for review Remote end closed connection without response + 123 container + 124 text 02:15 PM AI planning requested Restart inspection 02 + 125 container + 126 text 02:15 PM Camera observation received Restart inspection 02 + 127 container + 128 text 02:15 PM Requesting camera observation + 129 container + 130 text 02:15 PM Inspection started Restart inspection 02 + 131 container + 132 text 02:15 PM Preparing inspection + 133 container + 134 text 02:15 PM Action receipt checked Restart inspection 01 + 135 container + 136 text 02:15 PM Sending a guarded action + 137 container + 138 text 02:15 PM Action proposal accepted Restart inspection 01 + 139 container + 140 text 02:15 PM Checking the planned action + 141 container + 142 text 02:15 PM AI planning requested Restart inspection 01 + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 143 text 15 model requests · Reported tokens: 172,372 input / 2,008 output · Reporting incomplete (13 of 15 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/body-planning-restored.txt b/jevdual/results/workbench-restarts-20261012/ui/body-planning-restored.txt new file mode 100644 index 0000000..1eb041e --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/body-planning-restored.txt @@ -0,0 +1,80 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 105 checkbox Restart inspection 01 Completed, Value: 0 + 106 checkbox Restart inspection 02 Paused, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 107 text Restart inspection 02 + 108 text Paused + 16 button Resume, ID: pause + 109 text Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image + 17 container Description: Body connection, ID: network-card + 110 text Body connected + 111 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button Lose next reply, ID: fault-drop + 73 button Delay next reply, ID: fault-delay + 74 button Duplicate next command, ID: fault-duplicate + 112 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 113 text Last observation · Restart inspection 02 + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 114 text Captured · generation 10 + 115 text PAUSED + 116 text Paused. Resume when you are ready for the next action. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 117 text Pending + 104 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 118 text 24 events + 90 content list activity + 119 container + 120 text 02:16 PM Body restarted 1 -> 2 + 121 container + 122 text 02:16 PM Agent stopped for review Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image + 123 container + 124 text 02:15 PM Agent stopped for review operator_pause_requested + 125 container + 126 text 02:15 PM Agent stopped for review Remote end closed connection without response + 127 container + 128 text 02:15 PM AI planning requested Restart inspection 02 + 129 container + 130 text 02:15 PM Camera observation received Restart inspection 02 + 131 container + 132 text 02:15 PM Requesting camera observation + 133 container + 134 text 02:15 PM Inspection started Restart inspection 02 + 135 container + 136 text 02:15 PM Preparing inspection + 137 container + 138 text 02:15 PM Action receipt checked Restart inspection 01 + 139 container + 140 text 02:15 PM Sending a guarded action + 141 container + 142 text 02:15 PM Action proposal accepted Restart inspection 01 + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 143 text 15 model requests · Reported tokens: 172,372 input / 2,008 output · Reporting incomplete (13 of 15 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/body-planning-resumed.txt b/jevdual/results/workbench-restarts-20261012/ui/body-planning-resumed.txt new file mode 100644 index 0000000..b8706cb --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/body-planning-resumed.txt @@ -0,0 +1,80 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 105 checkbox Restart inspection 01 Completed, Value: 0 + 106 checkbox Restart inspection 02 Paused, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 107 text Restart inspection 02 + 108 text Running + 16 button Pause, ID: pause + 109 text Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image + 17 container Description: Body connection, ID: network-card + 110 text Body connected + 111 text Current body boot verified for explicit Resume + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button (disabled) Lose next reply, ID: fault-drop + 73 button (disabled) Delay next reply, ID: fault-delay + 74 button (disabled) Duplicate next command, ID: fault-duplicate + 112 text The next command reply will be lost. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 113 text Last observation · Restart inspection 02 + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 114 text Captured · generation 10 + 115 text AGENT + 116 text Waiting for the agent’s next observation. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 117 text Pending + 104 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 118 text 24 events + 90 content list activity + 119 container + 120 text 02:16 PM Agent resumed + 121 container + 122 text 02:16 PM Reply fault armed The next command reply will be lost. + 123 container + 124 text 02:16 PM Body restarted 1 -> 2 + 125 container + 126 text 02:16 PM Agent stopped for review Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image + 127 container + 128 text 02:15 PM Agent stopped for review operator_pause_requested + 129 container + 130 text 02:15 PM Agent stopped for review Remote end closed connection without response + 131 container + 132 text 02:15 PM AI planning requested Restart inspection 02 + 133 container + 134 text 02:15 PM Camera observation received Restart inspection 02 + 135 container + 136 text 02:15 PM Requesting camera observation + 137 container + 138 text 02:15 PM Inspection started Restart inspection 02 + 139 container + 140 text 02:15 PM Preparing inspection + 141 container + 142 text 02:15 PM Action receipt checked Restart inspection 01 + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 143 text 15 model requests · Reported tokens: 172,372 input / 2,008 output · Reporting incomplete (13 of 15 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-before.txt b/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-before.txt new file mode 100644 index 0000000..c54b336 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-before.txt @@ -0,0 +1,80 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button (disabled) + New job, ID: new-job + 8 container queue + 105 checkbox Restart inspection 01 Completed, Value: 0 + 106 checkbox Restart inspection 02 Needs attention, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 107 text Restart inspection 02 + 108 text Needs attention + 16 button (disabled) Pause, ID: pause + 109 text reply is uncertain; reconcile exact command without resending + 17 container Description: Body connection, ID: network-card + 110 text Body connected + 111 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button (disabled) Lose next reply, ID: fault-drop + 73 button (disabled) Delay next reply, ID: fault-delay + 74 button (disabled) Duplicate next command, ID: fault-duplicate + 112 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 113 text Last observation · Restart inspection 02 + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 114 text Captured · generation 10 + 115 text OUTCOME UNCERTAIN + 116 text The command outcome is uncertain. Reconnect if needed, then check its receipt before continuing. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 117 text Pending + 104 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 118 text 24 events + 90 content list activity + 119 container + 120 text 02:17 PM Agent stopped for review reply is uncertain; reconcile exact command without resending + 121 container + 122 text 02:17 PM Sending a guarded action + 123 container + 124 text 02:17 PM Action proposal accepted Restart inspection 02 + 125 container + 126 text 02:17 PM Checking the planned action + 127 container + 128 text 02:17 PM AI planning requested Restart inspection 02 + 129 container + 130 text 02:17 PM Camera observation received Restart inspection 02 + 131 container + 132 text 02:16 PM Requesting camera observation + 133 container + 134 text 02:16 PM Agent resumed + 135 container + 136 text 02:16 PM Reply fault armed The next command reply will be lost. + 137 container + 138 text 02:16 PM Body restarted 1 -> 2 + 139 container + 140 text 02:16 PM Agent stopped for review Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image + 141 container + 142 text 02:15 PM Agent stopped for review operator_pause_requested + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 143 text 16 model requests · Reported tokens: 185,456 input / 2,222 output · Reporting incomplete (14 of 16 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-offline.txt b/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-offline.txt new file mode 100644 index 0000000..c5250da --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-offline.txt @@ -0,0 +1,80 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button (disabled) + New job, ID: new-job + 8 container queue + 105 checkbox Restart inspection 01 Completed, Value: 0 + 106 checkbox Restart inspection 02 Paused, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 107 text Restart inspection 02 + 108 text Paused + 16 button (disabled) Resume, ID: pause + 109 text reply is uncertain; reconcile exact command without resending + 17 container Description: Body connection, ID: network-card + 110 text Body unavailable + 111 text Remote end closed connection without response + 20 button Reconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button (disabled) Lose next reply, ID: fault-drop + 73 button (disabled) Delay next reply, ID: fault-delay + 74 button (disabled) Duplicate next command, ID: fault-duplicate + 112 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 113 text Retained observation · body offline + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 114 text Retained · offline · generation 10 + 115 text DISCONNECTED + 116 text The body connection is unavailable. The last camera observation is retained. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 117 text Pending + 104 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 118 text 24 events + 90 content list activity + 119 container + 120 text 02:17 PM Agent stopped for review Remote end closed connection without response + 121 container + 122 text 02:17 PM Agent stopped for review reply is uncertain; reconcile exact command without resending + 123 container + 124 text 02:17 PM Sending a guarded action + 125 container + 126 text 02:17 PM Action proposal accepted Restart inspection 02 + 127 container + 128 text 02:17 PM Checking the planned action + 129 container + 130 text 02:17 PM AI planning requested Restart inspection 02 + 131 container + 132 text 02:17 PM Camera observation received Restart inspection 02 + 133 container + 134 text 02:16 PM Requesting camera observation + 135 container + 136 text 02:16 PM Agent resumed + 137 container + 138 text 02:16 PM Reply fault armed The next command reply will be lost. + 139 container + 140 text 02:16 PM Body restarted 1 -> 2 + 141 container + 142 text 02:16 PM Agent stopped for review Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 143 text 16 model requests · Reported tokens: 185,456 input / 2,222 output · Reporting incomplete (14 of 16 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-recovered.jpg b/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-recovered.jpg new file mode 100644 index 0000000000000000000000000000000000000000..73a441ccc1039d2d7cb62ee2f7edbda0be13b7ae GIT binary patch literal 91223 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
    7K;r@X2AHT5ILF-7hUs(YrO6n- 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 ua?>3z(fUgfB8jxpr^#%P_lq 3 + 121 container + 122 text 02:18 PM Agent stopped for review Body restarted from boot 2 to 3; check pending receipts and explicitly Resume for a fresh image + 123 container + 124 text 02:17 PM Agent stopped for review Remote end closed connection without response + 125 container + 126 text 02:17 PM Agent stopped for review reply is uncertain; reconcile exact command without resending + 127 container + 128 text 02:17 PM Sending a guarded action + 129 container + 130 text 02:17 PM Action proposal accepted Restart inspection 02 + 131 container + 132 text 02:17 PM Checking the planned action + 133 container + 134 text 02:17 PM AI planning requested Restart inspection 02 + 135 container + 136 text 02:17 PM Camera observation received Restart inspection 02 + 137 container + 138 text 02:16 PM Requesting camera observation + 139 container + 140 text 02:16 PM Agent resumed + 141 container + 142 text 02:16 PM Reply fault armed The next command reply will be lost. + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 143 text 16 model requests · Reported tokens: 185,456 input / 2,222 output · Reporting incomplete (14 of 16 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-resumed.ledger.txt b/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-resumed.ledger.txt new file mode 100644 index 0000000..6555e7e --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-resumed.ledger.txt @@ -0,0 +1,46 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 105 checkbox Restart inspection 01 Completed, Value: 0 + 106 checkbox Restart inspection 02 Paused, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 107 text Restart inspection 02 + 108 text Running + 16 button Pause, ID: pause + 17 container Description: Body connection, ID: network-card + 109 text Body connected + 110 text Current body boot verified for explicit Resume + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button Lose next reply, ID: fault-drop + 73 button Delay next reply, ID: fault-delay + 74 button Duplicate next command, ID: fault-duplicate + 111 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 112 text Last observation · Restart inspection 02 + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 113 text Captured · generation 10 + 114 text AGENT + 115 text Push the block right so its center reaches the measurement region. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 116 text Pending + 104 text The part’s visible footprint will be measured after its placement is verified. +[Main-panel excerpt; full browser capture is body-uncertain-resumed.txt] diff --git a/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-resumed.txt b/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-resumed.txt new file mode 100644 index 0000000..efcbbe6 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/body-uncertain-resumed.txt @@ -0,0 +1,79 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 105 checkbox Restart inspection 01 Completed, Value: 0 + 106 checkbox Restart inspection 02 Paused, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 107 text Restart inspection 02 + 108 text Running + 16 button Pause, ID: pause + 17 container Description: Body connection, ID: network-card + 109 text Body connected + 110 text Current body boot verified for explicit Resume + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button Lose next reply, ID: fault-drop + 73 button Delay next reply, ID: fault-delay + 74 button Duplicate next command, ID: fault-duplicate + 111 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 112 text Last observation · Restart inspection 02 + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 113 text Captured · generation 10 + 114 text AGENT + 115 text Push the block right so its center reaches the measurement region. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 116 text Pending + 104 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 117 text 24 events + 118 content list activity + 119 container + 120 text 02:18 PM Agent resumed + 121 container + 122 text 02:18 PM Command receipt recovered The agent remains paused until you resume. + 123 container + 124 text 02:18 PM Action receipt checked Restart inspection 02 + 125 container + 126 text 02:18 PM Body restarted 2 -> 3 + 127 container + 128 text 02:18 PM Agent stopped for review Body restarted from boot 2 to 3; check pending receipts and explicitly Resume for a fresh image + 129 container + 130 text 02:17 PM Agent stopped for review Remote end closed connection without response + 131 container + 132 text 02:17 PM Agent stopped for review reply is uncertain; reconcile exact command without resending + 133 container + 134 text 02:17 PM Sending a guarded action + 135 container + 136 text 02:17 PM Action proposal accepted Restart inspection 02 + 137 container + 138 text 02:17 PM Checking the planned action + 139 container + 140 text 02:17 PM AI planning requested Restart inspection 02 + 141 container + 142 text 02:17 PM Camera observation received Restart inspection 02 + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 143 text 16 model requests · Reported tokens: 185,456 input / 2,222 output · Reporting incomplete (14 of 16 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/completed.ledger.txt b/jevdual/results/workbench-restarts-20261012/ui/completed.ledger.txt new file mode 100644 index 0000000..f1886a3 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/completed.ledger.txt @@ -0,0 +1,54 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 140 checkbox Restart inspection 01 Completed, Value: 0 + 141 checkbox Restart inspection 02 Completed, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 142 text Restart inspection 02 + 143 text Running + 16 button Pause, ID: pause + 17 container Description: Body connection, ID: network-card + 144 text Body connected + 145 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button Lose next reply, ID: fault-drop + 73 button Delay next reply, ID: fault-delay + 74 button Duplicate next command, ID: fault-duplicate + 146 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 147 text Last camera observation + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 148 text Captured · generation 20 + 149 text COMPLETED + 150 text Measurement recorded and reset verified. The bench is ready for another job. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 151 text Historical result + 132 container measurement-result + 152 text 1,729 + 134 text Orange pixels + 135 container + 153 text 4,802.8 + 137 text mm² + 138 text Apparent footprint + 139 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI’s judgment. + 154 button Repeat job, ID: repeat +[Main-panel excerpt; full browser capture is completed.txt] diff --git a/jevdual/results/workbench-restarts-20261012/ui/completed.txt b/jevdual/results/workbench-restarts-20261012/ui/completed.txt new file mode 100644 index 0000000..10318ae --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/completed.txt @@ -0,0 +1,87 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 140 checkbox Restart inspection 01 Completed, Value: 0 + 141 checkbox Restart inspection 02 Completed, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 142 text Restart inspection 02 + 143 text Running + 16 button Pause, ID: pause + 17 container Description: Body connection, ID: network-card + 144 text Body connected + 145 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button Lose next reply, ID: fault-drop + 73 button Delay next reply, ID: fault-delay + 74 button Duplicate next command, ID: fault-duplicate + 146 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 147 text Last camera observation + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 148 text Captured · generation 20 + 149 text COMPLETED + 150 text Measurement recorded and reset verified. The bench is ready for another job. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 151 text Historical result + 132 container measurement-result + 152 text 1,729 + 134 text Orange pixels + 135 container + 153 text 4,802.8 + 137 text mm² + 138 text Apparent footprint + 139 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI’s judgment. + 154 button Repeat job, ID: repeat + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 155 text 24 events + 118 content list activity + 156 container + 157 text 02:21 PM Action receipt checked Restart inspection 02 + 158 container + 159 text 02:21 PM Sending a guarded action + 160 container + 161 text 02:21 PM Action proposal accepted Restart inspection 02 + 162 container + 163 text 02:21 PM Checking the planned action + 164 container + 165 text 02:21 PM AI planning requested Restart inspection 02 + 166 container + 167 text 02:21 PM Camera observation received Restart inspection 02 + 168 container + 169 text 02:21 PM Requesting camera observation + 170 container + 171 text 02:21 PM Agent resumed + 172 container + 173 text 02:20 PM Agent stopped for review timed out + 174 container + 175 text 02:20 PM Agent stopped for review timed out + 176 container + 177 text 02:20 PM Agent stopped for review timed out + 178 container + 179 text 02:20 PM Agent stopped for review timed out + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 180 text 29 model requests · Reported tokens: 343,310 input / 3,963 output · Reporting incomplete (26 of 29 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/disconnected.txt b/jevdual/results/workbench-restarts-20261012/ui/disconnected.txt new file mode 100644 index 0000000..11d90ad --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/disconnected.txt @@ -0,0 +1,80 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button (disabled) + New job, ID: new-job + 8 container queue + 75 checkbox Restart inspection 01 Needs attention, Value: 1 + 76 checkbox Restart inspection 02 Queued, Value: 0 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 77 text Restart inspection 01 + 78 text Needs attention + 16 button (disabled) Pause, ID: pause + 79 text Restarted with a retained command stage; check its exact receipt + 17 container Description: Body connection, ID: network-card + 80 text Body disconnected + 81 text Diagnostic link disconnected; cached observations are retained + 20 button Reconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button (disabled) Lose next reply, ID: fault-drop + 73 button (disabled) Delay next reply, ID: fault-delay + 74 button (disabled) Duplicate next command, ID: fault-duplicate + 82 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 83 text Retained observation · body offline + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 84 text Retained · offline · generation 0 + 85 text DISCONNECTED + 86 text The body connection is unavailable. The last camera observation is retained. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 87 text Pending + 38 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 88 text 21 events + 43 content list activity + 89 container + 90 text 02:13 PM Body disconnected Transport only; no body reset or replay + 91 container + 92 text 02:12 PM Agent stopped for review Restarted with a retained command stage; check its exact receipt + 93 container + 94 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending + 95 container + 96 text 02:12 PM Sending a guarded action + 97 container + 98 text 02:12 PM Action proposal accepted Restart inspection 01 + 99 container + 100 text 02:12 PM Checking the planned action + 101 container + 102 text 02:12 PM AI planning requested Restart inspection 01 + 103 container + 104 text 02:12 PM Camera observation received Restart inspection 01 + 105 container + 106 text 02:12 PM Requesting camera observation + 107 container + 108 text 02:12 PM Agent resumed + 109 container + 110 text 02:12 PM Reply fault armed The next command reply will be lost. + 111 container + 112 text 02:10 PM Agent stopped for review operator_pause_requested + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 113 text 2 model requests · Reported tokens: 13,063 input / 199 output · Reporting incomplete (1 of 2 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/handoff.jpg b/jevdual/results/workbench-restarts-20261012/ui/handoff.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ad7eff3d97b62819c47706c4333adb1ed4d80490 GIT binary patch literal 74170 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 literal 0 HcmV?d00001 diff --git a/jevdual/results/workbench-restarts-20261012/ui/handoff.txt b/jevdual/results/workbench-restarts-20261012/ui/handoff.txt new file mode 100644 index 0000000..484d03a --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/handoff.txt @@ -0,0 +1,81 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 9 checkbox Restart inspection 01 Completed, Value: 0 + 10 checkbox Restart inspection 02 Completed, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 14 text Restart inspection 02 + 15 text Paused + 16 button Resume, ID: pause + 17 container Description: Body connection, ID: network-card + 18 text Body connected + 19 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 22 button (collapsed) Test the simulated connection, Secondary Actions: Expand + 23 text Test the simulated connection + 24 container Camera observation + 25 text OVERHEAD CAMERA + 26 text Last camera observation + 27 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 29 text Captured · generation 20 + 30 text COMPLETED + 31 text Measurement recorded and reset verified. The bench is ready for another job. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 37 text Historical result + 38 container measurement-result + 39 text 1,729 + 40 text Orange pixels + 41 container + 42 text 4,802.8 + 43 text mm² + 44 text Apparent footprint + 45 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI’s judgment. + 46 button Repeat job, ID: repeat + 47 container Activity + 48 heading Activity, Value: 2, ID: activity-heading + 49 text Activity + 50 text 24 events + 51 content list activity + 52 container + 53 text 02:23 PM Body restarted 3 -> 4 + 54 container + 55 text 02:23 PM Agent stopped for review Body restarted from boot 3 to 4; check pending receipts and explicitly Resume for a fresh image + 56 container + 57 text 02:21 PM Action receipt checked Restart inspection 02 + 58 container + 59 text 02:21 PM Sending a guarded action + 60 container + 61 text 02:21 PM Action proposal accepted Restart inspection 02 + 62 container + 63 text 02:21 PM Checking the planned action + 64 container + 65 text 02:21 PM AI planning requested Restart inspection 02 + 66 container + 67 text 02:21 PM Camera observation received Restart inspection 02 + 68 container + 69 text 02:21 PM Requesting camera observation + 70 container + 71 text 02:21 PM Agent resumed + 72 container + 73 text 02:20 PM Agent stopped for review timed out + 74 container + 75 text 02:20 PM Agent stopped for review timed out + 76 button (collapsed) Session details, Secondary Actions: Expand + 77 text Session details + 78 text 29 model requests · Reported tokens: 343,310 input / 3,963 output · Reporting incomplete (26 of 29 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/reconnected.txt b/jevdual/results/workbench-restarts-20261012/ui/reconnected.txt new file mode 100644 index 0000000..60158fc --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/reconnected.txt @@ -0,0 +1,80 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button (disabled) + New job, ID: new-job + 8 container queue + 75 checkbox Restart inspection 01 Needs attention, Value: 1 + 76 checkbox Restart inspection 02 Queued, Value: 0 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 77 text Restart inspection 01 + 78 text Needs attention + 16 button (disabled) Pause, ID: pause + 79 text Restarted with a retained command stage; check its exact receipt + 17 container Description: Body connection, ID: network-card + 80 text Body connected + 81 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button (disabled) Lose next reply, ID: fault-drop + 73 button (disabled) Delay next reply, ID: fault-delay + 74 button (disabled) Duplicate next command, ID: fault-duplicate + 82 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 83 text Last observation · Restart inspection 01 + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 84 text Captured · generation 0 + 85 text OUTCOME UNCERTAIN + 86 text The command outcome is uncertain. Reconnect if needed, then check its receipt before continuing. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 87 text Pending + 38 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 88 text 22 events + 43 content list activity + 89 container + 90 text 02:13 PM Body reconnecting No command sent or replayed + 91 container + 92 text 02:13 PM Body disconnected Transport only; no body reset or replay + 93 container + 94 text 02:12 PM Agent stopped for review Restarted with a retained command stage; check its exact receipt + 95 container + 96 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending + 97 container + 98 text 02:12 PM Sending a guarded action + 99 container + 100 text 02:12 PM Action proposal accepted Restart inspection 01 + 101 container + 102 text 02:12 PM Checking the planned action + 103 container + 104 text 02:12 PM AI planning requested Restart inspection 01 + 105 container + 106 text 02:12 PM Camera observation received Restart inspection 01 + 107 container + 108 text 02:12 PM Requesting camera observation + 109 container + 110 text 02:12 PM Agent resumed + 111 container + 112 text 02:12 PM Reply fault armed The next command reply will be lost. + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 113 text 2 model requests · Reported tokens: 13,063 input / 199 output · Reporting incomplete (1 of 2 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/recovered.txt b/jevdual/results/workbench-restarts-20261012/ui/recovered.txt new file mode 100644 index 0000000..c2a4669 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/recovered.txt @@ -0,0 +1,80 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 75 checkbox Restart inspection 01 Paused, Value: 1 + 76 checkbox Restart inspection 02 Queued, Value: 0 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 77 text Restart inspection 01 + 78 text Paused + 16 button Resume, ID: pause + 79 text Receipt recovered. The agent is paused; choose Resume to observe the bench again and continue. + 17 container Description: Body connection, ID: network-card + 80 text Body connected + 81 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button Lose next reply, ID: fault-drop + 73 button Delay next reply, ID: fault-delay + 74 button Duplicate next command, ID: fault-duplicate + 82 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 83 text Last observation · Restart inspection 01 + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 84 text Captured · generation 0 + 85 text RECEIPT RECOVERED + 86 text The exact command receipt was recovered. The agent is paused until you resume. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 87 text Pending + 38 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 88 text 24 events + 90 content list activity + 91 container + 92 text 02:13 PM Command receipt recovered The agent remains paused until you resume. + 93 container + 94 text 02:13 PM Action receipt checked Restart inspection 01 + 95 container + 96 text 02:13 PM Body reconnecting No command sent or replayed + 97 container + 98 text 02:13 PM Body disconnected Transport only; no body reset or replay + 99 container + 100 text 02:12 PM Agent stopped for review Restarted with a retained command stage; check its exact receipt + 101 container + 102 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending + 103 container + 104 text 02:12 PM Sending a guarded action + 105 container + 106 text 02:12 PM Action proposal accepted Restart inspection 01 + 107 container + 108 text 02:12 PM Checking the planned action + 109 container + 110 text 02:12 PM AI planning requested Restart inspection 01 + 111 container + 112 text 02:12 PM Camera observation received Restart inspection 01 + 113 container + 114 text 02:12 PM Requesting camera observation + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 89 text 2 model requests · Reported tokens: 13,063 input / 199 output · Reporting incomplete (1 of 2 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/reloaded.ledger.txt b/jevdual/results/workbench-restarts-20261012/ui/reloaded.ledger.txt new file mode 100644 index 0000000..e8de9a0 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/reloaded.ledger.txt @@ -0,0 +1,48 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 9 checkbox Restart inspection 01 Completed, Value: 0 + 10 checkbox Restart inspection 02 Completed, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 14 text Restart inspection 02 + 15 text Running + 16 button Pause, ID: pause + 17 container Description: Body connection, ID: network-card + 18 text Body connected + 19 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 22 button (collapsed) Test the simulated connection, Secondary Actions: Expand + 23 text Test the simulated connection + 24 container Camera observation + 25 text OVERHEAD CAMERA + 26 text Last camera observation + 27 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 29 text Captured · generation 20 + 30 text COMPLETED + 31 text Measurement recorded and reset verified. The bench is ready for another job. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 37 text Historical result + 38 container measurement-result + 39 text 1,729 + 40 text Orange pixels + 41 container + 42 text 4,802.8 + 43 text mm² + 44 text Apparent footprint + 45 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI’s judgment. + 46 button Repeat job, ID: repeat +[Main-panel excerpt; full browser capture is reloaded.txt] diff --git a/jevdual/results/workbench-restarts-20261012/ui/reloaded.txt b/jevdual/results/workbench-restarts-20261012/ui/reloaded.txt new file mode 100644 index 0000000..b4d3765 --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/reloaded.txt @@ -0,0 +1,81 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 9 checkbox Restart inspection 01 Completed, Value: 0 + 10 checkbox Restart inspection 02 Completed, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 14 text Restart inspection 02 + 15 text Running + 16 button Pause, ID: pause + 17 container Description: Body connection, ID: network-card + 18 text Body connected + 19 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 22 button (collapsed) Test the simulated connection, Secondary Actions: Expand + 23 text Test the simulated connection + 24 container Camera observation + 25 text OVERHEAD CAMERA + 26 text Last camera observation + 27 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 29 text Captured · generation 20 + 30 text COMPLETED + 31 text Measurement recorded and reset verified. The bench is ready for another job. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 37 text Historical result + 38 container measurement-result + 39 text 1,729 + 40 text Orange pixels + 41 container + 42 text 4,802.8 + 43 text mm² + 44 text Apparent footprint + 45 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI’s judgment. + 46 button Repeat job, ID: repeat + 47 container Activity + 48 heading Activity, Value: 2, ID: activity-heading + 49 text Activity + 50 text 24 events + 51 content list activity + 52 container + 53 text 02:21 PM Action receipt checked Restart inspection 02 + 54 container + 55 text 02:21 PM Sending a guarded action + 56 container + 57 text 02:21 PM Action proposal accepted Restart inspection 02 + 58 container + 59 text 02:21 PM Checking the planned action + 60 container + 61 text 02:21 PM AI planning requested Restart inspection 02 + 62 container + 63 text 02:21 PM Camera observation received Restart inspection 02 + 64 container + 65 text 02:21 PM Requesting camera observation + 66 container + 67 text 02:21 PM Agent resumed + 68 container + 69 text 02:20 PM Agent stopped for review timed out + 70 container + 71 text 02:20 PM Agent stopped for review timed out + 72 container + 73 text 02:20 PM Agent stopped for review timed out + 74 container + 75 text 02:20 PM Agent stopped for review timed out + 76 button (collapsed) Session details, Secondary Actions: Expand + 77 text Session details + 78 text 29 model requests · Reported tokens: 343,310 input / 3,963 output · Reporting incomplete (26 of 29 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/resumed.txt b/jevdual/results/workbench-restarts-20261012/ui/resumed.txt new file mode 100644 index 0000000..adcdb1c --- /dev/null +++ b/jevdual/results/workbench-restarts-20261012/ui/resumed.txt @@ -0,0 +1,79 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 91 checkbox Restart inspection 01 Paused, Value: 1 + 92 checkbox Restart inspection 02 Queued, Value: 0 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 93 text Restart inspection 01 + 94 text Running + 16 button Pause, ID: pause + 17 container Description: Body connection, ID: network-card + 95 text Body connected + 96 text Current body boot verified for explicit Resume + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 68 container + 69 button (expanded) Test the simulated connection, Secondary Actions: Collapse + 70 text Test the simulated connection + 71 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume. + 72 button Lose next reply, ID: fault-drop + 73 button Delay next reply, ID: fault-delay + 74 button Duplicate next command, ID: fault-duplicate + 97 text No reply fault armed. + 24 container Camera observation + 25 text OVERHEAD CAMERA + 98 text Last observation · Restart inspection 01 + 60 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 99 text Captured · generation 0 + 100 text AGENT + 101 text Push the block right so its center enters the measurement zone. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 102 text Pending + 38 text The part’s visible footprint will be measured after its placement is verified. + 39 container Activity + 40 heading Activity, Value: 2, ID: activity-heading + 41 text Activity + 103 text 24 events + 90 content list activity + 104 container + 105 text 02:13 PM Requesting camera observation + 106 container + 107 text 02:13 PM Agent resumed + 108 container + 109 text 02:13 PM Command receipt recovered The agent remains paused until you resume. + 110 container + 111 text 02:13 PM Action receipt checked Restart inspection 01 + 112 container + 113 text 02:13 PM Body reconnecting No command sent or replayed + 114 container + 115 text 02:13 PM Body disconnected Transport only; no body reset or replay + 116 container + 117 text 02:12 PM Agent stopped for review Restarted with a retained command stage; check its exact receipt + 118 container + 119 text 02:12 PM Agent stopped for review reply is uncertain; reconcile exact command without resending + 120 container + 121 text 02:12 PM Sending a guarded action + 122 container + 123 text 02:12 PM Action proposal accepted Restart inspection 01 + 124 container + 125 text 02:12 PM Checking the planned action + 126 container + 127 text 02:12 PM AI planning requested Restart inspection 01 + 50 button (collapsed) Session details, Secondary Actions: Expand + 51 text Session details + 128 text 2 model requests · Reported tokens: 13,063 input / 199 output · Reporting incomplete (1 of 2 requests) + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-restarts-20261012/ui/transient-health-pause.jpg b/jevdual/results/workbench-restarts-20261012/ui/transient-health-pause.jpg new file mode 100644 index 0000000000000000000000000000000000000000..29e23a6947c314f8064db2a24fce31c87e266e1e GIT binary patch literal 87331 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 SYRR>f>i^^4(2(TMss91&?@ Date: Mon, 12 Oct 2026 14:33:11 -0400 Subject: [PATCH 144/216] Record packet v4 guest cold installation evidence --- jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md index 4cee512..366758c 100644 --- a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md +++ b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md @@ -32,3 +32,9 @@ Observed: Claude confirms exact03dc0079 artifact for U3 but identifies an N3 API Inferred: the process-local system-wide timeout, scoped to identity collection and reset to default during teardown, should cover those internal references without changing OS permissions; this remains under existing UF2 and needs corrected boundary verification before a new freeze. Next: correct the setter scope and cleanup restoration, retain old artifacts and refreeze the reviewed qualification candidate. Do not claim restoring an unknown previous custom timeout. Refs: Claude1791829172719781000; https://developer.apple.com/documentation/applicationservices/1459345-axuielementsetmessagingtimeout; source3d0984d; UF2 + +## UFU3 · update · 2026-10-12 14:32 +Observed: corrected process-global AX timeout checks pass with47helper cases and73combined checks. Claude approves the exact final packet eef3632506680d74b21b511cec905d73de2324f951e924b0716f2309490f590d, frozen at21599c6, with no blockers. The one-shot VM sender has closed after transferring312685bytes; guest hash and pristine verification match14members and the unchanged wheel9bb0440d. A new private guest environment completes all seven cold-install stages with exit0 and an actual passed receipt. The guest is unlocked and no v4 fixture/native effect/reset has occurred. +Changes: final-r2 is the sole guest qualification candidate; earlier preparation artifacts remain preserved. This is fresh installation state on the existing macOS26.6.2 guest, not a newly cold OS. Existing Terminal Accessibility has not yet been cleared; explicit supported per-host reset approval is pending. +Next: after reset approval, capture denied strict doctor and resource-free fixture refusal, retain their hashes before the actual grant, then record the same-host permission transition and restart before installed native and automatic-cleanup checks. UF1/UF2/UF3 remain open. +Refs: results/onboarding-fixture-v4-preparation-20261012; output/u2-packet-v4-final-r2; Claude1791829509202848000; guest footwork-u4/packet-verification.txt; guest footwork-u4/footwork/output/install-v1/receipt.json From edc5485f627530c4226cf107381523ef9ce82774 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:38:34 -0400 Subject: [PATCH 145/216] Preregister healthy-job health timeout investigation and guarded verification --- .../experiments/SIM12-workbench-health.md | 19 +++++++++++++++++++ .../notebook/2026-10-12-workbench-health.md | 13 +++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 jevdual/docs/experiments/SIM12-workbench-health.md create mode 100644 jevdual/docs/notebook/2026-10-12-workbench-health.md diff --git a/jevdual/docs/experiments/SIM12-workbench-health.md b/jevdual/docs/experiments/SIM12-workbench-health.md new file mode 100644 index 0000000..c302062 --- /dev/null +++ b/jevdual/docs/experiments/SIM12-workbench-health.md @@ -0,0 +1,19 @@ +# SIM12: Healthy work must survive a delayed health read + +Hypothesis: the workbench interprets a health-read deadline as confirmed body loss too early, cancelling otherwise healthy image-guided jobs. A bounded probe that distinguishes delayed observation from confirmed unsafe state can preserve progress without granting authority from old health evidence. + +Predictions if true: a live, unchanged body with a delayed health reply reproduces the original pause; a mechanism-level repair avoids that pause while preserving command admission checks. Identity/source changes, boot changes, unresolved effects, explicit disconnect, Pause and genuinely unavailable transport still suppress successor actions. An uncertain dispatch remains single-send until exact historical receipt recovery and explicit Resume. + +Predictions if false: the failure is caused by an actual body outage, already-closed ownership, a stale overlapping probe or an invalid body state; the repair hides loss, delays invalidation of known unsafe identity/epoch, grants admission on stale health, retries an effect or silently resumes a paused or uncertain job. + +Design: retain the previous paused product and SIM11 evidence. Inspect historical event timing and source independently for health-decision, transport/locking and probe-cost explanations. Record direct-body versus link probe timings and narrowly scoped instrumentation if needed. Commit a concrete causal prediction before its reproduction and repair. Reproduce through real sockets, preserve original failing output, repair the smallest demonstrated mechanism and run affected outage/reboot/uncertainty/pause tests. Freeze measured source before actual Codex calls. Drive two successive jobs in the browser with deterministic delayed health replies using an owned diagnostic harness; include explicit loss and exact receipt recovery. Independently verify placement, measurement, contact reset, model images, command sends and complete process cleanup. + +Primary metric: two independently verified actual-model jobs complete with zero unrequested pauses or cancelled decisions caused by the tested healthy health delay; injected health-delay intervals cannot admit commands without fresh pinned proof. + +Secondary checks: real unavailable transport still blocks effects; fast reboot invalidates old decisions; stale probes cannot overwrite newer controls/results; unknown commands remain uniquely indexed; receipt recovery stays read-only and requires Resume; UI accurately distinguishes waiting for health proof from disconnected or uncertain work. + +Guardrails: no retries of effect commands; no stale-image or stale-health authority; no relaxed identity/source/lease/freshness limits; no threshold increase to mask an unexplained delay; bounded owned probes and processes; no new remote exposure or hardware actuation; preserve failed attempts; commit predictions before substantive tests and freeze paid runs. Report uncertainty about the historical incident separately from a reproduced mechanism. + +Decision rule: adopt only after the original healthy-delay reproduction passes without unrequested Pause, recovery guards pass and the frozen browser/model trial independently passes. Otherwise retain evidence and report the exact unresolved boundary. + +Scope: same-Mac loopback simulation. The observed SIM11 health timeouts are historical evidence; their precise physical scheduling cause is not assumed. diff --git a/jevdual/docs/notebook/2026-10-12-workbench-health.md b/jevdual/docs/notebook/2026-10-12-workbench-health.md new file mode 100644 index 0000000..29f3533 --- /dev/null +++ b/jevdual/docs/notebook/2026-10-12-workbench-health.md @@ -0,0 +1,13 @@ +# Healthy-job health timeout investigation + +## SIM12-E1 · exploratory · 2026-10-12 14:38 +Question: which boundary caused the SIM11 healthy-job pause: expensive or queued body reads, a stale overlapping health probe, or treating a transport deadline as proof of loss? +Test: compare retained SIM11 event timing with independent source inspection, then use bounded direct-body/link probes and scoped timing instrumentation. Commit a causal prediction before a reproducing test or fix. +Refs: docs/experiments/SIM12-workbench-health.md; results/workbench-restarts-20261012/health-timeout-observation.json; tools/physical-workcell/output/sim11-browser-restarts-v2/ + +## SIM12-P1 · prediction · 2026-10-12 14:38 +Hypothesis: the host can keep a healthy job running while withholding new command admission during a delayed health read, and recover from fresh same-body/same-boot proof without weakening explicit controls or uncertain-command recovery. +Test: after causal reproduction and repair, run outage/epoch/uncertainty/pause regressions and two frozen actual image-guided browser jobs with owned health-delay injection; independently score native results and retained sends. +Predicts: delayed healthy reads cause bounded waiting rather than unrequested Pause; effects still need fresh pinned admission proof; actual loss/epoch/identity/unknown state blocks successors; two jobs complete without health-caused cancellation and with exact receipt recovery. +Against: stale health grants an effect, an unsafe body stays runnable, an unknown command is replayed, explicit Pause is overwritten, or actual-model verification fails. +Refs: docs/experiments/SIM12-workbench-health.md; results/workbench-health-20261012/ From 5c0c894bf2a792c52aef73893c714d6152a7fc69 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:39:16 -0400 Subject: [PATCH 146/216] Retain observed guest denied permission baseline --- jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md index 366758c..1dbda74 100644 --- a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md +++ b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md @@ -38,3 +38,9 @@ Observed: corrected process-global AX timeout checks pass with47helper cases and Changes: final-r2 is the sole guest qualification candidate; earlier preparation artifacts remain preserved. This is fresh installation state on the existing macOS26.6.2 guest, not a newly cold OS. Existing Terminal Accessibility has not yet been cleared; explicit supported per-host reset approval is pending. Next: after reset approval, capture denied strict doctor and resource-free fixture refusal, retain their hashes before the actual grant, then record the same-host permission transition and restart before installed native and automatic-cleanup checks. UF1/UF2/UF3 remain open. Refs: results/onboarding-fixture-v4-preparation-20261012; output/u2-packet-v4-final-r2; Claude1791829509202848000; guest footwork-u4/packet-verification.txt; guest footwork-u4/footwork/output/install-v1/receipt.json + +## UFU4 · update · 2026-10-12 14:39 +Observed: after specific user approval, supported guest Terminal-only Accessibility reset exits0 at18:34:59Z. Installed strict doctor reports accessibility_not_granted and exits1; frozen denied fixture exits2 with its explicit pre-resource refusal, and its directory is absent. At18:38:15Z the eight denial/install baseline hashes are retained and visibly printed before grant. The actual guest Accessibility pane shows Terminal OFF; action-time grant confirmation is pending. +Changes: a long public shell-input command was truncated with repeated characters by the VM input transport and was never executed. The owned shell was closed, its caffeinate hold ended, and another same-host shell now uses shorter commands and a new bounded awake hold. A preliminary hash glob included its own manifest; baseline-hashes.txt corrects this with explicit denial file groups, preserving the preliminary file. No product effect, permission grant, or qualifying fixture has occurred. +Next: capture the approved same-host ON transition, restart Terminal, then run installed strict doctor, fixture, native/replay/report and automatic cleanup. UF1/UF2/UF3 remain open. +Refs: guest permission-reset.txt; guest baseline-hashes.txt; guest doctor-before-exit.txt; guest denied-fixture-console.txt; guest denied-resource-check.txt; CUA Accessibility OFF observation; U3-packet-v4-permission-journey.md From 3de70f1de65a74e9285f651418852fe88672d2a4 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:49:29 -0400 Subject: [PATCH 147/216] Record baseline health timings and predict guarded slow-probe repair --- .../notebook/2026-10-12-workbench-health.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-12-workbench-health.md b/jevdual/docs/notebook/2026-10-12-workbench-health.md index 29f3533..fddaa8b 100644 --- a/jevdual/docs/notebook/2026-10-12-workbench-health.md +++ b/jevdual/docs/notebook/2026-10-12-workbench-health.md @@ -11,3 +11,23 @@ Test: after causal reproduction and repair, run outage/epoch/uncertainty/pause r Predicts: delayed healthy reads cause bounded waiting rather than unrequested Pause; effects still need fresh pinned admission proof; actual loss/epoch/identity/unknown state blocks successors; two jobs complete without health-caused cancellation and with exact receipt recovery. Against: stale health grants an effect, an unsafe body stays runnable, an unknown command is replayed, explicit Pause is overwritten, or actual-model verification fails. Refs: docs/experiments/SIM12-workbench-health.md; results/workbench-health-20261012/ + +## SIM12-U1 · update · 2026-10-12 14:47 +Observed: thirty-two sequential pinned body/link reads all succeeded. Direct state median was 92.1 ms and linked state median 94.3 ms; no observed maximum exceeded 136.7 ms. An isolated scan of 83 copied command records performed 249 file reads and 664 canonical request digest builds, with a 20.8 ms median. The warm paused baseline did not reproduce the historical deadline. Independent code review found that one auxiliary deadline cancels the model, full state checks share the body execution lock, and the link may keep its upstream read alive after the caller times out. +Inferred: receipt scanning adds real work but is not sufficient evidence for the original slow response. The confirmed logical weakness is promoting an ambiguous probe deadline to body loss. Bounded auxiliary reads and fresh authoritative admission proof can address that weakness without inferring the historical scheduling cause. +Next: reproduce isolated healthy slow reads, then separate inconclusive telemetry from fresh command admission and bound outstanding probes. +Refs: tools/physical-workcell/output/sim12-diagnosis/summary.json; tools/physical-workcell/output/sim12-diagnosis/timing.jsonl; tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/workbench_link.py + +## SIM12-DELAY · prediction · 2026-10-12 14:47 +Hypothesis: a healthy auxiliary read delayed beyond its deadline causes a false control cancellation in the original runtime. Treating that deadline as unconfirmed, while requiring fresh pinned ready state before lease and stage admission, preserves healthy progress and still prevents stale or unsafe authority. +Test: real TCP delay of only an auxiliary identity/state reply while a model decision waits; retain the failing original pause and recheck after repair. Pair with fresh-proof failure, epoch/identity changes, unknown outcomes, explicit controls and stale-probe overlap. +Predicts: the original path pauses/cancels despite a live unchanged body; the repaired path keeps the job running, obtains independent fresh full status before any command and completes the bounded action. Hard faults and explicit Pause continue to suppress admission. +Against: the original path already tolerates the delay, repaired code dispatches from cached health, accepts an old boot, cancels the healthy decision or erases pending uncertainty. +Refs: tools/physical-workcell/network_operator_runtime.py; tools/physical-workcell/test_network_operator.py + +## SIM12-FLIGHT · prediction · 2026-10-12 14:47 +Hypothesis: tagging only auxiliary identity/state reads and limiting them to one outstanding upstream request per path bounds the two-hop backlog without affecting untagged authoritative reads or any effect command. +Test: delay an actual upstream health response past the caller deadline, issue repeated tagged probes, and assert at most two upstream health reads, bounded inconclusive replies, no late-result reuse and owned worker cleanup. Challenge invalid probe routing and unchanged command faults/reconciliation. +Predicts: delayed auxiliary results never become command proof; full status still reaches the body independently; expired probe callers cannot produce an unbounded read fanout; all workers exit before ownership release. +Against: a probe annotation changes effect semantics, a cached response authorizes admission, outstanding readers grow with retries or workers survive cleanup. +Refs: tools/physical-workcell/workbench_link.py; tools/physical-workcell/test_workbench_link.py From 4f0f4cb1dc13ffee359a5e6b80ac32c295d5803a Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:52:05 -0400 Subject: [PATCH 148/216] Record captured guest Accessibility grant and restarted host --- jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md index 1dbda74..044e56d 100644 --- a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md +++ b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md @@ -44,3 +44,9 @@ Observed: after specific user approval, supported guest Terminal-only Accessibil Changes: a long public shell-input command was truncated with repeated characters by the VM input transport and was never executed. The owned shell was closed, its caffeinate hold ended, and another same-host shell now uses shorter commands and a new bounded awake hold. A preliminary hash glob included its own manifest; baseline-hashes.txt corrects this with explicit denial file groups, preserving the preliminary file. No product effect, permission grant, or qualifying fixture has occurred. Next: capture the approved same-host ON transition, restart Terminal, then run installed strict doctor, fixture, native/replay/report and automatic cleanup. UF1/UF2/UF3 remain open. Refs: guest permission-reset.txt; guest baseline-hashes.txt; guest doctor-before-exit.txt; guest denied-fixture-console.txt; guest denied-resource-check.txt; CUA Accessibility OFF observation; U3-packet-v4-permission-journey.md + +## UFU5 · update · 2026-10-12 14:51 +Observed: user approves the actual Terminal Accessibility grant. Codex clicks that exact guest switch after the18:40:09Z clock reading; refreshed UI visibly shows ON. No authentication prompt appears. Terminal is visibly quit and relaunched before installed strict doctor exits0, reporting Accessibility granted and Screen Recording not_granted. Frozen fixture-v1 reports ready in its hold phase; exact installed config generation exits0. The installed native trial has now started once; its outcome and automatic cleanup remain unobserved. +Changes: public-command transport truncation recurs on a long diagnostic readback; unexecuted input is discarded by closing only the owned shell. Short octal commands and explicit shell variables now preserve exact paths and arguments, which are visibly read back before the native trial. Plain special-character input was also refused without launching the intended hold; a short octal hold succeeds. These are operator transport events, not permission or product failures. +Next: retain trial result without repeating an uncertain effect, signal the exact owned fixture once, inspect automatic cleanup and absence, then export raw evidence for independent Claude review. UF1/UF2/UF3 remain open. +Refs: guest permission-grant.txt; guest terminal-restarted.txt; guest doctor-after-exit.txt; guest footwork/output/doctor-after.json; guest footwork/output/fixture-v1/fixture-status.json; guest config-exit.txt; U3-packet-v4-permission-journey.md From 0bcd5b0286fa5fbe07c06ba1d61bd8ff739cc012 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 14:55:54 -0400 Subject: [PATCH 149/216] Preserve failed v4 cleanup and predict bounded stale AX recovery --- .../notebook/2026-10-12-onboarding-fixture-v4.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md index 044e56d..e9661aa 100644 --- a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md +++ b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md @@ -50,3 +50,17 @@ Observed: user approves the actual Terminal Accessibility grant. Codex clicks th Changes: public-command transport truncation recurs on a long diagnostic readback; unexecuted input is discarded by closing only the owned shell. Short octal commands and explicit shell variables now preserve exact paths and arguments, which are visibly read back before the native trial. Plain special-character input was also refused without launching the intended hold; a short octal hold succeeds. These are operator transport events, not permission or product failures. Next: retain trial result without repeating an uncertain effect, signal the exact owned fixture once, inspect automatic cleanup and absence, then export raw evidence for independent Claude review. UF1/UF2/UF3 remain open. Refs: guest permission-grant.txt; guest terminal-restarted.txt; guest doctor-after-exit.txt; guest footwork/output/doctor-after.json; guest footwork/output/fixture-v1/fixture-status.json; guest config-exit.txt; U3-packet-v4-permission-journey.md + +## UFU6 · update · 2026-10-12 14:55 +Resolves: UF1 = failed; UF3 = failed +Observed: installed native-v1 exits0 and reports passed with its actual installed worker observed. Exact fixture PID52621 receives one SIGINT. The document disappears visually without an operator close; cleanup nevertheless records ax_attribute_refused:AXRole:-25202 and exits6. Owned browser52622 and listener cleanup are confirmed. File snapshots change from15to24bytes. Thus the required automatic confirmation gate fails; original frozen run-v1 remains failed and no new grant or native effect is retried. +Inferred: after successful close, a previously observed AX window or child becomes invalid while cleanup is inspecting its sheet tree. Invalid-element evidence must trigger bounded fresh observation, never substitute for absence. +Next: export immutable raw-v1 evidence; reproduce the close-versus-read race before correcting it, obtain Claude review, and qualify a separate frozen repair run. UF2 awaits final source/receipt review. +Refs: guest native-exit.txt; guest native-console.txt; guest footwork/output/fixture-v1/cleanup.json; guest fixture-exit.txt; guest cleanup-signal.txt; CUA document disappearance + +## UF4 · prediction · 2026-10-12 14:55 +Hypothesis: a narrow bounded retry of invalid AX element errors after AXPress permits fresh same-application window enumeration to confirm actual disappearance, without allowing read errors or changed identity to certify cleanup. +Test: reproduce the observed stale AXRole child/window race against21599c6; then cover a fresh readable absent window, unreadable AXWindows, persistent invalid element, renamed/reused identity and unrelated windows. Correct only fixture/helper tests, review with Claude and run a separately frozen fixture/native/automatic-cleanup trial on the same granted guest. Retain failed U3v1; a post-grant repair trial is not a new first-use pass. +Predicts: stale reads cause no extra action; confirmation requires a subsequent fresh readable AXWindows snapshot proving the original identity absent. Persistent errors remain bounded unknown/error, foreign identity refuses, and real repaired fixture closes automatically. +Against: an AX error alone confirms closure, a stale element is pressed again, an unrelated window is closed, retry exceeds the cleanup deadline, or live cleanup still lacks confirmation. +Refs: UFU6; scripts/capability_fixture.py close_owned_document/discard_button; frozen21599c6 From 8c6acc1997d28ea4e311eb435a2ce5ba49c75a5f Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 15:00:39 -0400 Subject: [PATCH 150/216] Retain healthy-probe failures and timestamp provenance --- jevdual/docs/notebook/2026-10-12-workbench-health.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-12-workbench-health.md b/jevdual/docs/notebook/2026-10-12-workbench-health.md index fddaa8b..a8cfeca 100644 --- a/jevdual/docs/notebook/2026-10-12-workbench-health.md +++ b/jevdual/docs/notebook/2026-10-12-workbench-health.md @@ -31,3 +31,14 @@ Test: delay an actual upstream health response past the caller deadline, issue r Predicts: delayed auxiliary results never become command proof; full status still reaches the body independently; expired probe callers cannot produce an unbounded read fanout; all workers exit before ownership release. Against: a probe annotation changes effect semantics, a cached response authorizes admission, outstanding readers grow with retries or workers survive cleanup. Refs: tools/physical-workcell/workbench_link.py; tools/physical-workcell/test_workbench_link.py + +## SIM12-U2 · update · 2026-10-12 15:00 +Observed: the original runtime failed a real-socket delayed healthy-state check, cancelling planning while the body remained ready. The original link also failed the repeated-probe test: six downstream probes created three concurrent upstream readers per path. Both meaningful failing logs are retained. Runtime repair uses fresh full ready status before every lease/stage and preserves planning on an inconclusive probe; link repair coalesces only annotated reads. An intermediate new-boot/delayed-state test found that unconfirmed readiness was being treated as known uncertainty; that classification was corrected and its failed output retained. A setup-only wrong interpreter path exited before the first runtime test and was not retained separately. +Inferred: false cancellation and read fanout are reproduced mechanisms; the warm baseline still does not establish the physical cause of the historical slow response. +Next: finish bounded probe cleanup and final control/admission regressions, freeze source, then drive the actual delayed-health browser trial. +Refs: tools/physical-workcell/output/sim12-health-before-fix.log; tools/physical-workcell/output/sim12-link-before-fix.log; tools/physical-workcell/output/sim12-health-targeted-v2.log; tools/physical-workcell/output/sim12-health-targeted-v3.log + +## SIM12-TIME · update · 2026-10-12 15:00 +Observed: the U1, DELAY and FLIGHT headings contain 14:47 from precomposed text; the clock output for that write was 14:49. Commit 3de70f1 holds all three entries before the reproductions and repairs. Earlier text remains unchanged. +Next: use the actual clock result when assembling later entries; Git settles prediction order. +Refs: commit 3de70f1 From 37ebfdb3054b977149d7b60b46254ddd852b749a Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 15:05:41 -0400 Subject: [PATCH 151/216] Separate inconclusive health probes from guarded command admission --- .../notebook/2026-10-12-workbench-health.md | 6 + tools/physical-workcell/NETWORK_WORKBENCH.md | 2 + .../NETWORK_WORKBENCH_CONTRACT.md | 6 +- .../network_bench_operator.html | 26 +- .../network_operator_runtime.py | 79 ++++- .../qualify_workbench_health.py | 334 ++++++++++++++++++ .../score_workbench_health.py | 150 ++++++++ .../test_network_operator.py | 205 ++++++++++- .../test_workbench_health.py | 168 +++++++++ .../physical-workcell/test_workbench_link.py | 228 ++++++++++++ tools/physical-workcell/workbench_link.py | 98 ++++- 11 files changed, 1267 insertions(+), 35 deletions(-) create mode 100644 tools/physical-workcell/qualify_workbench_health.py create mode 100644 tools/physical-workcell/score_workbench_health.py create mode 100644 tools/physical-workcell/test_workbench_health.py diff --git a/jevdual/docs/notebook/2026-10-12-workbench-health.md b/jevdual/docs/notebook/2026-10-12-workbench-health.md index a8cfeca..bfe8f83 100644 --- a/jevdual/docs/notebook/2026-10-12-workbench-health.md +++ b/jevdual/docs/notebook/2026-10-12-workbench-health.md @@ -42,3 +42,9 @@ Refs: tools/physical-workcell/output/sim12-health-before-fix.log; tools/physical Observed: the U1, DELAY and FLIGHT headings contain 14:47 from precomposed text; the clock output for that write was 14:49. Commit 3de70f1 holds all three entries before the reproductions and repairs. Earlier text remains unchanged. Next: use the actual clock result when assembling later entries; Git settles prediction order. Refs: commit 3de70f1 + +## SIM12-U3 · update · 2026-10-12 15:05 +Resolves: SIM12-DELAY = held; SIM12-FLIGHT = held +Observed: the repaired runtime passed all 26 real-socket/native checks, including fresh proof failure, changed boot, known uncertainty and explicit Pause during proof. The link passed 13 checks, bounding repeated delayed probes to one reader per path and joining them at close. Seven new harness/scorer checks passed. Before-fix failures remain retained. +Next: freeze the measured source, then test two actual image-guided jobs with diagnostic delayed health replies and browser receipt recovery. SIM12-P1 remains open until the independent product score. +Refs: tools/physical-workcell/output/sim12-runtime-final-v1.log; tools/physical-workcell/output/sim12-link-tests-final.log; tools/physical-workcell/output/sim12-harness-tests-v1/unittest.log diff --git a/tools/physical-workcell/NETWORK_WORKBENCH.md b/tools/physical-workcell/NETWORK_WORKBENCH.md index eda41f6..00e58ff 100644 --- a/tools/physical-workcell/NETWORK_WORKBENCH.md +++ b/tools/physical-workcell/NETWORK_WORKBENCH.md @@ -24,6 +24,8 @@ Expand **Test the simulated connection** to lose, delay or duplicate the next di Use **Disconnect** to close the diagnostic link. The last image and completed results remain visible as retained evidence. **Reconnect** restores transport and leaves the agent paused. For an uncertain command, choose **Check receipt**. This reads the exact original result without resending its action. If the receipt proves what happened, choose **Resume** to obtain a fresh observation and continue. Missing proof stays blocked. +**Checking body** means an auxiliary health reply is delayed. Planning may continue; every command still needs a fresh pinned body check before a lease and command stage are accepted. A cached image or old health result supplies no action authority. A known disconnect, changed boot or identity, unresolved effect, or failed command preflight still stops progress. Pause and uncertain-command recovery require the same explicit controls as before. + Restart the body by omitting `--initialize`; restart the host with the same root and exact port. Both identities persist. Body restart revokes leases. Host restart pauses the queue, keeps uncertain commands, and never replays them. Reloading the browser does not restart planning or reset the bench. A new body boot epoch also pauses planning when a fast restart escaped the outage poll. An earlier model decision cannot acquire authority to continue across that boundary. Pending historical commands keep their original epoch and identity: **Check receipt** reads their retained result, then **Resume** obtains a fresh observation. Workbench restart cancels its owned planner before releasing process ownership; its active unfinished job appears paused or uncertain as appropriate. diff --git a/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md b/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md index 6410c69..9cf7768 100644 --- a/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md +++ b/tools/physical-workcell/NETWORK_WORKBENCH_CONTRACT.md @@ -9,11 +9,13 @@ New modules: - `network_bench_operator.py`: init/serve CLI and guarded loopback HTTP. Mutations require exact Host, Origin and app ID. POST `/api/disconnect`, `/api/reconnect`, `/api/reconcile` take empty JSON; `/api/fault` takes `{mode, delay_s}` with mode above and delay in [0,2], always dispatch-only. Existing job/pause/resume routes retain their schemas. - `network_bench_operator.html`: live queue, exact downloaded camera frames, computer measurement, reset result, activity and network controls. -`connection`: `{state: 'connected'|'disconnected'|'unavailable', body_id, adapter_id, epoch, reason, fault: null|{mode, operation, delay_s}}`. Disconnected is the intentional diagnostic gate; unavailable means the real upstream is unreachable. Transport status does not establish freshness of a cached frame. +`connection`: `{state: 'connected'|'checking'|'disconnected'|'unavailable', body_id, adapter_id, epoch, reason, fault: null|{mode, operation, delay_s}}`. Checking means an auxiliary read was inconclusive; it preserves planning and the last verified boot without claiming current health or granting command authority. Disconnected is the intentional diagnostic gate; unavailable means transport or pinned proof failed. Transport status does not establish freshness of a cached frame. + +Auxiliary GET `/identity` and `/state` carry `X-Footwork-Health-Probe: 1`. The link permits one outstanding upstream probe per path and returns a bounded `504` with `{version: 1, kind: 'health_read_pending', path}` while that exact probe is pending. Late results are discarded rather than cached for another caller. Full untagged status and all command/lease paths keep their ordinary semantics; a probe annotation is rejected on effect routes. Probe workers remain owned until they exit. `recovery`: `{state: 'none'|'uncertain'|'recovered'|'blocked', command_id: null|string, operation: null|string, reason}`. Unknown blocks effects and lease rotation. Reconcile reads exact retained results and applies the pending host stage once; not-seen remains unknown until fenced. Recovered is paused until explicit Resume. UI shows an old frame as retained and never calls it live. Completed results remain visibly historical during disconnect. -The host writes stage/job/action/proposal context and the pre-send client command index before a client command, associates the unique new command, and clears the stage only after applying its result to queue/history. On restart, terminal client receipts may be read to settle that exact stage; unknown receipts remain blocked. No restart sends actions or automatically resumes. Resume observes a fresh TCP image before the next model decision. Control calls cancel pending model work; an unadmitted decision from an earlier control epoch cannot become a command. +The host reads fresh pinned full ready status before every command admission, compares its boot to the last verified epoch and checks control state before lease acquisition and again before stage persistence. Cached auxiliary health never grants admission. Successful preflight evidence records the body/adapter/source/epoch and canonical public-state digest. Failed authoritative proof pauses before a command is sent. The host then writes stage/job/action/proposal context and the pre-send client command index, associates the unique new command, and clears the stage only after applying its result to queue/history. On restart, terminal client receipts may be read to settle that exact stage; unknown receipts remain blocked. No restart sends actions or automatically resumes. Resume observes a fresh TCP image before the next model decision. Control calls cancel pending model work; an unadmitted decision from an earlier control epoch cannot become a command. Host admission occurs when the checked command stage is durably persisted under the control lock. After this point its network request is in flight and may reach the body after Pause or Disconnect; those controls prevent subsequent admissions. The body separately checks its own lease, freshness and limits before accepting any physical effect. Pause is not an interruption guarantee for a command already admitted by the host. If transport disappears, retain and reconcile that exact command. diff --git a/tools/physical-workcell/network_bench_operator.html b/tools/physical-workcell/network_bench_operator.html index 5ab2774..a3eadc4 100644 --- a/tools/physical-workcell/network_bench_operator.html +++ b/tools/physical-workcell/network_bench_operator.html @@ -47,6 +47,7 @@ const titles = {observe:'Observed the bench',measurement:'Recorded measurement',reset:'Verified reset',pause:'Pause requested',resume:'Agent resumed',queued:'Job queued',start_intent:'Starting job',inference:'AI planning requested',decision_withheld:'Earlier model reply withheld',disturbance_intent:'Recovery trial started',dispatch:'Action submitted',completed:'Job completed',halt:'Agent stopped for review',shutdown_model_exit:'Model process stopped',shutdown_work_exit:'In-flight work stopped',disconnect:'Body disconnected',reconnect:'Body reconnecting',reconciled:'Command receipt recovered',fault_armed:'Reply fault armed',health_unavailable:'Body unavailable',unavailable:'Body unavailable',body_epoch_changed:'Body restarted'}; if (item.kind === 'rpc_intent') return {title:requested[operation] || 'Sending a body request',detail:''}; if (item.kind === 'rpc_applied') return {title:received[operation] || 'Body receipt checked',detail:typeof item.intent === 'string' ? item.intent : ''}; + if (item.kind === 'admission_proof') return {title:'Fresh body check verified',detail:'The next command uses current body evidence.'}; if (item.kind === 'reconciled') return {title:titles.reconciled,detail:'The agent remains paused until you resume.'}; if (item.kind === 'fault_armed') return {title:titles.fault_armed,detail:({drop_after:'The next command reply will be lost.',delay_after:'The next command reply will be delayed.',duplicate:'The next command will be duplicated with the same identity.'}[operation] || 'A bounded simulation fault is ready.')}; if (item.kind === 'queued') return {title:titles.queued,detail:typeof item.intent === 'string' ? item.intent : ''}; @@ -55,7 +56,7 @@ } function selectedJob() { return state?.jobs?.find(job => job.job_id === selectedId) || state?.jobs?.find(job => job.job_id === state.active_job_id) || state?.jobs?.at(-1) || null; } function controlAllowed() { return Boolean(appId && !identityChanged && !mutating); } -function actionAllowed() { return Boolean(controlAllowed() && ['running','paused'].includes(state?.runner_status) && state?.connection?.state === 'connected' && !['uncertain','blocked'].includes(state?.recovery?.state)); } +function actionAllowed() { return Boolean(controlAllowed() && ['running','paused'].includes(state?.runner_status) && ['connected','checking'].includes(state?.connection?.state) && !['uncertain','blocked'].includes(state?.recovery?.state)); } function render() { if (!state) return; const jobs = Array.isArray(state.jobs) ? state.jobs : [], job = selectedJob(); @@ -64,13 +65,13 @@ const connection = state.connection || {state:'unavailable'}, recovery = state.recovery || {state:'blocked'}; const uncertain = ['uncertain','blocked'].includes(recovery.state); $('network-card').dataset.connection = connection.state; - text('connection-label', {connected:'Body connected',disconnected:'Body disconnected',unavailable:'Body unavailable'}[connection.state] || 'Checking body connection'); + text('connection-label', {connected:'Body connected',checking:'Checking body',disconnected:'Body disconnected',unavailable:'Body unavailable'}[connection.state] || 'Checking body connection'); $('connection-dot').style.background = connection.state === 'connected' ? '#457451' : '#b48235'; text('connection-reason', connection.reason || (connection.state === 'connected' ? 'The same persistent body serves successive jobs.' : 'Last observations and results are retained. Reconnecting does not replay commands.')); - text('disconnect', connection.state === 'connected' ? 'Disconnect' : 'Reconnect'); + text('disconnect', ['connected','checking'].includes(connection.state) ? 'Disconnect' : 'Reconnect'); $('disconnect').disabled = !controlAllowed(); - $('reconcile').disabled = !controlAllowed() || !uncertain || state.transport_pending || state.model_request_pending || connection.state !== 'connected'; - for (const id of ['fault-drop','fault-delay','fault-duplicate']) $(id).disabled = !controlAllowed() || uncertain || connection.state !== 'connected' || !state.simulation || Boolean(connection.fault); + $('reconcile').disabled = !controlAllowed() || !uncertain || state.transport_pending || state.model_request_pending || !['connected','checking'].includes(connection.state); + for (const id of ['fault-drop','fault-delay','fault-duplicate']) $(id).disabled = !controlAllowed() || uncertain || !['connected','checking'].includes(connection.state) || !state.simulation || Boolean(connection.fault); text('fault-status', connection.fault ? ({drop_after:'The next command reply will be lost.',delay_after:'The next command reply will be delayed.',duplicate:'The next command will be duplicated with the same identity.'}[connection.fault.mode] || 'A diagnostic reply fault is armed.') : 'No reply fault armed.'); $('runner-status').dataset.state = runner; text('runner-label', pausePending ? 'Pausing' : ({running:'Running',pausing:'Pausing',paused:'Paused',blocked:'Needs attention',stopped:'Stopped'}[runner] || 'Needs attention')); @@ -101,7 +102,7 @@ if (job?.status === 'unknown') { intent = 'The outcome needs attention. Review the recorded evidence before continuing.'; intentLabel = 'Needs attention'; } if (recovery.state === 'recovered') { intent = 'The exact command receipt was recovered. The agent is paused until you resume.'; intentLabel = 'Receipt recovered'; } if (uncertain) { intent = 'The command outcome is uncertain. Reconnect if needed, then check its receipt before continuing.'; intentLabel = 'Outcome uncertain'; } - if (connection.state !== 'connected') { intent = 'The body connection is unavailable. The last camera observation is retained.'; intentLabel = 'Disconnected'; } + if (!['connected','checking'].includes(connection.state)) { intent = 'The body connection is unavailable. The last camera observation is retained.'; intentLabel = 'Disconnected'; } if (identityChanged) { intent = 'This application changed. Reload to reconnect before sending another action.'; intentLabel = 'Connection changed'; } text('intent', intent); text('intent-label', intentLabel); const phaseIndex = !job || job.status === 'queued' ? -1 : job.status === 'completed' || job.phase === 'completed' ? 4 : job.phase === 'resetting' ? 2 : job.phase === 'measured' ? 2 : 0; @@ -130,6 +131,7 @@ else { if (uncertain) notice(recovery.reason || 'The command outcome is uncertain. Check its exact receipt before continuing.'); else if (recovery.state === 'recovered') notice('Receipt recovered. The agent is paused; choose Resume to observe the bench again and continue.'); + else if (connection.state === 'checking') notice('A health reply is delayed. Planning can continue; commands require a fresh body check.'); else if (connection.state !== 'connected') notice(connection.reason || 'The body is disconnected. Cached observations and completed results remain historical.'); else if (clientError) notice(clientError,'error'); else if (job?.error) notice(readableError(job.error),'error'); @@ -139,11 +141,13 @@ } updateFrame(state.current_frame, working); } +function frameStatus() { return state?.connection?.state === 'checking' ? 'Last captured · health unconfirmed' : state?.connection?.state !== 'connected' ? 'Retained · offline' : 'Captured'; } function updateFrame(frame, working) { - const offline = state?.connection?.state !== 'connected'; + const checking = state?.connection?.state === 'checking'; + const offline = !['connected','checking'].includes(state?.connection?.state); const available = Boolean(frame?.available && typeof frame.image_url === 'string'); const active = state?.jobs?.find(job => job.job_id === state.active_job_id); - text('camera-label', offline ? 'Retained observation · body offline' : active ? `Last observation · ${active.label}` : 'Last camera observation'); + text('camera-label', offline ? 'Retained observation · body offline' : checking ? 'Last observation · health unconfirmed' : active ? `Last observation · ${active.label}` : 'Last camera observation'); if (!available) { if (loadedGeneration !== null) text('frame-caption', `Last captured · generation ${loadedGeneration} · current frame unavailable`); else { $('placeholder').hidden = false; text('placeholder', state?.jobs?.length ? 'Waiting for the next camera observation.' : 'Add an inspection to see the bench through the agent’s camera.'); text('frame-caption','No frame captured'); } @@ -152,7 +156,7 @@ let url; try { url = new URL(frame.image_url,location.href); if (url.origin !== location.origin || url.pathname !== '/api/frame') throw new Error(); } catch { notice('The camera returned an unexpected image address.','error'); return; } const key = `${frame.generation}:${url.href}`; - if (key === lastFrameKey) { text('frame-caption',`${offline ? 'Retained · offline' : 'Captured'} · generation ${loadedGeneration}`); return; } + if (key === lastFrameKey) { text('frame-caption',`${frameStatus()} · generation ${loadedGeneration}`); return; } if (key === frameLoadingKey) return; frameLoadingKey = key; const candidate = new Image(); @@ -160,7 +164,7 @@ if (frameLoadingKey !== key || identityChanged) return; $('frame').src = url.href; $('frame').hidden = false; $('placeholder').hidden = true; loadedGeneration = frame.generation; lastFrameKey = key; frameLoadingKey = null; - text('frame-caption',`${state?.connection?.state !== 'connected' ? 'Retained · offline' : 'Captured'} · generation ${loadedGeneration}`); + text('frame-caption',`${frameStatus()} · generation ${loadedGeneration}`); }; candidate.onerror = () => { if (frameLoadingKey !== key) return; frameLoadingKey = null; text('frame-caption', loadedGeneration !== null ? `Last captured · generation ${loadedGeneration} · refresh unavailable` : 'Camera image unavailable'); }; candidate.src = url.href; @@ -222,7 +226,7 @@ catch (error) { clientError = `${error.message} The action was not retried automatically.`; } finally { render(); } } -$('disconnect').addEventListener('click', () => networkControl(state?.connection?.state === 'connected' ? '/api/disconnect' : '/api/reconnect')); +$('disconnect').addEventListener('click', () => networkControl(['connected','checking'].includes(state?.connection?.state) ? '/api/disconnect' : '/api/reconnect')); $('reconcile').addEventListener('click', () => networkControl('/api/reconcile')); $('fault-drop').addEventListener('click', () => networkControl('/api/fault',{mode:'drop_after',delay_s:0})); $('fault-delay').addEventListener('click', () => networkControl('/api/fault',{mode:'delay_after',delay_s:.8})); diff --git a/tools/physical-workcell/network_operator_runtime.py b/tools/physical-workcell/network_operator_runtime.py index 1ed9978..1653ec7 100644 --- a/tools/physical-workcell/network_operator_runtime.py +++ b/tools/physical-workcell/network_operator_runtime.py @@ -16,6 +16,14 @@ "B": {"x_min": .045, "x_max": .115, "y_min": -.025, "y_max": .025}} +class _ProbePending(Exception): + """Auxiliary read is unconfirmed; it cannot revoke or grant authority.""" + + +class _BodyUnresolved(protocol.Refusal): + """A public body read returned known unresolved effects.""" + + def sources(): return {name: protocol.sha(protocol.read_bytes(BASE / name)) for name in ( "network_operator_runtime.py", "network_bench_operator.py", "network_bench_operator.html", @@ -133,10 +141,12 @@ def _save(self): protocol.persist(self.root / "operator.json", self.m) self.saved_digest = protocol.sha(protocol.encoded(self.m)) - def _event(self, kind, intent="", outcome=""): + def _event(self, kind, intent="", outcome="", evidence=None): self.m["sequence"] += 1 value = {"seq": self.m["sequence"], "time": time.time(), "kind": kind, "intent": str(intent)[:1000], "outcome": str(outcome)[:1000]} + if evidence is not None: + value["evidence"] = evidence protocol.create_file(self.root / "events" / f"{value['seq']:06d}.json", protocol.encoded(value)) self.m["activity"] = (self.m["activity"] + [value])[-24:] self._save() @@ -159,13 +169,13 @@ def _refresh_health(self): pinned["epoch"] = self.m["connection"]["epoch"] remote_identity = pinned try: - status, content = body_client.http_call(self.link.origin, "GET", "/identity", timeout=.8) + status, content = self._probe_read("/identity", {}) if status != 200: raise protocol.Refusal("pinned body identity could not be verified") remote_identity = body_client.identity(protocol.decode(content)) if any(remote_identity[k] != pinned[k] for k in body_client.IDENTITY_KEYS - {"epoch"}): raise protocol.Refusal("pinned body or adapter identity changed") - status, content = body_client.http_call(self.link.origin, "GET", "/state", body_client.pinned_headers(pinned), timeout=.8) + status, content = self._probe_read("/state", body_client.pinned_headers(pinned)) remote = protocol.decode(content) if status != 200 or remote["identity"] != remote_identity: raise protocol.Refusal("pinned body state could not be verified") @@ -173,6 +183,8 @@ def _refresh_health(self): error = None if ready else "Independent body has unresolved effects" connection = "connected" blocked = not ready + except (TimeoutError, _ProbePending): + ready, error, connection, blocked = False, "Health read delayed; fresh body proof is required before any command", "checking", False except protocol.Refusal as exc: ready, error, connection, blocked = False, str(exc), "unavailable", True except (OSError, http.client.HTTPException, ValueError, KeyError) as exc: @@ -182,19 +194,33 @@ def _refresh_health(self): if (self.closing or self.transport_pending or control_epoch != self.control_epoch or transport_epoch != self.transport_epoch or not self.link.state()["connected"]): return False - if connection == "connected" and remote_identity["epoch"] != self.m["connection"]["epoch"]: - self._body_epoch_changed(remote_identity["epoch"], ready, known_unknown=not ready) + if connection in {"connected", "checking"} and remote_identity["epoch"] != self.m["connection"]["epoch"]: + self._body_epoch_changed(remote_identity["epoch"], ready, known_unknown=blocked) + if connection == "checking": + self.m["connection"].update(state="checking", reason=error) + self._save() return ready old = self.m["connection"]["state"] self.body_ready = ready self.m["connection"].update(state=connection, reason=error or "Body identity verified by read-only TCP health", epoch=remote_identity["epoch"]) - if not ready and (old != connection or self.m["runner_status"] == "running"): + if not ready and connection != "checking" and (old != connection or self.m["runner_status"] == "running"): self.cancel.set() self.control_epoch += 1 self._halt(error, blocked=blocked) self._save() return ready + def _probe_read(self, path, headers): + status, content = body_client.http_call(self.link.origin, "GET", path, + {**headers, "X-Footwork-Health-Probe": "1"}, timeout=.8) + if status == 504: + pending = protocol.decode(content) + if (isinstance(pending, dict) and type(pending.get("version")) is int and + pending == {"version": 1, "kind": "health_read_pending", "path": path}): + raise _ProbePending() + raise protocol.Refusal("health gateway returned an unverified pending response") + return status, content + def _retain(self, path, value): content = protocol.encoded(value) if path.exists(): @@ -370,10 +396,14 @@ def _rpc(self, operation, arguments, context): with self.lock: self._identity() if (self.closing or self.cancel.is_set() or self.m["runner_status"] != "running" or - self.m["connection"]["state"] != "connected" or not self.body_ready or self.m["stage"] or + self.m["connection"]["state"] not in {"connected", "checking"} or self.m["stage"] or context.get("decision_epoch", self.control_epoch) != self.control_epoch): return None - if len(self.client._load()["commands"]) >= MAX_COMMANDS: + journal = self.client._load() + if journal["pending_command_ids"]: + self._halt("An unknown client command blocks fresh admission", blocked=True) + return None + if len(journal["commands"]) >= MAX_COMMANDS: self._halt("Conservative network-command budget exhausted") return None epoch = self.control_epoch @@ -381,6 +411,16 @@ def _rpc(self, operation, arguments, context): self.transport_pending = True self.transport_epoch += 1 try: + _, verified, proof = self._public_status(include_proof=True) + with self.lock: + if epoch != self.control_epoch or self.cancel.is_set() or self.closing: + return None + if verified["epoch"] != known_body_epoch: + self._body_epoch_changed(verified["epoch"], ready=True) + return None + self.body_ready = True + self.m["connection"].update(state="connected", reason="Fresh pinned ready proof verified before command admission") + self._event("admission_proof", outcome=operation, evidence=proof) self.client.acquire(30) with self.lock: if epoch != self.control_epoch or self.cancel.is_set() or self.closing: @@ -391,7 +431,7 @@ def _rpc(self, operation, arguments, context): return None self.m["connection"]["epoch"] = journal["identity"]["epoch"] self.m["stage"] = {"operation": operation, "arguments": arguments, "context": context, - "before_commands": list(journal["commands"]), "command_id": None, "control_epoch": epoch} + "before_commands": list(journal["commands"]), "command_id": None, "control_epoch": epoch, "proof": proof} self._event("rpc_intent", outcome=operation) if operation == "start_job": result = self.client.start_job(arguments["job_id"], arguments["target_zone"]) @@ -420,7 +460,10 @@ def _rpc(self, operation, arguments, context): self._uncertain(str(exc)) else: self.m["connection"].update(state="unavailable", reason=str(exc)) - self._halt(str(exc)) + self.body_ready = False + self.cancel.set() + self.control_epoch += 1 + self._halt(str(exc), blocked=isinstance(exc, _BodyUnresolved)) return None finally: with self.lock: @@ -429,14 +472,20 @@ def _rpc(self, operation, arguments, context): self.m["runner_status"] = "paused" self._save() - def _public_status(self, include_identity=False): + def _public_status(self, include_identity=False, include_proof=False): status = self.client.status() remote = status["server_state"] + if remote.get("state") == "unknown": + raise _BodyUnresolved("Independent body has unresolved effects; fresh commands are blocked") if remote.get("state") != "ready": raise protocol.Refusal("public network body state is unavailable or unresolved") pinned = self.m["body_identity"] if any(remote["identity"][k] != pinned[k] for k in body_client.IDENTITY_KEYS - {"epoch"}): raise protocol.Refusal("network status belongs to another pinned body") + if include_proof: + proof = {k: remote["identity"][k] for k in ("body_id", "adapter_id", "source_sha256", "epoch")} + proof["state_sha256"] = protocol.sha(protocol.encoded(remote)) + return remote["bench"], remote["identity"], proof return (remote["bench"], remote["identity"]) if include_identity else remote["bench"] def _apply(self, envelope, result): @@ -531,7 +580,7 @@ def _apply_dispatch(self, job, stage, result, public): def reconcile(self): with self.lock: self._identity() - if self.transport_pending or self.in_model or self.m["connection"]["state"] != "connected": + if self.transport_pending or self.in_model or self.m["connection"]["state"] not in {"connected", "checking"}: raise protocol.Refusal("reconnect and wait for owned work before checking its receipt") token = self._associate() if self.m["stage"] else None if not token: @@ -566,7 +615,7 @@ def resume(self): self._identity() if self.closing or self.in_model or self.transport_pending or self.m["stage"] or self._journal()["pending_command_ids"]: raise protocol.Refusal("settle the exact pending stage and wait for owned work before Resume") - if self.m["connection"]["state"] != "connected": + if self.m["connection"]["state"] not in {"connected", "checking"}: raise protocol.Refusal("reconnect the pinned link before Resume") self.transport_pending = True self.transport_epoch += 1 @@ -575,12 +624,12 @@ def resume(self): _, remote_identity = self._public_status(include_identity=True) with self.lock: if (resume_epoch != self.control_epoch or self.closing or - self.m["connection"]["state"] != "connected"): + self.m["connection"]["state"] not in {"connected", "checking"}): raise protocol.Refusal("control changed while Resume was reading body status") self.control_epoch += 1 self.cancel.clear() self.body_ready = True - self.m["connection"].update(epoch=remote_identity["epoch"], reason="Current body boot verified for explicit Resume") + self.m["connection"].update(state="connected", epoch=remote_identity["epoch"], reason="Current body boot verified for explicit Resume") self.m.update(runner_status="running", reason="Resumed; next decision receives a fresh TCP image") self.m["recovery"] = {"state": "none", "command_id": None, "operation": None, "reason": "No pending command"} self._event("resume") diff --git a/tools/physical-workcell/qualify_workbench_health.py b/tools/physical-workcell/qualify_workbench_health.py new file mode 100644 index 0000000..05b04b2 --- /dev/null +++ b/tools/physical-workcell/qualify_workbench_health.py @@ -0,0 +1,334 @@ +"""Own a frozen browser trial and a bounded relay delaying tagged health replies. + +The relay never drives UI, plans actions, retries requests, or reads native state. +Only auxiliary GET /identity and /state replies receive the diagnostic delay. +""" +import argparse +import contextlib +import http.client +import json +import signal +import socket +import subprocess +import threading +import time +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from pathlib import Path +from urllib.parse import urlsplit + +import body_client +import order_protocol as protocol +import qualify_network_workbench as previous + +BASE, REPO = previous.BASE, previous.REPO +SOURCES = list(dict.fromkeys(previous.SOURCES + [BASE / name for name in ( + "qualify_workbench_health.py", "score_workbench_health.py")])) +DELAY = 1.2 +MAX_REQUESTS = 16384 +MAX_WORKERS = 8 + + +def retain(path, value): + previous.retain(path, value) + + +class HealthRelay: + """Bounded threaded TCP relay with immutable exact-byte request evidence.""" + + def __init__(self, upstream, root, port=0): + body_client.endpoint(upstream) + if type(port) is not int or not 0 <= port <= 65535: + raise protocol.Refusal("relay port must be a bounded integer") + self.upstream, self.root, self.port = upstream, protocol.directory(root, create=True), port + if any(self.root.iterdir()): + raise protocol.Refusal("health relay needs a fresh owned directory") + (self.root / "requests").mkdir(mode=0o700) + self.control_path = self.root.parent / "health-relay-control.json" + self.lock, self.stopping = threading.Lock(), threading.Event() + self.sequence = self.active = self.peak = self.finished = 0 + self.server = self.thread = self.origin = None + + def delay_for(self, tagged, path): + if not tagged: + return 0.0 + enabled, paths = True, ["/identity", "/state"] + if self.control_path.exists(): + control = protocol.decode(protocol.read_bytes(self.control_path)) + protocol.fields(control, ("enabled", "paths"), "owned health relay control") + if (type(control["enabled"]) is not bool or not isinstance(control["paths"], list) or + any(value not in ("/identity", "/state") for value in control["paths"]) or + len(set(control["paths"])) != len(control["paths"])): + raise protocol.Refusal("invalid owned health relay control") + enabled, paths = control["enabled"], control["paths"] + return DELAY if enabled and path in paths else 0.0 + + def start(self): + owner = self + + class Server(ThreadingHTTPServer): + daemon_threads = False + block_on_close = True + + def __init__(self, address, handler): + self.capacity = threading.BoundedSemaphore(MAX_WORKERS) + super().__init__(address, handler) + + def process_request(self, request, client_address): + if not self.capacity.acquire(blocking=False): + self.shutdown_request(request) + return + try: + super().process_request(request, client_address) + except BaseException: + self.capacity.release() + raise + + def process_request_thread(self, request, client_address): + try: + super().process_request_thread(request, client_address) + finally: + self.capacity.release() + + class Handler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + + def log_message(self, *_): + pass + + def do_GET(self): + self.forward() + + def do_POST(self): + self.forward() + + def forward(self): + started_wall, started_mono = time.time(), time.monotonic() + directory, record = None, None + with owner.lock: + owner.active += 1 + owner.peak = max(owner.peak, owner.active) + try: + self.connection.settimeout(30) + parsed = urlsplit(self.path) + probes = self.headers.get_all("X-Footwork-Health-Probe", []) + tagged = probes == ["1"] + if (self.headers.get_all("Host") != [owner.origin.removeprefix("http://")] or + self.headers.get_all("Origin") or self.headers.get_all("Transfer-Encoding") or + parsed.scheme or parsed.netloc or parsed.fragment or not self.path.startswith("/") or + probes and (not tagged or self.command != "GET" or self.path not in ("/identity", "/state"))): + raise protocol.Refusal("relay requires a closed loopback route and exact auxiliary probe tag") + reads = parsed.path in ("/identity", "/state") or parsed.path.startswith(("/images/", "/commands/")) + if self.command == "GET" and not reads or self.command == "POST" and self.path not in ("/lease", "/commands"): + raise protocol.Refusal("unsupported relay route") + lengths = self.headers.get_all("Content-Length", []) + if len(lengths) > 1 or lengths and (not lengths[0].isascii() or not lengths[0].isdigit() or int(lengths[0]) > protocol.MAX_BYTES): + raise protocol.Refusal("relay payload exceeds its bounded size") + length = int(lengths[0]) if lengths else 0 + if self.command == "GET" and length or self.command == "POST" and (length < 1 or self.headers.get_all("Content-Type") != ["application/json"]): + raise protocol.Refusal("relay requires exact bounded JSON framing") + headers = {key: value for key, value in self.headers.items() if key.lower() not in + {"host", "connection", "content-length", "transfer-encoding"}} + if len(headers) != len([key for key in self.headers if key.lower() not in + {"host", "connection", "content-length", "transfer-encoding"}]): + raise protocol.Refusal("duplicate relay headers are refused") + payload = self.rfile.read(length) + if len(payload) != length: + raise protocol.Refusal("relay payload is truncated") + operation = command_id = None + if self.command == "POST": + request = protocol.decode(payload) + operation = request.get("operation") if self.path == "/commands" else "lease" + command_id = request.get("command_id") if self.path == "/commands" else None + delay = owner.delay_for(tagged, self.path) + with owner.lock: + if owner.sequence >= MAX_REQUESTS: + raise protocol.Refusal("relay request evidence budget exhausted") + owner.sequence += 1 + sequence = owner.sequence + directory = owner.root / "requests" / f"{sequence:06d}" + directory.mkdir(mode=0o700) + record = {"sequence": sequence, "method": self.command, "path": self.path, + "tagged_health": tagged, "operation": operation, "command_id": command_id, + "headers": headers, "payload_sha256": protocol.sha(payload), + "started_wall": started_wall, "started_monotonic": started_mono, + "injected_delay_s": delay, "upstream_sends": 1} + protocol.create_file(directory / "request.bin", payload) + retain(directory / "request.json", record) + upstream_started = time.monotonic() + status, content = body_client.http_call(owner.upstream, self.command, self.path, headers, + payload if self.command == "POST" else None, timeout=30, maximum=body_client.MAX_IMAGE) + upstream_finished = time.monotonic() + protocol.create_file(directory / "response.bin", content) + retain(directory / "upstream.json", {"http_status": status, "response_sha256": protocol.sha(content), + "started_monotonic": upstream_started, "finished_monotonic": upstream_finished, + "wall": time.time(), "upstream_elapsed_s": upstream_finished - upstream_started}) + delay_started = time.monotonic() + interrupted = owner.stopping.wait(delay) if delay else False + delay_finished = time.monotonic() + delivered = False + if not interrupted: + self.send_response(status) + self.send_header("Content-Type", "image/png" if self.path.startswith("/images/") else "application/json") + self.send_header("Content-Length", str(len(content))) + self.send_header("Connection", "close") + self.end_headers() + self.wfile.write(content) + delivered = True + self.close_connection = True + retain(directory / "result.json", {"completed": True, "delivered": delivered, + "delay_interrupted": interrupted, "delay_elapsed_s": delay_finished - delay_started, + "finished_monotonic": time.monotonic(), "finished_wall": time.time(), + "elapsed_s": time.monotonic() - started_mono}) + except (OSError, http.client.HTTPException, protocol.Refusal, ValueError, TypeError, AttributeError) as exc: + if directory is not None and not (directory / "result.json").exists(): + retain(directory / "result.json", {"completed": False, "error": type(exc).__name__ + ": " + str(exc), + "finished_monotonic": time.monotonic(), "finished_wall": time.time()}) + self.close_connection = True + with contextlib.suppress(OSError): + self.connection.shutdown(socket.SHUT_RDWR) + finally: + with owner.lock: + owner.active -= 1 + owner.finished += 1 + + self.server = Server(("127.0.0.1", self.port), Handler) + self.origin = f"http://127.0.0.1:{self.server.server_port}" + self.thread = threading.Thread(target=self.server.serve_forever, kwargs={"poll_interval": .1}, name="health-relay") + self.thread.start() + retain(self.root / "ready.json", {"origin": self.origin, "upstream": self.upstream, + "delay_s": DELAY, "worker_bound": MAX_WORKERS, "source_sha256": protocol.sha(protocol.read_bytes(__file__))}) + return self + + def close(self): + self.stopping.set() + if self.server: + self.server.shutdown() + self.thread.join(3) + self.server.server_close() # Joins all non-daemon bounded request workers. + retain(self.root / "cleanup.json", {"server_thread_exited": not self.thread or not self.thread.is_alive(), + "active_workers": self.active, "peak_workers": self.peak, "completed_workers": self.finished, + "request_count": self.sequence, "worker_bound": MAX_WORKERS}) + + +def freeze(root, commit): + if subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=REPO, text=True).strip() != commit: + raise protocol.Refusal("trial must start at its named source commit") + files = {} + for path in SOURCES: + name = str(path.relative_to(REPO)) + content = protocol.read_bytes(path) + if subprocess.check_output(["git", "show", f"{commit}:{name}"], cwd=REPO) != content: + raise protocol.Refusal("trial source differs from its committed freeze: " + name) + files[name] = protocol.sha(content) + retain(root / "source-freeze.json", {"commit": commit, "files": files}) + + +def run(root, commit, body_port=0, browser_port=0, relay_port=0): + root = protocol.directory(root, create=True) + freeze(root, commit) + stopped = threading.Event() + signal.signal(signal.SIGTERM, lambda *_: stopped.set()) + signal.signal(signal.SIGINT, lambda *_: stopped.set()) + processes, logs = [], [] + ledger = {"source_commit": commit, "planner": "actual_codex_cli_images_over_TCP", "simulation": True, + "processes": [], "ready": False, "health_delay_s": DELAY, "limit_s": 2700} + + def launch(name, arguments): + log = (root / (name + ".log")).open("xb") + logs.append(log) + process = subprocess.Popen([str(BASE / ".venv/bin/python"), *arguments], cwd=REPO, stdout=log, stderr=log) + processes.append(process) + ledger["processes"].append({"role": name, "pid": process.pid}) + return process + + try: + body_port = body_port or previous.available_port() + browser_port = browser_port or previous.available_port() + if body_port == browser_port or relay_port and relay_port in (body_port, browser_port): + raise protocol.Refusal("trial services need distinct ports") + body_origin, browser_origin = f"http://127.0.0.1:{body_port}", f"http://127.0.0.1:{browser_port}" + launch("body", [str(BASE / "body_network.py"), "--root", str(root / "body"), "--port", str(body_port), "--initialize", "--diagnostic"]) + identity = previous.wait_json(body_origin, "/identity", processes) + retain(root / "identity.json", identity) + launch("health-relay", [str(BASE / "qualify_workbench_health.py"), "relay", "--root", str(root / "health-relay"), + "--upstream", body_origin, "--port", str(relay_port)]) + until = time.monotonic() + 20 + while not (root / "health-relay" / "ready.json").exists(): + if any(p.poll() is not None for p in processes) or time.monotonic() >= until: + raise protocol.Refusal("owned health relay failed to start") + stopped.wait(.1) + relay_ready = protocol.decode(protocol.read_bytes(root / "health-relay" / "ready.json")) + initialization = launch("initialize", [str(BASE / "network_bench_operator.py"), "init", "--root", str(root / "operator"), + "--body-origin", relay_ready["origin"]]) + if initialization.wait(timeout=30): + raise protocol.Refusal("network workbench initialization failed; evidence retained") + launch("workbench", [str(BASE / "network_bench_operator.py"), "serve", "--root", str(root / "operator"), + "--port", str(browser_port), "--backend", "codex"]) + running = [p for p, entry in zip(processes, ledger["processes"], strict=True) if entry["role"] != "initialize"] + initial = previous.wait_json(browser_origin, "/api/state", running) + retain(root / "initial-public.json", initial) + ledger.update(body_origin=body_origin, browser_origin=browser_origin, relay_origin=relay_ready["origin"], + ready=True, app_id=initial["app_id"], body_id=identity["body_id"]) + retain(root / "ready.json", ledger) + print(json.dumps(ledger), flush=True) + deadline = time.monotonic() + 2700 + while not stopped.is_set() and not (root / "stop-request.json").exists(): + if any(p.poll() is not None for p in running): + raise protocol.Refusal("owned trial service exited before requested cleanup") + if time.monotonic() >= deadline: + raise protocol.Refusal("health qualification exceeded its 45-minute bound") + stopped.wait(.2) + retain(root / "final-public.json", previous.wait_json(browser_origin, "/api/state", running)) + except BaseException as exc: + ledger["error"] = type(exc).__name__ + ": " + str(exc) + raise + finally: + for process in reversed(processes): + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=45) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + for entry, process in zip(ledger["processes"], processes, strict=True): + entry.update(exit_observed=process.poll() is not None, returncode=process.returncode) + for log in logs: + log.close() + ledger["owned_processes_exited"] = all(p.poll() is not None for p in processes) + retain(root / "process-ledger.json", ledger) + return ledger + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + commands = parser.add_subparsers(dest="command", required=True) + relay = commands.add_parser("relay") + relay.add_argument("--root", type=Path, required=True) + relay.add_argument("--upstream", required=True) + relay.add_argument("--port", type=int, default=0) + trial = commands.add_parser("trial") + trial.add_argument("--root", type=Path, required=True) + trial.add_argument("--source-commit", required=True) + for name in ("body-port", "browser-port", "relay-port"): + trial.add_argument("--" + name, type=int, default=0) + args = parser.parse_args() + if args.command == "relay": + stopped = threading.Event() + signal.signal(signal.SIGTERM, lambda *_: stopped.set()) + signal.signal(signal.SIGINT, lambda *_: stopped.set()) + owned = HealthRelay(args.upstream, args.root, args.port) + try: + owned.start() + print(json.dumps({"origin": owned.origin}), flush=True) + stopped.wait(2700) + finally: + owned.close() + else: + if any(not 0 <= value <= 65535 for value in (args.body_port, args.browser_port, args.relay_port)): + raise protocol.Refusal("trial ports must be in the TCP range") + print(json.dumps(run(args.root, args.source_commit, args.body_port, args.browser_port, args.relay_port)), flush=True) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/score_workbench_health.py b/tools/physical-workcell/score_workbench_health.py new file mode 100644 index 0000000..785a3da --- /dev/null +++ b/tools/physical-workcell/score_workbench_health.py @@ -0,0 +1,150 @@ +"""Independent health-delay qualification layered on unchanged SIM10 scoring.""" +import argparse +import json +from pathlib import Path + +import body_client +import order_protocol as protocol +import score_network_workbench as previous + +read = previous.read + + +def headers(record): + return {key.lower(): value for key, value in record["headers"].items()} + + +def relay_records(root): + records, valid = [], True + for directory in sorted((root / "health-relay" / "requests").iterdir()): + request = read(directory / "request.json") + result = read(directory / "result.json") + payload = protocol.read_bytes(directory / "request.bin") + upstream, content = None, None + if (directory / "upstream.json").exists(): + upstream = read(directory / "upstream.json") + content = protocol.read_bytes(directory / "response.bin", maximum=body_client.MAX_IMAGE) + valid &= (directory.name == f"{request['sequence']:06d}" and + request["payload_sha256"] == protocol.sha(payload) and request["upstream_sends"] == 1 and + upstream is not None and upstream["response_sha256"] == protocol.sha(content)) + if request["injected_delay_s"]: + valid &= request["tagged_health"] and request["method"] == "GET" and request["path"] in ("/identity", "/state") + elif request["method"] == "POST": + valid &= not request["tagged_health"] + records.append({"request": request, "result": result, "upstream": upstream, "content": content, + "payload": payload}) + valid &= bool(records) and [record["request"]["sequence"] for record in records] == list(range(1, len(records) + 1)) + return records, bool(valid) + + +def fresh_admissions(records, events, identity): + proofs = [event for event in events if event["kind"] == "admission_proof"] + commands = [record for record in records if record["request"]["method"] == "POST" and record["request"]["path"] == "/commands"] + leases = [record for record in records if record["request"]["method"] == "POST" and record["request"]["path"] == "/lease"] + states = [record for record in records if record["request"]["method"] == "GET" and record["request"]["path"] == "/state" and not record["request"]["tagged_health"]] + reports, used = [], set() + previous_command_finished = float("-inf") + for command in commands: + request, payload = command["request"], protocol.decode(command["payload"]) + candidates = [lease for lease in leases if lease["upstream"] and lease["upstream"]["http_status"] == 200 and + lease["upstream"]["finished_monotonic"] <= request["started_monotonic"] and + protocol.decode(lease["content"]).get("lease_id") == payload["lease_id"]] + lease = candidates[-1] if candidates else None + candidate_proofs = [event for event in proofs if event["time"] <= lease["request"]["started_wall"] and + event["outcome"] == payload["operation"]] if lease else [] + event = candidate_proofs[-1] if candidate_proofs else None + proof = event.get("evidence", {}) if event else {} + state_reads = [record for record in states if record["upstream"] and record["upstream"]["http_status"] == 200 and + record["upstream"]["wall"] <= event["time"] and record["request"]["started_monotonic"] > previous_command_finished and + protocol.sha(protocol.encoded(protocol.decode(record["content"]))) == proof.get("state_sha256")] if event else [] + state = max(state_reads, key=lambda record: record["request"]["started_monotonic"]) if state_reads else None + remote = protocol.decode(state["content"]) if state else {} + expected_headers = {key.lower(): value for key, value in body_client.pinned_headers(identity).items()} + ready = bool(lease and event and state and event["seq"] not in used and remote.get("state") == "ready" and + remote.get("identity") == identity and proof.get("epoch") == identity["epoch"] and + all(proof.get(key) == identity[key] for key in ("body_id", "adapter_id", "source_sha256")) and + all(headers(state["request"]).get(key) == value for key, value in expected_headers.items()) and + protocol.decode(lease["payload"])["expected_epoch"] == identity["epoch"] == payload["epoch"] and + state["request"]["started_monotonic"] <= state["upstream"]["finished_monotonic"] <= lease["request"]["started_monotonic"] < request["started_monotonic"]) + if event: + used.add(event["seq"]) + reports.append({"command_id": payload["command_id"], "operation": payload["operation"], "passed": ready, + "proof_event": event["seq"] if event else None, + "state_read_sequence": state["request"]["sequence"] if state else None, + "lease_sequence": lease["request"]["sequence"] if lease else None, + "command_sequence": request["sequence"]}) + if command["upstream"]: + previous_command_finished = command["upstream"]["finished_monotonic"] + return reports + + +def score(root): + root = protocol.directory(root) + base = previous.score(root) + records, relay_valid = relay_records(root) + identity = read(root / "identity.json") + events = [read(path) for path in sorted((root / "operator" / "events").glob("*.json"))] + admissions = fresh_admissions(records, events, identity) + long_reads = [] + natural_delays = [] + for record in records: + request, upstream, result = record["request"], record["upstream"], record["result"] + if request["tagged_health"] and upstream: + decoded = protocol.decode(record["content"]) + healthy = (decoded == identity if request["path"] == "/identity" else + decoded.get("identity") == identity and decoded.get("state") == "ready") + if healthy and upstream["http_status"] == 200 and upstream["upstream_elapsed_s"] >= .8: + natural_delays.append({"sequence": request["sequence"], "path": request["path"], + "upstream_elapsed_s": upstream["upstream_elapsed_s"]}) + if (request["injected_delay_s"] == 1.2 and upstream["http_status"] == 200 and healthy and + result.get("completed") and result.get("delivered") and not result.get("delay_interrupted") and + result["delay_elapsed_s"] >= 1.2): + long_reads.append({"sequence": request["sequence"], "path": request["path"], + "upstream_elapsed_s": upstream["upstream_elapsed_s"], + "injected_elapsed_s": result["delay_elapsed_s"]}) + ui = read(root / "ui-ledger.json") + steps = {step["name"]: step for step in ui["steps"]} + checking = steps.get("healthy_checking") + checking_ok = bool(checking and checking["state"]["runner_status"] == "running" and + checking["state"]["connection"]["state"] == "checking" and checking["state"]["active_job_id"] and + checking["state"]["recovery"]["state"] == "none" and + ("checking" in checking["visible_text"].casefold() or "waiting" in checking["visible_text"].casefold()) and + any(job["status"] == "running" for job in checking["state"]["jobs"])) + allowed_halt = steps.get("uncertain", {}).get("state", {}).get("recovery", {}).get("reason") + unexpected_halts = [event for event in events if event["kind"] == "halt" and event["outcome"] != allowed_halt] + model_outcomes = [read(path) for path in sorted((root / "operator" / "calls").glob("*/outcome.json"))] + cancelled = [index + 1 for index, outcome in enumerate(model_outcomes) if outcome.get("outcome") == "cancelled"] + cleanup = read(root / "health-relay" / "cleanup.json") + process = read(root / "process-ledger.json") + link_events = [read(path) for path in sorted((root / "operator" / "link" / "events").glob("*.json"))] + closed = next((event for event in reversed(link_events) if event["kind"] == "closed"), None) + # A clean host exit also requires its gateway close() to join the bounded readers. + readers_exited = bool(closed and cleanup["server_thread_exited"] and cleanup["active_workers"] == 0 and + cleanup["peak_workers"] <= cleanup["worker_bound"] == 8 and + process["owned_processes_exited"] and + all(item["exit_observed"] and item["returncode"] == 0 for item in process["processes"])) + readers_exited &= bool(closed and closed.get("health_readers_alive") == 0 and + 0 <= closed.get("health_readers_peak", 3) <= 2) + passed = bool(base["passed"] and relay_valid and len(long_reads) >= 3 and admissions and + all(report["passed"] for report in admissions) and checking_ok and not unexpected_halts and + not cancelled and readers_exited) + result = {"passed": passed, "base_qualification": base, "relay_evidence_valid": relay_valid, + "healthy_injected_long_read_count": len(long_reads), "healthy_injected_long_reads": long_reads[:64], + "genuine_upstream_long_read_count": len(natural_delays), "genuine_upstream_long_reads": natural_delays[:64], + "fresh_admission_proofs": admissions, "fresh_proof_every_rpc": bool(admissions and all(r["passed"] for r in admissions)), + "soft_checking_visible_while_running": checking_ok, "unexpected_halts": unexpected_halts, + "cancelled_model_calls": cancelled, "owned_readers_exited": readers_exited, + "relay_cleanup": cleanup, "scope": "same-Mac loopback simulation; 1.2s diagnostic auxiliary read delay"} + retain = protocol.create_file + retain(root / "health-qualification-score.json", protocol.encoded(result)) + return {key: result[key] for key in ("passed", "fresh_proof_every_rpc", "soft_checking_visible_while_running", "owned_readers_exited")} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, required=True) + print(json.dumps(score(parser.parse_args().root), sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/tools/physical-workcell/test_network_operator.py b/tools/physical-workcell/test_network_operator.py index 456b601..4caac18 100644 --- a/tools/physical-workcell/test_network_operator.py +++ b/tools/physical-workcell/test_network_operator.py @@ -62,6 +62,200 @@ def restart_same_body(self): self.assertGreater(current["epoch"], identity["epoch"]) return current + def test_healthy_delayed_probe_preserves_model_then_requires_fresh_admission_proof(self): + entered, release = threading.Event(), threading.Event() + def policy(*_): + entered.set() + release.wait(8) + return action("move", -.25, 0), {} + op = self.open(policy) + op.health_stop.set() + op.health_worker.join(4) + op.enqueue(self.job()) + worker = threading.Thread(target=op._step) + worker.start() + self.assertTrue(entered.wait(10)) + epoch = op.control_epoch + boot = op.state()["connection"]["epoch"] + original = self.service.state + reads = [] + def delayed_first_state(): + reads.append(time.monotonic()) + if len(reads) == 1: + time.sleep(1.1) + return original() + proofs = [] + status = op.client.status + def fresh_status(): + result = status() + proofs.append(result["server_state"]) + return result + try: + with mock.patch.object(self.service, "state", side_effect=delayed_first_state): + self.assertFalse(op._refresh_health()) + self.assertEqual(op.state()["connection"]["state"], "checking") + self.assertEqual(op.state()["connection"]["epoch"], boot) + self.assertEqual(op.control_epoch, epoch) + self.assertFalse(op.cancel.is_set()) + self.assertFalse(op.body_ready) + self.assertEqual(op.state()["runner_status"], "running") + with mock.patch.object(op.client, "status", side_effect=fresh_status): + release.set() + worker.join(15) + self.assertFalse(worker.is_alive()) + self.assertGreaterEqual(len(proofs), 2) # Proposal and dispatch each need fresh proof. + self.assertTrue(all(p["state"] == "ready" for p in proofs)) + self.assertEqual(self.service.body.status()["generation"], 1) + self.assertEqual(op.state()["runner_status"], "running") + self.assertEqual(op.state()["connection"]["state"], "connected") + finally: + release.set() + worker.join(15) + + def test_checking_health_cannot_admit_when_fresh_tcp_proof_times_out(self): + op = self.open(lambda *_: self.fail("proof failure reached model")) + op.health_stop.set() + op.health_worker.join(4) + op.enqueue(self.job()) + original = self.service.state + def delayed_state(): + time.sleep(1.1) + return original() + with mock.patch.object(self.service, "state", side_effect=delayed_state): + self.assertFalse(op._refresh_health()) + self.assertEqual(op.state()["connection"]["state"], "checking") + op.client.timeout = .05 + self.assertFalse(op._step()) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertTrue(op.cancel.is_set()) + self.assertIsNone(op.m["stage"]) + self.assertEqual(len(op._journal()["commands"]), 0) + self.assertIsNone(op._journal()["lease"]) + self.assertIsNone(self.service.body.status()["active_job"]) + + def test_checking_health_keeps_verified_boot_change_as_hard_veto(self): + op = self.open() + op.health_stop.set() + op.health_worker.join(4) + op.enqueue(self.job()) + current = self.restart_same_body() + original = self.service.state + def delayed_state(): + time.sleep(1.1) + return original() + with mock.patch.object(self.service, "state", side_effect=delayed_state): + self.assertFalse(op._refresh_health()) + self.assertEqual(op.state()["connection"]["epoch"], current["epoch"]) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertTrue(op.cancel.is_set()) + self.assertFalse(op._step()) + self.assertEqual(len(op._journal()["commands"]), 0) + + def test_checking_health_fresh_unknown_body_blocks_before_lease_or_stage(self): + op = self.open(lambda *_: self.fail("unknown body reached model")) + op.health_stop.set() + op.health_worker.join(4) + op.enqueue(self.job()) + original = self.service.state + reads = [] + def state_then_unknown(): + reads.append(1) + if len(reads) == 1: + time.sleep(1.1) + return original() + result = original() + result["state"] = "unknown" + return result + with mock.patch.object(self.service, "state", side_effect=state_then_unknown): + self.assertFalse(op._refresh_health()) + self.assertEqual(op.state()["connection"]["state"], "checking") + self.assertFalse(op._step()) + self.assertEqual(op.state()["runner_status"], "blocked") + self.assertTrue(op.cancel.is_set()) + self.assertIsNone(op.m["stage"]) + self.assertEqual(len(op._journal()["commands"]), 0) + self.assertIsNone(op._journal()["lease"]) + + def test_pause_during_fresh_admission_proof_prevents_lease_and_command(self): + op = self.open(lambda *_: self.fail("paused admission reached model")) + op.health_stop.set() + op.health_worker.join(4) + op.enqueue(self.job()) + entered, release = threading.Event(), threading.Event() + original = self.service.state + def delayed_state(): + entered.set() + release.wait(5) + return original() + with mock.patch.object(self.service, "state", side_effect=delayed_state): + worker = threading.Thread(target=op._step) + worker.start() + try: + self.assertTrue(entered.wait(5)) + self.assertTrue(op.state()["transport_pending"]) + self.assertIsNone(op.m["stage"]) + op.pause() + finally: + release.set() + worker.join(10) + self.assertFalse(worker.is_alive()) + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(len(op._journal()["commands"]), 0) + self.assertIsNone(op._journal()["lease"]) + self.assertIsNone(op.m["stage"]) + + def test_checking_does_not_release_unknown_and_exact_receipt_stays_paused(self): + decisions = iter((action("move", -.25, 0), action())) + op = self.open(lambda *_: (next(decisions), {})) + op.health_stop.set() + op.health_worker.join(4) + op.enqueue(self.job()) + op.fault({"mode": "drop_after", "delay_s": 0}) + self.assertFalse(op._step()) + token = op.m["stage"]["command_id"] + journal = op._journal() + original = self.service.state + def delayed_state(): + time.sleep(1.1) + return original() + with mock.patch.object(self.service, "state", side_effect=delayed_state): + self.assertFalse(op._refresh_health()) + self.assertEqual(op.state()["connection"]["state"], "checking") + self.assertEqual(op.state()["runner_status"], "blocked") + self.assertEqual(op.m["stage"]["command_id"], token) + self.assertFalse(op._step()) + with self.assertRaises(protocol.Refusal): + op.resume() + op.reconcile() + self.assertEqual(op.state()["runner_status"], "paused") + self.assertEqual(len(op._journal()["commands"]), len(journal["commands"])) + self.assertEqual(op._journal()["lease"], journal["lease"]) + self.assertEqual(op._journal()["commands"][token]["send_count"], 1) + self.assertEqual(self.service.body.status()["generation"], 1) + op.resume() + self.assertEqual(op.state()["connection"]["state"], "connected") + self.assertFalse(op._step()) + self.assertEqual(self.service.body.status()["generation"], 1) + + def test_checking_followed_by_changed_source_identity_cancels_and_blocks(self): + op = self.open() + op.health_stop.set() + op.health_worker.join(4) + original = self.service.state + def delayed_state(): + time.sleep(1.1) + return original() + with mock.patch.object(self.service, "state", side_effect=delayed_state): + self.assertFalse(op._refresh_health()) + self.assertEqual(op.state()["connection"]["state"], "checking") + wrong_identity = self.service.identity() + wrong_identity["source_sha256"] = "0" * 64 + with mock.patch.object(self.service, "identity", return_value=wrong_identity): + self.assertFalse(op._refresh_health()) + self.assertEqual(op.state()["runner_status"], "blocked") + self.assertTrue(op.cancel.is_set()) + self.assertEqual(len(op._journal()["commands"]), 0) + def test_health_first_fast_body_reboot_withholds_old_model_decision(self): entered, release = threading.Event(), threading.Event() decisions = iter((action("move", -.25, 0), action())) @@ -90,12 +284,14 @@ def policy(*_): def test_acquisition_first_reboot_cannot_authorize_old_decision_with_fresh_lease(self): calls = [] before = [] + old_leases = [] old_challenges = [] def policy(challenge, *_): calls.append(challenge) if len(calls) == 1: old_challenges.append(challenge["challenge_id"]) before.append(len(op._journal()["commands"])) + old_leases.append(op._journal()["lease"]) self.restart_same_body() return action("move", -.25, 0), {} return action(), {} @@ -108,7 +304,7 @@ def policy(challenge, *_): self.assertEqual(self.service.body.status()["generation"], 0) self.assertEqual(len(op._journal()["commands"]), before[0]) self.assertIsNone(op.m["stage"]) - self.assertEqual(op._journal()["lease"]["epoch"], self.service.epoch) + self.assertEqual(op._journal()["lease"], old_leases[0]) op.resume() self.assertFalse(op._step()) self.assertEqual(len(calls), 2) @@ -435,9 +631,12 @@ def test_stale_health_timeout_after_known_socket_dispatch_does_not_pause(self): op.health_worker.join(4) entered, release = threading.Event(), threading.Event() original = self.service.state + reads = [] def delayed_health_state(): - entered.set() - release.wait(5) + reads.append(1) + if len(reads) == 1: + entered.set() + release.wait(5) return original() with mock.patch.object(self.service, "state", side_effect=delayed_health_state): health = threading.Thread(target=op._refresh_health) diff --git a/tools/physical-workcell/test_workbench_health.py b/tools/physical-workcell/test_workbench_health.py new file mode 100644 index 0000000..e721b79 --- /dev/null +++ b/tools/physical-workcell/test_workbench_health.py @@ -0,0 +1,168 @@ +"""Diagnostic socket/byte conformance; no UI, model, or native-state trial.""" +import http.client +import threading +import time +import unittest +import uuid +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer + +import body_client +import order_protocol as protocol +import qualify_workbench_health as harness +import score_workbench_health as scorer + +IDENTITY = {"protocol": "footwork.body/1", "body_id": "body-test", "adapter_id": "adapter-test", + "source_sha256": "a" * 64, "epoch": 1, "simulation": True} + + +class HealthHarnessTests(unittest.TestCase): + def setUp(self): + self.root = protocol.directory(harness.BASE / "output" / ("sim12-harness-" + uuid.uuid4().hex[:12]), create=True) + self.calls, self.lock = [], threading.Lock() + owner = self + + class Handler(BaseHTTPRequestHandler): + def log_message(self, *_): + pass + + def do_GET(self): + self.reply() + + def do_POST(self): + self.reply() + + def reply(self): + length = int(self.headers.get("Content-Length", 0)) + payload = self.rfile.read(length) + with owner.lock: + owner.calls.append({"method": self.command, "path": self.path, "payload": payload, + "headers": dict(self.headers)}) + value = IDENTITY if self.path == "/identity" else {"identity": IDENTITY, "state": "ready"} + content = protocol.encoded(value) + self.send_response(200) + self.send_header("Content-Length", str(len(content))) + self.end_headers() + self.wfile.write(content) + + self.server = ThreadingHTTPServer(("127.0.0.1", 0), Handler) + self.thread = threading.Thread(target=self.server.serve_forever, kwargs={"poll_interval": .01}) + self.thread.start() + self.relay = harness.HealthRelay(f"http://127.0.0.1:{self.server.server_port}", self.root / "health-relay").start() + + def tearDown(self): + self.relay.close() + self.server.shutdown() + self.thread.join(3) + self.server.server_close() + self.assertFalse(self.thread.is_alive()) + cleanup = protocol.decode(protocol.read_bytes(self.relay.root / "cleanup.json")) + self.assertTrue(cleanup["server_thread_exited"]) + self.assertEqual(cleanup["active_workers"], 0) + self.assertLessEqual(cleanup["peak_workers"], harness.MAX_WORKERS) + + def read(self, path, tagged=False): + headers = {**body_client.pinned_headers(IDENTITY), **({"X-Footwork-Health-Probe": "1"} if tagged else {})} + started = time.monotonic() + status, content = body_client.http_call(self.relay.origin, "GET", path, headers, timeout=4) + return status, content, time.monotonic() - started + + def test_only_tagged_identity_and_state_receive_actual_delay(self): + for path in ("/identity", "/state"): + with self.subTest(path=path): + _, plain, _ = self.read(path) + status, tagged, elapsed = self.read(path, tagged=True) + self.assertEqual(status, 200) + self.assertEqual(tagged, plain) + self.assertGreaterEqual(elapsed, 1.2) + records, valid = scorer.relay_records(self.root) + self.assertTrue(valid) + self.assertEqual([record["request"]["injected_delay_s"] for record in records], [0, 1.2, 0, 1.2]) + self.assertEqual(len(self.calls), 4) + + def test_post_bytes_identity_headers_immediate_and_no_retry(self): + payload = b'{"operation":"dispatch","command_id":"diagnostic-command","literal":"exact bytes"}' + headers = body_client.pinned_headers(IDENTITY) + status, _ = body_client.http_call(self.relay.origin, "POST", "/commands", headers, payload, timeout=4) + self.assertEqual(status, 200) + self.assertEqual(len(self.calls), 1) + self.assertEqual(self.calls[0]["payload"], payload) + for key, value in headers.items(): + self.assertEqual(self.calls[0]["headers"][key], value) + records, valid = scorer.relay_records(self.root) + self.assertTrue(valid) + self.assertEqual(records[0]["request"]["operation"], "dispatch") + self.assertEqual(records[0]["request"]["injected_delay_s"], 0) + self.assertEqual(records[0]["request"]["upstream_sends"], 1) + + def test_probe_annotation_cannot_change_effect_or_image_routes(self): + for method, path, payload in (("POST", "/commands", b'{"operation":"dispatch"}'), + ("GET", "/images/diagnostic", None)): + with self.assertRaises((OSError, http.client.HTTPException)): + body_client.http_call(self.relay.origin, method, path, {"X-Footwork-Health-Probe": "1"}, payload, timeout=2) + self.assertEqual(self.calls, []) + self.assertEqual(self.relay.sequence, 0) + + def test_owned_control_selects_state_without_changing_normal_reads(self): + protocol.persist(self.root / "health-relay-control.json", {"enabled": True, "paths": ["/state"]}) + self.read("/identity", tagged=True) + self.read("/state", tagged=True) + self.read("/state") + records, valid = scorer.relay_records(self.root) + self.assertTrue(valid) + self.assertEqual([record["request"]["injected_delay_s"] for record in records], [0, 1.2, 0]) + + +class AdmissionScorerTests(unittest.TestCase): + def fixture(self): + remote = {"state": "ready", "identity": IDENTITY} + state = {"request": {"method": "GET", "path": "/state", "tagged_health": False, "sequence": 1, + "headers": body_client.pinned_headers(IDENTITY), "started_monotonic": 1.0}, + "upstream": {"http_status": 200, "wall": 2.0, "finished_monotonic": 2.0}, + "content": protocol.encoded(remote)} + lease = {"request": {"method": "POST", "path": "/lease", "sequence": 2, + "started_monotonic": 3.0, "started_wall": 3.0}, + "upstream": {"http_status": 200, "finished_monotonic": 3.1}, + "content": protocol.encoded({"lease_id": "lease-1"}), + "payload": protocol.encoded({"expected_epoch": 1})} + command = {"request": {"method": "POST", "path": "/commands", "sequence": 3, "started_monotonic": 4.0}, + "upstream": {"finished_monotonic": 5.0}, + "payload": protocol.encoded({"command_id": "command-1", "lease_id": "lease-1", "epoch": 1, + "operation": "dispatch"})} + event = {"kind": "admission_proof", "seq": 1, "time": 2.1, "outcome": "dispatch", + "evidence": {**{key: IDENTITY[key] for key in ("body_id", "adapter_id", "source_sha256", "epoch")}, + "state_sha256": protocol.sha(protocol.encoded(remote))}} + return [state, lease, command], [event] + + def test_exact_fresh_untagged_state_before_lease_and_command_passes(self): + records, events = self.fixture() + self.assertTrue(scorer.fresh_admissions(records, events, IDENTITY)[0]["passed"]) + + def test_tagged_stale_foreign_or_unbound_proof_fails(self): + for case in ("tagged", "late", "foreign", "missing", "wrong_header", "wrong_epoch"): + records, events = self.fixture() + if case == "tagged": + records[0]["request"]["tagged_health"] = True + elif case == "late": + records[0]["upstream"]["finished_monotonic"] = 3.5 + elif case == "foreign": + events[0]["evidence"]["body_id"] = "foreign" + elif case == "missing": + events = [] + elif case == "wrong_header": + records[0]["request"]["headers"]["X-Body-Id"] = "foreign" + else: + events[0]["evidence"]["epoch"] = 2 + with self.subTest(case=case): + self.assertFalse(scorer.fresh_admissions(records, events, IDENTITY)[0]["passed"]) + + def test_one_proof_cannot_authorize_a_second_command(self): + records, events = self.fixture() + duplicate = {**records[2], "request": {**records[2]["request"], "started_monotonic": 6.0, "sequence": 4}} + records.append(duplicate) + reports = scorer.fresh_admissions(records, events, IDENTITY) + self.assertTrue(reports[0]["passed"]) + self.assertFalse(reports[1]["passed"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/physical-workcell/test_workbench_link.py b/tools/physical-workcell/test_workbench_link.py index 125ed17..e6f7568 100644 --- a/tools/physical-workcell/test_workbench_link.py +++ b/tools/physical-workcell/test_workbench_link.py @@ -1,9 +1,15 @@ """Retained workbench-link checks with real TCP and unchanged native authority.""" +import concurrent.futures +import contextlib +import http.client import socket +import threading import time import unittest import uuid +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path +from unittest import mock import body_client import body_network @@ -12,6 +18,66 @@ BASE = Path(__file__).resolve().parent ZONE = {"x_min": .04, "x_max": .10, "y_min": -.025, "y_max": .025} +PROBE_HEADER = "X-Footwork-Health-Probe" + + +class DelayedHealthGateway: + """Test-only real TCP response barrier; never extends the product fault API.""" + def __init__(self, upstream, trickle=False): + self.upstream = upstream + self.release = threading.Event() + self.lock = threading.Lock() + self.calls = [] + self.active = {} + self.peak = {} + owner = self + + class Handler(BaseHTTPRequestHandler): + def log_message(self, *_): + pass + + def do_GET(self): + tagged = self.headers.get(PROBE_HEADER) == "1" + with owner.lock: + owner.calls.append({"path": self.path, "tagged": tagged}) + if tagged: + owner.active[self.path] = owner.active.get(self.path, 0) + 1 + owner.peak[self.path] = max(owner.peak.get(self.path, 0), owner.active[self.path]) + try: + if tagged and not trickle: + owner.release.wait(3) + headers = {key: value for key, value in self.headers.items() if key.lower() != "host"} + status, content = body_client.http_call(owner.upstream, "GET", self.path, headers, timeout=2) + self.send_response(status) + self.send_header("Content-Length", str(len(content))) + self.send_header("Connection", "close") + self.end_headers() + if tagged and trickle: + for byte in content: + try: + self.wfile.write(bytes([byte])) + self.wfile.flush() + except OSError: + break + time.sleep(.03) + else: + with contextlib.suppress(OSError): + self.wfile.write(content) + finally: + if tagged: + with owner.lock: + owner.active[self.path] -= 1 + + self.server = ThreadingHTTPServer(("127.0.0.1", 0), Handler) + self.origin = f"http://127.0.0.1:{self.server.server_port}" + self.thread = threading.Thread(target=self.server.serve_forever, kwargs={"poll_interval": .05}) + self.thread.start() + + def close(self): + self.release.set() + self.server.shutdown() + self.server.server_close() + self.thread.join() class WorkbenchLinkTests(unittest.TestCase): @@ -218,6 +284,168 @@ def test_idle_polling_does_not_exhaust_retained_command_journal(self): self.assertEqual(len(self.events()), before) self.evidence.append({"ordinary_state_polls": 10, "additional_journal_events": 0}) + def test_slow_auxiliary_probes_are_single_flight_and_never_reuse_late_results(self): + gateway = DelayedHealthGateway(self.server.origin) + link = workbench_link.WorkbenchLink(gateway.origin, self.root / "slow-link").start() + pinned = body_client.read_journal(self.root / "client" / "client.json")["identity"] + headers = {**body_client.pinned_headers(pinned), PROBE_HEADER: "1"} + def probe(path): + started = time.monotonic() + status, content = body_client.http_call(link.origin, "GET", path, headers, timeout=2) + return path, status, storage.decode(content), time.monotonic() - started + pool = concurrent.futures.ThreadPoolExecutor(max_workers=6) + futures = [] + try: + futures = [pool.submit(probe, path) for path in ("/state", "/identity", "/state", "/identity", "/state", "/identity")] + deadline = time.monotonic() + 1 + while time.monotonic() < deadline: + with gateway.lock: + if len(gateway.calls) >= 2: + break + time.sleep(.005) + status, fresh = body_client.http_call(link.origin, "GET", "/state", body_client.pinned_headers(pinned), timeout=2) + self.assertEqual(status, 200) + self.assertEqual(storage.decode(fresh)["identity"], pinned) + # The barrier outlasts the .8-second caller budget, then releases all owned transports. + time.sleep(.8) + repeated = [probe(path) for path in ("/state", "/identity")] + gateway.release.set() + results = [future.result() for future in futures] + repeated + with gateway.lock: + peak = dict(gateway.peak) + tagged_before = sum(call["tagged"] for call in gateway.calls) + self.evidence.append({"results": results, "upstream_peak_by_path": peak, + "tagged_upstream_calls": tagged_before, "independent_full_status": status}) + self.assertEqual(peak, {"/state": 1, "/identity": 1}) + self.assertEqual(tagged_before, 2) + for path, status, result, elapsed in results: + self.assertEqual(status, 504) + self.assertEqual(result, {"version": 1, "kind": "health_read_pending", "path": path}) + self.assertLess(elapsed, .8) + # A subsequent probe obtains a new upstream response rather than the discarded late one. + deadline = time.monotonic() + 2 + while time.monotonic() < deadline: + with gateway.lock: + if not any(gateway.active.values()): + break + time.sleep(.005) + for path in ("/state", "/identity"): + deadline = time.monotonic() + 2 + while True: + _, status, _, _ = probe(path) + if status == 200 or time.monotonic() >= deadline: + break + time.sleep(.005) + self.assertEqual(status, 200) + with gateway.lock: + self.assertEqual(sum(call["tagged"] for call in gateway.calls), 4) + finally: + gateway.release.set() + pool.shutdown(wait=True) + link.close() + gateway.close() + + def test_probe_annotation_is_refused_before_any_upstream_dispatch(self): + proposal = self.prepare() + manifest = body_client.read_journal(self.root / "client" / "client.json") + pinned = manifest["identity"] + request = {"protocol": body_client.PROTOCOL, "adapter_id": pinned["adapter_id"], "body_id": pinned["body_id"], + "source_sha256": pinned["source_sha256"], "client_id": manifest["client_id"], + "lease_id": manifest["lease"]["lease_id"], "epoch": manifest["lease"]["epoch"], + "command_id": "command-invalid-probe-" + uuid.uuid4().hex, "operation": "dispatch", + "arguments": {"proposal_id": proposal["proposal_id"]}} + payload = storage.encoded(request) + host, port = body_client.endpoint(self.link.origin) + before = {str(p.relative_to(self.root / "body" / "commands")): p.read_bytes() + for p in (self.root / "body" / "commands").rglob("*") if p.is_file()} + cases = [("GET", "/state", ["0"]), ("GET", "/identity", ["1", "1"]), + ("GET", "/identity?probe=1", ["1"]), ("GET", "/commands/missing", ["1"]), + ("POST", "/commands", ["1"])] + forwards = sum(event["kind"] == "forwarded" for event in self.events()) + for method, path, annotations in cases: + content = payload if method == "POST" else b"" + headers = [("Host", f"{host}:{port}"), *body_client.pinned_headers(pinned).items(), + ("Content-Length", str(len(content))), ("Content-Type", "application/json"), + *[(PROBE_HEADER, value) for value in annotations]] + wire = (f"{method} {path} HTTP/1.1\r\n" + "".join(f"{k}: {v}\r\n" for k, v in headers) + "\r\n").encode() + content + with socket.create_connection((host, port), timeout=2) as connection: + connection.sendall(wire) + try: + reply = connection.recv(1024) + except ConnectionResetError: + reply = b"" + self.assertEqual(reply, b"") + self.assertEqual(sum(event["kind"] == "forwarded" for event in self.events()), forwards) + self.assertEqual({str(p.relative_to(self.root / "body" / "commands")): p.read_bytes() + for p in (self.root / "body" / "commands").rglob("*") if p.is_file()}, before) + self.assertEqual(self.server.state()["bench"]["generation"], 0) + self.evidence.append({"refused_probe_routes": cases, "generation": 0}) + + def test_probe_cleanup_joins_upstream_readers_before_releasing_root(self): + gateway = DelayedHealthGateway(self.server.origin) + link = workbench_link.WorkbenchLink(gateway.origin, self.root / "cleanup-link").start() + origin = link.origin + finished = threading.Event() + closer = None + try: + status, _ = body_client.http_call(origin, "GET", "/identity", {PROBE_HEADER: "1"}, timeout=2) + self.assertEqual(status, 504) + owned = [flight["thread"] for flight in link._probe_flights.values()] + def close(): + link.close() + finished.set() + closer = threading.Thread(target=close) + closer.start() + self.assertFalse(finished.wait(.1)) + with self.assertRaises(storage.Refusal): + workbench_link.WorkbenchLink(gateway.origin, self.root / "cleanup-link").start() + gateway.release.set() + self.assertTrue(finished.wait(2)) + closer.join() + self.assertTrue(all(not thread.is_alive() for thread in owned)) + events = [storage.decode(storage.read_bytes(path)) for path in sorted((self.root / "cleanup-link" / "events").glob("*.json"))] + self.assertEqual(events[-1]["kind"], "closed") + self.assertEqual(events[-1]["health_readers_alive"], 0) + self.assertEqual(events[-1]["health_readers_peak"], 1) + frozen = {path.name: path.read_bytes() for path in (self.root / "cleanup-link" / "events").iterdir()} + time.sleep(.05) + self.assertEqual(frozen, {path.name: path.read_bytes() for path in (self.root / "cleanup-link" / "events").iterdir()}) + link = workbench_link.WorkbenchLink(gateway.origin, self.root / "cleanup-link").start() + self.assertEqual(link.origin, origin) + status, _ = body_client.http_call(origin, "GET", "/identity", {PROBE_HEADER: "1"}, timeout=2) + self.assertEqual(status, 200) + self.evidence.append({"joined_readers": len(owned), "restart_origin": origin, "closed": events[-1]}) + finally: + gateway.release.set() + if closer is not None: + closer.join(timeout=3) + link.close() + gateway.close() + + def test_probe_hard_failure_and_absolute_deadline_keep_transport_loss_semantics(self): + gateway = DelayedHealthGateway(self.server.origin, trickle=True) + link = workbench_link.WorkbenchLink(gateway.origin, self.root / "deadline-link").start() + try: + with mock.patch.object(workbench_link, "HEALTH_HARD_SECONDS", .15): + started = time.monotonic() + with self.assertRaises((OSError, http.client.HTTPException)): + body_client.http_call(link.origin, "GET", "/identity", {PROBE_HEADER: "1"}, timeout=2) + self.assertLess(time.monotonic() - started, .6) + link.close() + self.assertFalse(link._probe_flights) + self.evidence.append({"short_owned_hard_deadline_s": .15, "outcome": "transport_loss"}) + finally: + gateway.release.set() + link.close() + gateway.close() + # The production deadline remains thirty seconds, while an already dead body fails promptly. + self.assertEqual(workbench_link.HEALTH_HARD_SECONDS, 30) + self.server.close() + started = time.monotonic() + with self.assertRaises((OSError, http.client.HTTPException)): + body_client.http_call(self.link.origin, "GET", "/identity", {PROBE_HEADER: "1"}, timeout=2) + self.assertLess(time.monotonic() - started, .6) + if __name__ == "__main__": unittest.main() diff --git a/tools/physical-workcell/workbench_link.py b/tools/physical-workcell/workbench_link.py index cb58b50..3cd0f08 100644 --- a/tools/physical-workcell/workbench_link.py +++ b/tools/physical-workcell/workbench_link.py @@ -2,6 +2,7 @@ Command payload bytes and identity headers pass unchanged. One-shot faults are local diagnostics. Ordinary read-only identity/state polling is not journaled. +Tagged auxiliary reads are single flight per path; late replies are discarded. """ import concurrent.futures import contextlib @@ -21,6 +22,9 @@ MODES = {"drop_after", "delay_after", "duplicate"} MAX_EVENTS = 16384 +HEALTH_HEADER = "X-Footwork-Health-Probe" +HEALTH_SOFT_SECONDS = .6 +HEALTH_HARD_SECONDS = 30 class WorkbenchLink: @@ -35,6 +39,79 @@ def __init__(self, origin, root, port=0): self._mutex = threading.RLock() self._manifest = None self._server = self._thread = self._fd = None + self._probe_flights = {} + self._probe_closing = False + self._probe_peak = 0 + + def _probe_read(self, path, headers, flight): + """Owned read-only socket, with an absolute deadline even for trickled replies.""" + host, port = body_client.endpoint(self.upstream) + connection = http.client.HTTPConnection(host, port, timeout=HEALTH_HARD_SECONDS) + socket_lock, expired = threading.Lock(), threading.Event() + owned_socket = [None] + + def expire(): + expired.set() + with socket_lock: + transport = owned_socket[0] + if transport is not None: + with contextlib.suppress(OSError): + transport.shutdown(socket.SHUT_RDWR) + + timer = threading.Timer(max(0, flight["hard_deadline"] - time.monotonic()), expire) + timer.start() + try: + connection.connect() + with socket_lock: + owned_socket[0] = connection.sock + if expired.is_set(): + raise TimeoutError("auxiliary body read exceeded its hard deadline") + connection.request("GET", path, headers=headers) + response = connection.getresponse() + length = response.getheader("Content-Length") + if length is not None and (not length.isdigit() or int(length) > protocol.MAX_BYTES): + raise protocol.Refusal("body response exceeds its bounded size") + content = response.read(protocol.MAX_BYTES + 1) + if expired.is_set(): + raise TimeoutError("auxiliary body read exceeded its hard deadline") + if len(content) > protocol.MAX_BYTES: + raise protocol.Refusal("body response exceeds its bounded size") + if 300 <= response.status < 400: + raise protocol.Refusal("body redirects are refused") + flight["reply"] = response.status, content + except (OSError, http.client.HTTPException, protocol.Refusal, KeyError, TypeError, ValueError) as exc: + flight["error"] = exc + finally: + connection.close() + timer.cancel() + timer.join() + flight["finished_at"] = time.monotonic() + flight["done"].set() + # No journal writes or response reuse after an auxiliary caller expires. + + def _probe(self, path, headers): + pending = (504, protocol.encoded({"version": 1, "kind": "health_read_pending", "path": path})) + deadline = time.monotonic() + HEALTH_SOFT_SECONDS + with self._mutex: + if self._probe_closing: + raise protocol.Refusal("link is closing") + previous = self._probe_flights.get(path) + if previous is not None: + if previous["thread"].is_alive(): + return pending + del self._probe_flights[path] + flight = {"done": threading.Event(), "hard_deadline": time.monotonic() + HEALTH_HARD_SECONDS} + thread = threading.Thread(target=self._probe_read, args=(path, dict(headers), flight), + name="workbench-health-" + path.removeprefix("/")) + flight["thread"] = thread + self._probe_flights[path] = flight + thread.start() + self._probe_peak = max(self._probe_peak, sum(item["thread"].is_alive() for item in self._probe_flights.values())) + if not flight["done"].wait(max(0, deadline - time.monotonic())) or flight["finished_at"] > deadline: + return pending + if "error" in flight: + raise flight["error"] + return flight["reply"] def _public(self, manifest=None): m = self._manifest if manifest is None else manifest @@ -140,7 +217,7 @@ def drop(self): def handle_request(self): self.connection.settimeout(30) try: - payload, operation, command_id, headers, audit = self.validate_request() + payload, operation, command_id, headers, audit, probe = self.validate_request() with owner._mutex: if not owner._manifest["connected"]: if audit: @@ -170,7 +247,9 @@ def forward(copy_index): http_status=status, response_sha256=protocol.sha(content)) return status, content - if mode == "duplicate": + if probe: + status, content = owner._probe(self.path, headers) + elif mode == "duplicate": with concurrent.futures.ThreadPoolExecutor(max_workers=2) as pool: replies = [pool.submit(forward, index) for index in (1, 2)] responses = [reply.result() for reply in replies] @@ -208,6 +287,9 @@ def validate_request(self): read_route = parsed.path in {"/identity", "/state"} or parsed.path.startswith(("/commands/", "/images/")) if (self.command == "GET" and not read_route) or (self.command == "POST" and self.path not in {"/lease", "/commands"}): raise protocol.Refusal("unsupported link route") + probes = self.headers.get_all(HEALTH_HEADER, []) + if probes and (probes != ["1"] or self.command != "GET" or self.path not in {"/identity", "/state"}): + raise protocol.Refusal("auxiliary health annotation requires one exact read-only route") for name in ("X-Body-Id", "X-Adapter-Id", "X-Source-Sha256"): values = self.headers.get_all(name, []) if len(values) > 1 or (parsed.path != "/identity" and len(values) != 1): @@ -238,7 +320,7 @@ def validate_request(self): headers = {key: value for key, value in self.headers.items() if key.lower() not in {"host", "connection", "content-length", "transfer-encoding"}} headers["Content-Length"] = str(length) - return payload, operation, command_id, headers, parsed.path not in {"/identity", "/state"} + return payload, operation, command_id, headers, parsed.path not in {"/identity", "/state"}, bool(probes) server = ThreadingHTTPServer(("127.0.0.1", port), Handler) server.daemon_threads = False @@ -252,6 +334,7 @@ def validate_request(self): self._event("fault_cancelled_on_restart", _changes={"fault": None}, fault=cancelled) self._event("started", origin=self.origin, upstream=self.upstream, restarted=retained) self._server, self._fd = server, fd + self._probe_closing = False self._thread = threading.Thread(target=server.serve_forever, kwargs={"poll_interval": .1}, daemon=True) self._thread.start() return self @@ -291,11 +374,18 @@ def arm(self, mode, operation="dispatch", delay_s=.2): def close(self): if self._server is not None: + with self._mutex: + self._probe_closing = True self._server.shutdown() try: self._server.server_close() self._thread.join(timeout=2) - self._event("closed") + # Tagged callers finish at the soft bound; their upstream reads remain owned. + # Each worker's absolute hard deadline closes its socket before this join returns. + for flight in self._probe_flights.values(): + flight["thread"].join() + self._probe_flights.clear() + self._event("closed", health_readers_alive=0, health_readers_peak=self._probe_peak) finally: self._server = None os.close(self._fd) From 445a348ff31243c2f3d90baae9ce209d89bd7eac Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 15:05:58 -0400 Subject: [PATCH 152/216] Retry stale AX observations after owned document close --- .../2026-10-12-onboarding-fixture-v4.md | 7 + jevdual/scripts/capability_fixture.py | 49 ++++--- jevdual/tests/test_capability_fixture.py | 126 ++++++++++++++++++ 3 files changed, 165 insertions(+), 17 deletions(-) diff --git a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md index e9661aa..2db18be 100644 --- a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md +++ b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md @@ -64,3 +64,10 @@ Test: reproduce the observed stale AXRole child/window race against21599c6; then Predicts: stale reads cause no extra action; confirmation requires a subsequent fresh readable AXWindows snapshot proving the original identity absent. Persistent errors remain bounded unknown/error, foreign identity refuses, and real repaired fixture closes automatically. Against: an AX error alone confirms closure, a stale element is pressed again, an unrelated window is closed, retry exceeds the cleanup deadline, or live cleanup still lacks confirmation. Refs: UFU6; scripts/capability_fixture.py close_owned_document/discard_button; frozen21599c6 + +## UFU7 · update · 2026-10-12 15:03 +Resolves: UF3 = failed +Observed: UFU6 records two resolutions on one field, but the notebook reader recognizes only its first prediction. This single resolution makes the already observed failed U3v1 journey machine-readable. Worker boundary reproduction has five failures and one pass against21599c6; its narrow post-close invalid-observation retry passes55helper cases. Root independently reviews the diff and runs81combined checks, Ruff check/format and notebook validation successfully. AXPress errors remain terminal; confirmation still requires fresh readable absence and unchanged identity. +Changes: only fixture/helper tests change. The failed guest archive is being exported before a separately frozen repair packet; no original receipt is changed and no native effect is replayed. +Next: freeze the repair, obtain Claude review of source/artifact and original guest evidence, then perform the preregistered post-grant repair trial. UF4 remains open. +Refs: output/u2-fixture-v4-dev/uf4-before.txt; output/u2-fixture-v4-dev/uf4-after.txt; UFU6; tests/test_capability_fixture.py diff --git a/jevdual/scripts/capability_fixture.py b/jevdual/scripts/capability_fixture.py index 89ef749..a9850d8 100644 --- a/jevdual/scripts/capability_fixture.py +++ b/jevdual/scripts/capability_fixture.py @@ -161,26 +161,41 @@ def close_owned_document(pid: int, document: Path) -> dict: raise FixtureFailure("document_cleanup", "close_button_changed", 6) press(close, deadline) discarded = False + last_invalid = None while time.monotonic() < deadline: - current = owned_window(app, document, deadline) - if current is None: - # Do not mistake a renamed/reused window for observed disappearance. - if window in (ax_attribute(app, "AXWindows", deadline=deadline) or ()): + try: + current = owned_window(app, document, deadline) + if current is None: + # Do not mistake a renamed/reused window for observed disappearance. + if window in (ax_attribute(app, "AXWindows", deadline=deadline) or ()): + raise FixtureFailure("document_cleanup", "document_identity_changed", 6) + return {"status": "confirmed", "reason": "window_disappeared", "pid": pid} + if current != window: raise FixtureFailure("document_cleanup", "document_identity_changed", 6) - return {"status": "confirmed", "reason": "window_disappeared", "pid": pid} - if current != window: - raise FixtureFailure("document_cleanup", "document_identity_changed", 6) - discard = discard_button(window, deadline) - if discard is not None and not discarded: - if ( - owned_window(app, document, deadline) != window - or discard_button(window, deadline) != discard - ): - raise FixtureFailure("document_cleanup", "sheet_identity_changed", 6) - press(discard[1], deadline) - discarded = True + discard = discard_button(window, deadline) + if discard is not None and not discarded: + if ( + owned_window(app, document, deadline) != window + or discard_button(window, deadline) != discard + ): + raise FixtureFailure("document_cleanup", "sheet_identity_changed", 6) + press(discard[1], deadline) + discarded = True + last_invalid = None + except FixtureFailure as exc: + # A successful close can invalidate a previously observed child or + # window between reads. Only that observation error is retryable, + # only after the close press; it is never evidence of disappearance. + # Restart from fresh AXWindows and exact identity, never repeat AXPress. + if not (exc.reason.startswith("ax_attribute_refused:") and exc.reason.endswith(":-25202")): + raise + last_invalid = exc.reason time.sleep(0.1) - return {"status": "unknown", "reason": "window_still_present", "pid": pid} + return { + "status": "unknown", + "reason": "invalid_element_unresolved" if last_invalid else "window_still_present", + "pid": pid, + } except Exception as exc: # noqa: BLE001 - receipt boundary; independent cleanup must continue return {"status": "error", "reason": getattr(exc, "reason", type(exc).__name__), "pid": pid} diff --git a/jevdual/tests/test_capability_fixture.py b/jevdual/tests/test_capability_fixture.py index 3dc9185..cdbbfe7 100644 --- a/jevdual/tests/test_capability_fixture.py +++ b/jevdual/tests/test_capability_fixture.py @@ -880,3 +880,129 @@ def path(*args): with pytest.raises(expected): await module.scope_for(42, "http://127.0.0.1:1", document) assert calls == [1.0, 0] + + +@pytest.mark.parametrize("stale_target", ["child", "window"]) +def test_close_stale_observation_requires_fresh_readable_absence(monkeypatch, tmp_path, stale_target): + import ApplicationServices + + module, document, app, window, other, close, _, _, pressed = ax_world(monkeypatch, tmp_path) + child = {"AXRole": "AXGroup", "AXChildren": []} + window["AXChildren"] = [child] + original = ApplicationServices.AXUIElementCopyAttributeValue + observations = [] + + def press_close(element, _): + pressed.append(element) + return 0 # Closing is asynchronous; AX reference survives the press briefly. + + def attribute(element, key, arg): + if key == "AXWindows": + observations.append(list(app["AXWindows"])) + stale = ( + (element is child and key == "AXRole") + if stale_target == "child" + else (element is window and key == "AXDocument") + ) + if pressed and stale: + app["AXWindows"].remove(window) + return -25202, None + return original(element, key, arg) + + monkeypatch.setattr(ApplicationServices, "AXUIElementPerformAction", press_close) + monkeypatch.setattr(ApplicationServices, "AXUIElementCopyAttributeValue", attribute) + monkeypatch.setattr(module.time, "sleep", lambda _: None) + result = module.close_owned_document(43, document) + assert result["status"] == "confirmed", result + assert result["reason"] == "window_disappeared" + assert observations[-1] == [other] # A new successful AXWindows read certifies absence. + assert pressed == [close] # Never press the stale reference again. + + +@pytest.mark.parametrize("fresh", ["persistent_invalid", "unreadable", "renamed", "reused"]) +def test_close_stale_retry_refuses_unconfirmed_or_changed_identity(monkeypatch, tmp_path, fresh): + import ApplicationServices + + module, document, app, window, other, close, _, _, pressed = ax_world(monkeypatch, tmp_path) + child = {"AXRole": "AXGroup", "AXChildren": []} + window["AXChildren"] = [child] + original = ApplicationServices.AXUIElementCopyAttributeValue + stale, invalid_reads, elapsed = [False], [0], [0] + + def clock(): + value = elapsed[0] + elapsed[0] += 0.1 + return value + + monkeypatch.setattr(module.time, "monotonic", clock) + monkeypatch.setattr(module.time, "sleep", lambda _: None) + monkeypatch.setattr( + ApplicationServices, "AXUIElementPerformAction", lambda el, _: pressed.append(el) or 0 + ) + + def attribute(element, key, arg): + if pressed and element is child and key == "AXRole": + stale[0] = True + invalid_reads[0] += 1 + if fresh == "renamed": + window["AXDocument"] = other["AXDocument"] + elif fresh == "reused": + replacement = dict(window) + replacement["AXCloseButton"] = {"AXRole": "AXButton", "different": True} + app["AXWindows"] = [replacement, other] + return -25202, None + if stale[0] and fresh == "unreadable" and key == "AXWindows": + return -25211, None + return original(element, key, arg) + + monkeypatch.setattr(ApplicationServices, "AXUIElementCopyAttributeValue", attribute) + result = module.close_owned_document(43, document) + assert result["status"] != "confirmed" + assert pressed == [close] + assert other in app["AXWindows"] + if fresh in ("renamed", "reused"): + assert result["reason"] == "document_identity_changed" + elif fresh == "unreadable": + assert result["reason"] == "ax_attribute_refused:AXWindows:-25211" + + if fresh == "persistent_invalid": + assert invalid_reads[0] > 1 + assert elapsed[0] < module.CLEANUP_SECONDS + 0.3 + + +def test_invalid_element_before_close_never_retries_or_presses(monkeypatch, tmp_path): + import ApplicationServices + + module, document, _, window, _, _, _, _, pressed = ax_world(monkeypatch, tmp_path) + original = ApplicationServices.AXUIElementCopyAttributeValue + invalid_reads = [] + + def attribute(element, key, arg): + if element is window and key == "AXDocument": + invalid_reads.append(True) + return -25202, None + return original(element, key, arg) + + monkeypatch.setattr(ApplicationServices, "AXUIElementCopyAttributeValue", attribute) + result = module.close_owned_document(43, document) + assert result["status"] == "error" + assert invalid_reads == [True] and not pressed + + +def test_invalid_axpress_is_not_observation_retry(monkeypatch, tmp_path): + import ApplicationServices + + module, document, _, _, _, close, _, discard, pressed = ax_world(monkeypatch, tmp_path, edited=True) + original = ApplicationServices.AXUIElementPerformAction + + def action(element, name): + if element is discard: + pressed.append(element) + return -25202 + return original(element, name) + + monkeypatch.setattr(ApplicationServices, "AXUIElementPerformAction", action) + result = module.close_owned_document(43, document) + assert result["status"] == "error" + assert result["reason"] == "ax_press_refused:-25202" + assert pressed == [close, discard] From 2d1e8b318e0731f4bd71e74eeffa99612035fffe Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 15:08:57 -0400 Subject: [PATCH 153/216] Preserve failed U3 cleanup and preregister full repair journey --- .../2026-10-12-onboarding-fixture-v4.md | 8 + .../cleanup.json | 25 + .../doctor-after.json | 1 + .../doctor-before.json | 1 + .../install-receipt.json | 1521 +++++++++++++++++ .../native-receipt.json | 372 ++++ .../report.md | 5 + .../startup.json | 5 + .../summary.json | 36 + 9 files changed, 1974 insertions(+) create mode 100644 jevdual/results/u3-packet-v4-permission-20261012-v1/cleanup.json create mode 100644 jevdual/results/u3-packet-v4-permission-20261012-v1/doctor-after.json create mode 100644 jevdual/results/u3-packet-v4-permission-20261012-v1/doctor-before.json create mode 100644 jevdual/results/u3-packet-v4-permission-20261012-v1/install-receipt.json create mode 100644 jevdual/results/u3-packet-v4-permission-20261012-v1/native-receipt.json create mode 100644 jevdual/results/u3-packet-v4-permission-20261012-v1/report.md create mode 100644 jevdual/results/u3-packet-v4-permission-20261012-v1/startup.json create mode 100644 jevdual/results/u3-packet-v4-permission-20261012-v1/summary.json diff --git a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md index 2db18be..0720709 100644 --- a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md +++ b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md @@ -71,3 +71,11 @@ Observed: UFU6 records two resolutions on one field, but the notebook reader rec Changes: only fixture/helper tests change. The failed guest archive is being exported before a separately frozen repair packet; no original receipt is changed and no native effect is replayed. Next: freeze the repair, obtain Claude review of source/artifact and original guest evidence, then perform the preregistered post-grant repair trial. UF4 remains open. Refs: output/u2-fixture-v4-dev/uf4-before.txt; output/u2-fixture-v4-dev/uf4-after.txt; UFU6; tests/test_capability_fixture.py + +## UF5 · prediction · 2026-10-12 15:08 +Revises: UF4 +Hypothesis: the reviewed stale-observation repair permits all U3 gates in one separately frozen complete permission-state journey, avoiding a composite of different artifacts. +Test: use packet205577ee/source445a348 in a new guest root, verify pristine bytes and cold-install anew. With existing explicit guest permission authorization, reset only Terminal Accessibility through supported tccutil, hash denied doctor/resource-free refusal before the action-time approved switch, quit/relaunch Terminal and execute one installed append/replay/report trial and automatic cleanup. Retain failed U3v1. This replaces UF4's planned post-grant trial with a stricter full journey on the repaired artifact. +Predicts: the same frozen artifact supplies every denial/grant/restart/native/cleanup gate, stale AX reads never replay a close, and cleanup confirms fresh window absence plus browser/listener/worker absence without manual close or extra grants. +Against: any required gate fails, a read error substitutes for absence, action repeats, an unrelated resource is affected, or the artifact changes during measurement. +Refs: U3-packet-v4-permission-journey.md; UF4; Claude1791832031158825000; results/u3-packet-v4-permission-20261012-v1 diff --git a/jevdual/results/u3-packet-v4-permission-20261012-v1/cleanup.json b/jevdual/results/u3-packet-v4-permission-20261012-v1/cleanup.json new file mode 100644 index 0000000..e46a799 --- /dev/null +++ b/jevdual/results/u3-packet-v4-permission-20261012-v1/cleanup.json @@ -0,0 +1,25 @@ +{ + "document": { + "status": "error", + "reason": "ax_attribute_refused:AXRole:-25202", + "pid": 2817, + "file_before": { + "status": "observed", + "size_bytes": 15, + "sha256": "ac11060594d5bcde616f5e88156ea7c0f55e2cca74c2de52c4da375fbde33339" + }, + "file_after": { + "status": "observed", + "size_bytes": 24, + "sha256": "783172d2e6ac11f2c5450015856703ebe655b8c2aa86ca81b802ab1d8d210aee" + } + }, + "browser": { + "status": "confirmed", + "pid": 52622, + "returncode": 0 + }, + "listener": { + "status": "confirmed" + } +} diff --git a/jevdual/results/u3-packet-v4-permission-20261012-v1/doctor-after.json b/jevdual/results/u3-packet-v4-permission-20261012-v1/doctor-after.json new file mode 100644 index 0000000..2a4cedd --- /dev/null +++ b/jevdual/results/u3-packet-v4-permission-20261012-v1/doctor-after.json @@ -0,0 +1 @@ +{"platform": "darwin", "supported": true, "runtime": {"python_version": "3.14.7", "python_requirement": ">=3.11,<4.0", "python_compatible": true, "interpreter": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", "architecture": "arm64", "distribution": {"version": "0.0.1", "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "loaded_modules": {"jevdual": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", "jevdual.capability.setup": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/setup.py", "ApplicationServices": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py", "Quartz": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py"}}, "dependencies": {"browser-use": {"version": "0.13.10", "requirement": "==0.13.10", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "typesafe-sdk": {"version": "0.7.4", "requirement": "<1,>=0.7", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "orjson": {"version": "3.13.0", "requirement": ">=3.10", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "psutil": {"version": "7.2.2", "requirement": "==7.2.2", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "mcp": {"version": "2.1.1", "requirement": "==2.1.1", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "packaging": {"version": "26.3", "requirement": "<27,>=25", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "cua-driver": {"version": "0.28.2", "requirement": "==0.28.2", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-applicationservices": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-quartz": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-cocoa": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}}, "permissions": {"accessibility": "granted", "screen_recording": "not_granted"}, "scope": "not_checked", "journal": "not_checked", "warnings": ["Screen Recording is not qualified. Routes that capture pixels may require it."], "dependency_metadata": "installed distribution", "limitation": "macOS only: one loopback HTTP browser fixture and one identified TextEdit document. Window identity is checked when binding.", "provider_account_required": false, "rust_toolchain_required": false, "blockers": [], "prerequisite_status": "met", "qualification": "Prerequisites only. Window identity, current state, effects and job completion require separate checks."} diff --git a/jevdual/results/u3-packet-v4-permission-20261012-v1/doctor-before.json b/jevdual/results/u3-packet-v4-permission-20261012-v1/doctor-before.json new file mode 100644 index 0000000..d6dc989 --- /dev/null +++ b/jevdual/results/u3-packet-v4-permission-20261012-v1/doctor-before.json @@ -0,0 +1 @@ +{"platform": "darwin", "supported": true, "runtime": {"python_version": "3.14.7", "python_requirement": ">=3.11,<4.0", "python_compatible": true, "interpreter": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", "architecture": "arm64", "distribution": {"version": "0.0.1", "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "loaded_modules": {"jevdual": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", "jevdual.capability.setup": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/setup.py", "ApplicationServices": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py", "Quartz": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py"}}, "dependencies": {"browser-use": {"version": "0.13.10", "requirement": "==0.13.10", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "typesafe-sdk": {"version": "0.7.4", "requirement": "<1,>=0.7", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "orjson": {"version": "3.13.0", "requirement": ">=3.10", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "psutil": {"version": "7.2.2", "requirement": "==7.2.2", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "mcp": {"version": "2.1.1", "requirement": "==2.1.1", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "packaging": {"version": "26.3", "requirement": "<27,>=25", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "cua-driver": {"version": "0.28.2", "requirement": "==0.28.2", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-applicationservices": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-quartz": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}, "pyobjc-framework-cocoa": {"version": "12.2.2", "requirement": ">=12", "compatible": true, "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages"}}, "permissions": {"accessibility": "not_granted", "screen_recording": "not_granted"}, "scope": "not_checked", "journal": "not_checked", "warnings": ["Screen Recording is not qualified. Routes that capture pixels may require it."], "dependency_metadata": "installed distribution", "limitation": "macOS only: one loopback HTTP browser fixture and one identified TextEdit document. Window identity is checked when binding.", "provider_account_required": false, "rust_toolchain_required": false, "blockers": ["accessibility_not_granted"], "prerequisite_status": "blocked", "qualification": "Prerequisites only. Window identity, current state, effects and job completion require separate checks."} diff --git a/jevdual/results/u3-packet-v4-permission-20261012-v1/install-receipt.json b/jevdual/results/u3-packet-v4-permission-20261012-v1/install-receipt.json new file mode 100644 index 0000000..37ed9b0 --- /dev/null +++ b/jevdual/results/u3-packet-v4-permission-20261012-v1/install-receipt.json @@ -0,0 +1,1521 @@ +{ + "source_commit": "21599c641e4c54cad137b3c49e11142c5c14e596", + "host": { + "platform": "Darwin", + "machine": "arm64" + }, + "interpreter_requested": "/Library/Frameworks/Python.framework/Versions/3.14/bin/python3.14", + "wheel": "/Users/tom/footwork-u4/footwork/artifacts/jevdual-0.0.1-py3-none-any.whl", + "wheel_sha256": "9bb0440d7bd981df7dc70bbd22f97861a7ed32a88bf6de7a18c2f46982fef3a7", + "cache_initially_empty": true, + "system_site_packages": false, + "borrowed_dependencies": false, + "registry": "https://pypi.org/simple", + "binary_only": true, + "commands": [ + { + "stage": "venv", + "argv": [ + "/Users/tom/footwork-u2/tools/uv-aarch64-apple-darwin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/tom/footwork-u4/footwork/output/install-v1/empty-cache", + "--no-python-downloads", + "venv", + "--python", + "/Library/Frameworks/Python.framework/Versions/3.14/bin/python3.14", + "/Users/tom/footwork-u4/footwork/output/install-v1/venv" + ], + "returncode": 0 + }, + { + "stage": "install", + "argv": [ + "/Users/tom/footwork-u2/tools/uv-aarch64-apple-darwin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/tom/footwork-u4/footwork/output/install-v1/empty-cache", + "--no-python-downloads", + "pip", + "install", + "--python", + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "--default-index", + "https://pypi.org/simple", + "--only-binary", + ":all:", + "/Users/tom/footwork-u4/footwork/artifacts/jevdual-0.0.1-py3-none-any.whl" + ], + "returncode": 0 + }, + { + "stage": "consistency", + "argv": [ + "/Users/tom/footwork-u2/tools/uv-aarch64-apple-darwin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/tom/footwork-u4/footwork/output/install-v1/empty-cache", + "--no-python-downloads", + "pip", + "check", + "--python", + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python" + ], + "returncode": 0 + }, + { + "stage": "inventory", + "argv": [ + "/Users/tom/footwork-u2/tools/uv-aarch64-apple-darwin/uv", + "--no-config", + "--no-progress", + "--cache-dir", + "/Users/tom/footwork-u4/footwork/output/install-v1/empty-cache", + "--no-python-downloads", + "pip", + "list", + "--python", + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "--format", + "json" + ], + "returncode": 0 + }, + { + "stage": "origins", + "argv": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "-I", + "-c", + "\nimport sys,json,importlib.metadata,importlib\nfrom pathlib import Path\nimport jevdual,jevdual.capability.execution_worker as worker\nfrom jevdual._native import BACKEND\nnames=(\"cua_driver\",\"psutil\",\"mcp\",\"ApplicationServices\",\"Quartz\",\"Foundation\",\"packaging\")\nmodules={n:str(importlib.import_module(n).__file__) for n in names}\nprint(json.dumps({\"version\":sys.version,\"prefix\":sys.prefix,\"base_prefix\":sys.base_prefix,\"python\":sys.executable,\"package\":jevdual.__file__,\"worker\":worker.__file__,\"backend\":BACKEND,\"module_origins\":modules,\"sys_path\":sys.path}))\n" + ], + "returncode": 0 + }, + { + "stage": "doctor", + "argv": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/footwork-capability", + "doctor" + ], + "returncode": 0 + }, + { + "stage": "wheel-tags", + "argv": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "-I", + "-c", + "import json,importlib.metadata;print(json.dumps([{\"name\":d.metadata[\"Name\"],\"version\":d.version,\"tags\":[l[5:] for l in (d.read_text(\"WHEEL\") or \"\").splitlines() if l.startswith(\"Tag: \")]} for d in importlib.metadata.distributions()]))" + ], + "returncode": 0 + } + ], + "passed": true, + "limits": "Fresh dependencies on existing host OS/interpreter, not a fresh machine or TCC permission database.", + "origins": { + "version": "3.14.7 (v3.14.7:823f0323ee6, Aug 5 2026, 07:07:01) [Clang 21.0.0 (clang-2100.1.1.101)]", + "prefix": "/Users/tom/footwork-u4/footwork/output/install-v1/venv", + "base_prefix": "/Library/Frameworks/Python.framework/Versions/3.14", + "python": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "package": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", + "worker": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/execution_worker.py", + "backend": "pure-python", + "module_origins": { + "cua_driver": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py", + "psutil": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/psutil/__init__.py", + "mcp": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py", + "ApplicationServices": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py", + "Quartz": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py", + "Foundation": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/Foundation/__init__.py", + "packaging": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/packaging/__init__.py" + }, + "sys_path": [ + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python314.zip", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/lib-dynload", + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + ] + }, + "doctor": { + "platform": "darwin", + "supported": true, + "runtime": { + "python_version": "3.14.7", + "python_requirement": ">=3.11,<4.0", + "python_compatible": true, + "interpreter": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "architecture": "arm64", + "distribution": { + "version": "0.0.1", + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "loaded_modules": { + "jevdual": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", + "jevdual.capability.setup": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/setup.py", + "ApplicationServices": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py", + "Quartz": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py" + } + }, + "dependencies": { + "browser-use": { + "version": "0.13.10", + "requirement": "==0.13.10", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "typesafe-sdk": { + "version": "0.7.4", + "requirement": "<1,>=0.7", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "orjson": { + "version": "3.13.0", + "requirement": ">=3.10", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "psutil": { + "version": "7.2.2", + "requirement": "==7.2.2", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "mcp": { + "version": "2.1.1", + "requirement": "==2.1.1", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "packaging": { + "version": "26.3", + "requirement": "<27,>=25", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "cua-driver": { + "version": "0.28.2", + "requirement": "==0.28.2", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "pyobjc-framework-applicationservices": { + "version": "12.2.2", + "requirement": ">=12", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "pyobjc-framework-quartz": { + "version": "12.2.2", + "requirement": ">=12", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + }, + "pyobjc-framework-cocoa": { + "version": "12.2.2", + "requirement": ">=12", + "compatible": true, + "location": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + } + }, + "permissions": { + "accessibility": "granted", + "screen_recording": "not_granted" + }, + "scope": "not_checked", + "journal": "not_checked", + "warnings": [ + "Screen Recording is not qualified. Routes that capture pixels may require it." + ], + "dependency_metadata": "installed distribution", + "limitation": "macOS only: one loopback HTTP browser fixture and one identified TextEdit document. Window identity is checked when binding.", + "provider_account_required": false, + "rust_toolchain_required": false, + "blockers": [], + "prerequisite_status": "met", + "qualification": "Prerequisites only. Window identity, current state, effects and job completion require separate checks." + }, + "inventory": [ + { + "name": "aiofiles", + "version": "25.1.0" + }, + { + "name": "aiohappyeyeballs", + "version": "2.7.1" + }, + { + "name": "aiohttp", + "version": "3.14.3" + }, + { + "name": "aiosignal", + "version": "1.4.0" + }, + { + "name": "annotated-types", + "version": "0.8.0" + }, + { + "name": "anthropic", + "version": "0.76.0" + }, + { + "name": "anyio", + "version": "4.12.1" + }, + { + "name": "attrs", + "version": "26.1.0" + }, + { + "name": "backoff", + "version": "2.2.1" + }, + { + "name": "beautifulsoup4", + "version": "4.15.0" + }, + { + "name": "browser-harness", + "version": "0.1.13" + }, + { + "name": "browser-use", + "version": "0.13.10" + }, + { + "name": "browser-use-sdk", + "version": "3.4.2" + }, + { + "name": "bubus", + "version": "1.5.6" + }, + { + "name": "cdp-use", + "version": "1.4.5" + }, + { + "name": "certifi", + "version": "2026.7.22" + }, + { + "name": "cffi", + "version": "2.1.1" + }, + { + "name": "charset-normalizer", + "version": "3.5.2" + }, + { + "name": "click", + "version": "8.3.3" + }, + { + "name": "cloudpickle", + "version": "3.1.2" + }, + { + "name": "cryptography", + "version": "50.0.2" + }, + { + "name": "cua-driver", + "version": "0.28.2" + }, + { + "name": "cython", + "version": "3.3.0" + }, + { + "name": "distro", + "version": "1.9.0" + }, + { + "name": "docstring-parser", + "version": "0.18.0" + }, + { + "name": "fetch-use", + "version": "0.4.0" + }, + { + "name": "frozenlist", + "version": "1.8.0" + }, + { + "name": "google-api-core", + "version": "2.29.0" + }, + { + "name": "google-api-python-client", + "version": "2.188.0" + }, + { + "name": "google-auth", + "version": "2.48.0" + }, + { + "name": "google-auth-httplib2", + "version": "0.4.4" + }, + { + "name": "google-auth-oauthlib", + "version": "1.2.4" + }, + { + "name": "google-genai", + "version": "1.65.0" + }, + { + "name": "googleapis-common-protos", + "version": "1.75.5" + }, + { + "name": "groq", + "version": "1.0.0" + }, + { + "name": "h11", + "version": "0.16.0" + }, + { + "name": "httpcore", + "version": "1.0.9" + }, + { + "name": "httpcore2", + "version": "2.13.1" + }, + { + "name": "httplib2", + "version": "0.32.0" + }, + { + "name": "httpx", + "version": "0.28.1" + }, + { + "name": "httpx2", + "version": "2.13.1" + }, + { + "name": "idna", + "version": "3.20" + }, + { + "name": "inquirerpy", + "version": "0.3.4" + }, + { + "name": "jevdual", + "version": "0.0.1" + }, + { + "name": "jiter", + "version": "0.17.0" + }, + { + "name": "jsonschema", + "version": "4.26.0" + }, + { + "name": "jsonschema-specifications", + "version": "2025.9.1" + }, + { + "name": "lxml", + "version": "6.1.3" + }, + { + "name": "markdown-it-py", + "version": "4.2.0" + }, + { + "name": "markdownify", + "version": "1.2.2" + }, + { + "name": "mcp", + "version": "2.1.1" + }, + { + "name": "mcp-types", + "version": "2.1.1" + }, + { + "name": "mdurl", + "version": "0.1.2" + }, + { + "name": "multidict", + "version": "6.9.1" + }, + { + "name": "oauthlib", + "version": "4.0.0" + }, + { + "name": "ollama", + "version": "0.6.1" + }, + { + "name": "openai", + "version": "2.26.0" + }, + { + "name": "opentelemetry-api", + "version": "1.45.1" + }, + { + "name": "orjson", + "version": "3.13.0" + }, + { + "name": "packaging", + "version": "26.3" + }, + { + "name": "pfzy", + "version": "0.3.4" + }, + { + "name": "pillow", + "version": "12.3.0" + }, + { + "name": "portalocker", + "version": "4.4.0" + }, + { + "name": "posthog", + "version": "7.7.0" + }, + { + "name": "prompt-toolkit", + "version": "3.0.53" + }, + { + "name": "propcache", + "version": "0.5.4" + }, + { + "name": "proto-plus", + "version": "1.29.0" + }, + { + "name": "protobuf", + "version": "6.33.6" + }, + { + "name": "psutil", + "version": "7.2.2" + }, + { + "name": "pyasn1", + "version": "0.6.4" + }, + { + "name": "pyasn1-modules", + "version": "0.4.2" + }, + { + "name": "pycparser", + "version": "3.11" + }, + { + "name": "pydantic", + "version": "2.13.5" + }, + { + "name": "pydantic-core", + "version": "2.46.5" + }, + { + "name": "pydantic-settings", + "version": "2.15.0" + }, + { + "name": "pygments", + "version": "2.21.0" + }, + { + "name": "pyjwt", + "version": "2.15.1" + }, + { + "name": "pyobjc-core", + "version": "12.2.2" + }, + { + "name": "pyobjc-framework-applicationservices", + "version": "12.2.2" + }, + { + "name": "pyobjc-framework-cocoa", + "version": "12.2.2" + }, + { + "name": "pyobjc-framework-coretext", + "version": "12.2.2" + }, + { + "name": "pyobjc-framework-quartz", + "version": "12.2.2" + }, + { + "name": "pyotp", + "version": "2.9.0" + }, + { + "name": "pyparsing", + "version": "3.3.3" + }, + { + "name": "pypdf", + "version": "6.16.2" + }, + { + "name": "python-dateutil", + "version": "2.9.0.post0" + }, + { + "name": "python-docx", + "version": "1.2.0" + }, + { + "name": "python-dotenv", + "version": "1.2.2" + }, + { + "name": "python-multipart", + "version": "0.0.32" + }, + { + "name": "referencing", + "version": "0.37.0" + }, + { + "name": "reportlab", + "version": "4.4.9" + }, + { + "name": "requests", + "version": "2.33.0" + }, + { + "name": "requests-oauthlib", + "version": "2.0.0" + }, + { + "name": "rich", + "version": "14.3.3" + }, + { + "name": "rpds-py", + "version": "2026.9.1" + }, + { + "name": "rsa", + "version": "4.9.1" + }, + { + "name": "screeninfo", + "version": "0.8.1" + }, + { + "name": "six", + "version": "1.17.0" + }, + { + "name": "sniffio", + "version": "1.3.1" + }, + { + "name": "soupsieve", + "version": "3.0.3" + }, + { + "name": "sse-starlette", + "version": "3.5.0" + }, + { + "name": "starlette", + "version": "1.7.0" + }, + { + "name": "tenacity", + "version": "9.1.4" + }, + { + "name": "tqdm", + "version": "4.70.1" + }, + { + "name": "truststore", + "version": "0.10.4" + }, + { + "name": "typesafe-sdk", + "version": "0.7.4" + }, + { + "name": "typing-extensions", + "version": "4.15.0" + }, + { + "name": "typing-inspection", + "version": "0.4.4" + }, + { + "name": "uritemplate", + "version": "4.2.0" + }, + { + "name": "urllib3", + "version": "2.8.0" + }, + { + "name": "uuid7", + "version": "0.1.0" + }, + { + "name": "uvicorn", + "version": "0.54.0" + }, + { + "name": "wcwidth", + "version": "0.9.2" + }, + { + "name": "websockets", + "version": "15.0.1" + }, + { + "name": "yarl", + "version": "1.25.1" + } + ], + "wheel_tags": [ + { + "name": "anyio", + "version": "4.12.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "uvicorn", + "version": "0.54.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "groq", + "version": "1.0.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "oauthlib", + "version": "4.0.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "cloudpickle", + "version": "3.1.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyobjc-framework-CoreText", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "portalocker", + "version": "4.4.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "lxml", + "version": "6.1.3", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "packaging", + "version": "26.3", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "Pygments", + "version": "2.21.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "inquirerpy", + "version": "0.3.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "browser-harness", + "version": "0.1.13", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "prompt_toolkit", + "version": "3.0.53", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "jsonschema-specifications", + "version": "2025.9.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "soupsieve", + "version": "3.0.3", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "jiter", + "version": "0.17.0", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "typesafe-sdk", + "version": "0.7.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "jevdual", + "version": "0.0.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-api-python-client", + "version": "2.188.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "yarl", + "version": "1.25.1", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "posthog", + "version": "7.7.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "jsonschema", + "version": "4.26.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "orjson", + "version": "3.13.0", + "tags": [ + "cp314-cp314-macosx_15_0_arm64" + ] + }, + { + "name": "google-auth-oauthlib", + "version": "1.2.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "requests", + "version": "2.33.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "PyJWT", + "version": "2.15.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "opentelemetry-api", + "version": "1.45.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pydantic_core", + "version": "2.46.5", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "browser-use-sdk", + "version": "3.4.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyotp", + "version": "2.9.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "docstring_parser", + "version": "0.18.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "propcache", + "version": "0.5.4", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "mcp", + "version": "2.1.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "rich", + "version": "14.3.3", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "uritemplate", + "version": "4.2.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "reportlab", + "version": "4.4.9", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "tenacity", + "version": "9.1.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "aiofiles", + "version": "25.1.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyobjc-framework-Quartz", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "httpcore", + "version": "1.0.9", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "aiohappyeyeballs", + "version": "2.7.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "cryptography", + "version": "50.0.2", + "tags": [ + "cp311-abi3-macosx_11_0_arm64" + ] + }, + { + "name": "pyobjc-framework-Cocoa", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "wcwidth", + "version": "0.9.2", + "tags": [ + "cp310-abi3-macosx_11_0_arm64" + ] + }, + { + "name": "googleapis-common-protos", + "version": "1.75.5", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-genai", + "version": "1.65.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "tqdm", + "version": "4.70.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "urllib3", + "version": "2.8.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "python-dotenv", + "version": "1.2.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "h11", + "version": "0.16.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pydantic", + "version": "2.13.5", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "protobuf", + "version": "6.33.6", + "tags": [ + "cp39-abi3-macosx_10_9_universal2" + ] + }, + { + "name": "pydantic-settings", + "version": "2.15.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "sniffio", + "version": "1.3.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "rsa", + "version": "4.9.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyasn1", + "version": "0.6.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "screeninfo", + "version": "0.8.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "mdurl", + "version": "0.1.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "python-multipart", + "version": "0.0.32", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyobjc-framework-ApplicationServices", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "fetch-use", + "version": "0.4.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "python-dateutil", + "version": "2.9.0.post0", + "tags": [ + "py2-none-any", + "py3-none-any" + ] + }, + { + "name": "openai", + "version": "2.26.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyobjc-core", + "version": "12.2.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "click", + "version": "8.3.3", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "markdownify", + "version": "1.2.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "frozenlist", + "version": "1.8.0", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "cffi", + "version": "2.1.1", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "uuid7", + "version": "0.1.0", + "tags": [ + "py2-none-any", + "py3-none-any" + ] + }, + { + "name": "typing_extensions", + "version": "4.15.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "aiosignal", + "version": "1.4.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "certifi", + "version": "2026.7.22", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "browser-use", + "version": "0.13.10", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "annotated-types", + "version": "0.8.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "referencing", + "version": "0.37.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-auth-httplib2", + "version": "0.4.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pycparser", + "version": "3.11", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "markdown-it-py", + "version": "4.2.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-auth", + "version": "2.48.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "bubus", + "version": "1.5.6", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "typing-inspection", + "version": "0.4.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "starlette", + "version": "1.7.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "distro", + "version": "1.9.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pfzy", + "version": "0.3.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "rpds-py", + "version": "2026.9.1", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "httplib2", + "version": "0.32.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "python-docx", + "version": "1.2.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "attrs", + "version": "26.1.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "ollama", + "version": "0.6.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "websockets", + "version": "15.0.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pypdf", + "version": "6.16.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "httpx", + "version": "0.28.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "httpx2", + "version": "2.13.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "sse-starlette", + "version": "3.5.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "backoff", + "version": "2.2.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyasn1_modules", + "version": "0.4.2", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "google-api-core", + "version": "2.29.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "beautifulsoup4", + "version": "4.15.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "psutil", + "version": "7.2.2", + "tags": [ + "cp36-abi3-macosx_11_0_arm64" + ] + }, + { + "name": "aiohttp", + "version": "3.14.3", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "cdp-use", + "version": "1.4.5", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "truststore", + "version": "0.10.4", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "charset-normalizer", + "version": "3.5.2", + "tags": [ + "cp314-cp314-macosx_10_15_universal2" + ] + }, + { + "name": "pillow", + "version": "12.3.0", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "Cython", + "version": "3.3.0", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "proto-plus", + "version": "1.29.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "httpcore2", + "version": "2.13.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "pyparsing", + "version": "3.3.3", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "cua-driver", + "version": "0.28.2", + "tags": [ + "py3-none-macosx_13_0_universal2" + ] + }, + { + "name": "six", + "version": "1.17.0", + "tags": [ + "py2-none-any", + "py3-none-any" + ] + }, + { + "name": "requests-oauthlib", + "version": "2.0.0", + "tags": [ + "py2-none-any", + "py3-none-any" + ] + }, + { + "name": "multidict", + "version": "6.9.1", + "tags": [ + "cp314-cp314-macosx_11_0_arm64" + ] + }, + { + "name": "anthropic", + "version": "0.76.0", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "mcp-types", + "version": "2.1.1", + "tags": [ + "py3-none-any" + ] + }, + { + "name": "idna", + "version": "3.20", + "tags": [ + "py3-none-any" + ] + } + ], + "cache_bytes_after_install": 391982537, + "private_state": { + "private-home": "/Users/tom/footwork-u4/footwork/output/install-v1/private-home", + "private-config": "/Users/tom/footwork-u4/footwork/output/install-v1/private-config", + "private-cache": "/Users/tom/footwork-u4/footwork/output/install-v1/private-cache", + "private-temp": "/Users/tom/footwork-u4/footwork/output/install-v1/private-temp" + } +} diff --git a/jevdual/results/u3-packet-v4-permission-20261012-v1/native-receipt.json b/jevdual/results/u3-packet-v4-permission-20261012-v1/native-receipt.json new file mode 100644 index 0000000..084360c --- /dev/null +++ b/jevdual/results/u3-packet-v4-permission-20261012-v1/native-receipt.json @@ -0,0 +1,372 @@ +{ + "passed": true, + "source_commit": "21599c641e4c54cad137b3c49e11142c5c14e596", + "origins": { + "artifact_version": "0.0.1", + "python": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u4/footwork/output/install-v1/venv", + "kernel_executable": "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python", + "kernel_argv0": "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python", + "package": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py", + "worker": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/capability/execution_worker.py", + "backend": "pure-python", + "sys_path": [ + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python314.zip", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14", + "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/lib-dynload", + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages" + ] + }, + "actual_runtime_contexts": [ + { + "role": "worker", + "operation": "op_a3c8d3e60e2d", + "pid": 53493, + "python": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u4/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py" + ], + "mcp": null, + "ApplicationServices": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py" + ], + "Quartz": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py" + ], + "Foundation": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/Foundation/__init__.py" + ] + }, + "cua_library": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/libcua_driver_sdk.dylib", + "home": "/Users/tom/footwork-u4/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791831095436142000 + }, + { + "role": "server", + "operation": null, + "pid": 53368, + "python": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u4/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py" + ], + "mcp": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py" + ], + "ApplicationServices": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/ApplicationServices/__init__.py" + ], + "Quartz": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/Quartz/__init__.py" + ], + "Foundation": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/Foundation/__init__.py" + ] + }, + "cua_library": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/libcua_driver_sdk.dylib", + "home": "/Users/tom/footwork-u4/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791831094548872000 + }, + { + "role": "server", + "operation": null, + "pid": 53368, + "python": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u4/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": null, + "mcp": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py" + ], + "ApplicationServices": null, + "Quartz": null, + "Foundation": null + }, + "cua_library": null, + "home": "/Users/tom/footwork-u4/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791831093299192000 + }, + { + "role": "server", + "operation": null, + "pid": 53523, + "python": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u4/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": null, + "mcp": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py" + ], + "ApplicationServices": null, + "Quartz": null, + "Foundation": null + }, + "cua_library": null, + "home": "/Users/tom/footwork-u4/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791831096739411000 + }, + { + "role": "server", + "operation": null, + "pid": 53368, + "python": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/bin/python", + "prefix": "/Users/tom/footwork-u4/footwork/output/install-v1/venv", + "modules": { + "jevdual": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/jevdual/__init__.py" + ], + "jevdual.capability.execution_worker": null, + "cua_driver": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/__init__.py" + ], + "mcp": [ + "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/mcp/__init__.py" + ], + "ApplicationServices": null, + "Quartz": null, + "Foundation": null + }, + "cua_library": "/Users/tom/footwork-u4/footwork/output/install-v1/venv/lib/python3.14/site-packages/cua_driver/libcua_driver_sdk.dylib", + "home": "/Users/tom/footwork-u4/footwork/output/install-v1/private-home", + "user_site_disabled": true, + "browser_telemetry_disabled": true, + "browser_cloud_sync_disabled": true, + "as_of_ns": 1791831093759737000 + } + ], + "emitted_configuration_checked": true, + "initialized": { + "capabilities": { + "experimental": {}, + "tools": { + "listChanged": false + } + }, + "protocolVersion": "2025-06-18", + "serverInfo": { + "name": "footwork-capability", + "version": "0.0.1" + } + }, + "worker_proofs": [ + { + "registration": { + "nonce": "8c75f10165e6462babbdb4bdc61c669a", + "operation_id": "op_a3c8d3e60e2d", + "packet_digest": "0ebc4a7e56c0d4c4d1a118abf20e411f4a3c35cfe7181b58872bec7c37f92528", + "pgid": 53493, + "pid": 53493, + "request_digest": "30225dcd2278b572fc206259c7bcca93b56586cc42b1bdca0d0564bf1d20eb51", + "start": "0x1.ab34b0daf2c41p+30", + "version": 1 + }, + "cmdline": [ + "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python", + "-I", + "-m", + "jevdual.capability.execution_worker", + "--packet", + "/Users/tom/footwork-u4/footwork/output/job-v1/operations.sqlite.executions/op_a3c8d3e60e2d/packet.json" + ], + "executable": "/Library/Frameworks/Python.framework/Versions/3.14/Resources/Python.app/Contents/MacOS/Python" + } + ], + "action": { + "is_error": false, + "schema_version": "1", + "operation_id": "op_a3c8d3e60e2d", + "disposition": "applied", + "state": "final", + "phase": "sent", + "summary": "Historical append confirmed by retained execution evidence; current agreement is separate.", + "repeat": false, + "evidence": { + "execution_receipt": { + "disposition": "applied", + "error": null, + "evidence": { + "after": { + "length": 24, + "sha256": "783172d2e6ac11f2c5450015856703ebe655b8c2aa86ca81b802ab1d8d210aee" + }, + "before": { + "length": 15, + "sha256": "ac11060594d5bcde616f5e88156ea7c0f55e2cca74c2de52c4da375fbde33339" + }, + "driver_effect": "confirmed", + "identity": { + "boot": "11EBDE2F-6F02-4282-B73B-6DB59AABD9A1", + "device": 16777233, + "document": "/Users/tom/footwork-u4/footwork/output/fixture-v1/fixture-v1-invoice.txt", + "inode": 163250, + "pid": 2817, + "start": "0x1.ab2ff26e1fcadp+30" + }, + "identity_after": { + "boot": "11EBDE2F-6F02-4282-B73B-6DB59AABD9A1", + "device": 16777233, + "document": "/Users/tom/footwork-u4/footwork/output/fixture-v1/fixture-v1-invoice.txt", + "inode": 163250, + "pid": 2817, + "start": "0x1.ab2ff26e1fcadp+30" + }, + "readback": { + "kind": "exact_field_readback", + "passed": true, + "persistence": "not_checked" + } + }, + "nonce": "8c75f10165e6462babbdb4bdc61c669a", + "operation_id": "op_a3c8d3e60e2d", + "packet_digest": "0ebc4a7e56c0d4c4d1a118abf20e411f4a3c35cfe7181b58872bec7c37f92528", + "phase": "sent", + "request_digest": "30225dcd2278b572fc206259c7bcca93b56586cc42b1bdca0d0564bf1d20eb51", + "version": 1 + }, + "readback": { + "kind": "exact_field_readback", + "passed": true, + "persistence": "not_checked", + "outcome": "applied", + "historical": true + } + }, + "reporting": { + "historical_effect": "applied", + "disk_persistence": "not_checked", + "guidance": "Disk persistence was not checked. Do not claim the file is saved or unsaved. Report the retained execution result separately from current document agreement." + }, + "client_token": "installed-once" + }, + "repeat": { + "is_error": false, + "schema_version": "1", + "operation_id": "op_a3c8d3e60e2d", + "disposition": "applied", + "state": "final", + "phase": "sent", + "summary": "Historical append confirmed by retained execution evidence; current agreement is separate.", + "repeat": true, + "evidence": { + "execution_receipt": { + "disposition": "applied", + "error": null, + "evidence": { + "after": { + "length": 24, + "sha256": "783172d2e6ac11f2c5450015856703ebe655b8c2aa86ca81b802ab1d8d210aee" + }, + "before": { + "length": 15, + "sha256": "ac11060594d5bcde616f5e88156ea7c0f55e2cca74c2de52c4da375fbde33339" + }, + "driver_effect": "confirmed", + "identity": { + "boot": "11EBDE2F-6F02-4282-B73B-6DB59AABD9A1", + "device": 16777233, + "document": "/Users/tom/footwork-u4/footwork/output/fixture-v1/fixture-v1-invoice.txt", + "inode": 163250, + "pid": 2817, + "start": "0x1.ab2ff26e1fcadp+30" + }, + "identity_after": { + "boot": "11EBDE2F-6F02-4282-B73B-6DB59AABD9A1", + "device": 16777233, + "document": "/Users/tom/footwork-u4/footwork/output/fixture-v1/fixture-v1-invoice.txt", + "inode": 163250, + "pid": 2817, + "start": "0x1.ab2ff26e1fcadp+30" + }, + "readback": { + "kind": "exact_field_readback", + "passed": true, + "persistence": "not_checked" + } + }, + "nonce": "8c75f10165e6462babbdb4bdc61c669a", + "operation_id": "op_a3c8d3e60e2d", + "packet_digest": "0ebc4a7e56c0d4c4d1a118abf20e411f4a3c35cfe7181b58872bec7c37f92528", + "phase": "sent", + "request_digest": "30225dcd2278b572fc206259c7bcca93b56586cc42b1bdca0d0564bf1d20eb51", + "version": 1 + }, + "readback": { + "kind": "exact_field_readback", + "passed": true, + "persistence": "not_checked", + "outcome": "applied", + "historical": true + } + }, + "reporting": { + "historical_effect": "applied", + "disk_persistence": "not_checked", + "guidance": "Disk persistence was not checked. Do not claim the file is saved or unsaved. Report the retained execution result separately from current document agreement." + }, + "client_token": "installed-once" + }, + "report": { + "schema_version": "1", + "scope": "all_admitted_task_operations", + "validation": { + "accepted": true, + "reasons": [] + }, + "operation_completion": "completed", + "operations": [ + { + "operation": "op_a3c8d3e60e2d", + "state": "final", + "disposition": "applied", + "updated": 1791831096.0829408, + "created": 1791831094.731467 + } + ], + "persistence": "not_checked", + "current_state": "not_checked", + "task": "task_e773ee572b84420b9c1eeed7173ead46", + "snapshot_digest": "09aecceb2931e9ecde82e51cfa1010701352a5884f119109171d253305391b17", + "ledger_span": { + "first_created": 1791831094.731467, + "last_updated": 1791831096.0829408, + "count": 1 + }, + "accepted_host_claim": "completed", + "as_of": 1791831096.956186, + "trusted_summary": "1 recorded operations confirmed applied; 0 attempts confirmed no input. These are historical effects, not certification of the host job. Full task ledger: 1 records, 2026-10-12T18:51:34.731467+00:00 through 2026-10-12T18:51:36.082941+00:00. Current document state and disk persistence are not certified by this report." + }, + "oracle_actual": "Invoice report\n17.25 USD", + "owned_worker_finished": true, + "limits": "Existing host OS/system frameworks/permissions. Fresh dependency/private-home qualification." +} diff --git a/jevdual/results/u3-packet-v4-permission-20261012-v1/report.md b/jevdual/results/u3-packet-v4-permission-20261012-v1/report.md new file mode 100644 index 0000000..5ad2337 --- /dev/null +++ b/jevdual/results/u3-packet-v4-permission-20261012-v1/report.md @@ -0,0 +1,5 @@ +U3v1 failed its required automatic document confirmation gate. Frozen packet eef36325/source21599c6 cold-installed seven stages, refused without Accessibility before resource creation, captured the user-approved Terminal OFF→ON transition, and passed strict doctor after Terminal restart. The installed native trial passed its exact append oracle, same-token server restart/replay, one durable final/applied/sent operation and accepted host completion report. The worker used the installed environment and private HOME. Screen Recording remained not granted. + +One SIGINT automatically removed the document from view; cleanup returned ax_attribute_refused:AXRole:-25202 and exit6. Browser/listener cleanup and independently observed owned process/listener absence passed. No manual document close or Automation grant occurred. File snapshots changed15→24bytes; disk persistence remains not_checked. The original run stays failed. A repair trial will have separate frozen source/evidence. + +Raw archive output/u3-export-v1/evidence-v1.zip retains86members; eight pre-grant baseline hashes independently match. An optional operator AX readback probe failed with NameError before querying windows and adds no evidence. Archive doctor paths carry a relative Users/tom prefix due to zip absolute input; no path traversal. Guest fixture document contents were not included by the misnamed invoice.txt archive glob; the native receipt contains the actual oracle and cleanup file snapshots. diff --git a/jevdual/results/u3-packet-v4-permission-20261012-v1/startup.json b/jevdual/results/u3-packet-v4-permission-20261012-v1/startup.json new file mode 100644 index 0000000..f60a11e --- /dev/null +++ b/jevdual/results/u3-packet-v4-permission-20261012-v1/startup.json @@ -0,0 +1,5 @@ +{ + "status": "ready", + "pid": 52622, + "port": 49236 +} diff --git a/jevdual/results/u3-packet-v4-permission-20261012-v1/summary.json b/jevdual/results/u3-packet-v4-permission-20261012-v1/summary.json new file mode 100644 index 0000000..3c771aa --- /dev/null +++ b/jevdual/results/u3-packet-v4-permission-20261012-v1/summary.json @@ -0,0 +1,36 @@ +{ + "passed": false, + "classification": "fresh permission state on previously provisioned guest", + "packet_sha256": "eef3632506680d74b21b511cec905d73de2324f951e924b0716f2309490f590d", + "source_commit": "21599c641e4c54cad137b3c49e11142c5c14e596", + "raw_archive_sha256": "2d9a03ef17016aa7894e8679c4fd1fbe492e667e335bff8cd4cf01e38ee65427", + "baseline_hashes_match": { + "permission-reset.txt": true, + "doctor-before-exit.txt": true, + "doctor-before-stderr.txt": true, + "denied-fixture-console.txt": true, + "denied-fixture-exit.txt": true, + "denied-resource-check.txt": true, + "footwork/output/doctor-before.json": true, + "footwork/output/install-v1/receipt.json": true + }, + "durable_rows": [ + [ + "op_a3c8d3e60e2d", + "final", + "applied", + "sent" + ] + ], + "install": true, + "denied_baseline": true, + "observed_approved_grant": true, + "terminal_restart": true, + "strict_doctor_after": true, + "native": true, + "automatic_document_confirmation": false, + "fixture_exit": 6, + "manual_document_close": false, + "browser_listener_cleanup": true, + "disk_persistence": "not_checked" +} From 0f81db398cce0ac8f84386b123086b418c56482f Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 15:15:53 -0400 Subject: [PATCH 154/216] Record repaired packet installation and corrected denied baseline --- jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md index 0720709..66586f3 100644 --- a/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md +++ b/jevdual/docs/notebook/2026-10-12-onboarding-fixture-v4.md @@ -79,3 +79,9 @@ Test: use packet205577ee/source445a348 in a new guest root, verify pristine byte Predicts: the same frozen artifact supplies every denial/grant/restart/native/cleanup gate, stale AX reads never replay a close, and cleanup confirms fresh window absence plus browser/listener/worker absence without manual close or extra grants. Against: any required gate fails, a read error substitutes for absence, action repeats, an unrelated resource is affected, or the artifact changes during measurement. Refs: U3-packet-v4-permission-journey.md; UF4; Claude1791832031158825000; results/u3-packet-v4-permission-20261012-v1 + +## UFU8 · update · 2026-10-12 15:15 +Observed: Claude independently verifies original raw evidence and its sole cleanup failure, then approves exact205577ee for full UF5. New guest root footwork-u4-repair verifies14pristine members and cold-installs all seven stages,115packages. Supported Terminal-only reset succeeds19:11:29Z. Denied installed doctor/refusal are observed with no fixture directory. Corrected same-command exit capture retains doctor1/refusal2/absence0, with nine baseline hashes visibly printed before grant. No repaired native effect has occurred. +Changes: the public input wrapper invokes printf before eval, so separate later echo of the prior exit is invalid; initial exit files remain as operator logging errors. Only resource-free denial probes repeat in distinct v2 names, capturing actual exits in the same eval. A preliminary manifest glob includes itself; qualified-baseline.txt uses explicit groups and is the authoritative baseline. These do not change product source or permission state. +Next: actual same-host grant confirmation, Terminal relaunch, installed native and automatic cleanup, export and independent receipt review. UF4/UF5 remain open; prior failed U3v1 is unchanged. +Refs: guest footwork-u4-repair/qualified-baseline.txt; guest doctor-before-v2-exit.txt; guest denied-fixture-v2-exit.txt; Claude1791832201147781000 From 00e6f8b212d4c96ae9a25c8f2c190c3e8686bde4 Mon Sep 17 00:00:00 2001 From: Tom Main Date: Mon, 12 Oct 2026 15:17:26 -0400 Subject: [PATCH 155/216] Qualify healthy workbench progress and guarded recovery under delayed probes --- .../experiments/SIM12-workbench-health.md | 2 + .../notebook/2026-10-12-workbench-health.md | 18 + .../attempt-ledger.json | 11 + .../conformance.json | 15 + .../workbench-health-20261012/diagnosis.json | 116 + .../final-public.json | 320 ++ .../workbench-health-20261012/handoff.json | 116 + .../health-qualification-score.json | 1164 ++++++ .../workbench-health-20261012/identity.json | 8 + .../preserved-baseline.json | 12 + .../process-ledger.json | 40 + .../qualification-score.json | 724 ++++ .../relay-cleanup.json | 8 + .../workbench-health-20261012/report.md | 30 + .../review-audit-unscoped.json | 3340 ++++++++++++++++ .../review-audit.json | 3353 +++++++++++++++++ .../workbench-health-20261012/review-audit.py | 176 + .../source-freeze.json | 33 + .../workbench-health-20261012/summary.json | 32 + .../workbench-health-20261012/ui-ledger.json | 758 ++++ .../ui/completed.png | Bin 0 -> 47647 bytes .../ui/completed.txt | 88 + .../workbench-health-20261012/ui/handoff.png | Bin 0 -> 32779 bytes .../workbench-health-20261012/ui/handoff.txt | 81 + .../ui/healthy_checking.png | Bin 0 -> 39624 bytes .../ui/healthy_checking.txt | 74 + .../ui/recovered.png | Bin 0 -> 47071 bytes .../ui/recovered.txt | 87 + .../ui/second_identity_delay.png | Bin 0 -> 47596 bytes .../ui/second_identity_delay.txt | 87 + tools/physical-workcell/NETWORK_WORKBENCH.md | 2 + 31 files changed, 10695 insertions(+) create mode 100644 jevdual/results/workbench-health-20261012/attempt-ledger.json create mode 100644 jevdual/results/workbench-health-20261012/conformance.json create mode 100644 jevdual/results/workbench-health-20261012/diagnosis.json create mode 100644 jevdual/results/workbench-health-20261012/final-public.json create mode 100644 jevdual/results/workbench-health-20261012/handoff.json create mode 100644 jevdual/results/workbench-health-20261012/health-qualification-score.json create mode 100644 jevdual/results/workbench-health-20261012/identity.json create mode 100644 jevdual/results/workbench-health-20261012/preserved-baseline.json create mode 100644 jevdual/results/workbench-health-20261012/process-ledger.json create mode 100644 jevdual/results/workbench-health-20261012/qualification-score.json create mode 100644 jevdual/results/workbench-health-20261012/relay-cleanup.json create mode 100644 jevdual/results/workbench-health-20261012/report.md create mode 100644 jevdual/results/workbench-health-20261012/review-audit-unscoped.json create mode 100644 jevdual/results/workbench-health-20261012/review-audit.json create mode 100644 jevdual/results/workbench-health-20261012/review-audit.py create mode 100644 jevdual/results/workbench-health-20261012/source-freeze.json create mode 100644 jevdual/results/workbench-health-20261012/summary.json create mode 100644 jevdual/results/workbench-health-20261012/ui-ledger.json create mode 100644 jevdual/results/workbench-health-20261012/ui/completed.png create mode 100644 jevdual/results/workbench-health-20261012/ui/completed.txt create mode 100644 jevdual/results/workbench-health-20261012/ui/handoff.png create mode 100644 jevdual/results/workbench-health-20261012/ui/handoff.txt create mode 100644 jevdual/results/workbench-health-20261012/ui/healthy_checking.png create mode 100644 jevdual/results/workbench-health-20261012/ui/healthy_checking.txt create mode 100644 jevdual/results/workbench-health-20261012/ui/recovered.png create mode 100644 jevdual/results/workbench-health-20261012/ui/recovered.txt create mode 100644 jevdual/results/workbench-health-20261012/ui/second_identity_delay.png create mode 100644 jevdual/results/workbench-health-20261012/ui/second_identity_delay.txt diff --git a/jevdual/docs/experiments/SIM12-workbench-health.md b/jevdual/docs/experiments/SIM12-workbench-health.md index c302062..ac21a15 100644 --- a/jevdual/docs/experiments/SIM12-workbench-health.md +++ b/jevdual/docs/experiments/SIM12-workbench-health.md @@ -17,3 +17,5 @@ Guardrails: no retries of effect commands; no stale-image or stale-health author Decision rule: adopt only after the original healthy-delay reproduction passes without unrequested Pause, recovery guards pass and the frozen browser/model trial independently passes. Otherwise retain evidence and report the exact unresolved boundary. Scope: same-Mac loopback simulation. The observed SIM11 health timeouts are historical evidence; their precise physical scheduling cause is not assumed. + +Result: held for the tested mechanism and scope. Frozen source `37ebfdb3054b977149d7b60b46254ddd852b749a` completed two actual image-guided jobs under 1.2-second auxiliary health delays, with zero unexpected halts or cancelled model calls. Independent scoring verified fresh pinned proof before all 83 commands, exact receipt recovery without resend, native placement, measurement and contact reset. Original runtime and probe-backlog failures remain retained; 117 distinct conformance checks passed. The historical scheduling cause remains unresolved. See [report](../../results/workbench-health-20261012/report.md). diff --git a/jevdual/docs/notebook/2026-10-12-workbench-health.md b/jevdual/docs/notebook/2026-10-12-workbench-health.md index bfe8f83..104f402 100644 --- a/jevdual/docs/notebook/2026-10-12-workbench-health.md +++ b/jevdual/docs/notebook/2026-10-12-workbench-health.md @@ -48,3 +48,21 @@ Resolves: SIM12-DELAY = held; SIM12-FLIGHT = held Observed: the repaired runtime passed all 26 real-socket/native checks, including fresh proof failure, changed boot, known uncertainty and explicit Pause during proof. The link passed 13 checks, bounding repeated delayed probes to one reader per path and joining them at close. Seven new harness/scorer checks passed. Before-fix failures remain retained. Next: freeze the measured source, then test two actual image-guided jobs with diagnostic delayed health replies and browser receipt recovery. SIM12-P1 remains open until the independent product score. Refs: tools/physical-workcell/output/sim12-runtime-final-v1.log; tools/physical-workcell/output/sim12-link-tests-final.log; tools/physical-workcell/output/sim12-harness-tests-v1/unittest.log + +## SIM12-U4 · update · 2026-10-12 15:15 +Resolves: SIM12-FLIGHT = held +Observed: U3 combined two resolutions on one line; the notebook reader retained FLIGHT as open. Thirteen link checks independently passed the reader bound and cleanup. The actual trial also closed its link with zero owned readers, and its relay joined all workers after 685 requests with peak concurrency two. +Next: retain the independent product score and close the package. +Refs: tools/physical-workcell/output/sim12-link-tests-final.log; results/workbench-health-20261012/relay-cleanup.json; results/workbench-health-20261012/health-qualification-score.json + +## SIM12-U5 · update · 2026-10-12 15:15 +Resolves: SIM12-P1 = held +Observed: frozen source 37ebfdb3054b977149d7b60b46254ddd852b749a completed two actual image-guided browser jobs with 27 model decisions, 83 commands and zero cancelled calls or unexpected halts. Independent scoring verified native placement, one SQLite measurement each, contact resets, exact image/proposal/receipt bindings, and fresh pinned admission proof for every command. The lost reply retained nineteen commands through disconnect, reconnect and exact receipt recovery; explicit Resume preceded new work. Browser reload sent nothing. The trial retained 173 healthy delayed replies and no naturally slow upstream read of at least 0.8 seconds. All four owned processes exited zero before scoring. +Next: hand off the connected paused workbench with injection disabled; retain the supplemental exposure audit and limitations separately. +Refs: results/workbench-health-20261012/health-qualification-score.json; results/workbench-health-20261012/qualification-score.json; results/workbench-health-20261012/summary.json; tools/physical-workcell/output/sim12-browser-health-v1/ + +## SIM12-S1 · summary · 2026-10-12 15:15 +Established: a delayed auxiliary read caused a reproduced false cancellation, and repeated probes caused a reproduced reader backlog. The repair distinguishes checking from confirmed unsafe state, bounds probes, discards late replies and requires independent fresh status before each lease/stage. The actual product completed successive jobs under delays with exact receipt recovery. One hundred seventeen distinct conformance checks passed. After scoring, retained roots restarted for handoff at body boot two; administrative restart and relay replacement added guarded halt events after the measured event cutoff 284 while already paused, with no new model or effect commands. +Uncertain: the precise scheduling cause of the original SIM11 delay remains unresolved. Warm baseline probes and this trial did not reproduce a naturally slow upstream reply. Simulation does not qualify hardware, sudden power loss or authenticated remote control. Saved qualification scores describe the stopped trial before handoff; the live journal subsequently contains administrative events. +Decision: adopt the repair and leave the product paused, connected, with both completed results and no pending work. Keep frozen trial evidence and handoff evidence distinct. +Refs: results/workbench-health-20261012/report.md; results/workbench-health-20261012/handoff.json; docs/experiments/SIM12-workbench-health.md; commit 37ebfdb diff --git a/jevdual/results/workbench-health-20261012/attempt-ledger.json b/jevdual/results/workbench-health-20261012/attempt-ledger.json new file mode 100644 index 0000000..2e98e64 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/attempt-ledger.json @@ -0,0 +1,11 @@ +{ + "source_commit": "37ebfdb3054b977149d7b60b46254ddd852b749a", + "before_fix": [ + "tools/physical-workcell/output/sim12-health-before-fix.log", + "tools/physical-workcell/output/sim12-link-before-fix.log" + ], + "intermediate_failure": "tools/physical-workcell/output/sim12-health-targeted-v2.log", + "setup_only_unretained": "Wrong relative interpreter path exited127 before tests; reported in notebook SIM12-U2", + "actual_trial": "tools/physical-workcell/output/sim12-browser-health-v1", + "historical_warm_probes": "32 sequential reads succeeded; physical scheduling cause of original SIM11 timeout remains unresolved" +} diff --git a/jevdual/results/workbench-health-20261012/conformance.json b/jevdual/results/workbench-health-20261012/conformance.json new file mode 100644 index 0000000..05eba7c --- /dev/null +++ b/jevdual/results/workbench-health-20261012/conformance.json @@ -0,0 +1,15 @@ +{ + "runtime": { + "passed": 26, + "log": "tools/physical-workcell/output/sim12-runtime-final-v1.log" + }, + "core_network_HTTP_including_link": { + "passed": 84, + "log": "tools/physical-workcell/output/sim12-core-network-regression.log" + }, + "harness_scorer": { + "passed": 7, + "log": "tools/physical-workcell/output/sim12-harness-tests-v1/unittest.log" + }, + "total_distinct_suite_checks": 117 +} diff --git a/jevdual/results/workbench-health-20261012/diagnosis.json b/jevdual/results/workbench-health-20261012/diagnosis.json new file mode 100644 index 0000000..ed68637 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/diagnosis.json @@ -0,0 +1,116 @@ +{ + "isolated_transport_scan": { + "max_s": 0.029363750014454126, + "median_s": 0.020804957952350378, + "samples": [ + { + "bytes_read": 576223, + "counts": { + "canonical_request_digest": 664, + "intent.json": 83, + "result.json": 166 + }, + "elapsed_s": 0.02449941704981029, + "iteration": 0, + "records": 83, + "unresolved_count": 0 + }, + { + "bytes_read": 576223, + "counts": { + "canonical_request_digest": 664, + "intent.json": 83, + "result.json": 166 + }, + "elapsed_s": 0.020804957952350378, + "iteration": 1, + "records": 83, + "unresolved_count": 0 + }, + { + "bytes_read": 576223, + "counts": { + "canonical_request_digest": 664, + "intent.json": 83, + "result.json": 166 + }, + "elapsed_s": 0.029363750014454126, + "iteration": 2, + "records": 83, + "unresolved_count": 0 + }, + { + "bytes_read": 576223, + "counts": { + "canonical_request_digest": 664, + "intent.json": 83, + "result.json": 166 + }, + "elapsed_s": 0.019083166029304266, + "iteration": 3, + "records": 83, + "unresolved_count": 0 + }, + { + "bytes_read": 576223, + "counts": { + "canonical_request_digest": 664, + "intent.json": 83, + "result.json": 166 + }, + "elapsed_s": 0.018134792102500796, + "iteration": 4, + "records": 83, + "unresolved_count": 0 + } + ], + "scope": "copied immutable command journal only; no service/native constructor or effects" + }, + "no_model_calls": true, + "no_native_actions": true, + "routes": { + "direct_identity": { + "max_connect_s": 0.003117375075817108, + "max_headers_s": 0.07855645893141627, + "max_s": 0.0818679581861943, + "median_s": 0.025921083986759186, + "min_s": 0.022658249828964472, + "samples": 8, + "successes": 8 + }, + "direct_state": { + "max_connect_s": 0.00038674985989928246, + "max_headers_s": 0.13627387513406575, + "max_s": 0.13670033309608698, + "median_s": 0.09210818749852479, + "min_s": 0.08545674988999963, + "samples": 8, + "successes": 8 + }, + "linked_identity": { + "max_connect_s": 0.000262250192463398, + "max_headers_s": 0.03264912497252226, + "max_s": 0.03301991708576679, + "median_s": 0.02526693802792579, + "min_s": 0.024027250008657575, + "samples": 8, + "successes": 8 + }, + "linked_state": { + "max_connect_s": 0.00039504189044237137, + "max_headers_s": 0.12115875002928078, + "max_s": 0.12164500006474555, + "median_s": 0.09428881213534623, + "min_s": 0.0896729591768235, + "samples": 8, + "successes": 8 + } + }, + "samples": 32, + "sequential_requests": true, + "source_sha256": { + "body_client.py": "40388c238192d923888c9852b363314801dcf65c7266aadc8c377d3810aeb33d", + "body_network.py": "95fd21597bcdd9e982a698859cd1219ae4522062e332c50fea233629dbfb343c", + "workbench_link.py": "578d94684463bcb3d7f2d45d9ba68abcd27d8a27f7f39538323a269e251c330e" + } +} diff --git a/jevdual/results/workbench-health-20261012/final-public.json b/jevdual/results/workbench-health-20261012/final-public.json new file mode 100644 index 0000000..a15ed79 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/final-public.json @@ -0,0 +1,320 @@ +{ + "active_job_id": null, + "activity": [ + { + "intent": "Health inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-e6cd1a382110409ab381d5fd4c4cc3b0", + "seq": 261, + "time": 1791832252.5547252 + }, + { + "evidence": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787", + "state_sha256": "c51f62b6b7e6b77045faa7e62b207b6083aae7cea93bc688b1d5d13ebc2183a9" + }, + "intent": "", + "kind": "admission_proof", + "outcome": "dispatch", + "seq": 262, + "time": 1791832252.67232 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 263, + "time": 1791832252.76916 + }, + { + "intent": "Health inspection 02", + "kind": "rpc_applied", + "outcome": "dispatch: command-34752e8b30564841a21d087d561a5930", + "seq": 264, + "time": 1791832253.140799 + }, + { + "evidence": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787", + "state_sha256": "c91ba6318b8583251c817e27b82994527fd14970642478cf703ba8623ab401ee" + }, + "intent": "", + "kind": "admission_proof", + "outcome": "observe", + "seq": 265, + "time": 1791832253.259854 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 266, + "time": 1791832253.339296 + }, + { + "intent": "Health inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-c966c8b893db42eb84c5b0616acca391", + "seq": 267, + "time": 1791832253.647178 + }, + { + "intent": "Health inspection 02", + "kind": "inference", + "outcome": "12", + "seq": 268, + "time": 1791832253.650083 + }, + { + "evidence": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787", + "state_sha256": "507e8fc580d3a1de3645c79017d29cbdb19fbe08c7bb29b53151c86cb670beb8" + }, + "intent": "", + "kind": "admission_proof", + "outcome": "propose", + "seq": 269, + "time": 1791832261.705438 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 270, + "time": 1791832261.803793 + }, + { + "intent": "Health inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-c8ad5019377e44159aef0ee22364b18f", + "seq": 271, + "time": 1791832261.969871 + }, + { + "evidence": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787", + "state_sha256": "6f79059dab5d68858756144c67eaf9be40238e57b91180f0f3da17633c09fdad" + }, + "intent": "", + "kind": "admission_proof", + "outcome": "dispatch", + "seq": 272, + "time": 1791832262.110875 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 273, + "time": 1791832262.20136 + }, + { + "intent": "Health inspection 02", + "kind": "rpc_applied", + "outcome": "dispatch: command-10a03ed616ea4d96a26e96ae0973c32b", + "seq": 274, + "time": 1791832262.66578 + }, + { + "evidence": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787", + "state_sha256": "b7771a9f856f21997220b7646337a78d909ab9201902d30832ec913dc2ce5243" + }, + "intent": "", + "kind": "admission_proof", + "outcome": "observe", + "seq": 275, + "time": 1791832262.80537 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "observe", + "seq": 276, + "time": 1791832262.8756638 + }, + { + "intent": "Health inspection 02", + "kind": "rpc_applied", + "outcome": "observe: command-6b6e57d717d249c7811ef4708c6b8667", + "seq": 277, + "time": 1791832263.206536 + }, + { + "intent": "Health inspection 02", + "kind": "inference", + "outcome": "13", + "seq": 278, + "time": 1791832263.209843 + }, + { + "evidence": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787", + "state_sha256": "ad60b3ef58d11abfe414f2b391c8adbf9ce89722fe1594db2aeb69a6db2098ef" + }, + "intent": "", + "kind": "admission_proof", + "outcome": "propose", + "seq": 279, + "time": 1791832269.831627 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "propose", + "seq": 280, + "time": 1791832269.9314198 + }, + { + "intent": "Health inspection 02", + "kind": "rpc_applied", + "outcome": "propose: command-594d54e2793d428bbb42f80713e94ed3", + "seq": 281, + "time": 1791832270.19759 + }, + { + "evidence": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787", + "state_sha256": "1cd6c2dd647f4e3bfccb6b46456551baf8e02d9b03e8eeb6ad8d00f54372e53b" + }, + "intent": "", + "kind": "admission_proof", + "outcome": "dispatch", + "seq": 282, + "time": 1791832270.339628 + }, + { + "intent": "", + "kind": "rpc_intent", + "outcome": "dispatch", + "seq": 283, + "time": 1791832270.4208908 + }, + { + "intent": "Health inspection 02", + "kind": "rpc_applied", + "outcome": "dispatch: command-bd5377590da74532a8333ac5ca2a72b3", + "seq": 284, + "time": 1791832270.9544058 + } + ], + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Health read delayed; fresh body proof is required before any command", + "state": "checking" + }, + "current_frame": { + "available": true, + "generation": 21, + "image_url": "/api/frame?generation=21&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Finish reset with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 11, + "image_sha256": "e47008c08f81d1ed137d87f021a4273e354a0c3d79e0c9b1da21e6dbeaf28429", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "kind": "finish_reset", + "native_time_s": 22.28199999999853, + "operation_id": "agent-53ec814ec65e409f894ccaf9c1dd2c2a", + "pusher_home_verified": true, + "reset_contact_samples": 3166, + "reset_native_steps": 7940, + "state_sha256": "0de60aca2a69c72c36eb8396ce0c3e420c60000ca6190ec36315207e14c804a4" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "Verify the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 21, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "kind": "finish_reset", + "native_time_s": 43.03000000000662, + "operation_id": "agent-6ec3f611bd9042a5b9a1acc3867b74e7", + "pusher_home_verified": true, + "reset_contact_samples": 3304, + "reset_native_steps": 8106, + "state_sha256": "d3bdf81922c73fc0177d3453905a0376c365e73434d7708da14061adba34ddf7" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "pending_operation": null, + "readiness": { + "ready": false, + "reason": "Resumed; next decision receives a fresh TCP image" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running", + "simulation": true, + "transport_pending": false, + "usage": { + "calls": 27, + "input_tokens": 352734, + "output_tokens": 4129, + "reported_calls": 27, + "token_usage_complete": true + } +} diff --git a/jevdual/results/workbench-health-20261012/handoff.json b/jevdual/results/workbench-health-20261012/handoff.json new file mode 100644 index 0000000..f697e71 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/handoff.json @@ -0,0 +1,116 @@ +{ + "processes": [ + { + "role": "body", + "pid": 84367 + }, + { + "role": "health-relay", + "pid": 84666, + "prior_diagnostic_pid": 84373, + "prior_diagnostic_exited": true + }, + { + "role": "workbench", + "pid": 84375 + } + ], + "body_identity": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 2, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" + }, + "browser_origin": "http://127.0.0.1:51377", + "relay_origin": "http://127.0.0.1:49270", + "relay_root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim12-handoff/persistent-relay", + "body_root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim12-browser-health-v1/body", + "operator_root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim12-browser-health-v1/operator", + "delay_injection": false, + "public": { + "app_id": "433d80f43f4148ef87d341b6d117396d", + "runner_status": "paused", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 2, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "model_request_pending": false, + "active_job_id": null, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Finish reset with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 11, + "image_sha256": "e47008c08f81d1ed137d87f021a4273e354a0c3d79e0c9b1da21e6dbeaf28429", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "kind": "finish_reset", + "native_time_s": 22.28199999999853, + "operation_id": "agent-53ec814ec65e409f894ccaf9c1dd2c2a", + "pusher_home_verified": true, + "reset_contact_samples": 3166, + "reset_native_steps": 7940, + "state_sha256": "0de60aca2a69c72c36eb8396ce0c3e420c60000ca6190ec36315207e14c804a4" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "Verify the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 21, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "kind": "finish_reset", + "native_time_s": 43.03000000000662, + "operation_id": "agent-6ec3f611bd9042a5b9a1acc3867b74e7", + "pusher_home_verified": true, + "reset_contact_samples": 3304, + "reset_native_steps": 8106, + "state_sha256": "d3bdf81922c73fc0177d3453905a0376c365e73434d7708da14061adba34ddf7" + }, + "status": "completed", + "target": "B" + } + ] + }, + "relay_bounded_workers": 8, + "relay_has_trial_deadline": false +} diff --git a/jevdual/results/workbench-health-20261012/health-qualification-score.json b/jevdual/results/workbench-health-20261012/health-qualification-score.json new file mode 100644 index 0000000..7d99026 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/health-qualification-score.json @@ -0,0 +1,1164 @@ +{ + "base_qualification": { + "browser_transitions_passed": true, + "completed_cycles": 2, + "lost_reply_reconciled_without_resend": true, + "model_boundaries_passed": true, + "passed": true, + "source_unchanged": true + }, + "cancelled_model_calls": [], + "fresh_admission_proofs": [ + { + "command_id": "command-accc773656494216b8991d02cab9b603", + "command_sequence": 16, + "lease_sequence": 15, + "operation": "start_job", + "passed": true, + "proof_event": 2, + "state_read_sequence": 13 + }, + { + "command_id": "command-85d8b423ec7c4a53bb1987fb1a62bdf6", + "command_sequence": 20, + "lease_sequence": 19, + "operation": "observe", + "passed": true, + "proof_event": 5, + "state_read_sequence": 17 + }, + { + "command_id": "command-b93638f4643f4d35b5cde6fde06ed807", + "command_sequence": 32, + "lease_sequence": 31, + "operation": "propose", + "passed": true, + "proof_event": 10, + "state_read_sequence": 29 + }, + { + "command_id": "command-a44e60b9d8c24bdaa49e479c4b0ef780", + "command_sequence": 36, + "lease_sequence": 35, + "operation": "dispatch", + "passed": true, + "proof_event": 13, + "state_read_sequence": 33 + }, + { + "command_id": "command-79dcaf5d02e048449c681748167c446a", + "command_sequence": 40, + "lease_sequence": 39, + "operation": "observe", + "passed": true, + "proof_event": 16, + "state_read_sequence": 37 + }, + { + "command_id": "command-069d2460341443e69bbcd0b5f39b91f2", + "command_sequence": 49, + "lease_sequence": 48, + "operation": "propose", + "passed": true, + "proof_event": 20, + "state_read_sequence": 46 + }, + { + "command_id": "command-20fde1f33f97495cade8fce105d16ae4", + "command_sequence": 53, + "lease_sequence": 52, + "operation": "dispatch", + "passed": true, + "proof_event": 23, + "state_read_sequence": 50 + }, + { + "command_id": "command-107896fd188d4b72be6d2a6debd2ba0c", + "command_sequence": 57, + "lease_sequence": 56, + "operation": "observe", + "passed": true, + "proof_event": 26, + "state_read_sequence": 54 + }, + { + "command_id": "command-1bc0e6eb4e064fe1b7b66dfbf750968a", + "command_sequence": 68, + "lease_sequence": 67, + "operation": "propose", + "passed": true, + "proof_event": 30, + "state_read_sequence": 65 + }, + { + "command_id": "command-70f9b8c19b59452693061139bda6c71b", + "command_sequence": 72, + "lease_sequence": 71, + "operation": "dispatch", + "passed": true, + "proof_event": 33, + "state_read_sequence": 69 + }, + { + "command_id": "command-16683e1227d84968879714ddd0556488", + "command_sequence": 76, + "lease_sequence": 75, + "operation": "observe", + "passed": true, + "proof_event": 36, + "state_read_sequence": 73 + }, + { + "command_id": "command-1fb29328cf0a4c7e800022c949b77f7a", + "command_sequence": 85, + "lease_sequence": 84, + "operation": "propose", + "passed": true, + "proof_event": 40, + "state_read_sequence": 82 + }, + { + "command_id": "command-f1e1760598fa4cd89339d2d2091f8d1a", + "command_sequence": 89, + "lease_sequence": 88, + "operation": "dispatch", + "passed": true, + "proof_event": 43, + "state_read_sequence": 86 + }, + { + "command_id": "command-1a4dc2ad405846ecbdfaed4b2d825f3e", + "command_sequence": 94, + "lease_sequence": 93, + "operation": "observe", + "passed": true, + "proof_event": 46, + "state_read_sequence": 91 + }, + { + "command_id": "command-55007cfbc1d7410d92d582397af2555b", + "command_sequence": 103, + "lease_sequence": 102, + "operation": "propose", + "passed": true, + "proof_event": 50, + "state_read_sequence": 100 + }, + { + "command_id": "command-ee7b8dee4444416c98f550c3e5a7c01f", + "command_sequence": 107, + "lease_sequence": 106, + "operation": "dispatch", + "passed": true, + "proof_event": 53, + "state_read_sequence": 104 + }, + { + "command_id": "command-77279a97fd4a4ff2aee720c0b7a46c40", + "command_sequence": 111, + "lease_sequence": 110, + "operation": "observe", + "passed": true, + "proof_event": 56, + "state_read_sequence": 108 + }, + { + "command_id": "command-3211cda07dda4c5c8dd2cc700fdaad98", + "command_sequence": 121, + "lease_sequence": 120, + "operation": "propose", + "passed": true, + "proof_event": 61, + "state_read_sequence": 118 + }, + { + "command_id": "command-e52c9ef5005a410fb80600b4ad7f947a", + "command_sequence": 125, + "lease_sequence": 124, + "operation": "dispatch", + "passed": true, + "proof_event": 64, + "state_read_sequence": 122 + }, + { + "command_id": "command-97245de4fa73480c87503051fc90a8a9", + "command_sequence": 179, + "lease_sequence": 178, + "operation": "observe", + "passed": true, + "proof_event": 72, + "state_read_sequence": 176 + }, + { + "command_id": "command-5457db2a5bcf4cd3ba1b306e5182ede1", + "command_sequence": 200, + "lease_sequence": 199, + "operation": "propose", + "passed": true, + "proof_event": 76, + "state_read_sequence": 197 + }, + { + "command_id": "command-d4045c653de542aea3cd3f100603a0dd", + "command_sequence": 204, + "lease_sequence": 203, + "operation": "dispatch", + "passed": true, + "proof_event": 79, + "state_read_sequence": 201 + }, + { + "command_id": "command-127c700baa7e4224a9f4d4d1654380fc", + "command_sequence": 208, + "lease_sequence": 207, + "operation": "observe", + "passed": true, + "proof_event": 82, + "state_read_sequence": 205 + }, + { + "command_id": "command-12d35e26325248a5881960ffcbd97a6f", + "command_sequence": 223, + "lease_sequence": 222, + "operation": "propose", + "passed": true, + "proof_event": 86, + "state_read_sequence": 220 + }, + { + "command_id": "command-fb95362e732c42c793f505dd7673ea38", + "command_sequence": 227, + "lease_sequence": 226, + "operation": "dispatch", + "passed": true, + "proof_event": 89, + "state_read_sequence": 224 + }, + { + "command_id": "command-5365431f8f094a738c04898a662544f5", + "command_sequence": 231, + "lease_sequence": 230, + "operation": "observe", + "passed": true, + "proof_event": 92, + "state_read_sequence": 228 + }, + { + "command_id": "command-1ca372f4627f44ca820de2e16d58a939", + "command_sequence": 246, + "lease_sequence": 245, + "operation": "propose", + "passed": true, + "proof_event": 96, + "state_read_sequence": 243 + }, + { + "command_id": "command-8074e0e06a9d46f68b944f8a3949a7d5", + "command_sequence": 250, + "lease_sequence": 249, + "operation": "dispatch", + "passed": true, + "proof_event": 99, + "state_read_sequence": 247 + }, + { + "command_id": "command-58c9af8646c94c0b9e453fb32e4622f1", + "command_sequence": 254, + "lease_sequence": 253, + "operation": "observe", + "passed": true, + "proof_event": 102, + "state_read_sequence": 251 + }, + { + "command_id": "command-706d43a193d349b0abb2a1a2e213670d", + "command_sequence": 269, + "lease_sequence": 268, + "operation": "propose", + "passed": true, + "proof_event": 106, + "state_read_sequence": 266 + }, + { + "command_id": "command-f01b770705654cf0b746795ef56a5e51", + "command_sequence": 273, + "lease_sequence": 272, + "operation": "dispatch", + "passed": true, + "proof_event": 109, + "state_read_sequence": 270 + }, + { + "command_id": "command-01c5b18c0f4848ab83a3a506c6164bd7", + "command_sequence": 277, + "lease_sequence": 276, + "operation": "observe", + "passed": true, + "proof_event": 112, + "state_read_sequence": 274 + }, + { + "command_id": "command-455161d907e44cc2a0c00c4713404a47", + "command_sequence": 292, + "lease_sequence": 291, + "operation": "propose", + "passed": true, + "proof_event": 116, + "state_read_sequence": 289 + }, + { + "command_id": "command-c085b10cc40c44539a927aa06c7a4339", + "command_sequence": 296, + "lease_sequence": 295, + "operation": "dispatch", + "passed": true, + "proof_event": 119, + "state_read_sequence": 293 + }, + { + "command_id": "command-7c91d1e39cc047049a3c4453e8b35923", + "command_sequence": 300, + "lease_sequence": 299, + "operation": "observe", + "passed": true, + "proof_event": 122, + "state_read_sequence": 297 + }, + { + "command_id": "command-02d0ee9bb015446e974769918792b02f", + "command_sequence": 313, + "lease_sequence": 312, + "operation": "propose", + "passed": true, + "proof_event": 126, + "state_read_sequence": 310 + }, + { + "command_id": "command-15941d3c6bb74b9a8916ec43a2fe0e1f", + "command_sequence": 317, + "lease_sequence": 316, + "operation": "dispatch", + "passed": true, + "proof_event": 129, + "state_read_sequence": 314 + }, + { + "command_id": "command-f615d864a28e4af88536d43c26a06e7c", + "command_sequence": 321, + "lease_sequence": 320, + "operation": "observe", + "passed": true, + "proof_event": 132, + "state_read_sequence": 318 + }, + { + "command_id": "command-d11cdb7e2538490784e2e8a2425572b7", + "command_sequence": 334, + "lease_sequence": 333, + "operation": "propose", + "passed": true, + "proof_event": 136, + "state_read_sequence": 331 + }, + { + "command_id": "command-cdf687139f2e43cab73f3afa8053018d", + "command_sequence": 338, + "lease_sequence": 337, + "operation": "dispatch", + "passed": true, + "proof_event": 139, + "state_read_sequence": 335 + }, + { + "command_id": "command-6db96f5e11fc4baebb1607c174a5898f", + "command_sequence": 342, + "lease_sequence": 341, + "operation": "observe", + "passed": true, + "proof_event": 142, + "state_read_sequence": 339 + }, + { + "command_id": "command-000b1a6737a14842a6b79c23e0a5ca92", + "command_sequence": 357, + "lease_sequence": 356, + "operation": "propose", + "passed": true, + "proof_event": 146, + "state_read_sequence": 354 + }, + { + "command_id": "command-72de9f33d999438198fc8b176ee89f6d", + "command_sequence": 361, + "lease_sequence": 360, + "operation": "dispatch", + "passed": true, + "proof_event": 149, + "state_read_sequence": 358 + }, + { + "command_id": "command-155208c1dd824b43a411bf0d9f879dc9", + "command_sequence": 366, + "lease_sequence": 365, + "operation": "start_job", + "passed": true, + "proof_event": 152, + "state_read_sequence": 363 + }, + { + "command_id": "command-debb71a7f11f45b1b2093c2da309bb26", + "command_sequence": 370, + "lease_sequence": 369, + "operation": "observe", + "passed": true, + "proof_event": 155, + "state_read_sequence": 367 + }, + { + "command_id": "command-8fe46178c8564d2b8af7b48dd51ceb69", + "command_sequence": 387, + "lease_sequence": 386, + "operation": "propose", + "passed": true, + "proof_event": 159, + "state_read_sequence": 384 + }, + { + "command_id": "command-1fdd5229845447258a05de892ad29824", + "command_sequence": 391, + "lease_sequence": 390, + "operation": "dispatch", + "passed": true, + "proof_event": 162, + "state_read_sequence": 388 + }, + { + "command_id": "command-7e14ebef15814262bf16ee0a417469ea", + "command_sequence": 395, + "lease_sequence": 394, + "operation": "observe", + "passed": true, + "proof_event": 165, + "state_read_sequence": 392 + }, + { + "command_id": "command-a6931c3bf281480fb0dd090384b20178", + "command_sequence": 408, + "lease_sequence": 407, + "operation": "propose", + "passed": true, + "proof_event": 169, + "state_read_sequence": 405 + }, + { + "command_id": "command-5a3fb52b0a34409da8c43ce284d498f8", + "command_sequence": 412, + "lease_sequence": 411, + "operation": "dispatch", + "passed": true, + "proof_event": 172, + "state_read_sequence": 409 + }, + { + "command_id": "command-6371aeae6cdb432c851d1a095b64f85e", + "command_sequence": 416, + "lease_sequence": 415, + "operation": "observe", + "passed": true, + "proof_event": 175, + "state_read_sequence": 413 + }, + { + "command_id": "command-020d09130bdf4e10b2e30aed41ee93fd", + "command_sequence": 433, + "lease_sequence": 432, + "operation": "propose", + "passed": true, + "proof_event": 179, + "state_read_sequence": 430 + }, + { + "command_id": "command-185d0f856fbc4990be03fb5a4d680444", + "command_sequence": 437, + "lease_sequence": 436, + "operation": "dispatch", + "passed": true, + "proof_event": 182, + "state_read_sequence": 434 + }, + { + "command_id": "command-271d260ff225464ca18069efe6b89a3f", + "command_sequence": 442, + "lease_sequence": 441, + "operation": "observe", + "passed": true, + "proof_event": 185, + "state_read_sequence": 439 + }, + { + "command_id": "command-8bc103965b3b4b548f0ab2a4f6529315", + "command_sequence": 455, + "lease_sequence": 454, + "operation": "propose", + "passed": true, + "proof_event": 189, + "state_read_sequence": 452 + }, + { + "command_id": "command-52b299434a2a4354ae1a0c27f7afda73", + "command_sequence": 459, + "lease_sequence": 458, + "operation": "dispatch", + "passed": true, + "proof_event": 192, + "state_read_sequence": 456 + }, + { + "command_id": "command-b50b8172d84a4c2ca69c1b13799c0cd3", + "command_sequence": 463, + "lease_sequence": 462, + "operation": "observe", + "passed": true, + "proof_event": 195, + "state_read_sequence": 460 + }, + { + "command_id": "command-55878c3e64e7438786d949269a3ca632", + "command_sequence": 478, + "lease_sequence": 477, + "operation": "propose", + "passed": true, + "proof_event": 199, + "state_read_sequence": 475 + }, + { + "command_id": "command-3c4907bffd1043b7841f4f7a81e14c2e", + "command_sequence": 482, + "lease_sequence": 481, + "operation": "dispatch", + "passed": true, + "proof_event": 202, + "state_read_sequence": 479 + }, + { + "command_id": "command-a3d1bf0c87ed4d748bcfddf5acbcdbc8", + "command_sequence": 486, + "lease_sequence": 485, + "operation": "observe", + "passed": true, + "proof_event": 205, + "state_read_sequence": 483 + }, + { + "command_id": "command-c2820c925b7b43e48231001f02731ba6", + "command_sequence": 501, + "lease_sequence": 500, + "operation": "propose", + "passed": true, + "proof_event": 209, + "state_read_sequence": 498 + }, + { + "command_id": "command-8a9753d1c9604e3094a1478b421465f0", + "command_sequence": 505, + "lease_sequence": 504, + "operation": "dispatch", + "passed": true, + "proof_event": 212, + "state_read_sequence": 502 + }, + { + "command_id": "command-c21a6cfb3b154f799bb67d2695787ef8", + "command_sequence": 509, + "lease_sequence": 508, + "operation": "observe", + "passed": true, + "proof_event": 215, + "state_read_sequence": 506 + }, + { + "command_id": "command-6d7f70c0e5b14d6494d7eb02930b9d66", + "command_sequence": 524, + "lease_sequence": 523, + "operation": "propose", + "passed": true, + "proof_event": 219, + "state_read_sequence": 521 + }, + { + "command_id": "command-7d2c4e20bc454be996d99dc7edeea280", + "command_sequence": 528, + "lease_sequence": 527, + "operation": "dispatch", + "passed": true, + "proof_event": 222, + "state_read_sequence": 525 + }, + { + "command_id": "command-3352c7fd2fb14ffcaf69c1b27c6c53d9", + "command_sequence": 532, + "lease_sequence": 531, + "operation": "observe", + "passed": true, + "proof_event": 225, + "state_read_sequence": 529 + }, + { + "command_id": "command-896ce409c627486b9104d8d7415cefd3", + "command_sequence": 551, + "lease_sequence": 550, + "operation": "propose", + "passed": true, + "proof_event": 229, + "state_read_sequence": 548 + }, + { + "command_id": "command-1875feda0eaf4c058b771536779ccd62", + "command_sequence": 555, + "lease_sequence": 554, + "operation": "dispatch", + "passed": true, + "proof_event": 232, + "state_read_sequence": 552 + }, + { + "command_id": "command-844f1072836b419fa30a4c4f4a8697f1", + "command_sequence": 559, + "lease_sequence": 558, + "operation": "observe", + "passed": true, + "proof_event": 235, + "state_read_sequence": 556 + }, + { + "command_id": "command-7d6435405eaf4824b97108643856b361", + "command_sequence": 572, + "lease_sequence": 571, + "operation": "propose", + "passed": true, + "proof_event": 239, + "state_read_sequence": 569 + }, + { + "command_id": "command-7408e15ea38244a592d2800662c2b3c8", + "command_sequence": 576, + "lease_sequence": 575, + "operation": "dispatch", + "passed": true, + "proof_event": 242, + "state_read_sequence": 573 + }, + { + "command_id": "command-3cdfb3055b044aeeb059afc8731dac9c", + "command_sequence": 580, + "lease_sequence": 579, + "operation": "observe", + "passed": true, + "proof_event": 245, + "state_read_sequence": 577 + }, + { + "command_id": "command-59ebc979948340c1bceb69a8e01ac2aa", + "command_sequence": 597, + "lease_sequence": 596, + "operation": "propose", + "passed": true, + "proof_event": 249, + "state_read_sequence": 594 + }, + { + "command_id": "command-7761812fccc94a208c8f3e2dc26c28ec", + "command_sequence": 601, + "lease_sequence": 600, + "operation": "dispatch", + "passed": true, + "proof_event": 252, + "state_read_sequence": 598 + }, + { + "command_id": "command-2e37938e1f6a4a63b928572e1cf365af", + "command_sequence": 605, + "lease_sequence": 604, + "operation": "observe", + "passed": true, + "proof_event": 255, + "state_read_sequence": 602 + }, + { + "command_id": "command-e6cd1a382110409ab381d5fd4c4cc3b0", + "command_sequence": 620, + "lease_sequence": 619, + "operation": "propose", + "passed": true, + "proof_event": 259, + "state_read_sequence": 617 + }, + { + "command_id": "command-34752e8b30564841a21d087d561a5930", + "command_sequence": 624, + "lease_sequence": 623, + "operation": "dispatch", + "passed": true, + "proof_event": 262, + "state_read_sequence": 621 + }, + { + "command_id": "command-c966c8b893db42eb84c5b0616acca391", + "command_sequence": 628, + "lease_sequence": 627, + "operation": "observe", + "passed": true, + "proof_event": 265, + "state_read_sequence": 625 + }, + { + "command_id": "command-c8ad5019377e44159aef0ee22364b18f", + "command_sequence": 638, + "lease_sequence": 637, + "operation": "propose", + "passed": true, + "proof_event": 269, + "state_read_sequence": 635 + }, + { + "command_id": "command-10a03ed616ea4d96a26e96ae0973c32b", + "command_sequence": 642, + "lease_sequence": 641, + "operation": "dispatch", + "passed": true, + "proof_event": 272, + "state_read_sequence": 639 + }, + { + "command_id": "command-6b6e57d717d249c7811ef4708c6b8667", + "command_sequence": 646, + "lease_sequence": 645, + "operation": "observe", + "passed": true, + "proof_event": 275, + "state_read_sequence": 643 + }, + { + "command_id": "command-594d54e2793d428bbb42f80713e94ed3", + "command_sequence": 655, + "lease_sequence": 654, + "operation": "propose", + "passed": true, + "proof_event": 279, + "state_read_sequence": 652 + }, + { + "command_id": "command-bd5377590da74532a8333ac5ca2a72b3", + "command_sequence": 659, + "lease_sequence": 658, + "operation": "dispatch", + "passed": true, + "proof_event": 282, + "state_read_sequence": 656 + } + ], + "fresh_proof_every_rpc": true, + "genuine_upstream_long_read_count": 0, + "genuine_upstream_long_reads": [], + "healthy_injected_long_read_count": 173, + "healthy_injected_long_reads": [ + { + "injected_elapsed_s": 1.2040192501153797, + "path": "/identity", + "sequence": 2, + "upstream_elapsed_s": 0.002776124980300665 + }, + { + "injected_elapsed_s": 1.2024811250157654, + "path": "/identity", + "sequence": 3, + "upstream_elapsed_s": 0.005044083809480071 + }, + { + "injected_elapsed_s": 1.2039304592180997, + "path": "/identity", + "sequence": 4, + "upstream_elapsed_s": 0.0035592911299318075 + }, + { + "injected_elapsed_s": 1.2020084999967366, + "path": "/identity", + "sequence": 5, + "upstream_elapsed_s": 0.0029993748757988214 + }, + { + "injected_elapsed_s": 1.2050337500404567, + "path": "/identity", + "sequence": 6, + "upstream_elapsed_s": 0.0033572500105947256 + }, + { + "injected_elapsed_s": 1.203755582915619, + "path": "/identity", + "sequence": 7, + "upstream_elapsed_s": 0.09075575019232929 + }, + { + "injected_elapsed_s": 1.2050538749899715, + "path": "/identity", + "sequence": 8, + "upstream_elapsed_s": 0.0031042909249663353 + }, + { + "injected_elapsed_s": 1.203882124973461, + "path": "/identity", + "sequence": 9, + "upstream_elapsed_s": 0.0031348341144621372 + }, + { + "injected_elapsed_s": 1.204291749978438, + "path": "/identity", + "sequence": 10, + "upstream_elapsed_s": 0.005035291891545057 + }, + { + "injected_elapsed_s": 1.2027659590821713, + "path": "/identity", + "sequence": 11, + "upstream_elapsed_s": 0.002828457858413458 + }, + { + "injected_elapsed_s": 1.2050365000031888, + "path": "/identity", + "sequence": 12, + "upstream_elapsed_s": 0.003178749931976199 + }, + { + "injected_elapsed_s": 1.201763124903664, + "path": "/identity", + "sequence": 22, + "upstream_elapsed_s": 0.00289629097096622 + }, + { + "injected_elapsed_s": 1.2055749581195414, + "path": "/identity", + "sequence": 23, + "upstream_elapsed_s": 0.002508667064830661 + }, + { + "injected_elapsed_s": 1.205075625097379, + "path": "/identity", + "sequence": 24, + "upstream_elapsed_s": 0.003260375000536442 + }, + { + "injected_elapsed_s": 1.2044482911005616, + "path": "/identity", + "sequence": 25, + "upstream_elapsed_s": 0.003892249893397093 + }, + { + "injected_elapsed_s": 1.204990333179012, + "path": "/identity", + "sequence": 26, + "upstream_elapsed_s": 0.003343291115015745 + }, + { + "injected_elapsed_s": 1.2049401660915464, + "path": "/identity", + "sequence": 27, + "upstream_elapsed_s": 0.0034893339034169912 + }, + { + "injected_elapsed_s": 1.204629332991317, + "path": "/identity", + "sequence": 28, + "upstream_elapsed_s": 0.003361874958500266 + }, + { + "injected_elapsed_s": 1.2040073750540614, + "path": "/identity", + "sequence": 42, + "upstream_elapsed_s": 0.00299987499602139 + }, + { + "injected_elapsed_s": 1.2035016249865294, + "path": "/identity", + "sequence": 43, + "upstream_elapsed_s": 0.0031940829940140247 + }, + { + "injected_elapsed_s": 1.2012091248761863, + "path": "/identity", + "sequence": 44, + "upstream_elapsed_s": 0.004062541993334889 + }, + { + "injected_elapsed_s": 1.2042698750738055, + "path": "/identity", + "sequence": 45, + "upstream_elapsed_s": 0.002662374870851636 + }, + { + "injected_elapsed_s": 1.2008610831107944, + "path": "/identity", + "sequence": 59, + "upstream_elapsed_s": 0.0025203339755535126 + }, + { + "injected_elapsed_s": 1.2012784169055521, + "path": "/identity", + "sequence": 60, + "upstream_elapsed_s": 0.009544290835037827 + }, + { + "injected_elapsed_s": 1.2050834170076996, + "path": "/identity", + "sequence": 61, + "upstream_elapsed_s": 0.0035029591526836157 + }, + { + "injected_elapsed_s": 1.2050489170942456, + "path": "/identity", + "sequence": 62, + "upstream_elapsed_s": 0.0033430408220738173 + }, + { + "injected_elapsed_s": 1.200188459130004, + "path": "/identity", + "sequence": 63, + "upstream_elapsed_s": 0.004118707962334156 + }, + { + "injected_elapsed_s": 1.2050984590314329, + "path": "/identity", + "sequence": 64, + "upstream_elapsed_s": 0.007497084094211459 + }, + { + "injected_elapsed_s": 1.2025703340768814, + "path": "/identity", + "sequence": 78, + "upstream_elapsed_s": 0.0029468329157680273 + }, + { + "injected_elapsed_s": 1.2046614589635283, + "path": "/identity", + "sequence": 79, + "upstream_elapsed_s": 0.009623541962355375 + }, + { + "injected_elapsed_s": 1.2050566668622196, + "path": "/identity", + "sequence": 80, + "upstream_elapsed_s": 0.003390332916751504 + }, + { + "injected_elapsed_s": 1.2048170422203839, + "path": "/identity", + "sequence": 81, + "upstream_elapsed_s": 0.00339320907369256 + }, + { + "injected_elapsed_s": 1.2029053340665996, + "path": "/identity", + "sequence": 96, + "upstream_elapsed_s": 0.012598375091329217 + }, + { + "injected_elapsed_s": 1.2034727919381112, + "path": "/identity", + "sequence": 97, + "upstream_elapsed_s": 0.01664000004529953 + }, + { + "injected_elapsed_s": 1.2048349999822676, + "path": "/identity", + "sequence": 98, + "upstream_elapsed_s": 0.019909291993826628 + }, + { + "injected_elapsed_s": 1.2022679159417748, + "path": "/identity", + "sequence": 99, + "upstream_elapsed_s": 0.016452833777293563 + }, + { + "injected_elapsed_s": 1.2038175829220563, + "path": "/identity", + "sequence": 113, + "upstream_elapsed_s": 0.013531167060136795 + }, + { + "injected_elapsed_s": 1.2040615831501782, + "path": "/identity", + "sequence": 114, + "upstream_elapsed_s": 0.013567666988819838 + }, + { + "injected_elapsed_s": 1.2006667500827461, + "path": "/identity", + "sequence": 115, + "upstream_elapsed_s": 0.021057708887383342 + }, + { + "injected_elapsed_s": 1.2005423330701888, + "path": "/identity", + "sequence": 116, + "upstream_elapsed_s": 0.014461665879935026 + }, + { + "injected_elapsed_s": 1.204718666849658, + "path": "/identity", + "sequence": 117, + "upstream_elapsed_s": 0.017344833118841052 + }, + { + "injected_elapsed_s": 1.2039870421867818, + "path": "/identity", + "sequence": 126, + "upstream_elapsed_s": 0.019155291141942143 + }, + { + "injected_elapsed_s": 1.2014507499989122, + "path": "/identity", + "sequence": 127, + "upstream_elapsed_s": 0.012994375079870224 + }, + { + "injected_elapsed_s": 1.2014389999676496, + "path": "/identity", + "sequence": 128, + "upstream_elapsed_s": 0.02700358279980719 + }, + { + "injected_elapsed_s": 1.2036458330694586, + "path": "/identity", + "sequence": 129, + "upstream_elapsed_s": 0.01330141699872911 + }, + { + "injected_elapsed_s": 1.2067252080887556, + "path": "/identity", + "sequence": 130, + "upstream_elapsed_s": 0.024299542186781764 + }, + { + "injected_elapsed_s": 1.2093212499748915, + "path": "/identity", + "sequence": 131, + "upstream_elapsed_s": 0.033242583042010665 + }, + { + "injected_elapsed_s": 1.2037583331111819, + "path": "/identity", + "sequence": 132, + "upstream_elapsed_s": 0.0233499170280993 + }, + { + "injected_elapsed_s": 1.2021812500897795, + "path": "/identity", + "sequence": 133, + "upstream_elapsed_s": 0.023109209025278687 + }, + { + "injected_elapsed_s": 1.2020818751771003, + "path": "/state", + "sequence": 211, + "upstream_elapsed_s": 0.04533958388492465 + }, + { + "injected_elapsed_s": 1.2005837499164045, + "path": "/state", + "sequence": 213, + "upstream_elapsed_s": 0.04676191695034504 + }, + { + "injected_elapsed_s": 1.2046695840544999, + "path": "/state", + "sequence": 215, + "upstream_elapsed_s": 0.04107379191555083 + }, + { + "injected_elapsed_s": 1.2013546251691878, + "path": "/state", + "sequence": 217, + "upstream_elapsed_s": 0.04071483411826193 + }, + { + "injected_elapsed_s": 1.2013900419697165, + "path": "/state", + "sequence": 219, + "upstream_elapsed_s": 0.041966750053688884 + }, + { + "injected_elapsed_s": 1.2015124999452382, + "path": "/state", + "sequence": 234, + "upstream_elapsed_s": 0.04945133300498128 + }, + { + "injected_elapsed_s": 1.2010567500256002, + "path": "/state", + "sequence": 236, + "upstream_elapsed_s": 0.04513141606003046 + }, + { + "injected_elapsed_s": 1.2007370002102107, + "path": "/state", + "sequence": 238, + "upstream_elapsed_s": 0.046239792136475444 + }, + { + "injected_elapsed_s": 1.2003611251711845, + "path": "/state", + "sequence": 240, + "upstream_elapsed_s": 0.05429583298973739 + }, + { + "injected_elapsed_s": 1.20504245813936, + "path": "/state", + "sequence": 242, + "upstream_elapsed_s": 0.04574579210020602 + }, + { + "injected_elapsed_s": 1.202794292010367, + "path": "/state", + "sequence": 257, + "upstream_elapsed_s": 0.04627279192209244 + }, + { + "injected_elapsed_s": 1.2046860409900546, + "path": "/state", + "sequence": 259, + "upstream_elapsed_s": 0.04723550006747246 + }, + { + "injected_elapsed_s": 1.2001820839941502, + "path": "/state", + "sequence": 261, + "upstream_elapsed_s": 0.047370166052132845 + }, + { + "injected_elapsed_s": 1.2050447911024094, + "path": "/state", + "sequence": 263, + "upstream_elapsed_s": 0.04227699991315603 + }, + { + "injected_elapsed_s": 1.2012766250409186, + "path": "/state", + "sequence": 265, + "upstream_elapsed_s": 0.056063625030219555 + } + ], + "owned_readers_exited": true, + "passed": true, + "relay_cleanup": { + "active_workers": 0, + "completed_workers": 685, + "peak_workers": 2, + "request_count": 685, + "server_thread_exited": true, + "worker_bound": 8 + }, + "relay_evidence_valid": true, + "scope": "same-Mac loopback simulation; 1.2s diagnostic auxiliary read delay", + "soft_checking_visible_while_running": true, + "unexpected_halts": [] +} diff --git a/jevdual/results/workbench-health-20261012/identity.json b/jevdual/results/workbench-health-20261012/identity.json new file mode 100644 index 0000000..c505c87 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/identity.json @@ -0,0 +1,8 @@ +{ + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "protocol": "footwork.body/1", + "simulation": true, + "source_sha256": "10833c9f931a9d762c93d13b6061795fa5c3b4be9ac6151eaf38427b47f04787" +} diff --git a/jevdual/results/workbench-health-20261012/preserved-baseline.json b/jevdual/results/workbench-health-20261012/preserved-baseline.json new file mode 100644 index 0000000..30ce9fb --- /dev/null +++ b/jevdual/results/workbench-health-20261012/preserved-baseline.json @@ -0,0 +1,12 @@ +{ + "previous_root": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim11-browser-restarts-v2", + "body_id": "a26eb04332df4e1e9f3f0f307db47644", + "app_id": "878fad93039a4e86b4dcc5529f118f20", + "completed_jobs": 2, + "source_commit": "3de70f1de65a74e9285f651418852fe88672d2a4", + "preserved_sources": "/Users/thomasmain/projects/footwork/tools/physical-workcell/output/sim12-preserved-baseline/source", + "stopped_owned_pids": [ + 8139, + 8145 + ] +} diff --git a/jevdual/results/workbench-health-20261012/process-ledger.json b/jevdual/results/workbench-health-20261012/process-ledger.json new file mode 100644 index 0000000..b887c30 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/process-ledger.json @@ -0,0 +1,40 @@ +{ + "app_id": "433d80f43f4148ef87d341b6d117396d", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "body_origin": "http://127.0.0.1:51373", + "browser_origin": "http://127.0.0.1:51377", + "health_delay_s": 1.2, + "limit_s": 2700, + "owned_processes_exited": true, + "planner": "actual_codex_cli_images_over_TCP", + "processes": [ + { + "exit_observed": true, + "pid": 63766, + "returncode": 0, + "role": "body" + }, + { + "exit_observed": true, + "pid": 63768, + "returncode": 0, + "role": "health-relay" + }, + { + "exit_observed": true, + "pid": 63773, + "returncode": 0, + "role": "initialize" + }, + { + "exit_observed": true, + "pid": 63779, + "returncode": 0, + "role": "workbench" + } + ], + "ready": true, + "relay_origin": "http://127.0.0.1:49270", + "simulation": true, + "source_commit": "37ebfdb3054b977149d7b60b46254ddd852b749a" +} diff --git a/jevdual/results/workbench-health-20261012/qualification-score.json b/jevdual/results/workbench-health-20261012/qualification-score.json new file mode 100644 index 0000000..cddb0b7 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/qualification-score.json @@ -0,0 +1,724 @@ +{ + "body_id": "eea757a5363c43ca81de4a2f78715534", + "browser_transitions_passed": true, + "calls": [ + { + "action": "move", + "call": 1, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13076, + "output_tokens": 213 + }, + "withheld": false + }, + { + "action": "move", + "call": 2, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12681, + "output_tokens": 168 + }, + "withheld": false + }, + { + "action": "measure", + "call": 3, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 12752, + "output_tokens": 142 + }, + "withheld": false + }, + { + "action": "begin_reset", + "call": 4, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13288, + "output_tokens": 42 + }, + "withheld": false + }, + { + "action": "move", + "call": 5, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12887, + "output_tokens": 158 + }, + "withheld": false + }, + { + "action": "move", + "call": 6, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 12958, + "output_tokens": 183 + }, + "withheld": false + }, + { + "action": "move", + "call": 7, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13496, + "output_tokens": 190 + }, + "withheld": false + }, + { + "action": "move", + "call": 8, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13038, + "output_tokens": 185 + }, + "withheld": false + }, + { + "action": "move", + "call": 9, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13040, + "output_tokens": 156 + }, + "withheld": false + }, + { + "action": "move", + "call": 10, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13041, + "output_tokens": 182 + }, + "withheld": false + }, + { + "action": "move", + "call": 11, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13503, + "output_tokens": 134 + }, + "withheld": false + }, + { + "action": "move", + "call": 12, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13516, + "output_tokens": 131 + }, + "withheld": false + }, + { + "action": "finish_reset", + "call": 13, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13052, + "output_tokens": 112 + }, + "withheld": false + }, + { + "action": "move", + "call": 1, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13057, + "output_tokens": 194 + }, + "withheld": false + }, + { + "action": "move", + "call": 2, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 12678, + "output_tokens": 142 + }, + "withheld": false + }, + { + "action": "move", + "call": 3, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13215, + "output_tokens": 187 + }, + "withheld": false + }, + { + "action": "measure", + "call": 4, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 12821, + "output_tokens": 134 + }, + "withheld": false + }, + { + "action": "begin_reset", + "call": 5, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10880, + "input_tokens": 13358, + "output_tokens": 42 + }, + "withheld": false + }, + { + "action": "move", + "call": 6, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 12957, + "output_tokens": 189 + }, + "withheld": false + }, + { + "action": "move", + "call": 7, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13032, + "output_tokens": 137 + }, + "withheld": false + }, + { + "action": "move", + "call": 8, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13033, + "output_tokens": 229 + }, + "withheld": false + }, + { + "action": "move", + "call": 9, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13038, + "output_tokens": 175 + }, + "withheld": false + }, + { + "action": "move", + "call": 10, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13039, + "output_tokens": 182 + }, + "withheld": false + }, + { + "action": "move", + "call": 11, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13039, + "output_tokens": 161 + }, + "withheld": false + }, + { + "action": "move", + "call": 12, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 10368, + "input_tokens": 13047, + "output_tokens": 135 + }, + "withheld": false + }, + { + "action": "move", + "call": 13, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 0, + "input_tokens": 13044, + "output_tokens": 121 + }, + "withheld": false + }, + { + "action": "finish_reset", + "call": 14, + "core_receipt_bound": true, + "exact_TCP_image": true, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_process_reaped": true, + "no_private_pose": true, + "one_client_send_bound": true, + "usage": { + "cached_input_tokens": 3968, + "input_tokens": 13048, + "output_tokens": 105 + }, + "withheld": false + } + ], + "completed_cycles": 2, + "lost_reply_reconciled_without_resend": true, + "model_boundaries_passed": true, + "owned_processes_exited": true, + "passed": true, + "scope": "browser UI and actual image policy over loopback TCP simulation", + "scores": [ + { + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "measurement_receipt": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "generation": 3, + "image_sha256": "abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 6.401999999999517, + "operation_id": "agent-48fcf185c3fc465ea239b3ade25ddf5b", + "source_kind": "mujoco_simulation", + "state_sha256": "f6e8a7529bd2326775b9043e7a716b126906ab7003fafbc6f229c159b904c7d0", + "version": 1, + "worker_pid": 66283 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.06580390404818154, + -1.5285398651025924e-10, + 0.034995730455369904 + ], + "external_force_cleared": true, + "generation": 3, + "native_time_s": 6.401999999999517, + "pusher_home": false, + "pusher_xyz": [ + -0.029999970057503877, + 1.0537612379601558e-25, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "f6e8a7529bd2326775b9043e7a716b126906ab7003fafbc6f229c159b904c7d0" + }, + "model_calls": 14, + "motion_count": 11, + "passed": true, + "reset_receipt": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 11, + "image_sha256": "e47008c08f81d1ed137d87f021a4273e354a0c3d79e0c9b1da21e6dbeaf28429", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "kind": "finish_reset", + "native_time_s": 22.28199999999853, + "operation_id": "agent-53ec814ec65e409f894ccaf9c1dd2c2a", + "pusher_home_verified": true, + "reset_contact_samples": 3166, + "reset_native_steps": 7940, + "state_sha256": "0de60aca2a69c72c36eb8396ce0c3e420c60000ca6190ec36315207e14c804a4" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11082008854694171, + -2.0220096198944655e-09, + 0.034995730455369765 + ], + "external_force_cleared": true, + "generation": 11, + "native_time_s": 22.28199999999853, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "0de60aca2a69c72c36eb8396ce0c3e420c60000ca6190ec36315207e14c804a4" + } + }, + { + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "measurement_receipt": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "generation": 13, + "image_sha256": "6f3ad87788edf85031472937026d8d6bfe0a4e8304ca20491585684be65d6725", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "measurement": { + "block_box": [ + 345, + 159, + 387, + 201 + ], + "block_center_xy": [ + 0.07666666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 365.085020242915, + 179.50722961249278 + ], + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 26.817999999996015, + "operation_id": "agent-eb4c669d330d4019afbef8648c3bf058", + "source_kind": "mujoco_simulation", + "state_sha256": "d1a7c1fbfc10e537f714dd8dfb5bc518914f1a36ec5477a71b4ad4f0f78969c3", + "version": 1, + "worker_pid": 75476 + }, + "measurement_state": { + "block_center_in_zone": true, + "block_xyz": [ + 0.07584523883164036, + -2.021993327103355e-09, + 0.03499573045536984 + ], + "external_force_cleared": true, + "generation": 13, + "native_time_s": 26.817999999996015, + "pusher_home": false, + "pusher_xyz": [ + -0.029999969669727955, + 5.643066017863546e-26, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "d1a7c1fbfc10e537f714dd8dfb5bc518914f1a36ec5477a71b4ad4f0f78969c3" + }, + "model_calls": 13, + "motion_count": 10, + "passed": true, + "reset_receipt": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 21, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "kind": "finish_reset", + "native_time_s": 43.03000000000662, + "operation_id": "agent-6ec3f611bd9042a5b9a1acc3867b74e7", + "pusher_home_verified": true, + "reset_contact_samples": 3304, + "reset_native_steps": 8106, + "state_sha256": "d3bdf81922c73fc0177d3453905a0376c365e73434d7708da14061adba34ddf7" + }, + "reset_state": { + "block_center_in_zone": true, + "block_xyz": [ + -0.11578232825908402, + -4.197266959787217e-09, + 0.03499573045536993 + ], + "external_force_cleared": true, + "generation": 21, + "native_time_s": 43.03000000000662, + "pusher_home": true, + "pusher_xyz": [ + -0.3, + 3.071149644023488e-08, + 0.06 + ], + "role": "independent_native_state_scorer", + "state_sha256": "d3bdf81922c73fc0177d3453905a0376c365e73434d7708da14061adba34ddf7" + } + } + ], + "source_commit": "37ebfdb3054b977149d7b60b46254ddd852b749a", + "source_unchanged": true, + "sqlite": { + "count": 2, + "role": "independent_read_only_sqlite_scorer", + "rows": [ + { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "generation": 13, + "image_sha256": "6f3ad87788edf85031472937026d8d6bfe0a4e8304ca20491585684be65d6725", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "operation_id": "agent-eb4c669d330d4019afbef8648c3bf058", + "receipt": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "generation": 13, + "image_sha256": "6f3ad87788edf85031472937026d8d6bfe0a4e8304ca20491585684be65d6725", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "measurement": { + "block_box": [ + 345, + 159, + 387, + 201 + ], + "block_center_xy": [ + 0.07666666666666666, + 0.0 + ], + "centroid_pixel_xy": [ + 365.085020242915, + 179.50722961249278 + ], + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "native_time_s": 26.817999999996015, + "operation_id": "agent-eb4c669d330d4019afbef8648c3bf058", + "source_kind": "mujoco_simulation", + "state_sha256": "d1a7c1fbfc10e537f714dd8dfb5bc518914f1a36ec5477a71b4ad4f0f78969c3", + "version": 1, + "worker_pid": 75476 + }, + "state_sha256": "d1a7c1fbfc10e537f714dd8dfb5bc518914f1a36ec5477a71b4ad4f0f78969c3" + }, + { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "generation": 3, + "image_sha256": "abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "operation_id": "agent-48fcf185c3fc465ea239b3ade25ddf5b", + "receipt": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "generation": 3, + "image_sha256": "abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "measurement": { + "block_box": [ + 339, + 159, + 381, + 201 + ], + "block_center_xy": [ + 0.06666666666666667, + 0.0 + ], + "centroid_pixel_xy": [ + 359.0486674391657, + 179.5393974507532 + ], + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "native_time_s": 6.401999999999517, + "operation_id": "agent-48fcf185c3fc465ea239b3ade25ddf5b", + "source_kind": "mujoco_simulation", + "state_sha256": "f6e8a7529bd2326775b9043e7a716b126906ab7003fafbc6f229c159b904c7d0", + "version": 1, + "worker_pid": 66283 + }, + "state_sha256": "f6e8a7529bd2326775b9043e7a716b126906ab7003fafbc6f229c159b904c7d0" + } + ] + }, + "transport_command_count": 83, + "transport_journal_bound": true, + "ui_steps": [ + "completed", + "disconnected", + "healthy_checking", + "offline_receipt", + "reconnected", + "recovered", + "reloaded", + "resumed", + "successive_checking", + "uncertain" + ] +} diff --git a/jevdual/results/workbench-health-20261012/relay-cleanup.json b/jevdual/results/workbench-health-20261012/relay-cleanup.json new file mode 100644 index 0000000..0374b50 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/relay-cleanup.json @@ -0,0 +1,8 @@ +{ + "active_workers": 0, + "completed_workers": 685, + "peak_workers": 2, + "request_count": 685, + "server_thread_exited": true, + "worker_bound": 8 +} diff --git a/jevdual/results/workbench-health-20261012/report.md b/jevdual/results/workbench-health-20261012/report.md new file mode 100644 index 0000000..488b38a --- /dev/null +++ b/jevdual/results/workbench-health-20261012/report.md @@ -0,0 +1,30 @@ +# Delayed health checks without false pauses + +Two actual image-guided jobs completed under deliberately delayed health replies with zero unexpected halts or cancelled decisions. The [independent health score](health-qualification-score.json) passed on frozen source `37ebfdb3054b977149d7b60b46254ddd852b749a`. Every one of 83 commands had fresh pinned ready-state proof before its lease and durable admission. The [native/model score](qualification-score.json) separately verified placement, one SQLite measurement per job, contact resets, exact TCP images and proposal/receipt bindings. + +The original runtime treated one auxiliary health deadline as body loss and cancelled healthy planning. A real-socket delayed response reproduced that false pause. Repeated slow probes also reproduced six concurrent upstream readers, three per path. The repaired link permits one reader per identity/state path, returns a bounded pending response, discards late results and joins its readers before releasing ownership. The runtime shows **Checking body** for an inconclusive auxiliary read, keeps planning available and requires an independent full status check before every command. Failed authoritative proof still pauses progress; identity, source, boot, lease, freshness, unknown-effect and explicit Pause guards remain in force. Body, client and core policy files were unchanged. + +The [diagnosis](diagnosis.json) distinguishes that reproduced mechanism from the earlier incident's unexplained physical scheduling delay. Thirty-two warm sequential pinned reads all succeeded; direct state median was 92.1 ms and linked state median 94.3 ms, with no maximum above 136.7 ms. An isolated scan of 83 copied command records took a median 20.8 ms. Those measurements show real overhead but do not establish why the historical reply crossed its deadline. + +| Product check | Retained evidence | +| --- | --- | +| Healthy planning under delayed health | Browser showed Checking body while the active AI continued planning; 173 healthy replies received 1.2-second injected delays | +| Successive jobs | Health inspection 01 used 14 decisions; Health inspection 02 used 13; both completed measurement and contact reset | +| Lost command reply | The command became uncertain and blocked successors; disconnect, reconnect and receipt recovery kept the count at nineteen | +| Recovery | Check receipt read the exact retained outcome without resending; the agent remained paused until explicit Resume obtained fresh evidence | +| Reload | Both completed jobs and all 83 command records remained; no command was added | +| Cleanup | All four owned trial processes exited zero; the relay joined workers after 685 requests, with peak concurrency two; the link retained zero live health readers | + +The trial used both delayed paths, then disabled injection for the explicit receipt recovery sequence, then delayed state reads and finally identity reads during the second job. The supplemental [exposure audit](review-audit.json) correlates delayed replies with actual model intervals, checks both paths during both jobs and strengthens proof matching. No naturally slow upstream reply of at least 0.8 seconds occurred in this trial. Artificial delay establishes tolerance to the tested condition, not the cause of the original incident. + +[Conformance](conformance.json) passed 117 distinct checks: 26 runtime socket/native cases, 84 core/network/link/HTTP checks and seven harness/scorer cases. Ruff, JavaScript syntax, notebook and whitespace checks passed. The [attempt ledger](attempt-ledger.json) retains the original failing runtime and backlog checks, the intermediate boot-classification failure, and the unretained setup-only interpreter-path error. No measured source changed during the actual model run. + +Scoring occurred after the trial stopped and before user handoff. The saved final public state ends at event 284. Restarting the retained roots for handoff advanced the body to boot two and added administrative restart/outage halt events while the host was already paused. These later events remain in the live journal and are distinguished in the supplemental audit; the saved scores describe the stopped trial. Raw prompts, model output and full relay traces remain in ignored storage at `tools/physical-workcell/output/sim12-browser-health-v1/`. + +The [live workbench](http://127.0.0.1:51377/) is connected and paused, with both results retained and no active job, model request or uncertain command. [Handoff metadata](handoff.json) records the owned body, persistent relay and workbench PIDs, roots and identities. Delay injection is disabled. The handoff relay has bounded workers and waits for explicit shutdown; it does not inherit the qualification harness's 45-minute trial deadline. + +Scope remains same-Mac loopback simulation. Physical hardware, sudden process death during persistence and authenticated cross-machine access remain unqualified. Reproduce with a new trial root using the [runbook](../../../tools/physical-workcell/NETWORK_WORKBENCH.md) and [preregistered experiment](../../docs/experiments/SIM12-workbench-health.md); score after stopping and before restarting that root for handoff. + +![AI planning continues while health is unconfirmed](ui/healthy_checking.png) + +![Exact receipt recovery leaves the agent paused](ui/recovered.png) diff --git a/jevdual/results/workbench-health-20261012/review-audit-unscoped.json b/jevdual/results/workbench-health-20261012/review-audit-unscoped.json new file mode 100644 index 0000000..2fb8763 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/review-audit-unscoped.json @@ -0,0 +1,3340 @@ +{ + "audit_kind": "supplemental_post_run_read_only_review", + "audit_source_sha256": "a38d99756a83f0fd9ea2ed136eec2c8e04b80ffd50be4af569ae835ccbdb588b", + "both_jobs_both_paths_overlap_actual_model": true, + "cancelled_calls": [], + "control_events": [ + { + "intent": "", + "kind": "halt", + "outcome": "reply is uncertain; reconcile exact command without resending", + "seq": 66, + "time": 1791832016.9072719 + }, + { + "intent": "", + "kind": "disconnect", + "outcome": "Transport only; no body reset or replay", + "seq": 67, + "time": 1791832033.026589 + }, + { + "intent": "", + "kind": "reconnect", + "outcome": "No command sent or replayed", + "seq": 68, + "time": 1791832051.478241 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 71, + "time": 1791832069.452853 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image", + "seq": 285, + "time": 1791832363.512448 + } + ], + "frozen_source_commit": "37ebfdb3054b977149d7b60b46254ddd852b749a", + "frozen_source_unchanged": true, + "healthy_checking_same_application_and_body": true, + "healthy_delayed_reads": [ + { + "delay_finished_wall": 1791831951.136652, + "delay_started_wall": 1791831949.9326327, + "genuine_upstream_elapsed_s": 0.002776124980300665, + "injected_elapsed_s": 1.2040192501153797, + "model_overlaps": [], + "path": "/identity", + "sequence": 2, + "wall_monotonic_offset_range_s": 0.00032067298889160156 + }, + { + "delay_finished_wall": 1791831952.751093, + "delay_started_wall": 1791831951.5486119, + "genuine_upstream_elapsed_s": 0.005044083809480071, + "injected_elapsed_s": 1.2024811250157654, + "model_overlaps": [], + "path": "/identity", + "sequence": 3, + "wall_monotonic_offset_range_s": 0.0005669593811035156 + }, + { + "delay_finished_wall": 1791831954.359777, + "delay_started_wall": 1791831953.1558466, + "genuine_upstream_elapsed_s": 0.0035592911299318075, + "injected_elapsed_s": 1.2039304592180997, + "model_overlaps": [], + "path": "/identity", + "sequence": 4, + "wall_monotonic_offset_range_s": 0.0003485679626464844 + }, + { + "delay_finished_wall": 1791831955.967743, + "delay_started_wall": 1791831954.7657344, + "genuine_upstream_elapsed_s": 0.0029993748757988214, + "injected_elapsed_s": 1.2020084999967366, + "model_overlaps": [], + "path": "/identity", + "sequence": 5, + "wall_monotonic_offset_range_s": 0.00022411346435546875 + }, + { + "delay_finished_wall": 1791831957.5783129, + "delay_started_wall": 1791831956.373279, + "genuine_upstream_elapsed_s": 0.0033572500105947256, + "injected_elapsed_s": 1.2050337500404567, + "model_overlaps": [], + "path": "/identity", + "sequence": 6, + "wall_monotonic_offset_range_s": 0.00037097930908203125 + }, + { + "delay_finished_wall": 1791831959.320833, + "delay_started_wall": 1791831958.1170774, + "genuine_upstream_elapsed_s": 0.09075575019232929, + "injected_elapsed_s": 1.203755582915619, + "model_overlaps": [], + "path": "/identity", + "sequence": 7, + "wall_monotonic_offset_range_s": 0.0005834102630615234 + }, + { + "delay_finished_wall": 1791831960.801874, + "delay_started_wall": 1791831959.59682, + "genuine_upstream_elapsed_s": 0.0031042909249663353, + "injected_elapsed_s": 1.2050538749899715, + "model_overlaps": [], + "path": "/identity", + "sequence": 8, + "wall_monotonic_offset_range_s": 0.0002377033233642578 + }, + { + "delay_finished_wall": 1791831962.408829, + "delay_started_wall": 1791831961.2049468, + "genuine_upstream_elapsed_s": 0.0031348341144621372, + "injected_elapsed_s": 1.203882124973461, + "model_overlaps": [], + "path": "/identity", + "sequence": 9, + "wall_monotonic_offset_range_s": 0.0003495216369628906 + }, + { + "delay_finished_wall": 1791831964.0189052, + "delay_started_wall": 1791831962.8146133, + "genuine_upstream_elapsed_s": 0.005035291891545057, + "injected_elapsed_s": 1.204291749978438, + "model_overlaps": [], + "path": "/identity", + "sequence": 10, + "wall_monotonic_offset_range_s": 0.0006890296936035156 + }, + { + "delay_finished_wall": 1791831965.624738, + "delay_started_wall": 1791831964.421972, + "genuine_upstream_elapsed_s": 0.002828457858413458, + "injected_elapsed_s": 1.2027659590821713, + "model_overlaps": [], + "path": "/identity", + "sequence": 11, + "wall_monotonic_offset_range_s": 0.00026869773864746094 + }, + { + "delay_finished_wall": 1791831967.239062, + "delay_started_wall": 1791831966.0340257, + "genuine_upstream_elapsed_s": 0.003178749931976199, + "injected_elapsed_s": 1.2050365000031888, + "model_overlaps": [], + "path": "/identity", + "sequence": 12, + "wall_monotonic_offset_range_s": 0.0002815723419189453 + }, + { + "delay_finished_wall": 1791831968.8454201, + "delay_started_wall": 1791831967.643657, + "genuine_upstream_elapsed_s": 0.00289629097096622, + "injected_elapsed_s": 1.201763124903664, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2017631530761719 + } + ], + "path": "/identity", + "sequence": 22, + "wall_monotonic_offset_range_s": 0.00020837783813476562 + }, + { + "delay_finished_wall": 1791831970.458034, + "delay_started_wall": 1791831969.252459, + "genuine_upstream_elapsed_s": 0.002508667064830661, + "injected_elapsed_s": 1.2055749581195414, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2055749893188477 + } + ], + "path": "/identity", + "sequence": 23, + "wall_monotonic_offset_range_s": 0.0002646446228027344 + }, + { + "delay_finished_wall": 1791831972.06533, + "delay_started_wall": 1791831970.8602543, + "genuine_upstream_elapsed_s": 0.003260375000536442, + "injected_elapsed_s": 1.205075625097379, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.205075740814209 + } + ], + "path": "/identity", + "sequence": 24, + "wall_monotonic_offset_range_s": 0.0003116130828857422 + }, + { + "delay_finished_wall": 1791831973.677821, + "delay_started_wall": 1791831972.4733727, + "genuine_upstream_elapsed_s": 0.003892249893397093, + "injected_elapsed_s": 1.2044482911005616, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2044482231140137 + } + ], + "path": "/identity", + "sequence": 25, + "wall_monotonic_offset_range_s": 0.0011014938354492188 + }, + { + "delay_finished_wall": 1791831975.285738, + "delay_started_wall": 1791831974.0807476, + "genuine_upstream_elapsed_s": 0.003343291115015745, + "injected_elapsed_s": 1.204990333179012, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2049903869628906 + } + ], + "path": "/identity", + "sequence": 26, + "wall_monotonic_offset_range_s": 0.00025391578674316406 + }, + { + "delay_finished_wall": 1791831976.8951979, + "delay_started_wall": 1791831975.6902578, + "genuine_upstream_elapsed_s": 0.0034893339034169912, + "injected_elapsed_s": 1.2049401660915464, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2049400806427002 + } + ], + "path": "/identity", + "sequence": 27, + "wall_monotonic_offset_range_s": 0.0002818107604980469 + }, + { + "delay_finished_wall": 1791831978.499134, + "delay_started_wall": 1791831977.2945046, + "genuine_upstream_elapsed_s": 0.003361874958500266, + "injected_elapsed_s": 1.204629332991317, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.7861673831939697 + } + ], + "path": "/identity", + "sequence": 28, + "wall_monotonic_offset_range_s": 0.0003018379211425781 + }, + { + "delay_finished_wall": 1791831980.10637, + "delay_started_wall": 1791831978.9023626, + "genuine_upstream_elapsed_s": 0.00299987499602139, + "injected_elapsed_s": 1.2040073750540614, + "model_overlaps": [ + { + "call": 2, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2040073871612549 + } + ], + "path": "/identity", + "sequence": 42, + "wall_monotonic_offset_range_s": 0.0002627372741699219 + }, + { + "delay_finished_wall": 1791831981.715692, + "delay_started_wall": 1791831980.5121903, + "genuine_upstream_elapsed_s": 0.0031940829940140247, + "injected_elapsed_s": 1.2035016249865294, + "model_overlaps": [ + { + "call": 2, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2035017013549805 + } + ], + "path": "/identity", + "sequence": 43, + "wall_monotonic_offset_range_s": 0.0002980232238769531 + }, + { + "delay_finished_wall": 1791831983.322252, + "delay_started_wall": 1791831982.121043, + "genuine_upstream_elapsed_s": 0.004062541993334889, + "injected_elapsed_s": 1.2012091248761863, + "model_overlaps": [ + { + "call": 2, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2012090682983398 + } + ], + "path": "/identity", + "sequence": 44, + "wall_monotonic_offset_range_s": 0.00027871131896972656 + }, + { + "delay_finished_wall": 1791831984.93428, + "delay_started_wall": 1791831983.73001, + "genuine_upstream_elapsed_s": 0.002662374870851636, + "injected_elapsed_s": 1.2042698750738055, + "model_overlaps": [ + { + "call": 2, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.0789592266082764 + } + ], + "path": "/identity", + "sequence": 45, + "wall_monotonic_offset_range_s": 0.00023412704467773438 + }, + { + "delay_finished_wall": 1791831986.539777, + "delay_started_wall": 1791831985.338916, + "genuine_upstream_elapsed_s": 0.0025203339755535126, + "injected_elapsed_s": 1.2008610831107944, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2008609771728516 + } + ], + "path": "/identity", + "sequence": 59, + "wall_monotonic_offset_range_s": 0.00014352798461914062 + }, + { + "delay_finished_wall": 1791831988.159762, + "delay_started_wall": 1791831986.9584835, + "genuine_upstream_elapsed_s": 0.009544290835037827, + "injected_elapsed_s": 1.2012784169055521, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2012784481048584 + } + ], + "path": "/identity", + "sequence": 60, + "wall_monotonic_offset_range_s": 0.00033092498779296875 + }, + { + "delay_finished_wall": 1791831989.7679, + "delay_started_wall": 1791831988.5628166, + "genuine_upstream_elapsed_s": 0.0035029591526836157, + "injected_elapsed_s": 1.2050834170076996, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050833702087402 + } + ], + "path": "/identity", + "sequence": 61, + "wall_monotonic_offset_range_s": 0.00027179718017578125 + }, + { + "delay_finished_wall": 1791831991.377156, + "delay_started_wall": 1791831990.1721072, + "genuine_upstream_elapsed_s": 0.0033430408220738173, + "injected_elapsed_s": 1.2050489170942456, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050487995147705 + } + ], + "path": "/identity", + "sequence": 62, + "wall_monotonic_offset_range_s": 0.0002346038818359375 + }, + { + "delay_finished_wall": 1791831992.996601, + "delay_started_wall": 1791831991.7964127, + "genuine_upstream_elapsed_s": 0.004118707962334156, + "injected_elapsed_s": 1.200188459130004, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.200188398361206 + } + ], + "path": "/identity", + "sequence": 63, + "wall_monotonic_offset_range_s": 0.005568981170654297 + }, + { + "delay_finished_wall": 1791831994.607224, + "delay_started_wall": 1791831993.4021256, + "genuine_upstream_elapsed_s": 0.007497084094211459, + "injected_elapsed_s": 1.2050984590314329, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050983905792236 + } + ], + "path": "/identity", + "sequence": 64, + "wall_monotonic_offset_range_s": 0.0003578662872314453 + }, + { + "delay_finished_wall": 1791831997.214113, + "delay_started_wall": 1791831996.0115426, + "genuine_upstream_elapsed_s": 0.0029468329157680273, + "injected_elapsed_s": 1.2025703340768814, + "model_overlaps": [ + { + "call": 4, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2025704383850098 + } + ], + "path": "/identity", + "sequence": 78, + "wall_monotonic_offset_range_s": 0.00033402442932128906 + }, + { + "delay_finished_wall": 1791831998.838238, + "delay_started_wall": 1791831997.6335766, + "genuine_upstream_elapsed_s": 0.009623541962355375, + "injected_elapsed_s": 1.2046614589635283, + "model_overlaps": [ + { + "call": 4, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2046613693237305 + } + ], + "path": "/identity", + "sequence": 79, + "wall_monotonic_offset_range_s": 0.0003039836883544922 + }, + { + "delay_finished_wall": 1791832000.441949, + "delay_started_wall": 1791831999.2368922, + "genuine_upstream_elapsed_s": 0.003390332916751504, + "injected_elapsed_s": 1.2050566668622196, + "model_overlaps": [ + { + "call": 4, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050566673278809 + } + ], + "path": "/identity", + "sequence": 80, + "wall_monotonic_offset_range_s": 0.00024771690368652344 + }, + { + "delay_finished_wall": 1791832002.051035, + "delay_started_wall": 1791832000.8462179, + "genuine_upstream_elapsed_s": 0.00339320907369256, + "injected_elapsed_s": 1.2048170422203839, + "model_overlaps": [ + { + "call": 4, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.8470175266265869 + } + ], + "path": "/identity", + "sequence": 81, + "wall_monotonic_offset_range_s": 0.0002200603485107422 + }, + { + "delay_finished_wall": 1791832003.6653, + "delay_started_wall": 1791832002.4623945, + "genuine_upstream_elapsed_s": 0.012598375091329217, + "injected_elapsed_s": 1.2029053340665996, + "model_overlaps": [ + { + "call": 5, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.1388180255889893 + } + ], + "path": "/identity", + "sequence": 96, + "wall_monotonic_offset_range_s": 0.00030541419982910156 + }, + { + "delay_finished_wall": 1791832005.285439, + "delay_started_wall": 1791832004.0819662, + "genuine_upstream_elapsed_s": 0.01664000004529953, + "injected_elapsed_s": 1.2034727919381112, + "model_overlaps": [ + { + "call": 5, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2034728527069092 + } + ], + "path": "/identity", + "sequence": 97, + "wall_monotonic_offset_range_s": 0.0003800392150878906 + }, + { + "delay_finished_wall": 1791832006.90365, + "delay_started_wall": 1791832005.698815, + "genuine_upstream_elapsed_s": 0.019909291993826628, + "injected_elapsed_s": 1.2048349999822676, + "model_overlaps": [ + { + "call": 5, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2048349380493164 + } + ], + "path": "/identity", + "sequence": 98, + "wall_monotonic_offset_range_s": 0.0004360675811767578 + }, + { + "delay_finished_wall": 1791832008.506123, + "delay_started_wall": 1791832007.3038552, + "genuine_upstream_elapsed_s": 0.016452833777293563, + "injected_elapsed_s": 1.2022679159417748, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.40236496925354004 + } + ], + "path": "/identity", + "sequence": 99, + "wall_monotonic_offset_range_s": 0.0002734661102294922 + }, + { + "delay_finished_wall": 1791832010.115941, + "delay_started_wall": 1791832008.9121234, + "genuine_upstream_elapsed_s": 0.013531167060136795, + "injected_elapsed_s": 1.2038175829220563, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.20381760597229 + } + ], + "path": "/identity", + "sequence": 113, + "wall_monotonic_offset_range_s": 0.0002827644348144531 + }, + { + "delay_finished_wall": 1791832011.727929, + "delay_started_wall": 1791832010.5238676, + "genuine_upstream_elapsed_s": 0.013567666988819838, + "injected_elapsed_s": 1.2040615831501782, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.204061508178711 + } + ], + "path": "/identity", + "sequence": 114, + "wall_monotonic_offset_range_s": 0.0003399848937988281 + }, + { + "delay_finished_wall": 1791832013.34195, + "delay_started_wall": 1791832012.1412833, + "genuine_upstream_elapsed_s": 0.021057708887383342, + "injected_elapsed_s": 1.2006667500827461, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2006666660308838 + } + ], + "path": "/identity", + "sequence": 115, + "wall_monotonic_offset_range_s": 0.000274658203125 + }, + { + "delay_finished_wall": 1791832014.943507, + "delay_started_wall": 1791832013.7429645, + "genuine_upstream_elapsed_s": 0.014461665879935026, + "injected_elapsed_s": 1.2005423330701888, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2005424499511719 + } + ], + "path": "/identity", + "sequence": 116, + "wall_monotonic_offset_range_s": 0.00047659873962402344 + }, + { + "delay_finished_wall": 1791832016.56296, + "delay_started_wall": 1791832015.3582413, + "genuine_upstream_elapsed_s": 0.017344833118841052, + "injected_elapsed_s": 1.204718666849658, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.8864147663116455 + } + ], + "path": "/identity", + "sequence": 117, + "wall_monotonic_offset_range_s": 0.0005025863647460938 + }, + { + "delay_finished_wall": 1791832018.174688, + "delay_started_wall": 1791832016.970701, + "genuine_upstream_elapsed_s": 0.019155291141942143, + "injected_elapsed_s": 1.2039870421867818, + "model_overlaps": [], + "path": "/identity", + "sequence": 126, + "wall_monotonic_offset_range_s": 0.00030732154846191406 + }, + { + "delay_finished_wall": 1791832019.776822, + "delay_started_wall": 1791832018.5753713, + "genuine_upstream_elapsed_s": 0.012994375079870224, + "injected_elapsed_s": 1.2014507499989122, + "model_overlaps": [], + "path": "/identity", + "sequence": 127, + "wall_monotonic_offset_range_s": 0.00035262107849121094 + }, + { + "delay_finished_wall": 1791832021.3976462, + "delay_started_wall": 1791832020.1962073, + "genuine_upstream_elapsed_s": 0.02700358279980719, + "injected_elapsed_s": 1.2014389999676496, + "model_overlaps": [], + "path": "/identity", + "sequence": 128, + "wall_monotonic_offset_range_s": 0.0003247261047363281 + }, + { + "delay_finished_wall": 1791832022.9915159, + "delay_started_wall": 1791832021.78787, + "genuine_upstream_elapsed_s": 0.01330141699872911, + "injected_elapsed_s": 1.2036458330694586, + "model_overlaps": [], + "path": "/identity", + "sequence": 129, + "wall_monotonic_offset_range_s": 0.0003898143768310547 + }, + { + "delay_finished_wall": 1791832024.675057, + "delay_started_wall": 1791832023.4683318, + "genuine_upstream_elapsed_s": 0.024299542186781764, + "injected_elapsed_s": 1.2067252080887556, + "model_overlaps": [], + "path": "/identity", + "sequence": 130, + "wall_monotonic_offset_range_s": 0.00021409988403320312 + }, + { + "delay_finished_wall": 1791832026.3910022, + "delay_started_wall": 1791832025.181681, + "genuine_upstream_elapsed_s": 0.033242583042010665, + "injected_elapsed_s": 1.2093212499748915, + "model_overlaps": [], + "path": "/identity", + "sequence": 131, + "wall_monotonic_offset_range_s": 0.0005581378936767578 + }, + { + "delay_finished_wall": 1791832027.847797, + "delay_started_wall": 1791832026.6440387, + "genuine_upstream_elapsed_s": 0.0233499170280993, + "injected_elapsed_s": 1.2037583331111819, + "model_overlaps": [], + "path": "/identity", + "sequence": 132, + "wall_monotonic_offset_range_s": 0.0006263256072998047 + }, + { + "delay_finished_wall": 1791832029.485719, + "delay_started_wall": 1791832028.2835376, + "genuine_upstream_elapsed_s": 0.023109209025278687, + "injected_elapsed_s": 1.2021812500897795, + "model_overlaps": [], + "path": "/identity", + "sequence": 133, + "wall_monotonic_offset_range_s": 0.0005357265472412109 + }, + { + "delay_finished_wall": 1791832081.0974221, + "delay_started_wall": 1791832079.8953402, + "genuine_upstream_elapsed_s": 0.04533958388492465, + "injected_elapsed_s": 1.2020818751771003, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2020819187164307 + } + ], + "path": "/state", + "sequence": 211, + "wall_monotonic_offset_range_s": 0.00023651123046875 + }, + { + "delay_finished_wall": 1791832082.7192068, + "delay_started_wall": 1791832081.518623, + "genuine_upstream_elapsed_s": 0.04676191695034504, + "injected_elapsed_s": 1.2005837499164045, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2005836963653564 + } + ], + "path": "/state", + "sequence": 213, + "wall_monotonic_offset_range_s": 0.0003616809844970703 + }, + { + "delay_finished_wall": 1791832084.339633, + "delay_started_wall": 1791832083.1349635, + "genuine_upstream_elapsed_s": 0.04107379191555083, + "injected_elapsed_s": 1.2046695840544999, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.20466947555542 + } + ], + "path": "/state", + "sequence": 215, + "wall_monotonic_offset_range_s": 0.0002899169921875 + }, + { + "delay_finished_wall": 1791832085.960802, + "delay_started_wall": 1791832084.7594473, + "genuine_upstream_elapsed_s": 0.04071483411826193, + "injected_elapsed_s": 1.2013546251691878, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.201354742050171 + } + ], + "path": "/state", + "sequence": 217, + "wall_monotonic_offset_range_s": 0.00032806396484375 + }, + { + "delay_finished_wall": 1791832087.585452, + "delay_started_wall": 1791832086.384062, + "genuine_upstream_elapsed_s": 0.041966750053688884, + "injected_elapsed_s": 1.2013900419697165, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.9910397529602051 + } + ], + "path": "/state", + "sequence": 219, + "wall_monotonic_offset_range_s": 0.00026154518127441406 + }, + { + "delay_finished_wall": 1791832090.22193, + "delay_started_wall": 1791832089.0204175, + "genuine_upstream_elapsed_s": 0.04945133300498128, + "injected_elapsed_s": 1.2015124999452382, + "model_overlaps": [ + { + "call": 9, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2015125751495361 + } + ], + "path": "/state", + "sequence": 234, + "wall_monotonic_offset_range_s": 0.0002675056457519531 + }, + { + "delay_finished_wall": 1791832091.845014, + "delay_started_wall": 1791832090.6439574, + "genuine_upstream_elapsed_s": 0.04513141606003046, + "injected_elapsed_s": 1.2010567500256002, + "model_overlaps": [ + { + "call": 9, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.201056718826294 + } + ], + "path": "/state", + "sequence": 236, + "wall_monotonic_offset_range_s": 0.0003001689910888672 + }, + { + "delay_finished_wall": 1791832093.470641, + "delay_started_wall": 1791832092.269904, + "genuine_upstream_elapsed_s": 0.046239792136475444, + "injected_elapsed_s": 1.2007370002102107, + "model_overlaps": [ + { + "call": 9, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2007369995117188 + } + ], + "path": "/state", + "sequence": 238, + "wall_monotonic_offset_range_s": 0.0003094673156738281 + }, + { + "delay_finished_wall": 1791832095.102564, + "delay_started_wall": 1791832093.902203, + "genuine_upstream_elapsed_s": 0.05429583298973739, + "injected_elapsed_s": 1.2003611251711845, + "model_overlaps": [ + { + "call": 9, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2003610134124756 + } + ], + "path": "/state", + "sequence": 240, + "wall_monotonic_offset_range_s": 0.0003120899200439453 + }, + { + "delay_finished_wall": 1791832096.736833, + "delay_started_wall": 1791832095.5317907, + "genuine_upstream_elapsed_s": 0.04574579210020602, + "injected_elapsed_s": 1.20504245813936, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.24535512924194336 + } + ], + "path": "/state", + "sequence": 242, + "wall_monotonic_offset_range_s": 0.004605531692504883 + }, + { + "delay_finished_wall": 1791832098.352134, + "delay_started_wall": 1791832097.1493397, + "genuine_upstream_elapsed_s": 0.04627279192209244, + "injected_elapsed_s": 1.202794292010367, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2027943134307861 + } + ], + "path": "/state", + "sequence": 257, + "wall_monotonic_offset_range_s": 0.0003185272216796875 + }, + { + "delay_finished_wall": 1791832099.991491, + "delay_started_wall": 1791832098.7868052, + "genuine_upstream_elapsed_s": 0.04723550006747246, + "injected_elapsed_s": 1.2046860409900546, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.204685926437378 + } + ], + "path": "/state", + "sequence": 259, + "wall_monotonic_offset_range_s": 0.000301361083984375 + }, + { + "delay_finished_wall": 1791832101.614825, + "delay_started_wall": 1791832100.4146428, + "genuine_upstream_elapsed_s": 0.047370166052132845, + "injected_elapsed_s": 1.2001820839941502, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2001821994781494 + } + ], + "path": "/state", + "sequence": 261, + "wall_monotonic_offset_range_s": 0.0003604888916015625 + }, + { + "delay_finished_wall": 1791832103.239155, + "delay_started_wall": 1791832102.0341103, + "genuine_upstream_elapsed_s": 0.04227699991315603, + "injected_elapsed_s": 1.2050447911024094, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050447463989258 + } + ], + "path": "/state", + "sequence": 263, + "wall_monotonic_offset_range_s": 0.0004055500030517578 + }, + { + "delay_finished_wall": 1791832104.877825, + "delay_started_wall": 1791832103.6765485, + "genuine_upstream_elapsed_s": 0.056063625030219555, + "injected_elapsed_s": 1.2012766250409186, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.19235777854919434 + }, + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.09160304069519043 + } + ], + "path": "/state", + "sequence": 265, + "wall_monotonic_offset_range_s": 0.0004611015319824219 + }, + { + "delay_finished_wall": 1791832106.4973052, + "delay_started_wall": 1791832105.292261, + "genuine_upstream_elapsed_s": 0.046128083020448685, + "injected_elapsed_s": 1.2050441671162844, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050442695617676 + } + ], + "path": "/state", + "sequence": 280, + "wall_monotonic_offset_range_s": 0.0004367828369140625 + }, + { + "delay_finished_wall": 1791832108.148909, + "delay_started_wall": 1791832106.9444427, + "genuine_upstream_elapsed_s": 0.0588835421949625, + "injected_elapsed_s": 1.2044663750566542, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2044663429260254 + } + ], + "path": "/state", + "sequence": 282, + "wall_monotonic_offset_range_s": 0.0002453327178955078 + }, + { + "delay_finished_wall": 1791832109.773719, + "delay_started_wall": 1791832108.572417, + "genuine_upstream_elapsed_s": 0.050575749948620796, + "injected_elapsed_s": 1.2013020410668105, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2013020515441895 + } + ], + "path": "/state", + "sequence": 284, + "wall_monotonic_offset_range_s": 0.00033092498779296875 + }, + { + "delay_finished_wall": 1791832111.400123, + "delay_started_wall": 1791832110.1959536, + "genuine_upstream_elapsed_s": 0.046160792000591755, + "injected_elapsed_s": 1.204169207951054, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2041692733764648 + } + ], + "path": "/state", + "sequence": 286, + "wall_monotonic_offset_range_s": 0.0002598762512207031 + }, + { + "delay_finished_wall": 1791832113.030656, + "delay_started_wall": 1791832111.8256311, + "genuine_upstream_elapsed_s": 0.044818750116974115, + "injected_elapsed_s": 1.205024957889691, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.0970909595489502 + } + ], + "path": "/state", + "sequence": 288, + "wall_monotonic_offset_range_s": 0.0003409385681152344 + }, + { + "delay_finished_wall": 1791832115.661109, + "delay_started_wall": 1791832114.4575708, + "genuine_upstream_elapsed_s": 0.04853254184126854, + "injected_elapsed_s": 1.203538167057559, + "model_overlaps": [ + { + "call": 12, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.203538179397583 + } + ], + "path": "/state", + "sequence": 303, + "wall_monotonic_offset_range_s": 0.0002593994140625 + }, + { + "delay_finished_wall": 1791832117.282847, + "delay_started_wall": 1791832116.0813665, + "genuine_upstream_elapsed_s": 0.04559245798736811, + "injected_elapsed_s": 1.2014803329948336, + "model_overlaps": [ + { + "call": 12, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2014803886413574 + } + ], + "path": "/state", + "sequence": 305, + "wall_monotonic_offset_range_s": 0.00033092498779296875 + }, + { + "delay_finished_wall": 1791832118.914329, + "delay_started_wall": 1791832117.7099512, + "genuine_upstream_elapsed_s": 0.048586250049993396, + "injected_elapsed_s": 1.2043779590167105, + "model_overlaps": [ + { + "call": 12, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2043778896331787 + } + ], + "path": "/state", + "sequence": 307, + "wall_monotonic_offset_range_s": 0.0003142356872558594 + }, + { + "delay_finished_wall": 1791832120.540607, + "delay_started_wall": 1791832119.338083, + "genuine_upstream_elapsed_s": 0.04915620805695653, + "injected_elapsed_s": 1.2025240000803024, + "model_overlaps": [ + { + "call": 12, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.202523946762085 + } + ], + "path": "/state", + "sequence": 309, + "wall_monotonic_offset_range_s": 0.0002961158752441406 + }, + { + "delay_finished_wall": 1791832123.173666, + "delay_started_wall": 1791832121.9724607, + "genuine_upstream_elapsed_s": 0.05501812510192394, + "injected_elapsed_s": 1.2012051669880748, + "model_overlaps": [ + { + "call": 13, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2012052536010742 + } + ], + "path": "/state", + "sequence": 324, + "wall_monotonic_offset_range_s": 0.0004284381866455078 + }, + { + "delay_finished_wall": 1791832124.797261, + "delay_started_wall": 1791832123.5969458, + "genuine_upstream_elapsed_s": 0.05386095796711743, + "injected_elapsed_s": 1.20031529199332, + "model_overlaps": [ + { + "call": 13, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.200315237045288 + } + ], + "path": "/state", + "sequence": 326, + "wall_monotonic_offset_range_s": 0.0003066062927246094 + }, + { + "delay_finished_wall": 1791832126.434151, + "delay_started_wall": 1791832125.228527, + "genuine_upstream_elapsed_s": 0.05417429096996784, + "injected_elapsed_s": 1.2056237920187414, + "model_overlaps": [ + { + "call": 13, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2056238651275635 + } + ], + "path": "/state", + "sequence": 328, + "wall_monotonic_offset_range_s": 0.0003712177276611328 + }, + { + "delay_finished_wall": 1791832128.0681322, + "delay_started_wall": 1791832126.8663008, + "genuine_upstream_elapsed_s": 0.059533082880079746, + "injected_elapsed_s": 1.2018312909640372, + "model_overlaps": [ + { + "call": 13, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.201831340789795 + } + ], + "path": "/state", + "sequence": 330, + "wall_monotonic_offset_range_s": 0.0003476142883300781 + }, + { + "delay_finished_wall": 1791832130.698807, + "delay_started_wall": 1791832129.4979184, + "genuine_upstream_elapsed_s": 0.05425262497738004, + "injected_elapsed_s": 1.2008886248804629, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2008886337280273 + } + ], + "path": "/state", + "sequence": 345, + "wall_monotonic_offset_range_s": 0.000308990478515625 + }, + { + "delay_finished_wall": 1791832132.343055, + "delay_started_wall": 1791832131.1425955, + "genuine_upstream_elapsed_s": 0.07181812496855855, + "injected_elapsed_s": 1.2004595410544425, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2004594802856445 + } + ], + "path": "/state", + "sequence": 347, + "wall_monotonic_offset_range_s": 0.0002918243408203125 + }, + { + "delay_finished_wall": 1791832133.955904, + "delay_started_wall": 1791832132.7540894, + "genuine_upstream_elapsed_s": 0.052502250066027045, + "injected_elapsed_s": 1.2018145839683712, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2018146514892578 + } + ], + "path": "/state", + "sequence": 349, + "wall_monotonic_offset_range_s": 0.0005249977111816406 + }, + { + "delay_finished_wall": 1791832135.582197, + "delay_started_wall": 1791832134.3774855, + "genuine_upstream_elapsed_s": 0.04988845787011087, + "injected_elapsed_s": 1.2047113340813667, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2047114372253418 + } + ], + "path": "/state", + "sequence": 351, + "wall_monotonic_offset_range_s": 0.0002865791320800781 + }, + { + "delay_finished_wall": 1791832137.22383, + "delay_started_wall": 1791832136.022428, + "genuine_upstream_elapsed_s": 0.06868283404037356, + "injected_elapsed_s": 1.2014020418282598, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.35050058364868164 + } + ], + "path": "/state", + "sequence": 353, + "wall_monotonic_offset_range_s": 0.0003383159637451172 + }, + { + "delay_finished_wall": 1791832138.840893, + "delay_started_wall": 1791832137.6358533, + "genuine_upstream_elapsed_s": 0.05692441714927554, + "injected_elapsed_s": 1.2050397919956595, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2050397396087646 + } + ], + "path": "/state", + "sequence": 373, + "wall_monotonic_offset_range_s": 0.00036334991455078125 + }, + { + "delay_finished_wall": 1791832140.523594, + "delay_started_wall": 1791832139.3210244, + "genuine_upstream_elapsed_s": 0.08095504203811288, + "injected_elapsed_s": 1.2025694160256535, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2025694847106934 + } + ], + "path": "/state", + "sequence": 375, + "wall_monotonic_offset_range_s": 0.0003018379211425781 + }, + { + "delay_finished_wall": 1791832142.144813, + "delay_started_wall": 1791832140.9398186, + "genuine_upstream_elapsed_s": 0.06230750004760921, + "injected_elapsed_s": 1.2049943341407925, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2049944400787354 + } + ], + "path": "/state", + "sequence": 377, + "wall_monotonic_offset_range_s": 0.00025177001953125 + }, + { + "delay_finished_wall": 1791832143.774648, + "delay_started_wall": 1791832142.5730557, + "genuine_upstream_elapsed_s": 0.05781725002452731, + "injected_elapsed_s": 1.2015922078862786, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.201592206954956 + } + ], + "path": "/state", + "sequence": 379, + "wall_monotonic_offset_range_s": 0.0005812644958496094 + }, + { + "delay_finished_wall": 1791832145.40432, + "delay_started_wall": 1791832144.1992726, + "genuine_upstream_elapsed_s": 0.05713516683317721, + "injected_elapsed_s": 1.2050473750568926, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.205047369003296 + } + ], + "path": "/state", + "sequence": 381, + "wall_monotonic_offset_range_s": 0.0003993511199951172 + }, + { + "delay_finished_wall": 1791832147.056463, + "delay_started_wall": 1791832145.8514771, + "genuine_upstream_elapsed_s": 0.07064691698178649, + "injected_elapsed_s": 1.2049859159160405, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.6222236156463623 + } + ], + "path": "/state", + "sequence": 383, + "wall_monotonic_offset_range_s": 0.0005612373352050781 + }, + { + "delay_finished_wall": 1791832149.664667, + "delay_started_wall": 1791832148.461329, + "genuine_upstream_elapsed_s": 0.05194795900024474, + "injected_elapsed_s": 1.2033379168715328, + "model_overlaps": [ + { + "call": 2, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2033379077911377 + } + ], + "path": "/state", + "sequence": 398, + "wall_monotonic_offset_range_s": 0.0003561973571777344 + }, + { + "delay_finished_wall": 1791832151.294802, + "delay_started_wall": 1791832150.0908835, + "genuine_upstream_elapsed_s": 0.052277165930718184, + "injected_elapsed_s": 1.2039184591267258, + "model_overlaps": [ + { + "call": 2, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20391845703125 + } + ], + "path": "/state", + "sequence": 400, + "wall_monotonic_offset_range_s": 0.00032806396484375 + }, + { + "delay_finished_wall": 1791832152.944254, + "delay_started_wall": 1791832151.7392159, + "genuine_upstream_elapsed_s": 0.07039116695523262, + "injected_elapsed_s": 1.2050380420405418, + "model_overlaps": [ + { + "call": 2, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.205038070678711 + } + ], + "path": "/state", + "sequence": 402, + "wall_monotonic_offset_range_s": 0.0005617141723632812 + }, + { + "delay_finished_wall": 1791832154.562625, + "delay_started_wall": 1791832153.3620024, + "genuine_upstream_elapsed_s": 0.060910666128620505, + "injected_elapsed_s": 1.2006225001532584, + "model_overlaps": [ + { + "call": 2, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20062255859375 + } + ], + "path": "/state", + "sequence": 404, + "wall_monotonic_offset_range_s": 0.0006086826324462891 + }, + { + "delay_finished_wall": 1791832157.187784, + "delay_started_wall": 1791832155.9839876, + "genuine_upstream_elapsed_s": 0.054760915925726295, + "injected_elapsed_s": 1.2037962921895087, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20379638671875 + } + ], + "path": "/state", + "sequence": 419, + "wall_monotonic_offset_range_s": 0.002040386199951172 + }, + { + "delay_finished_wall": 1791832158.8312519, + "delay_started_wall": 1791832157.6299183, + "genuine_upstream_elapsed_s": 0.06451662513427436, + "injected_elapsed_s": 1.2013334999792278, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2013335227966309 + } + ], + "path": "/state", + "sequence": 421, + "wall_monotonic_offset_range_s": 0.0003459453582763672 + }, + { + "delay_finished_wall": 1791832160.4510279, + "delay_started_wall": 1791832159.2491255, + "genuine_upstream_elapsed_s": 0.05649487487971783, + "injected_elapsed_s": 1.2019024998880923, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2019023895263672 + } + ], + "path": "/state", + "sequence": 423, + "wall_monotonic_offset_range_s": 0.0005939006805419922 + }, + { + "delay_finished_wall": 1791832162.102963, + "delay_started_wall": 1791832160.9011786, + "genuine_upstream_elapsed_s": 0.06587324989959598, + "injected_elapsed_s": 1.2017843751236796, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.201784372329712 + } + ], + "path": "/state", + "sequence": 425, + "wall_monotonic_offset_range_s": 0.0006198883056640625 + }, + { + "delay_finished_wall": 1791832163.716691, + "delay_started_wall": 1791832162.5151398, + "genuine_upstream_elapsed_s": 0.05449808295816183, + "injected_elapsed_s": 1.2015511670615524, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2015511989593506 + } + ], + "path": "/state", + "sequence": 427, + "wall_monotonic_offset_range_s": 0.0002949237823486328 + }, + { + "delay_finished_wall": 1791832165.361527, + "delay_started_wall": 1791832164.1579523, + "genuine_upstream_elapsed_s": 0.07102287514135242, + "injected_elapsed_s": 1.203574666986242, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.15041804313659668 + } + ], + "path": "/state", + "sequence": 429, + "wall_monotonic_offset_range_s": 0.0006797313690185547 + }, + { + "delay_finished_wall": 1791832168.0370932, + "delay_started_wall": 1791832166.8349886, + "genuine_upstream_elapsed_s": 0.09905841713771224, + "injected_elapsed_s": 1.2021046250592917, + "model_overlaps": [ + { + "call": 4, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2021045684814453 + } + ], + "path": "/state", + "sequence": 445, + "wall_monotonic_offset_range_s": 0.0002818107604980469 + }, + { + "delay_finished_wall": 1791832169.681438, + "delay_started_wall": 1791832168.4777927, + "genuine_upstream_elapsed_s": 0.09563441714271903, + "injected_elapsed_s": 1.203645166940987, + "model_overlaps": [ + { + "call": 4, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2036452293395996 + } + ], + "path": "/state", + "sequence": 447, + "wall_monotonic_offset_range_s": 0.0003516674041748047 + }, + { + "delay_finished_wall": 1791832171.319584, + "delay_started_wall": 1791832170.1186836, + "genuine_upstream_elapsed_s": 0.09399583307094872, + "injected_elapsed_s": 1.2009002920240164, + "model_overlaps": [ + { + "call": 4, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2009003162384033 + } + ], + "path": "/state", + "sequence": 449, + "wall_monotonic_offset_range_s": 0.0005812644958496094 + }, + { + "delay_finished_wall": 1791832172.953556, + "delay_started_wall": 1791832171.753168, + "genuine_upstream_elapsed_s": 0.08927262504585087, + "injected_elapsed_s": 1.200387875083834, + "model_overlaps": [ + { + "call": 4, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.32279539108276367 + } + ], + "path": "/state", + "sequence": 451, + "wall_monotonic_offset_range_s": 0.0003695487976074219 + }, + { + "delay_finished_wall": 1791832175.5946329, + "delay_started_wall": 1791832174.3903122, + "genuine_upstream_elapsed_s": 0.08938425011001527, + "injected_elapsed_s": 1.2043205830268562, + "model_overlaps": [ + { + "call": 5, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2043206691741943 + } + ], + "path": "/state", + "sequence": 466, + "wall_monotonic_offset_range_s": 0.00030350685119628906 + }, + { + "delay_finished_wall": 1791832177.2314198, + "delay_started_wall": 1791832176.030892, + "genuine_upstream_elapsed_s": 0.08454362489283085, + "injected_elapsed_s": 1.2005280000157654, + "model_overlaps": [ + { + "call": 5, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2005279064178467 + } + ], + "path": "/state", + "sequence": 468, + "wall_monotonic_offset_range_s": 0.0006012916564941406 + }, + { + "delay_finished_wall": 1791832178.8902102, + "delay_started_wall": 1791832177.6890914, + "genuine_upstream_elapsed_s": 0.10279183299280703, + "injected_elapsed_s": 1.2011187500320375, + "model_overlaps": [ + { + "call": 5, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2011187076568604 + } + ], + "path": "/state", + "sequence": 470, + "wall_monotonic_offset_range_s": 0.0003154277801513672 + }, + { + "delay_finished_wall": 1791832180.523807, + "delay_started_wall": 1791832179.3190742, + "genuine_upstream_elapsed_s": 0.09166183299385011, + "injected_elapsed_s": 1.2047327919863164, + "model_overlaps": [ + { + "call": 5, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.204732894897461 + } + ], + "path": "/state", + "sequence": 472, + "wall_monotonic_offset_range_s": 0.0003097057342529297 + }, + { + "delay_finished_wall": 1791832182.173342, + "delay_started_wall": 1791832180.9683156, + "genuine_upstream_elapsed_s": 0.09823537501506507, + "injected_elapsed_s": 1.205026458017528, + "model_overlaps": [], + "path": "/state", + "sequence": 474, + "wall_monotonic_offset_range_s": 0.0003254413604736328 + }, + { + "delay_finished_wall": 1791832184.845115, + "delay_started_wall": 1791832183.6415613, + "genuine_upstream_elapsed_s": 0.1093828750308603, + "injected_elapsed_s": 1.2035536249168217, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2035536766052246 + } + ], + "path": "/state", + "sequence": 489, + "wall_monotonic_offset_range_s": 0.0005691051483154297 + }, + { + "delay_finished_wall": 1791832186.476904, + "delay_started_wall": 1791832185.2725573, + "genuine_upstream_elapsed_s": 0.09748349990695715, + "injected_elapsed_s": 1.204346542013809, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2043466567993164 + } + ], + "path": "/state", + "sequence": 491, + "wall_monotonic_offset_range_s": 0.00036978721618652344 + }, + { + "delay_finished_wall": 1791832188.116647, + "delay_started_wall": 1791832186.9127026, + "genuine_upstream_elapsed_s": 0.09679954196326435, + "injected_elapsed_s": 1.2039444581605494, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.203944444656372 + } + ], + "path": "/state", + "sequence": 493, + "wall_monotonic_offset_range_s": 0.0013127326965332031 + }, + { + "delay_finished_wall": 1791832189.75743, + "delay_started_wall": 1791832188.5523894, + "genuine_upstream_elapsed_s": 0.0957978330552578, + "injected_elapsed_s": 1.205040582921356, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.205040693283081 + } + ], + "path": "/state", + "sequence": 495, + "wall_monotonic_offset_range_s": 0.0003192424774169922 + }, + { + "delay_finished_wall": 1791832191.387458, + "delay_started_wall": 1791832190.1836927, + "genuine_upstream_elapsed_s": 0.08754870807752013, + "injected_elapsed_s": 1.2037652910221368, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2037653923034668 + } + ], + "path": "/state", + "sequence": 497, + "wall_monotonic_offset_range_s": 0.00024628639221191406 + }, + { + "delay_finished_wall": 1791832195.1446521, + "delay_started_wall": 1791832193.9439216, + "genuine_upstream_elapsed_s": 0.19697441696189344, + "injected_elapsed_s": 1.2007305829320103, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.200730562210083 + } + ], + "path": "/state", + "sequence": 512, + "wall_monotonic_offset_range_s": 0.00048828125 + }, + { + "delay_finished_wall": 1791832196.679007, + "delay_started_wall": 1791832195.4773612, + "genuine_upstream_elapsed_s": 0.09738016710616648, + "injected_elapsed_s": 1.2016459580045193, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.201645851135254 + } + ], + "path": "/state", + "sequence": 514, + "wall_monotonic_offset_range_s": 0.000316619873046875 + }, + { + "delay_finished_wall": 1791832198.432412, + "delay_started_wall": 1791832197.22811, + "genuine_upstream_elapsed_s": 0.1660980840679258, + "injected_elapsed_s": 1.2043019169941545, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2043018341064453 + } + ], + "path": "/state", + "sequence": 516, + "wall_monotonic_offset_range_s": 0.0003120899200439453 + }, + { + "delay_finished_wall": 1791832200.023287, + "delay_started_wall": 1791832198.821372, + "genuine_upstream_elapsed_s": 0.10865400009788573, + "injected_elapsed_s": 1.2019149158149958, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2019150257110596 + } + ], + "path": "/state", + "sequence": 518, + "wall_monotonic_offset_range_s": 0.0007584095001220703 + }, + { + "delay_finished_wall": 1791832201.67074, + "delay_started_wall": 1791832200.4670024, + "genuine_upstream_elapsed_s": 0.11654558405280113, + "injected_elapsed_s": 1.2037374170031399, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.0191373825073242 + } + ], + "path": "/state", + "sequence": 520, + "wall_monotonic_offset_range_s": 0.00032782554626464844 + }, + { + "delay_finished_wall": 1791832204.3241541, + "delay_started_wall": 1791832203.1212535, + "genuine_upstream_elapsed_s": 0.11968966713175178, + "injected_elapsed_s": 1.2029006250668317, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2029006481170654 + } + ], + "path": "/state", + "sequence": 535, + "wall_monotonic_offset_range_s": 0.0002541542053222656 + }, + { + "delay_finished_wall": 1791832205.943559, + "delay_started_wall": 1791832204.7405307, + "genuine_upstream_elapsed_s": 0.09816970909014344, + "injected_elapsed_s": 1.203028209041804, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2030282020568848 + } + ], + "path": "/state", + "sequence": 537, + "wall_monotonic_offset_range_s": 0.0002627372741699219 + }, + { + "delay_finished_wall": 1791832207.5819252, + "delay_started_wall": 1791832206.377185, + "genuine_upstream_elapsed_s": 0.09490183321759105, + "injected_elapsed_s": 1.2047400001902133, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.204740047454834 + } + ], + "path": "/state", + "sequence": 539, + "wall_monotonic_offset_range_s": 0.0003991127014160156 + }, + { + "delay_finished_wall": 1791832209.210984, + "delay_started_wall": 1791832208.0081983, + "genuine_upstream_elapsed_s": 0.08556483290158212, + "injected_elapsed_s": 1.2027858330402523, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2027857303619385 + } + ], + "path": "/state", + "sequence": 541, + "wall_monotonic_offset_range_s": 0.0003407001495361328 + }, + { + "delay_finished_wall": 1791832210.8634849, + "delay_started_wall": 1791832209.658373, + "genuine_upstream_elapsed_s": 0.09433629107661545, + "injected_elapsed_s": 1.2051117080263793, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2051117420196533 + } + ], + "path": "/state", + "sequence": 543, + "wall_monotonic_offset_range_s": 0.0002968311309814453 + }, + { + "delay_finished_wall": 1791832212.57867, + "delay_started_wall": 1791832211.3756423, + "genuine_upstream_elapsed_s": 0.1304359589703381, + "injected_elapsed_s": 1.2030276670120656, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2030277252197266 + } + ], + "path": "/state", + "sequence": 545, + "wall_monotonic_offset_range_s": 0.0003571510314941406 + }, + { + "delay_finished_wall": 1791832214.220621, + "delay_started_wall": 1791832213.0155869, + "genuine_upstream_elapsed_s": 0.1333520410116762, + "injected_elapsed_s": 1.205034333979711, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.3882322311401367 + } + ], + "path": "/state", + "sequence": 547, + "wall_monotonic_offset_range_s": 0.00029397010803222656 + }, + { + "delay_finished_wall": 1791832216.812608, + "delay_started_wall": 1791832215.61119, + "genuine_upstream_elapsed_s": 0.08992187515832484, + "injected_elapsed_s": 1.2014179578982294, + "model_overlaps": [ + { + "call": 9, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2014179229736328 + } + ], + "path": "/state", + "sequence": 562, + "wall_monotonic_offset_range_s": 0.0003185272216796875 + }, + { + "delay_finished_wall": 1791832218.466902, + "delay_started_wall": 1791832217.2640164, + "genuine_upstream_elapsed_s": 0.10495808301493526, + "injected_elapsed_s": 1.2028855830430984, + "model_overlaps": [ + { + "call": 9, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.202885627746582 + } + ], + "path": "/state", + "sequence": 564, + "wall_monotonic_offset_range_s": 0.0003886222839355469 + }, + { + "delay_finished_wall": 1791832220.111368, + "delay_started_wall": 1791832218.9085712, + "genuine_upstream_elapsed_s": 0.10092691704630852, + "injected_elapsed_s": 1.2027965830639005, + "model_overlaps": [ + { + "call": 9, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2027966976165771 + } + ], + "path": "/state", + "sequence": 566, + "wall_monotonic_offset_range_s": 0.0003330707550048828 + }, + { + "delay_finished_wall": 1791832221.7597818, + "delay_started_wall": 1791832220.5593228, + "genuine_upstream_elapsed_s": 0.10268970811739564, + "injected_elapsed_s": 1.2004589578136802, + "model_overlaps": [ + { + "call": 9, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2004590034484863 + } + ], + "path": "/state", + "sequence": 568, + "wall_monotonic_offset_range_s": 0.0002837181091308594 + }, + { + "delay_finished_wall": 1791832225.4402492, + "delay_started_wall": 1791832224.2368987, + "genuine_upstream_elapsed_s": 0.12126195780001581, + "injected_elapsed_s": 1.2033504580613226, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20335054397583 + } + ], + "path": "/state", + "sequence": 583, + "wall_monotonic_offset_range_s": 0.0022809505462646484 + }, + { + "delay_finished_wall": 1791832227.076514, + "delay_started_wall": 1791832225.872466, + "genuine_upstream_elapsed_s": 0.12050370895303786, + "injected_elapsed_s": 1.2040479579009116, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2040479183197021 + } + ], + "path": "/state", + "sequence": 585, + "wall_monotonic_offset_range_s": 0.0003409385681152344 + }, + { + "delay_finished_wall": 1791832228.698619, + "delay_started_wall": 1791832227.4964974, + "genuine_upstream_elapsed_s": 0.09993179212324321, + "injected_elapsed_s": 1.2021215830463916, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2021214962005615 + } + ], + "path": "/state", + "sequence": 587, + "wall_monotonic_offset_range_s": 0.0005545616149902344 + }, + { + "delay_finished_wall": 1791832230.342627, + "delay_started_wall": 1791832229.1391137, + "genuine_upstream_elapsed_s": 0.1068087921012193, + "injected_elapsed_s": 1.2035132918972522, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2035133838653564 + } + ], + "path": "/state", + "sequence": 589, + "wall_monotonic_offset_range_s": 0.00033020973205566406 + }, + { + "delay_finished_wall": 1791832232.0394418, + "delay_started_wall": 1791832230.8349648, + "genuine_upstream_elapsed_s": 0.09745725011453032, + "injected_elapsed_s": 1.2044771250803024, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.204477071762085 + } + ], + "path": "/state", + "sequence": 591, + "wall_monotonic_offset_range_s": 0.00030493736267089844 + }, + { + "delay_finished_wall": 1791832233.691145, + "delay_started_wall": 1791832232.4860492, + "genuine_upstream_elapsed_s": 0.11080433311872184, + "injected_elapsed_s": 1.2050957919564098, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.1795988082885742 + } + ], + "path": "/state", + "sequence": 593, + "wall_monotonic_offset_range_s": 0.0002911090850830078 + }, + { + "delay_finished_wall": 1791832245.443464, + "delay_started_wall": 1791832244.2379303, + "genuine_upstream_elapsed_s": 0.12208491703495383, + "injected_elapsed_s": 1.2055337911006063, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.205533742904663 + } + ], + "path": "/state", + "sequence": 608, + "wall_monotonic_offset_range_s": 0.0003032684326171875 + }, + { + "delay_finished_wall": 1791832247.1843069, + "delay_started_wall": 1791832245.9779978, + "genuine_upstream_elapsed_s": 0.19989608298055828, + "injected_elapsed_s": 1.20630900003016, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2063090801239014 + } + ], + "path": "/state", + "sequence": 610, + "wall_monotonic_offset_range_s": 0.0006725788116455078 + }, + { + "delay_finished_wall": 1791832248.728961, + "delay_started_wall": 1791832247.5280106, + "genuine_upstream_elapsed_s": 0.10658545885235071, + "injected_elapsed_s": 1.2009502919390798, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2009503841400146 + } + ], + "path": "/state", + "sequence": 612, + "wall_monotonic_offset_range_s": 0.00034689903259277344 + }, + { + "delay_finished_wall": 1791832250.64911, + "delay_started_wall": 1791832249.445706, + "genuine_upstream_elapsed_s": 0.274660708848387, + "injected_elapsed_s": 1.2034040831495076, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.203404188156128 + } + ], + "path": "/state", + "sequence": 614, + "wall_monotonic_offset_range_s": 0.0013229846954345703 + }, + { + "delay_finished_wall": 1791832252.131116, + "delay_started_wall": 1791832250.9289129, + "genuine_upstream_elapsed_s": 0.11848937487229705, + "injected_elapsed_s": 1.202203124994412, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2022030353546143 + } + ], + "path": "/state", + "sequence": 616, + "wall_monotonic_offset_range_s": 0.00039649009704589844 + }, + { + "delay_finished_wall": 1791832255.648841, + "delay_started_wall": 1791832254.4483225, + "genuine_upstream_elapsed_s": 0.024830207927152514, + "injected_elapsed_s": 1.200518290977925, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2005183696746826 + } + ], + "path": "/identity", + "sequence": 630, + "wall_monotonic_offset_range_s": 0.00040221214294433594 + }, + { + "delay_finished_wall": 1791832257.266772, + "delay_started_wall": 1791832256.064008, + "genuine_upstream_elapsed_s": 0.029722166946157813, + "injected_elapsed_s": 1.2027640838641673, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2027640342712402 + } + ], + "path": "/identity", + "sequence": 631, + "wall_monotonic_offset_range_s": 0.00035691261291503906 + }, + { + "delay_finished_wall": 1791832258.873054, + "delay_started_wall": 1791832257.672685, + "genuine_upstream_elapsed_s": 0.03023020806722343, + "injected_elapsed_s": 1.2003691669087857, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.200369119644165 + } + ], + "path": "/identity", + "sequence": 632, + "wall_monotonic_offset_range_s": 0.0008234977722167969 + }, + { + "delay_finished_wall": 1791832260.484274, + "delay_started_wall": 1791832259.279202, + "genuine_upstream_elapsed_s": 0.029689125018194318, + "injected_elapsed_s": 1.2050719999242574, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2050719261169434 + } + ], + "path": "/identity", + "sequence": 633, + "wall_monotonic_offset_range_s": 0.0003199577331542969 + }, + { + "delay_finished_wall": 1791832262.09807, + "delay_started_wall": 1791832260.895133, + "genuine_upstream_elapsed_s": 0.03271045791916549, + "injected_elapsed_s": 1.2029367920476943, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.6850109100341797 + } + ], + "path": "/identity", + "sequence": 634, + "wall_monotonic_offset_range_s": 0.00032401084899902344 + }, + { + "delay_finished_wall": 1791832264.7211719, + "delay_started_wall": 1791832263.5168095, + "genuine_upstream_elapsed_s": 0.0447540411259979, + "injected_elapsed_s": 1.2043624999932945, + "model_overlaps": [ + { + "call": 13, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.204362392425537 + } + ], + "path": "/identity", + "sequence": 648, + "wall_monotonic_offset_range_s": 0.0003616809844970703 + }, + { + "delay_finished_wall": 1791832266.3139899, + "delay_started_wall": 1791832265.1089513, + "genuine_upstream_elapsed_s": 0.028605000115931034, + "injected_elapsed_s": 1.2050385000184178, + "model_overlaps": [ + { + "call": 13, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2050385475158691 + } + ], + "path": "/identity", + "sequence": 649, + "wall_monotonic_offset_range_s": 0.0003781318664550781 + }, + { + "delay_finished_wall": 1791832267.919033, + "delay_started_wall": 1791832266.7139947, + "genuine_upstream_elapsed_s": 0.02525570895522833, + "injected_elapsed_s": 1.2050382499583066, + "model_overlaps": [ + { + "call": 13, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20503830909729 + } + ], + "path": "/identity", + "sequence": 650, + "wall_monotonic_offset_range_s": 0.00035643577575683594 + }, + { + "delay_finished_wall": 1791832269.526366, + "delay_started_wall": 1791832268.3221338, + "genuine_upstream_elapsed_s": 0.023437874857336283, + "injected_elapsed_s": 1.2042323329951614, + "model_overlaps": [ + { + "call": 13, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2042322158813477 + } + ], + "path": "/identity", + "sequence": 651, + "wall_monotonic_offset_range_s": 0.0003230571746826172 + }, + { + "delay_finished_wall": 1791832273.146421, + "delay_started_wall": 1791832271.9417524, + "genuine_upstream_elapsed_s": 0.026460542110726237, + "injected_elapsed_s": 1.2046686250250787, + "model_overlaps": [], + "path": "/identity", + "sequence": 661, + "wall_monotonic_offset_range_s": 0.0002894401550292969 + }, + { + "delay_finished_wall": 1791832274.7546492, + "delay_started_wall": 1791832273.5496144, + "genuine_upstream_elapsed_s": 0.02605204191058874, + "injected_elapsed_s": 1.2050346250180155, + "model_overlaps": [], + "path": "/identity", + "sequence": 662, + "wall_monotonic_offset_range_s": 0.00043654441833496094 + }, + { + "delay_finished_wall": 1791832276.3647099, + "delay_started_wall": 1791832275.159664, + "genuine_upstream_elapsed_s": 0.024871707893908024, + "injected_elapsed_s": 1.2050458330195397, + "model_overlaps": [], + "path": "/identity", + "sequence": 663, + "wall_monotonic_offset_range_s": 0.0003113746643066406 + }, + { + "delay_finished_wall": 1791832277.976248, + "delay_started_wall": 1791832276.7734878, + "genuine_upstream_elapsed_s": 0.027691290946677327, + "injected_elapsed_s": 1.2027602919843048, + "model_overlaps": [], + "path": "/identity", + "sequence": 664, + "wall_monotonic_offset_range_s": 0.00038623809814453125 + }, + { + "delay_finished_wall": 1791832279.578651, + "delay_started_wall": 1791832278.3785973, + "genuine_upstream_elapsed_s": 0.024854457937180996, + "injected_elapsed_s": 1.2000537081621587, + "model_overlaps": [], + "path": "/identity", + "sequence": 665, + "wall_monotonic_offset_range_s": 0.00032401084899902344 + }, + { + "delay_finished_wall": 1791832281.194527, + "delay_started_wall": 1791832279.9924984, + "genuine_upstream_elapsed_s": 0.027741792146116495, + "injected_elapsed_s": 1.2020284999161959, + "model_overlaps": [], + "path": "/identity", + "sequence": 666, + "wall_monotonic_offset_range_s": 0.0002951622009277344 + }, + { + "delay_finished_wall": 1791832282.808212, + "delay_started_wall": 1791832281.6038282, + "genuine_upstream_elapsed_s": 0.033845792058855295, + "injected_elapsed_s": 1.204383792122826, + "model_overlaps": [], + "path": "/identity", + "sequence": 667, + "wall_monotonic_offset_range_s": 0.00036454200744628906 + }, + { + "delay_finished_wall": 1791832284.4161339, + "delay_started_wall": 1791832283.211826, + "genuine_upstream_elapsed_s": 0.03321212506853044, + "injected_elapsed_s": 1.204307832987979, + "model_overlaps": [], + "path": "/identity", + "sequence": 668, + "wall_monotonic_offset_range_s": 0.00027680397033691406 + }, + { + "delay_finished_wall": 1791832286.023186, + "delay_started_wall": 1791832284.8185112, + "genuine_upstream_elapsed_s": 0.031950625125318766, + "injected_elapsed_s": 1.2046747910790145, + "model_overlaps": [], + "path": "/identity", + "sequence": 669, + "wall_monotonic_offset_range_s": 0.0003528594970703125 + }, + { + "delay_finished_wall": 1791832287.63012, + "delay_started_wall": 1791832286.425594, + "genuine_upstream_elapsed_s": 0.025775166926905513, + "injected_elapsed_s": 1.204525833018124, + "model_overlaps": [], + "path": "/identity", + "sequence": 670, + "wall_monotonic_offset_range_s": 0.0003333091735839844 + }, + { + "delay_finished_wall": 1791832289.234438, + "delay_started_wall": 1791832288.0331938, + "genuine_upstream_elapsed_s": 0.023571416968479753, + "injected_elapsed_s": 1.2012440001126379, + "model_overlaps": [], + "path": "/identity", + "sequence": 671, + "wall_monotonic_offset_range_s": 0.00030875205993652344 + }, + { + "delay_finished_wall": 1791832290.857811, + "delay_started_wall": 1791832289.6537929, + "genuine_upstream_elapsed_s": 0.03697133297100663, + "injected_elapsed_s": 1.2040182081982493, + "model_overlaps": [], + "path": "/identity", + "sequence": 672, + "wall_monotonic_offset_range_s": 0.0004439353942871094 + }, + { + "delay_finished_wall": 1791832292.550731, + "delay_started_wall": 1791832291.347129, + "genuine_upstream_elapsed_s": 0.10883808392100036, + "injected_elapsed_s": 1.203601917019114, + "model_overlaps": [], + "path": "/identity", + "sequence": 673, + "wall_monotonic_offset_range_s": 0.0004405975341796875 + }, + { + "delay_finished_wall": 1791832294.067949, + "delay_started_wall": 1791832292.8650882, + "genuine_upstream_elapsed_s": 0.024111542152240872, + "injected_elapsed_s": 1.2028609160333872, + "model_overlaps": [], + "path": "/identity", + "sequence": 674, + "wall_monotonic_offset_range_s": 0.00026679039001464844 + }, + { + "delay_finished_wall": 1791832295.688381, + "delay_started_wall": 1791832294.487985, + "genuine_upstream_elapsed_s": 0.035032999934628606, + "injected_elapsed_s": 1.2003959577996284, + "model_overlaps": [], + "path": "/identity", + "sequence": 675, + "wall_monotonic_offset_range_s": 0.00037360191345214844 + }, + { + "delay_finished_wall": 1791832297.2962801, + "delay_started_wall": 1791832296.0939546, + "genuine_upstream_elapsed_s": 0.03289383416995406, + "injected_elapsed_s": 1.2023255832027644, + "model_overlaps": [], + "path": "/identity", + "sequence": 676, + "wall_monotonic_offset_range_s": 0.0004773139953613281 + }, + { + "delay_finished_wall": 1791832298.916022, + "delay_started_wall": 1791832297.7152755, + "genuine_upstream_elapsed_s": 0.04468645807355642, + "injected_elapsed_s": 1.2007464580237865, + "model_overlaps": [], + "path": "/identity", + "sequence": 677, + "wall_monotonic_offset_range_s": 0.000461578369140625 + }, + { + "delay_finished_wall": 1791832300.50497, + "delay_started_wall": 1791832299.302549, + "genuine_upstream_elapsed_s": 0.024397874949499965, + "injected_elapsed_s": 1.2024210828822106, + "model_overlaps": [], + "path": "/identity", + "sequence": 678, + "wall_monotonic_offset_range_s": 0.0003190040588378906 + }, + { + "delay_finished_wall": 1791832302.12138, + "delay_started_wall": 1791832300.916171, + "genuine_upstream_elapsed_s": 0.0270841249730438, + "injected_elapsed_s": 1.205209042178467, + "model_overlaps": [], + "path": "/identity", + "sequence": 679, + "wall_monotonic_offset_range_s": 0.00034427642822265625 + }, + { + "delay_finished_wall": 1791832303.727721, + "delay_started_wall": 1791832302.5242665, + "genuine_upstream_elapsed_s": 0.025939082959666848, + "injected_elapsed_s": 1.2034545419737697, + "model_overlaps": [], + "path": "/identity", + "sequence": 680, + "wall_monotonic_offset_range_s": 0.00041365623474121094 + }, + { + "delay_finished_wall": 1791832305.343824, + "delay_started_wall": 1791832304.138787, + "genuine_upstream_elapsed_s": 0.03202695888467133, + "injected_elapsed_s": 1.2050369170028716, + "model_overlaps": [], + "path": "/identity", + "sequence": 681, + "wall_monotonic_offset_range_s": 0.00038743019104003906 + }, + { + "delay_finished_wall": 1791832306.948216, + "delay_started_wall": 1791832305.7446063, + "genuine_upstream_elapsed_s": 0.026920791948214173, + "injected_elapsed_s": 1.2036097499076277, + "model_overlaps": [], + "path": "/identity", + "sequence": 682, + "wall_monotonic_offset_range_s": 0.00027108192443847656 + }, + { + "delay_finished_wall": 1791832308.563554, + "delay_started_wall": 1791832307.3598785, + "genuine_upstream_elapsed_s": 0.031036084052175283, + "injected_elapsed_s": 1.2036756249144673, + "model_overlaps": [], + "path": "/identity", + "sequence": 683, + "wall_monotonic_offset_range_s": 0.0003514289855957031 + }, + { + "delay_finished_wall": 1791832310.165736, + "delay_started_wall": 1791832308.9651709, + "genuine_upstream_elapsed_s": 0.024415332823991776, + "injected_elapsed_s": 1.200565000064671, + "model_overlaps": [], + "path": "/identity", + "sequence": 684, + "wall_monotonic_offset_range_s": 0.0003516674041748047 + }, + { + "delay_finished_wall": 1791832311.7797499, + "delay_started_wall": 1791832310.576029, + "genuine_upstream_elapsed_s": 0.02451429096981883, + "injected_elapsed_s": 1.203720834106207, + "model_overlaps": [], + "path": "/identity", + "sequence": 685, + "wall_monotonic_offset_range_s": 0.00028967857360839844 + } + ], + "jobs": [ + { + "both_paths_overlap_model": true, + "final_status": "completed", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "path_coverage": { + "/identity": { + "healthy_injected_reads_overlapping_model": 30, + "model_calls": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "relay_sequences": [ + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 42, + 43, + 44, + 45, + 59, + 60, + 61, + 62, + 63, + 64, + 78, + 79, + 80, + 81, + 96, + 97, + 98, + 99, + 113, + 114, + 115, + 116, + 117 + ] + }, + "/state": { + "healthy_injected_reads_overlapping_model": 33, + "model_calls": [ + 8, + 9, + 10, + 11, + 12, + 13, + 14 + ], + "relay_sequences": [ + 211, + 213, + 215, + 217, + 219, + 234, + 236, + 238, + 240, + 242, + 257, + 259, + 261, + 263, + 265, + 280, + 282, + 284, + 286, + 288, + 303, + 305, + 307, + 309, + 324, + 326, + 328, + 330, + 345, + 347, + 349, + 351, + 353 + ] + } + } + }, + { + "both_paths_overlap_model": true, + "final_status": "completed", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "path_coverage": { + "/identity": { + "healthy_injected_reads_overlapping_model": 9, + "model_calls": [ + 12, + 13 + ], + "relay_sequences": [ + 630, + 631, + 632, + 633, + 634, + 648, + 649, + 650, + 651 + ] + }, + "/state": { + "healthy_injected_reads_overlapping_model": 56, + "model_calls": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "relay_sequences": [ + 373, + 375, + 377, + 379, + 381, + 383, + 398, + 400, + 402, + 404, + 419, + 421, + 423, + 425, + 427, + 429, + 445, + 447, + 449, + 451, + 466, + 468, + 470, + 472, + 489, + 491, + 493, + 495, + 497, + 512, + 514, + 516, + 518, + 520, + 535, + 537, + 539, + 541, + 543, + 545, + 547, + 562, + 564, + 566, + 568, + 583, + 585, + 587, + 589, + 591, + 593, + 608, + 610, + 612, + 614, + 616 + ] + } + } + } + ], + "limits": [ + "This supplementary audit was authored after source freeze; it does not replace the frozen qualifier.", + "Model intervals use provider started_at plus monotonic elapsed_s; delay windows use recorded send time minus measured wait.", + "Wall/monotonic offset spread is retained to expose timing precision limits.", + "Overlap establishes exposure during model planning; it does not prove the cause of the historical SIM11 timeout." + ], + "model_calls": [ + { + "call": 1, + "elapsed_s": 8.888634625123814, + "finished_wall": 1791832146.4737008, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832137.585066 + }, + { + "call": 2, + "elapsed_s": 7.371869457885623, + "finished_wall": 1791832154.8865297, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832147.5146601 + }, + { + "call": 3, + "elapsed_s": 8.43007241608575, + "finished_wall": 1791832164.3083704, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832155.878298 + }, + { + "call": 4, + "elapsed_s": 6.128192666918039, + "finished_wall": 1791832172.0759635, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832165.9477708 + }, + { + "call": 5, + "elapsed_s": 7.361145915929228, + "finished_wall": 1791832180.94438, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832173.583234 + }, + { + "call": 6, + "elapsed_s": 8.747338708955795, + "finished_wall": 1791832191.5603619, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832182.813023 + }, + { + "call": 7, + "elapsed_s": 8.426699750125408, + "finished_wall": 1791832201.4861398, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832193.0594401 + }, + { + "call": 8, + "elapsed_s": 10.435514916898683, + "finished_wall": 1791832213.403819, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832202.9683042 + }, + { + "call": 9, + "elapsed_s": 6.884068874875084, + "finished_wall": 1791832221.844614, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832214.960545 + }, + { + "call": 10, + "elapsed_s": 10.11140904109925, + "finished_wall": 1791832233.665648, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832223.554239 + }, + { + "call": 11, + "elapsed_s": 8.000156666850671, + "finished_wall": 1791832252.1834106, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832244.183254 + }, + { + "call": 12, + "elapsed_s": 7.8165919170714915, + "finished_wall": 1791832261.580144, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832253.763552 + }, + { + "call": 13, + "elapsed_s": 6.307222834089771, + "finished_wall": 1791832269.6300058, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832263.322783 + }, + { + "call": 1, + "elapsed_s": 10.586642124922946, + "finished_wall": 1791831978.080672, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791831967.49403 + }, + { + "call": 2, + "elapsed_s": 6.294448249973357, + "finished_wall": 1791831984.8089693, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791831978.5145211 + }, + { + "call": 3, + "elapsed_s": 9.542235415894538, + "finished_wall": 1791831994.7687895, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791831985.2265542 + }, + { + "call": 4, + "elapsed_s": 6.4462542498949915, + "finished_wall": 1791832001.6932354, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791831995.2469811 + }, + { + "call": 5, + "elapsed_s": 4.764401749940589, + "finished_wall": 1791832007.2908835, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832002.5264819 + }, + { + "call": 6, + "elapsed_s": 8.140898042125627, + "finished_wall": 1791832016.244656, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832008.103758 + }, + { + "call": 7, + "elapsed_s": 8.440171458059922, + "finished_wall": 1791832078.4239416, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832069.9837701 + }, + { + "call": 8, + "elapsed_s": 8.132765874965116, + "finished_wall": 1791832087.3751018, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832079.242336 + }, + { + "call": 9, + "elapsed_s": 7.226740124868229, + "finished_wall": 1791832095.51877, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832088.2920299 + }, + { + "call": 10, + "elapsed_s": 7.37742824992165, + "finished_wall": 1791832103.8689063, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832096.491478 + }, + { + "call": 11, + "elapsed_s": 8.136500083142892, + "finished_wall": 1791832112.922722, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832104.786222 + }, + { + "call": 12, + "elapsed_s": 6.762274875072762, + "finished_wall": 1791832120.609567, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832113.847292 + }, + { + "call": 13, + "elapsed_s": 6.597302458947524, + "finished_wall": 1791832128.1300006, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832121.5326982 + }, + { + "call": 14, + "elapsed_s": 7.210898624965921, + "finished_wall": 1791832136.3729286, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832129.16203 + } + ], + "passed": true, + "proof_count": 83, + "proof_events_unique": true, + "strengthened_admission_bindings": [ + { + "command_id": "command-accc773656494216b8991d02cab9b603", + "passed": true + }, + { + "command_id": "command-85d8b423ec7c4a53bb1987fb1a62bdf6", + "passed": true + }, + { + "command_id": "command-b93638f4643f4d35b5cde6fde06ed807", + "passed": true + }, + { + "command_id": "command-a44e60b9d8c24bdaa49e479c4b0ef780", + "passed": true + }, + { + "command_id": "command-79dcaf5d02e048449c681748167c446a", + "passed": true + }, + { + "command_id": "command-069d2460341443e69bbcd0b5f39b91f2", + "passed": true + }, + { + "command_id": "command-20fde1f33f97495cade8fce105d16ae4", + "passed": true + }, + { + "command_id": "command-107896fd188d4b72be6d2a6debd2ba0c", + "passed": true + }, + { + "command_id": "command-1bc0e6eb4e064fe1b7b66dfbf750968a", + "passed": true + }, + { + "command_id": "command-70f9b8c19b59452693061139bda6c71b", + "passed": true + }, + { + "command_id": "command-16683e1227d84968879714ddd0556488", + "passed": true + }, + { + "command_id": "command-1fb29328cf0a4c7e800022c949b77f7a", + "passed": true + }, + { + "command_id": "command-f1e1760598fa4cd89339d2d2091f8d1a", + "passed": true + }, + { + "command_id": "command-1a4dc2ad405846ecbdfaed4b2d825f3e", + "passed": true + }, + { + "command_id": "command-55007cfbc1d7410d92d582397af2555b", + "passed": true + }, + { + "command_id": "command-ee7b8dee4444416c98f550c3e5a7c01f", + "passed": true + }, + { + "command_id": "command-77279a97fd4a4ff2aee720c0b7a46c40", + "passed": true + }, + { + "command_id": "command-3211cda07dda4c5c8dd2cc700fdaad98", + "passed": true + }, + { + "command_id": "command-e52c9ef5005a410fb80600b4ad7f947a", + "passed": true + }, + { + "command_id": "command-97245de4fa73480c87503051fc90a8a9", + "passed": true + }, + { + "command_id": "command-5457db2a5bcf4cd3ba1b306e5182ede1", + "passed": true + }, + { + "command_id": "command-d4045c653de542aea3cd3f100603a0dd", + "passed": true + }, + { + "command_id": "command-127c700baa7e4224a9f4d4d1654380fc", + "passed": true + }, + { + "command_id": "command-12d35e26325248a5881960ffcbd97a6f", + "passed": true + }, + { + "command_id": "command-fb95362e732c42c793f505dd7673ea38", + "passed": true + }, + { + "command_id": "command-5365431f8f094a738c04898a662544f5", + "passed": true + }, + { + "command_id": "command-1ca372f4627f44ca820de2e16d58a939", + "passed": true + }, + { + "command_id": "command-8074e0e06a9d46f68b944f8a3949a7d5", + "passed": true + }, + { + "command_id": "command-58c9af8646c94c0b9e453fb32e4622f1", + "passed": true + }, + { + "command_id": "command-706d43a193d349b0abb2a1a2e213670d", + "passed": true + }, + { + "command_id": "command-f01b770705654cf0b746795ef56a5e51", + "passed": true + }, + { + "command_id": "command-01c5b18c0f4848ab83a3a506c6164bd7", + "passed": true + }, + { + "command_id": "command-455161d907e44cc2a0c00c4713404a47", + "passed": true + }, + { + "command_id": "command-c085b10cc40c44539a927aa06c7a4339", + "passed": true + }, + { + "command_id": "command-7c91d1e39cc047049a3c4453e8b35923", + "passed": true + }, + { + "command_id": "command-02d0ee9bb015446e974769918792b02f", + "passed": true + }, + { + "command_id": "command-15941d3c6bb74b9a8916ec43a2fe0e1f", + "passed": true + }, + { + "command_id": "command-f615d864a28e4af88536d43c26a06e7c", + "passed": true + }, + { + "command_id": "command-d11cdb7e2538490784e2e8a2425572b7", + "passed": true + }, + { + "command_id": "command-cdf687139f2e43cab73f3afa8053018d", + "passed": true + }, + { + "command_id": "command-6db96f5e11fc4baebb1607c174a5898f", + "passed": true + }, + { + "command_id": "command-000b1a6737a14842a6b79c23e0a5ca92", + "passed": true + }, + { + "command_id": "command-72de9f33d999438198fc8b176ee89f6d", + "passed": true + }, + { + "command_id": "command-155208c1dd824b43a411bf0d9f879dc9", + "passed": true + }, + { + "command_id": "command-debb71a7f11f45b1b2093c2da309bb26", + "passed": true + }, + { + "command_id": "command-8fe46178c8564d2b8af7b48dd51ceb69", + "passed": true + }, + { + "command_id": "command-1fdd5229845447258a05de892ad29824", + "passed": true + }, + { + "command_id": "command-7e14ebef15814262bf16ee0a417469ea", + "passed": true + }, + { + "command_id": "command-a6931c3bf281480fb0dd090384b20178", + "passed": true + }, + { + "command_id": "command-5a3fb52b0a34409da8c43ce284d498f8", + "passed": true + }, + { + "command_id": "command-6371aeae6cdb432c851d1a095b64f85e", + "passed": true + }, + { + "command_id": "command-020d09130bdf4e10b2e30aed41ee93fd", + "passed": true + }, + { + "command_id": "command-185d0f856fbc4990be03fb5a4d680444", + "passed": true + }, + { + "command_id": "command-271d260ff225464ca18069efe6b89a3f", + "passed": true + }, + { + "command_id": "command-8bc103965b3b4b548f0ab2a4f6529315", + "passed": true + }, + { + "command_id": "command-52b299434a2a4354ae1a0c27f7afda73", + "passed": true + }, + { + "command_id": "command-b50b8172d84a4c2ca69c1b13799c0cd3", + "passed": true + }, + { + "command_id": "command-55878c3e64e7438786d949269a3ca632", + "passed": true + }, + { + "command_id": "command-3c4907bffd1043b7841f4f7a81e14c2e", + "passed": true + }, + { + "command_id": "command-a3d1bf0c87ed4d748bcfddf5acbcdbc8", + "passed": true + }, + { + "command_id": "command-c2820c925b7b43e48231001f02731ba6", + "passed": true + }, + { + "command_id": "command-8a9753d1c9604e3094a1478b421465f0", + "passed": true + }, + { + "command_id": "command-c21a6cfb3b154f799bb67d2695787ef8", + "passed": true + }, + { + "command_id": "command-6d7f70c0e5b14d6494d7eb02930b9d66", + "passed": true + }, + { + "command_id": "command-7d2c4e20bc454be996d99dc7edeea280", + "passed": true + }, + { + "command_id": "command-3352c7fd2fb14ffcaf69c1b27c6c53d9", + "passed": true + }, + { + "command_id": "command-896ce409c627486b9104d8d7415cefd3", + "passed": true + }, + { + "command_id": "command-1875feda0eaf4c058b771536779ccd62", + "passed": true + }, + { + "command_id": "command-844f1072836b419fa30a4c4f4a8697f1", + "passed": true + }, + { + "command_id": "command-7d6435405eaf4824b97108643856b361", + "passed": true + }, + { + "command_id": "command-7408e15ea38244a592d2800662c2b3c8", + "passed": true + }, + { + "command_id": "command-3cdfb3055b044aeeb059afc8731dac9c", + "passed": true + }, + { + "command_id": "command-59ebc979948340c1bceb69a8e01ac2aa", + "passed": true + }, + { + "command_id": "command-7761812fccc94a208c8f3e2dc26c28ec", + "passed": true + }, + { + "command_id": "command-2e37938e1f6a4a63b928572e1cf365af", + "passed": true + }, + { + "command_id": "command-e6cd1a382110409ab381d5fd4c4cc3b0", + "passed": true + }, + { + "command_id": "command-34752e8b30564841a21d087d561a5930", + "passed": true + }, + { + "command_id": "command-c966c8b893db42eb84c5b0616acca391", + "passed": true + }, + { + "command_id": "command-c8ad5019377e44159aef0ee22364b18f", + "passed": true + }, + { + "command_id": "command-10a03ed616ea4d96a26e96ae0973c32b", + "passed": true + }, + { + "command_id": "command-6b6e57d717d249c7811ef4708c6b8667", + "passed": true + }, + { + "command_id": "command-594d54e2793d428bbb42f80713e94ed3", + "passed": true + }, + { + "command_id": "command-bd5377590da74532a8333ac5ca2a72b3", + "passed": true + } + ], + "unused_admission_proof_events": [] +} diff --git a/jevdual/results/workbench-health-20261012/review-audit.json b/jevdual/results/workbench-health-20261012/review-audit.json new file mode 100644 index 0000000..8d17d05 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/review-audit.json @@ -0,0 +1,3353 @@ +{ + "audit_kind": "supplemental_post_run_read_only_review", + "audit_source_sha256": "9cece1c833596638481205ccfd8c784df4b0246fea1959673c18b6edfd3bb880", + "both_jobs_both_paths_overlap_actual_model": true, + "cancelled_calls": [], + "frozen_source_commit": "37ebfdb3054b977149d7b60b46254ddd852b749a", + "frozen_source_unchanged": true, + "healthy_checking_same_application_and_body": true, + "healthy_delayed_reads": [ + { + "delay_finished_wall": 1791831951.136652, + "delay_started_wall": 1791831949.9326327, + "genuine_upstream_elapsed_s": 0.002776124980300665, + "injected_elapsed_s": 1.2040192501153797, + "model_overlaps": [], + "path": "/identity", + "sequence": 2, + "wall_monotonic_offset_range_s": 0.00032067298889160156 + }, + { + "delay_finished_wall": 1791831952.751093, + "delay_started_wall": 1791831951.5486119, + "genuine_upstream_elapsed_s": 0.005044083809480071, + "injected_elapsed_s": 1.2024811250157654, + "model_overlaps": [], + "path": "/identity", + "sequence": 3, + "wall_monotonic_offset_range_s": 0.0005669593811035156 + }, + { + "delay_finished_wall": 1791831954.359777, + "delay_started_wall": 1791831953.1558466, + "genuine_upstream_elapsed_s": 0.0035592911299318075, + "injected_elapsed_s": 1.2039304592180997, + "model_overlaps": [], + "path": "/identity", + "sequence": 4, + "wall_monotonic_offset_range_s": 0.0003485679626464844 + }, + { + "delay_finished_wall": 1791831955.967743, + "delay_started_wall": 1791831954.7657344, + "genuine_upstream_elapsed_s": 0.0029993748757988214, + "injected_elapsed_s": 1.2020084999967366, + "model_overlaps": [], + "path": "/identity", + "sequence": 5, + "wall_monotonic_offset_range_s": 0.00022411346435546875 + }, + { + "delay_finished_wall": 1791831957.5783129, + "delay_started_wall": 1791831956.373279, + "genuine_upstream_elapsed_s": 0.0033572500105947256, + "injected_elapsed_s": 1.2050337500404567, + "model_overlaps": [], + "path": "/identity", + "sequence": 6, + "wall_monotonic_offset_range_s": 0.00037097930908203125 + }, + { + "delay_finished_wall": 1791831959.320833, + "delay_started_wall": 1791831958.1170774, + "genuine_upstream_elapsed_s": 0.09075575019232929, + "injected_elapsed_s": 1.203755582915619, + "model_overlaps": [], + "path": "/identity", + "sequence": 7, + "wall_monotonic_offset_range_s": 0.0005834102630615234 + }, + { + "delay_finished_wall": 1791831960.801874, + "delay_started_wall": 1791831959.59682, + "genuine_upstream_elapsed_s": 0.0031042909249663353, + "injected_elapsed_s": 1.2050538749899715, + "model_overlaps": [], + "path": "/identity", + "sequence": 8, + "wall_monotonic_offset_range_s": 0.0002377033233642578 + }, + { + "delay_finished_wall": 1791831962.408829, + "delay_started_wall": 1791831961.2049468, + "genuine_upstream_elapsed_s": 0.0031348341144621372, + "injected_elapsed_s": 1.203882124973461, + "model_overlaps": [], + "path": "/identity", + "sequence": 9, + "wall_monotonic_offset_range_s": 0.0003495216369628906 + }, + { + "delay_finished_wall": 1791831964.0189052, + "delay_started_wall": 1791831962.8146133, + "genuine_upstream_elapsed_s": 0.005035291891545057, + "injected_elapsed_s": 1.204291749978438, + "model_overlaps": [], + "path": "/identity", + "sequence": 10, + "wall_monotonic_offset_range_s": 0.0006890296936035156 + }, + { + "delay_finished_wall": 1791831965.624738, + "delay_started_wall": 1791831964.421972, + "genuine_upstream_elapsed_s": 0.002828457858413458, + "injected_elapsed_s": 1.2027659590821713, + "model_overlaps": [], + "path": "/identity", + "sequence": 11, + "wall_monotonic_offset_range_s": 0.00026869773864746094 + }, + { + "delay_finished_wall": 1791831967.239062, + "delay_started_wall": 1791831966.0340257, + "genuine_upstream_elapsed_s": 0.003178749931976199, + "injected_elapsed_s": 1.2050365000031888, + "model_overlaps": [], + "path": "/identity", + "sequence": 12, + "wall_monotonic_offset_range_s": 0.0002815723419189453 + }, + { + "delay_finished_wall": 1791831968.8454201, + "delay_started_wall": 1791831967.643657, + "genuine_upstream_elapsed_s": 0.00289629097096622, + "injected_elapsed_s": 1.201763124903664, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2017631530761719 + } + ], + "path": "/identity", + "sequence": 22, + "wall_monotonic_offset_range_s": 0.00020837783813476562 + }, + { + "delay_finished_wall": 1791831970.458034, + "delay_started_wall": 1791831969.252459, + "genuine_upstream_elapsed_s": 0.002508667064830661, + "injected_elapsed_s": 1.2055749581195414, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2055749893188477 + } + ], + "path": "/identity", + "sequence": 23, + "wall_monotonic_offset_range_s": 0.0002646446228027344 + }, + { + "delay_finished_wall": 1791831972.06533, + "delay_started_wall": 1791831970.8602543, + "genuine_upstream_elapsed_s": 0.003260375000536442, + "injected_elapsed_s": 1.205075625097379, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.205075740814209 + } + ], + "path": "/identity", + "sequence": 24, + "wall_monotonic_offset_range_s": 0.0003116130828857422 + }, + { + "delay_finished_wall": 1791831973.677821, + "delay_started_wall": 1791831972.4733727, + "genuine_upstream_elapsed_s": 0.003892249893397093, + "injected_elapsed_s": 1.2044482911005616, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2044482231140137 + } + ], + "path": "/identity", + "sequence": 25, + "wall_monotonic_offset_range_s": 0.0011014938354492188 + }, + { + "delay_finished_wall": 1791831975.285738, + "delay_started_wall": 1791831974.0807476, + "genuine_upstream_elapsed_s": 0.003343291115015745, + "injected_elapsed_s": 1.204990333179012, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2049903869628906 + } + ], + "path": "/identity", + "sequence": 26, + "wall_monotonic_offset_range_s": 0.00025391578674316406 + }, + { + "delay_finished_wall": 1791831976.8951979, + "delay_started_wall": 1791831975.6902578, + "genuine_upstream_elapsed_s": 0.0034893339034169912, + "injected_elapsed_s": 1.2049401660915464, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2049400806427002 + } + ], + "path": "/identity", + "sequence": 27, + "wall_monotonic_offset_range_s": 0.0002818107604980469 + }, + { + "delay_finished_wall": 1791831978.499134, + "delay_started_wall": 1791831977.2945046, + "genuine_upstream_elapsed_s": 0.003361874958500266, + "injected_elapsed_s": 1.204629332991317, + "model_overlaps": [ + { + "call": 1, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.7861673831939697 + } + ], + "path": "/identity", + "sequence": 28, + "wall_monotonic_offset_range_s": 0.0003018379211425781 + }, + { + "delay_finished_wall": 1791831980.10637, + "delay_started_wall": 1791831978.9023626, + "genuine_upstream_elapsed_s": 0.00299987499602139, + "injected_elapsed_s": 1.2040073750540614, + "model_overlaps": [ + { + "call": 2, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2040073871612549 + } + ], + "path": "/identity", + "sequence": 42, + "wall_monotonic_offset_range_s": 0.0002627372741699219 + }, + { + "delay_finished_wall": 1791831981.715692, + "delay_started_wall": 1791831980.5121903, + "genuine_upstream_elapsed_s": 0.0031940829940140247, + "injected_elapsed_s": 1.2035016249865294, + "model_overlaps": [ + { + "call": 2, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2035017013549805 + } + ], + "path": "/identity", + "sequence": 43, + "wall_monotonic_offset_range_s": 0.0002980232238769531 + }, + { + "delay_finished_wall": 1791831983.322252, + "delay_started_wall": 1791831982.121043, + "genuine_upstream_elapsed_s": 0.004062541993334889, + "injected_elapsed_s": 1.2012091248761863, + "model_overlaps": [ + { + "call": 2, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2012090682983398 + } + ], + "path": "/identity", + "sequence": 44, + "wall_monotonic_offset_range_s": 0.00027871131896972656 + }, + { + "delay_finished_wall": 1791831984.93428, + "delay_started_wall": 1791831983.73001, + "genuine_upstream_elapsed_s": 0.002662374870851636, + "injected_elapsed_s": 1.2042698750738055, + "model_overlaps": [ + { + "call": 2, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.0789592266082764 + } + ], + "path": "/identity", + "sequence": 45, + "wall_monotonic_offset_range_s": 0.00023412704467773438 + }, + { + "delay_finished_wall": 1791831986.539777, + "delay_started_wall": 1791831985.338916, + "genuine_upstream_elapsed_s": 0.0025203339755535126, + "injected_elapsed_s": 1.2008610831107944, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2008609771728516 + } + ], + "path": "/identity", + "sequence": 59, + "wall_monotonic_offset_range_s": 0.00014352798461914062 + }, + { + "delay_finished_wall": 1791831988.159762, + "delay_started_wall": 1791831986.9584835, + "genuine_upstream_elapsed_s": 0.009544290835037827, + "injected_elapsed_s": 1.2012784169055521, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2012784481048584 + } + ], + "path": "/identity", + "sequence": 60, + "wall_monotonic_offset_range_s": 0.00033092498779296875 + }, + { + "delay_finished_wall": 1791831989.7679, + "delay_started_wall": 1791831988.5628166, + "genuine_upstream_elapsed_s": 0.0035029591526836157, + "injected_elapsed_s": 1.2050834170076996, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050833702087402 + } + ], + "path": "/identity", + "sequence": 61, + "wall_monotonic_offset_range_s": 0.00027179718017578125 + }, + { + "delay_finished_wall": 1791831991.377156, + "delay_started_wall": 1791831990.1721072, + "genuine_upstream_elapsed_s": 0.0033430408220738173, + "injected_elapsed_s": 1.2050489170942456, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050487995147705 + } + ], + "path": "/identity", + "sequence": 62, + "wall_monotonic_offset_range_s": 0.0002346038818359375 + }, + { + "delay_finished_wall": 1791831992.996601, + "delay_started_wall": 1791831991.7964127, + "genuine_upstream_elapsed_s": 0.004118707962334156, + "injected_elapsed_s": 1.200188459130004, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.200188398361206 + } + ], + "path": "/identity", + "sequence": 63, + "wall_monotonic_offset_range_s": 0.005568981170654297 + }, + { + "delay_finished_wall": 1791831994.607224, + "delay_started_wall": 1791831993.4021256, + "genuine_upstream_elapsed_s": 0.007497084094211459, + "injected_elapsed_s": 1.2050984590314329, + "model_overlaps": [ + { + "call": 3, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050983905792236 + } + ], + "path": "/identity", + "sequence": 64, + "wall_monotonic_offset_range_s": 0.0003578662872314453 + }, + { + "delay_finished_wall": 1791831997.214113, + "delay_started_wall": 1791831996.0115426, + "genuine_upstream_elapsed_s": 0.0029468329157680273, + "injected_elapsed_s": 1.2025703340768814, + "model_overlaps": [ + { + "call": 4, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2025704383850098 + } + ], + "path": "/identity", + "sequence": 78, + "wall_monotonic_offset_range_s": 0.00033402442932128906 + }, + { + "delay_finished_wall": 1791831998.838238, + "delay_started_wall": 1791831997.6335766, + "genuine_upstream_elapsed_s": 0.009623541962355375, + "injected_elapsed_s": 1.2046614589635283, + "model_overlaps": [ + { + "call": 4, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2046613693237305 + } + ], + "path": "/identity", + "sequence": 79, + "wall_monotonic_offset_range_s": 0.0003039836883544922 + }, + { + "delay_finished_wall": 1791832000.441949, + "delay_started_wall": 1791831999.2368922, + "genuine_upstream_elapsed_s": 0.003390332916751504, + "injected_elapsed_s": 1.2050566668622196, + "model_overlaps": [ + { + "call": 4, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050566673278809 + } + ], + "path": "/identity", + "sequence": 80, + "wall_monotonic_offset_range_s": 0.00024771690368652344 + }, + { + "delay_finished_wall": 1791832002.051035, + "delay_started_wall": 1791832000.8462179, + "genuine_upstream_elapsed_s": 0.00339320907369256, + "injected_elapsed_s": 1.2048170422203839, + "model_overlaps": [ + { + "call": 4, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.8470175266265869 + } + ], + "path": "/identity", + "sequence": 81, + "wall_monotonic_offset_range_s": 0.0002200603485107422 + }, + { + "delay_finished_wall": 1791832003.6653, + "delay_started_wall": 1791832002.4623945, + "genuine_upstream_elapsed_s": 0.012598375091329217, + "injected_elapsed_s": 1.2029053340665996, + "model_overlaps": [ + { + "call": 5, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.1388180255889893 + } + ], + "path": "/identity", + "sequence": 96, + "wall_monotonic_offset_range_s": 0.00030541419982910156 + }, + { + "delay_finished_wall": 1791832005.285439, + "delay_started_wall": 1791832004.0819662, + "genuine_upstream_elapsed_s": 0.01664000004529953, + "injected_elapsed_s": 1.2034727919381112, + "model_overlaps": [ + { + "call": 5, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2034728527069092 + } + ], + "path": "/identity", + "sequence": 97, + "wall_monotonic_offset_range_s": 0.0003800392150878906 + }, + { + "delay_finished_wall": 1791832006.90365, + "delay_started_wall": 1791832005.698815, + "genuine_upstream_elapsed_s": 0.019909291993826628, + "injected_elapsed_s": 1.2048349999822676, + "model_overlaps": [ + { + "call": 5, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2048349380493164 + } + ], + "path": "/identity", + "sequence": 98, + "wall_monotonic_offset_range_s": 0.0004360675811767578 + }, + { + "delay_finished_wall": 1791832008.506123, + "delay_started_wall": 1791832007.3038552, + "genuine_upstream_elapsed_s": 0.016452833777293563, + "injected_elapsed_s": 1.2022679159417748, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.40236496925354004 + } + ], + "path": "/identity", + "sequence": 99, + "wall_monotonic_offset_range_s": 0.0002734661102294922 + }, + { + "delay_finished_wall": 1791832010.115941, + "delay_started_wall": 1791832008.9121234, + "genuine_upstream_elapsed_s": 0.013531167060136795, + "injected_elapsed_s": 1.2038175829220563, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.20381760597229 + } + ], + "path": "/identity", + "sequence": 113, + "wall_monotonic_offset_range_s": 0.0002827644348144531 + }, + { + "delay_finished_wall": 1791832011.727929, + "delay_started_wall": 1791832010.5238676, + "genuine_upstream_elapsed_s": 0.013567666988819838, + "injected_elapsed_s": 1.2040615831501782, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.204061508178711 + } + ], + "path": "/identity", + "sequence": 114, + "wall_monotonic_offset_range_s": 0.0003399848937988281 + }, + { + "delay_finished_wall": 1791832013.34195, + "delay_started_wall": 1791832012.1412833, + "genuine_upstream_elapsed_s": 0.021057708887383342, + "injected_elapsed_s": 1.2006667500827461, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2006666660308838 + } + ], + "path": "/identity", + "sequence": 115, + "wall_monotonic_offset_range_s": 0.000274658203125 + }, + { + "delay_finished_wall": 1791832014.943507, + "delay_started_wall": 1791832013.7429645, + "genuine_upstream_elapsed_s": 0.014461665879935026, + "injected_elapsed_s": 1.2005423330701888, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2005424499511719 + } + ], + "path": "/identity", + "sequence": 116, + "wall_monotonic_offset_range_s": 0.00047659873962402344 + }, + { + "delay_finished_wall": 1791832016.56296, + "delay_started_wall": 1791832015.3582413, + "genuine_upstream_elapsed_s": 0.017344833118841052, + "injected_elapsed_s": 1.204718666849658, + "model_overlaps": [ + { + "call": 6, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.8864147663116455 + } + ], + "path": "/identity", + "sequence": 117, + "wall_monotonic_offset_range_s": 0.0005025863647460938 + }, + { + "delay_finished_wall": 1791832018.174688, + "delay_started_wall": 1791832016.970701, + "genuine_upstream_elapsed_s": 0.019155291141942143, + "injected_elapsed_s": 1.2039870421867818, + "model_overlaps": [], + "path": "/identity", + "sequence": 126, + "wall_monotonic_offset_range_s": 0.00030732154846191406 + }, + { + "delay_finished_wall": 1791832019.776822, + "delay_started_wall": 1791832018.5753713, + "genuine_upstream_elapsed_s": 0.012994375079870224, + "injected_elapsed_s": 1.2014507499989122, + "model_overlaps": [], + "path": "/identity", + "sequence": 127, + "wall_monotonic_offset_range_s": 0.00035262107849121094 + }, + { + "delay_finished_wall": 1791832021.3976462, + "delay_started_wall": 1791832020.1962073, + "genuine_upstream_elapsed_s": 0.02700358279980719, + "injected_elapsed_s": 1.2014389999676496, + "model_overlaps": [], + "path": "/identity", + "sequence": 128, + "wall_monotonic_offset_range_s": 0.0003247261047363281 + }, + { + "delay_finished_wall": 1791832022.9915159, + "delay_started_wall": 1791832021.78787, + "genuine_upstream_elapsed_s": 0.01330141699872911, + "injected_elapsed_s": 1.2036458330694586, + "model_overlaps": [], + "path": "/identity", + "sequence": 129, + "wall_monotonic_offset_range_s": 0.0003898143768310547 + }, + { + "delay_finished_wall": 1791832024.675057, + "delay_started_wall": 1791832023.4683318, + "genuine_upstream_elapsed_s": 0.024299542186781764, + "injected_elapsed_s": 1.2067252080887556, + "model_overlaps": [], + "path": "/identity", + "sequence": 130, + "wall_monotonic_offset_range_s": 0.00021409988403320312 + }, + { + "delay_finished_wall": 1791832026.3910022, + "delay_started_wall": 1791832025.181681, + "genuine_upstream_elapsed_s": 0.033242583042010665, + "injected_elapsed_s": 1.2093212499748915, + "model_overlaps": [], + "path": "/identity", + "sequence": 131, + "wall_monotonic_offset_range_s": 0.0005581378936767578 + }, + { + "delay_finished_wall": 1791832027.847797, + "delay_started_wall": 1791832026.6440387, + "genuine_upstream_elapsed_s": 0.0233499170280993, + "injected_elapsed_s": 1.2037583331111819, + "model_overlaps": [], + "path": "/identity", + "sequence": 132, + "wall_monotonic_offset_range_s": 0.0006263256072998047 + }, + { + "delay_finished_wall": 1791832029.485719, + "delay_started_wall": 1791832028.2835376, + "genuine_upstream_elapsed_s": 0.023109209025278687, + "injected_elapsed_s": 1.2021812500897795, + "model_overlaps": [], + "path": "/identity", + "sequence": 133, + "wall_monotonic_offset_range_s": 0.0005357265472412109 + }, + { + "delay_finished_wall": 1791832081.0974221, + "delay_started_wall": 1791832079.8953402, + "genuine_upstream_elapsed_s": 0.04533958388492465, + "injected_elapsed_s": 1.2020818751771003, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2020819187164307 + } + ], + "path": "/state", + "sequence": 211, + "wall_monotonic_offset_range_s": 0.00023651123046875 + }, + { + "delay_finished_wall": 1791832082.7192068, + "delay_started_wall": 1791832081.518623, + "genuine_upstream_elapsed_s": 0.04676191695034504, + "injected_elapsed_s": 1.2005837499164045, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2005836963653564 + } + ], + "path": "/state", + "sequence": 213, + "wall_monotonic_offset_range_s": 0.0003616809844970703 + }, + { + "delay_finished_wall": 1791832084.339633, + "delay_started_wall": 1791832083.1349635, + "genuine_upstream_elapsed_s": 0.04107379191555083, + "injected_elapsed_s": 1.2046695840544999, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.20466947555542 + } + ], + "path": "/state", + "sequence": 215, + "wall_monotonic_offset_range_s": 0.0002899169921875 + }, + { + "delay_finished_wall": 1791832085.960802, + "delay_started_wall": 1791832084.7594473, + "genuine_upstream_elapsed_s": 0.04071483411826193, + "injected_elapsed_s": 1.2013546251691878, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.201354742050171 + } + ], + "path": "/state", + "sequence": 217, + "wall_monotonic_offset_range_s": 0.00032806396484375 + }, + { + "delay_finished_wall": 1791832087.585452, + "delay_started_wall": 1791832086.384062, + "genuine_upstream_elapsed_s": 0.041966750053688884, + "injected_elapsed_s": 1.2013900419697165, + "model_overlaps": [ + { + "call": 8, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.9910397529602051 + } + ], + "path": "/state", + "sequence": 219, + "wall_monotonic_offset_range_s": 0.00026154518127441406 + }, + { + "delay_finished_wall": 1791832090.22193, + "delay_started_wall": 1791832089.0204175, + "genuine_upstream_elapsed_s": 0.04945133300498128, + "injected_elapsed_s": 1.2015124999452382, + "model_overlaps": [ + { + "call": 9, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2015125751495361 + } + ], + "path": "/state", + "sequence": 234, + "wall_monotonic_offset_range_s": 0.0002675056457519531 + }, + { + "delay_finished_wall": 1791832091.845014, + "delay_started_wall": 1791832090.6439574, + "genuine_upstream_elapsed_s": 0.04513141606003046, + "injected_elapsed_s": 1.2010567500256002, + "model_overlaps": [ + { + "call": 9, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.201056718826294 + } + ], + "path": "/state", + "sequence": 236, + "wall_monotonic_offset_range_s": 0.0003001689910888672 + }, + { + "delay_finished_wall": 1791832093.470641, + "delay_started_wall": 1791832092.269904, + "genuine_upstream_elapsed_s": 0.046239792136475444, + "injected_elapsed_s": 1.2007370002102107, + "model_overlaps": [ + { + "call": 9, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2007369995117188 + } + ], + "path": "/state", + "sequence": 238, + "wall_monotonic_offset_range_s": 0.0003094673156738281 + }, + { + "delay_finished_wall": 1791832095.102564, + "delay_started_wall": 1791832093.902203, + "genuine_upstream_elapsed_s": 0.05429583298973739, + "injected_elapsed_s": 1.2003611251711845, + "model_overlaps": [ + { + "call": 9, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2003610134124756 + } + ], + "path": "/state", + "sequence": 240, + "wall_monotonic_offset_range_s": 0.0003120899200439453 + }, + { + "delay_finished_wall": 1791832096.736833, + "delay_started_wall": 1791832095.5317907, + "genuine_upstream_elapsed_s": 0.04574579210020602, + "injected_elapsed_s": 1.20504245813936, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.24535512924194336 + } + ], + "path": "/state", + "sequence": 242, + "wall_monotonic_offset_range_s": 0.004605531692504883 + }, + { + "delay_finished_wall": 1791832098.352134, + "delay_started_wall": 1791832097.1493397, + "genuine_upstream_elapsed_s": 0.04627279192209244, + "injected_elapsed_s": 1.202794292010367, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2027943134307861 + } + ], + "path": "/state", + "sequence": 257, + "wall_monotonic_offset_range_s": 0.0003185272216796875 + }, + { + "delay_finished_wall": 1791832099.991491, + "delay_started_wall": 1791832098.7868052, + "genuine_upstream_elapsed_s": 0.04723550006747246, + "injected_elapsed_s": 1.2046860409900546, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.204685926437378 + } + ], + "path": "/state", + "sequence": 259, + "wall_monotonic_offset_range_s": 0.000301361083984375 + }, + { + "delay_finished_wall": 1791832101.614825, + "delay_started_wall": 1791832100.4146428, + "genuine_upstream_elapsed_s": 0.047370166052132845, + "injected_elapsed_s": 1.2001820839941502, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2001821994781494 + } + ], + "path": "/state", + "sequence": 261, + "wall_monotonic_offset_range_s": 0.0003604888916015625 + }, + { + "delay_finished_wall": 1791832103.239155, + "delay_started_wall": 1791832102.0341103, + "genuine_upstream_elapsed_s": 0.04227699991315603, + "injected_elapsed_s": 1.2050447911024094, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050447463989258 + } + ], + "path": "/state", + "sequence": 263, + "wall_monotonic_offset_range_s": 0.0004055500030517578 + }, + { + "delay_finished_wall": 1791832104.877825, + "delay_started_wall": 1791832103.6765485, + "genuine_upstream_elapsed_s": 0.056063625030219555, + "injected_elapsed_s": 1.2012766250409186, + "model_overlaps": [ + { + "call": 10, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.19235777854919434 + }, + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.09160304069519043 + } + ], + "path": "/state", + "sequence": 265, + "wall_monotonic_offset_range_s": 0.0004611015319824219 + }, + { + "delay_finished_wall": 1791832106.4973052, + "delay_started_wall": 1791832105.292261, + "genuine_upstream_elapsed_s": 0.046128083020448685, + "injected_elapsed_s": 1.2050441671162844, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2050442695617676 + } + ], + "path": "/state", + "sequence": 280, + "wall_monotonic_offset_range_s": 0.0004367828369140625 + }, + { + "delay_finished_wall": 1791832108.148909, + "delay_started_wall": 1791832106.9444427, + "genuine_upstream_elapsed_s": 0.0588835421949625, + "injected_elapsed_s": 1.2044663750566542, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2044663429260254 + } + ], + "path": "/state", + "sequence": 282, + "wall_monotonic_offset_range_s": 0.0002453327178955078 + }, + { + "delay_finished_wall": 1791832109.773719, + "delay_started_wall": 1791832108.572417, + "genuine_upstream_elapsed_s": 0.050575749948620796, + "injected_elapsed_s": 1.2013020410668105, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2013020515441895 + } + ], + "path": "/state", + "sequence": 284, + "wall_monotonic_offset_range_s": 0.00033092498779296875 + }, + { + "delay_finished_wall": 1791832111.400123, + "delay_started_wall": 1791832110.1959536, + "genuine_upstream_elapsed_s": 0.046160792000591755, + "injected_elapsed_s": 1.204169207951054, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2041692733764648 + } + ], + "path": "/state", + "sequence": 286, + "wall_monotonic_offset_range_s": 0.0002598762512207031 + }, + { + "delay_finished_wall": 1791832113.030656, + "delay_started_wall": 1791832111.8256311, + "genuine_upstream_elapsed_s": 0.044818750116974115, + "injected_elapsed_s": 1.205024957889691, + "model_overlaps": [ + { + "call": 11, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.0970909595489502 + } + ], + "path": "/state", + "sequence": 288, + "wall_monotonic_offset_range_s": 0.0003409385681152344 + }, + { + "delay_finished_wall": 1791832115.661109, + "delay_started_wall": 1791832114.4575708, + "genuine_upstream_elapsed_s": 0.04853254184126854, + "injected_elapsed_s": 1.203538167057559, + "model_overlaps": [ + { + "call": 12, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.203538179397583 + } + ], + "path": "/state", + "sequence": 303, + "wall_monotonic_offset_range_s": 0.0002593994140625 + }, + { + "delay_finished_wall": 1791832117.282847, + "delay_started_wall": 1791832116.0813665, + "genuine_upstream_elapsed_s": 0.04559245798736811, + "injected_elapsed_s": 1.2014803329948336, + "model_overlaps": [ + { + "call": 12, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2014803886413574 + } + ], + "path": "/state", + "sequence": 305, + "wall_monotonic_offset_range_s": 0.00033092498779296875 + }, + { + "delay_finished_wall": 1791832118.914329, + "delay_started_wall": 1791832117.7099512, + "genuine_upstream_elapsed_s": 0.048586250049993396, + "injected_elapsed_s": 1.2043779590167105, + "model_overlaps": [ + { + "call": 12, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2043778896331787 + } + ], + "path": "/state", + "sequence": 307, + "wall_monotonic_offset_range_s": 0.0003142356872558594 + }, + { + "delay_finished_wall": 1791832120.540607, + "delay_started_wall": 1791832119.338083, + "genuine_upstream_elapsed_s": 0.04915620805695653, + "injected_elapsed_s": 1.2025240000803024, + "model_overlaps": [ + { + "call": 12, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.202523946762085 + } + ], + "path": "/state", + "sequence": 309, + "wall_monotonic_offset_range_s": 0.0002961158752441406 + }, + { + "delay_finished_wall": 1791832123.173666, + "delay_started_wall": 1791832121.9724607, + "genuine_upstream_elapsed_s": 0.05501812510192394, + "injected_elapsed_s": 1.2012051669880748, + "model_overlaps": [ + { + "call": 13, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2012052536010742 + } + ], + "path": "/state", + "sequence": 324, + "wall_monotonic_offset_range_s": 0.0004284381866455078 + }, + { + "delay_finished_wall": 1791832124.797261, + "delay_started_wall": 1791832123.5969458, + "genuine_upstream_elapsed_s": 0.05386095796711743, + "injected_elapsed_s": 1.20031529199332, + "model_overlaps": [ + { + "call": 13, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.200315237045288 + } + ], + "path": "/state", + "sequence": 326, + "wall_monotonic_offset_range_s": 0.0003066062927246094 + }, + { + "delay_finished_wall": 1791832126.434151, + "delay_started_wall": 1791832125.228527, + "genuine_upstream_elapsed_s": 0.05417429096996784, + "injected_elapsed_s": 1.2056237920187414, + "model_overlaps": [ + { + "call": 13, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2056238651275635 + } + ], + "path": "/state", + "sequence": 328, + "wall_monotonic_offset_range_s": 0.0003712177276611328 + }, + { + "delay_finished_wall": 1791832128.0681322, + "delay_started_wall": 1791832126.8663008, + "genuine_upstream_elapsed_s": 0.059533082880079746, + "injected_elapsed_s": 1.2018312909640372, + "model_overlaps": [ + { + "call": 13, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.201831340789795 + } + ], + "path": "/state", + "sequence": 330, + "wall_monotonic_offset_range_s": 0.0003476142883300781 + }, + { + "delay_finished_wall": 1791832130.698807, + "delay_started_wall": 1791832129.4979184, + "genuine_upstream_elapsed_s": 0.05425262497738004, + "injected_elapsed_s": 1.2008886248804629, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2008886337280273 + } + ], + "path": "/state", + "sequence": 345, + "wall_monotonic_offset_range_s": 0.000308990478515625 + }, + { + "delay_finished_wall": 1791832132.343055, + "delay_started_wall": 1791832131.1425955, + "genuine_upstream_elapsed_s": 0.07181812496855855, + "injected_elapsed_s": 1.2004595410544425, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2004594802856445 + } + ], + "path": "/state", + "sequence": 347, + "wall_monotonic_offset_range_s": 0.0002918243408203125 + }, + { + "delay_finished_wall": 1791832133.955904, + "delay_started_wall": 1791832132.7540894, + "genuine_upstream_elapsed_s": 0.052502250066027045, + "injected_elapsed_s": 1.2018145839683712, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2018146514892578 + } + ], + "path": "/state", + "sequence": 349, + "wall_monotonic_offset_range_s": 0.0005249977111816406 + }, + { + "delay_finished_wall": 1791832135.582197, + "delay_started_wall": 1791832134.3774855, + "genuine_upstream_elapsed_s": 0.04988845787011087, + "injected_elapsed_s": 1.2047113340813667, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 1.2047114372253418 + } + ], + "path": "/state", + "sequence": 351, + "wall_monotonic_offset_range_s": 0.0002865791320800781 + }, + { + "delay_finished_wall": 1791832137.22383, + "delay_started_wall": 1791832136.022428, + "genuine_upstream_elapsed_s": 0.06868283404037356, + "injected_elapsed_s": 1.2014020418282598, + "model_overlaps": [ + { + "call": 14, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "overlap_s": 0.35050058364868164 + } + ], + "path": "/state", + "sequence": 353, + "wall_monotonic_offset_range_s": 0.0003383159637451172 + }, + { + "delay_finished_wall": 1791832138.840893, + "delay_started_wall": 1791832137.6358533, + "genuine_upstream_elapsed_s": 0.05692441714927554, + "injected_elapsed_s": 1.2050397919956595, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2050397396087646 + } + ], + "path": "/state", + "sequence": 373, + "wall_monotonic_offset_range_s": 0.00036334991455078125 + }, + { + "delay_finished_wall": 1791832140.523594, + "delay_started_wall": 1791832139.3210244, + "genuine_upstream_elapsed_s": 0.08095504203811288, + "injected_elapsed_s": 1.2025694160256535, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2025694847106934 + } + ], + "path": "/state", + "sequence": 375, + "wall_monotonic_offset_range_s": 0.0003018379211425781 + }, + { + "delay_finished_wall": 1791832142.144813, + "delay_started_wall": 1791832140.9398186, + "genuine_upstream_elapsed_s": 0.06230750004760921, + "injected_elapsed_s": 1.2049943341407925, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2049944400787354 + } + ], + "path": "/state", + "sequence": 377, + "wall_monotonic_offset_range_s": 0.00025177001953125 + }, + { + "delay_finished_wall": 1791832143.774648, + "delay_started_wall": 1791832142.5730557, + "genuine_upstream_elapsed_s": 0.05781725002452731, + "injected_elapsed_s": 1.2015922078862786, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.201592206954956 + } + ], + "path": "/state", + "sequence": 379, + "wall_monotonic_offset_range_s": 0.0005812644958496094 + }, + { + "delay_finished_wall": 1791832145.40432, + "delay_started_wall": 1791832144.1992726, + "genuine_upstream_elapsed_s": 0.05713516683317721, + "injected_elapsed_s": 1.2050473750568926, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.205047369003296 + } + ], + "path": "/state", + "sequence": 381, + "wall_monotonic_offset_range_s": 0.0003993511199951172 + }, + { + "delay_finished_wall": 1791832147.056463, + "delay_started_wall": 1791832145.8514771, + "genuine_upstream_elapsed_s": 0.07064691698178649, + "injected_elapsed_s": 1.2049859159160405, + "model_overlaps": [ + { + "call": 1, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.6222236156463623 + } + ], + "path": "/state", + "sequence": 383, + "wall_monotonic_offset_range_s": 0.0005612373352050781 + }, + { + "delay_finished_wall": 1791832149.664667, + "delay_started_wall": 1791832148.461329, + "genuine_upstream_elapsed_s": 0.05194795900024474, + "injected_elapsed_s": 1.2033379168715328, + "model_overlaps": [ + { + "call": 2, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2033379077911377 + } + ], + "path": "/state", + "sequence": 398, + "wall_monotonic_offset_range_s": 0.0003561973571777344 + }, + { + "delay_finished_wall": 1791832151.294802, + "delay_started_wall": 1791832150.0908835, + "genuine_upstream_elapsed_s": 0.052277165930718184, + "injected_elapsed_s": 1.2039184591267258, + "model_overlaps": [ + { + "call": 2, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20391845703125 + } + ], + "path": "/state", + "sequence": 400, + "wall_monotonic_offset_range_s": 0.00032806396484375 + }, + { + "delay_finished_wall": 1791832152.944254, + "delay_started_wall": 1791832151.7392159, + "genuine_upstream_elapsed_s": 0.07039116695523262, + "injected_elapsed_s": 1.2050380420405418, + "model_overlaps": [ + { + "call": 2, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.205038070678711 + } + ], + "path": "/state", + "sequence": 402, + "wall_monotonic_offset_range_s": 0.0005617141723632812 + }, + { + "delay_finished_wall": 1791832154.562625, + "delay_started_wall": 1791832153.3620024, + "genuine_upstream_elapsed_s": 0.060910666128620505, + "injected_elapsed_s": 1.2006225001532584, + "model_overlaps": [ + { + "call": 2, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20062255859375 + } + ], + "path": "/state", + "sequence": 404, + "wall_monotonic_offset_range_s": 0.0006086826324462891 + }, + { + "delay_finished_wall": 1791832157.187784, + "delay_started_wall": 1791832155.9839876, + "genuine_upstream_elapsed_s": 0.054760915925726295, + "injected_elapsed_s": 1.2037962921895087, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20379638671875 + } + ], + "path": "/state", + "sequence": 419, + "wall_monotonic_offset_range_s": 0.002040386199951172 + }, + { + "delay_finished_wall": 1791832158.8312519, + "delay_started_wall": 1791832157.6299183, + "genuine_upstream_elapsed_s": 0.06451662513427436, + "injected_elapsed_s": 1.2013334999792278, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2013335227966309 + } + ], + "path": "/state", + "sequence": 421, + "wall_monotonic_offset_range_s": 0.0003459453582763672 + }, + { + "delay_finished_wall": 1791832160.4510279, + "delay_started_wall": 1791832159.2491255, + "genuine_upstream_elapsed_s": 0.05649487487971783, + "injected_elapsed_s": 1.2019024998880923, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2019023895263672 + } + ], + "path": "/state", + "sequence": 423, + "wall_monotonic_offset_range_s": 0.0005939006805419922 + }, + { + "delay_finished_wall": 1791832162.102963, + "delay_started_wall": 1791832160.9011786, + "genuine_upstream_elapsed_s": 0.06587324989959598, + "injected_elapsed_s": 1.2017843751236796, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.201784372329712 + } + ], + "path": "/state", + "sequence": 425, + "wall_monotonic_offset_range_s": 0.0006198883056640625 + }, + { + "delay_finished_wall": 1791832163.716691, + "delay_started_wall": 1791832162.5151398, + "genuine_upstream_elapsed_s": 0.05449808295816183, + "injected_elapsed_s": 1.2015511670615524, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2015511989593506 + } + ], + "path": "/state", + "sequence": 427, + "wall_monotonic_offset_range_s": 0.0002949237823486328 + }, + { + "delay_finished_wall": 1791832165.361527, + "delay_started_wall": 1791832164.1579523, + "genuine_upstream_elapsed_s": 0.07102287514135242, + "injected_elapsed_s": 1.203574666986242, + "model_overlaps": [ + { + "call": 3, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.15041804313659668 + } + ], + "path": "/state", + "sequence": 429, + "wall_monotonic_offset_range_s": 0.0006797313690185547 + }, + { + "delay_finished_wall": 1791832168.0370932, + "delay_started_wall": 1791832166.8349886, + "genuine_upstream_elapsed_s": 0.09905841713771224, + "injected_elapsed_s": 1.2021046250592917, + "model_overlaps": [ + { + "call": 4, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2021045684814453 + } + ], + "path": "/state", + "sequence": 445, + "wall_monotonic_offset_range_s": 0.0002818107604980469 + }, + { + "delay_finished_wall": 1791832169.681438, + "delay_started_wall": 1791832168.4777927, + "genuine_upstream_elapsed_s": 0.09563441714271903, + "injected_elapsed_s": 1.203645166940987, + "model_overlaps": [ + { + "call": 4, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2036452293395996 + } + ], + "path": "/state", + "sequence": 447, + "wall_monotonic_offset_range_s": 0.0003516674041748047 + }, + { + "delay_finished_wall": 1791832171.319584, + "delay_started_wall": 1791832170.1186836, + "genuine_upstream_elapsed_s": 0.09399583307094872, + "injected_elapsed_s": 1.2009002920240164, + "model_overlaps": [ + { + "call": 4, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2009003162384033 + } + ], + "path": "/state", + "sequence": 449, + "wall_monotonic_offset_range_s": 0.0005812644958496094 + }, + { + "delay_finished_wall": 1791832172.953556, + "delay_started_wall": 1791832171.753168, + "genuine_upstream_elapsed_s": 0.08927262504585087, + "injected_elapsed_s": 1.200387875083834, + "model_overlaps": [ + { + "call": 4, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.32279539108276367 + } + ], + "path": "/state", + "sequence": 451, + "wall_monotonic_offset_range_s": 0.0003695487976074219 + }, + { + "delay_finished_wall": 1791832175.5946329, + "delay_started_wall": 1791832174.3903122, + "genuine_upstream_elapsed_s": 0.08938425011001527, + "injected_elapsed_s": 1.2043205830268562, + "model_overlaps": [ + { + "call": 5, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2043206691741943 + } + ], + "path": "/state", + "sequence": 466, + "wall_monotonic_offset_range_s": 0.00030350685119628906 + }, + { + "delay_finished_wall": 1791832177.2314198, + "delay_started_wall": 1791832176.030892, + "genuine_upstream_elapsed_s": 0.08454362489283085, + "injected_elapsed_s": 1.2005280000157654, + "model_overlaps": [ + { + "call": 5, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2005279064178467 + } + ], + "path": "/state", + "sequence": 468, + "wall_monotonic_offset_range_s": 0.0006012916564941406 + }, + { + "delay_finished_wall": 1791832178.8902102, + "delay_started_wall": 1791832177.6890914, + "genuine_upstream_elapsed_s": 0.10279183299280703, + "injected_elapsed_s": 1.2011187500320375, + "model_overlaps": [ + { + "call": 5, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2011187076568604 + } + ], + "path": "/state", + "sequence": 470, + "wall_monotonic_offset_range_s": 0.0003154277801513672 + }, + { + "delay_finished_wall": 1791832180.523807, + "delay_started_wall": 1791832179.3190742, + "genuine_upstream_elapsed_s": 0.09166183299385011, + "injected_elapsed_s": 1.2047327919863164, + "model_overlaps": [ + { + "call": 5, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.204732894897461 + } + ], + "path": "/state", + "sequence": 472, + "wall_monotonic_offset_range_s": 0.0003097057342529297 + }, + { + "delay_finished_wall": 1791832182.173342, + "delay_started_wall": 1791832180.9683156, + "genuine_upstream_elapsed_s": 0.09823537501506507, + "injected_elapsed_s": 1.205026458017528, + "model_overlaps": [], + "path": "/state", + "sequence": 474, + "wall_monotonic_offset_range_s": 0.0003254413604736328 + }, + { + "delay_finished_wall": 1791832184.845115, + "delay_started_wall": 1791832183.6415613, + "genuine_upstream_elapsed_s": 0.1093828750308603, + "injected_elapsed_s": 1.2035536249168217, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2035536766052246 + } + ], + "path": "/state", + "sequence": 489, + "wall_monotonic_offset_range_s": 0.0005691051483154297 + }, + { + "delay_finished_wall": 1791832186.476904, + "delay_started_wall": 1791832185.2725573, + "genuine_upstream_elapsed_s": 0.09748349990695715, + "injected_elapsed_s": 1.204346542013809, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2043466567993164 + } + ], + "path": "/state", + "sequence": 491, + "wall_monotonic_offset_range_s": 0.00036978721618652344 + }, + { + "delay_finished_wall": 1791832188.116647, + "delay_started_wall": 1791832186.9127026, + "genuine_upstream_elapsed_s": 0.09679954196326435, + "injected_elapsed_s": 1.2039444581605494, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.203944444656372 + } + ], + "path": "/state", + "sequence": 493, + "wall_monotonic_offset_range_s": 0.0013127326965332031 + }, + { + "delay_finished_wall": 1791832189.75743, + "delay_started_wall": 1791832188.5523894, + "genuine_upstream_elapsed_s": 0.0957978330552578, + "injected_elapsed_s": 1.205040582921356, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.205040693283081 + } + ], + "path": "/state", + "sequence": 495, + "wall_monotonic_offset_range_s": 0.0003192424774169922 + }, + { + "delay_finished_wall": 1791832191.387458, + "delay_started_wall": 1791832190.1836927, + "genuine_upstream_elapsed_s": 0.08754870807752013, + "injected_elapsed_s": 1.2037652910221368, + "model_overlaps": [ + { + "call": 6, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2037653923034668 + } + ], + "path": "/state", + "sequence": 497, + "wall_monotonic_offset_range_s": 0.00024628639221191406 + }, + { + "delay_finished_wall": 1791832195.1446521, + "delay_started_wall": 1791832193.9439216, + "genuine_upstream_elapsed_s": 0.19697441696189344, + "injected_elapsed_s": 1.2007305829320103, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.200730562210083 + } + ], + "path": "/state", + "sequence": 512, + "wall_monotonic_offset_range_s": 0.00048828125 + }, + { + "delay_finished_wall": 1791832196.679007, + "delay_started_wall": 1791832195.4773612, + "genuine_upstream_elapsed_s": 0.09738016710616648, + "injected_elapsed_s": 1.2016459580045193, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.201645851135254 + } + ], + "path": "/state", + "sequence": 514, + "wall_monotonic_offset_range_s": 0.000316619873046875 + }, + { + "delay_finished_wall": 1791832198.432412, + "delay_started_wall": 1791832197.22811, + "genuine_upstream_elapsed_s": 0.1660980840679258, + "injected_elapsed_s": 1.2043019169941545, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2043018341064453 + } + ], + "path": "/state", + "sequence": 516, + "wall_monotonic_offset_range_s": 0.0003120899200439453 + }, + { + "delay_finished_wall": 1791832200.023287, + "delay_started_wall": 1791832198.821372, + "genuine_upstream_elapsed_s": 0.10865400009788573, + "injected_elapsed_s": 1.2019149158149958, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2019150257110596 + } + ], + "path": "/state", + "sequence": 518, + "wall_monotonic_offset_range_s": 0.0007584095001220703 + }, + { + "delay_finished_wall": 1791832201.67074, + "delay_started_wall": 1791832200.4670024, + "genuine_upstream_elapsed_s": 0.11654558405280113, + "injected_elapsed_s": 1.2037374170031399, + "model_overlaps": [ + { + "call": 7, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.0191373825073242 + } + ], + "path": "/state", + "sequence": 520, + "wall_monotonic_offset_range_s": 0.00032782554626464844 + }, + { + "delay_finished_wall": 1791832204.3241541, + "delay_started_wall": 1791832203.1212535, + "genuine_upstream_elapsed_s": 0.11968966713175178, + "injected_elapsed_s": 1.2029006250668317, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2029006481170654 + } + ], + "path": "/state", + "sequence": 535, + "wall_monotonic_offset_range_s": 0.0002541542053222656 + }, + { + "delay_finished_wall": 1791832205.943559, + "delay_started_wall": 1791832204.7405307, + "genuine_upstream_elapsed_s": 0.09816970909014344, + "injected_elapsed_s": 1.203028209041804, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2030282020568848 + } + ], + "path": "/state", + "sequence": 537, + "wall_monotonic_offset_range_s": 0.0002627372741699219 + }, + { + "delay_finished_wall": 1791832207.5819252, + "delay_started_wall": 1791832206.377185, + "genuine_upstream_elapsed_s": 0.09490183321759105, + "injected_elapsed_s": 1.2047400001902133, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.204740047454834 + } + ], + "path": "/state", + "sequence": 539, + "wall_monotonic_offset_range_s": 0.0003991127014160156 + }, + { + "delay_finished_wall": 1791832209.210984, + "delay_started_wall": 1791832208.0081983, + "genuine_upstream_elapsed_s": 0.08556483290158212, + "injected_elapsed_s": 1.2027858330402523, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2027857303619385 + } + ], + "path": "/state", + "sequence": 541, + "wall_monotonic_offset_range_s": 0.0003407001495361328 + }, + { + "delay_finished_wall": 1791832210.8634849, + "delay_started_wall": 1791832209.658373, + "genuine_upstream_elapsed_s": 0.09433629107661545, + "injected_elapsed_s": 1.2051117080263793, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2051117420196533 + } + ], + "path": "/state", + "sequence": 543, + "wall_monotonic_offset_range_s": 0.0002968311309814453 + }, + { + "delay_finished_wall": 1791832212.57867, + "delay_started_wall": 1791832211.3756423, + "genuine_upstream_elapsed_s": 0.1304359589703381, + "injected_elapsed_s": 1.2030276670120656, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2030277252197266 + } + ], + "path": "/state", + "sequence": 545, + "wall_monotonic_offset_range_s": 0.0003571510314941406 + }, + { + "delay_finished_wall": 1791832214.220621, + "delay_started_wall": 1791832213.0155869, + "genuine_upstream_elapsed_s": 0.1333520410116762, + "injected_elapsed_s": 1.205034333979711, + "model_overlaps": [ + { + "call": 8, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.3882322311401367 + } + ], + "path": "/state", + "sequence": 547, + "wall_monotonic_offset_range_s": 0.00029397010803222656 + }, + { + "delay_finished_wall": 1791832216.812608, + "delay_started_wall": 1791832215.61119, + "genuine_upstream_elapsed_s": 0.08992187515832484, + "injected_elapsed_s": 1.2014179578982294, + "model_overlaps": [ + { + "call": 9, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2014179229736328 + } + ], + "path": "/state", + "sequence": 562, + "wall_monotonic_offset_range_s": 0.0003185272216796875 + }, + { + "delay_finished_wall": 1791832218.466902, + "delay_started_wall": 1791832217.2640164, + "genuine_upstream_elapsed_s": 0.10495808301493526, + "injected_elapsed_s": 1.2028855830430984, + "model_overlaps": [ + { + "call": 9, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.202885627746582 + } + ], + "path": "/state", + "sequence": 564, + "wall_monotonic_offset_range_s": 0.0003886222839355469 + }, + { + "delay_finished_wall": 1791832220.111368, + "delay_started_wall": 1791832218.9085712, + "genuine_upstream_elapsed_s": 0.10092691704630852, + "injected_elapsed_s": 1.2027965830639005, + "model_overlaps": [ + { + "call": 9, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2027966976165771 + } + ], + "path": "/state", + "sequence": 566, + "wall_monotonic_offset_range_s": 0.0003330707550048828 + }, + { + "delay_finished_wall": 1791832221.7597818, + "delay_started_wall": 1791832220.5593228, + "genuine_upstream_elapsed_s": 0.10268970811739564, + "injected_elapsed_s": 1.2004589578136802, + "model_overlaps": [ + { + "call": 9, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2004590034484863 + } + ], + "path": "/state", + "sequence": 568, + "wall_monotonic_offset_range_s": 0.0002837181091308594 + }, + { + "delay_finished_wall": 1791832225.4402492, + "delay_started_wall": 1791832224.2368987, + "genuine_upstream_elapsed_s": 0.12126195780001581, + "injected_elapsed_s": 1.2033504580613226, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20335054397583 + } + ], + "path": "/state", + "sequence": 583, + "wall_monotonic_offset_range_s": 0.0022809505462646484 + }, + { + "delay_finished_wall": 1791832227.076514, + "delay_started_wall": 1791832225.872466, + "genuine_upstream_elapsed_s": 0.12050370895303786, + "injected_elapsed_s": 1.2040479579009116, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2040479183197021 + } + ], + "path": "/state", + "sequence": 585, + "wall_monotonic_offset_range_s": 0.0003409385681152344 + }, + { + "delay_finished_wall": 1791832228.698619, + "delay_started_wall": 1791832227.4964974, + "genuine_upstream_elapsed_s": 0.09993179212324321, + "injected_elapsed_s": 1.2021215830463916, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2021214962005615 + } + ], + "path": "/state", + "sequence": 587, + "wall_monotonic_offset_range_s": 0.0005545616149902344 + }, + { + "delay_finished_wall": 1791832230.342627, + "delay_started_wall": 1791832229.1391137, + "genuine_upstream_elapsed_s": 0.1068087921012193, + "injected_elapsed_s": 1.2035132918972522, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2035133838653564 + } + ], + "path": "/state", + "sequence": 589, + "wall_monotonic_offset_range_s": 0.00033020973205566406 + }, + { + "delay_finished_wall": 1791832232.0394418, + "delay_started_wall": 1791832230.8349648, + "genuine_upstream_elapsed_s": 0.09745725011453032, + "injected_elapsed_s": 1.2044771250803024, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.204477071762085 + } + ], + "path": "/state", + "sequence": 591, + "wall_monotonic_offset_range_s": 0.00030493736267089844 + }, + { + "delay_finished_wall": 1791832233.691145, + "delay_started_wall": 1791832232.4860492, + "genuine_upstream_elapsed_s": 0.11080433311872184, + "injected_elapsed_s": 1.2050957919564098, + "model_overlaps": [ + { + "call": 10, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.1795988082885742 + } + ], + "path": "/state", + "sequence": 593, + "wall_monotonic_offset_range_s": 0.0002911090850830078 + }, + { + "delay_finished_wall": 1791832245.443464, + "delay_started_wall": 1791832244.2379303, + "genuine_upstream_elapsed_s": 0.12208491703495383, + "injected_elapsed_s": 1.2055337911006063, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.205533742904663 + } + ], + "path": "/state", + "sequence": 608, + "wall_monotonic_offset_range_s": 0.0003032684326171875 + }, + { + "delay_finished_wall": 1791832247.1843069, + "delay_started_wall": 1791832245.9779978, + "genuine_upstream_elapsed_s": 0.19989608298055828, + "injected_elapsed_s": 1.20630900003016, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2063090801239014 + } + ], + "path": "/state", + "sequence": 610, + "wall_monotonic_offset_range_s": 0.0006725788116455078 + }, + { + "delay_finished_wall": 1791832248.728961, + "delay_started_wall": 1791832247.5280106, + "genuine_upstream_elapsed_s": 0.10658545885235071, + "injected_elapsed_s": 1.2009502919390798, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2009503841400146 + } + ], + "path": "/state", + "sequence": 612, + "wall_monotonic_offset_range_s": 0.00034689903259277344 + }, + { + "delay_finished_wall": 1791832250.64911, + "delay_started_wall": 1791832249.445706, + "genuine_upstream_elapsed_s": 0.274660708848387, + "injected_elapsed_s": 1.2034040831495076, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.203404188156128 + } + ], + "path": "/state", + "sequence": 614, + "wall_monotonic_offset_range_s": 0.0013229846954345703 + }, + { + "delay_finished_wall": 1791832252.131116, + "delay_started_wall": 1791832250.9289129, + "genuine_upstream_elapsed_s": 0.11848937487229705, + "injected_elapsed_s": 1.202203124994412, + "model_overlaps": [ + { + "call": 11, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2022030353546143 + } + ], + "path": "/state", + "sequence": 616, + "wall_monotonic_offset_range_s": 0.00039649009704589844 + }, + { + "delay_finished_wall": 1791832255.648841, + "delay_started_wall": 1791832254.4483225, + "genuine_upstream_elapsed_s": 0.024830207927152514, + "injected_elapsed_s": 1.200518290977925, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2005183696746826 + } + ], + "path": "/identity", + "sequence": 630, + "wall_monotonic_offset_range_s": 0.00040221214294433594 + }, + { + "delay_finished_wall": 1791832257.266772, + "delay_started_wall": 1791832256.064008, + "genuine_upstream_elapsed_s": 0.029722166946157813, + "injected_elapsed_s": 1.2027640838641673, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2027640342712402 + } + ], + "path": "/identity", + "sequence": 631, + "wall_monotonic_offset_range_s": 0.00035691261291503906 + }, + { + "delay_finished_wall": 1791832258.873054, + "delay_started_wall": 1791832257.672685, + "genuine_upstream_elapsed_s": 0.03023020806722343, + "injected_elapsed_s": 1.2003691669087857, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.200369119644165 + } + ], + "path": "/identity", + "sequence": 632, + "wall_monotonic_offset_range_s": 0.0008234977722167969 + }, + { + "delay_finished_wall": 1791832260.484274, + "delay_started_wall": 1791832259.279202, + "genuine_upstream_elapsed_s": 0.029689125018194318, + "injected_elapsed_s": 1.2050719999242574, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2050719261169434 + } + ], + "path": "/identity", + "sequence": 633, + "wall_monotonic_offset_range_s": 0.0003199577331542969 + }, + { + "delay_finished_wall": 1791832262.09807, + "delay_started_wall": 1791832260.895133, + "genuine_upstream_elapsed_s": 0.03271045791916549, + "injected_elapsed_s": 1.2029367920476943, + "model_overlaps": [ + { + "call": 12, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 0.6850109100341797 + } + ], + "path": "/identity", + "sequence": 634, + "wall_monotonic_offset_range_s": 0.00032401084899902344 + }, + { + "delay_finished_wall": 1791832264.7211719, + "delay_started_wall": 1791832263.5168095, + "genuine_upstream_elapsed_s": 0.0447540411259979, + "injected_elapsed_s": 1.2043624999932945, + "model_overlaps": [ + { + "call": 13, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.204362392425537 + } + ], + "path": "/identity", + "sequence": 648, + "wall_monotonic_offset_range_s": 0.0003616809844970703 + }, + { + "delay_finished_wall": 1791832266.3139899, + "delay_started_wall": 1791832265.1089513, + "genuine_upstream_elapsed_s": 0.028605000115931034, + "injected_elapsed_s": 1.2050385000184178, + "model_overlaps": [ + { + "call": 13, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2050385475158691 + } + ], + "path": "/identity", + "sequence": 649, + "wall_monotonic_offset_range_s": 0.0003781318664550781 + }, + { + "delay_finished_wall": 1791832267.919033, + "delay_started_wall": 1791832266.7139947, + "genuine_upstream_elapsed_s": 0.02525570895522833, + "injected_elapsed_s": 1.2050382499583066, + "model_overlaps": [ + { + "call": 13, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.20503830909729 + } + ], + "path": "/identity", + "sequence": 650, + "wall_monotonic_offset_range_s": 0.00035643577575683594 + }, + { + "delay_finished_wall": 1791832269.526366, + "delay_started_wall": 1791832268.3221338, + "genuine_upstream_elapsed_s": 0.023437874857336283, + "injected_elapsed_s": 1.2042323329951614, + "model_overlaps": [ + { + "call": 13, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "overlap_s": 1.2042322158813477 + } + ], + "path": "/identity", + "sequence": 651, + "wall_monotonic_offset_range_s": 0.0003230571746826172 + }, + { + "delay_finished_wall": 1791832273.146421, + "delay_started_wall": 1791832271.9417524, + "genuine_upstream_elapsed_s": 0.026460542110726237, + "injected_elapsed_s": 1.2046686250250787, + "model_overlaps": [], + "path": "/identity", + "sequence": 661, + "wall_monotonic_offset_range_s": 0.0002894401550292969 + }, + { + "delay_finished_wall": 1791832274.7546492, + "delay_started_wall": 1791832273.5496144, + "genuine_upstream_elapsed_s": 0.02605204191058874, + "injected_elapsed_s": 1.2050346250180155, + "model_overlaps": [], + "path": "/identity", + "sequence": 662, + "wall_monotonic_offset_range_s": 0.00043654441833496094 + }, + { + "delay_finished_wall": 1791832276.3647099, + "delay_started_wall": 1791832275.159664, + "genuine_upstream_elapsed_s": 0.024871707893908024, + "injected_elapsed_s": 1.2050458330195397, + "model_overlaps": [], + "path": "/identity", + "sequence": 663, + "wall_monotonic_offset_range_s": 0.0003113746643066406 + }, + { + "delay_finished_wall": 1791832277.976248, + "delay_started_wall": 1791832276.7734878, + "genuine_upstream_elapsed_s": 0.027691290946677327, + "injected_elapsed_s": 1.2027602919843048, + "model_overlaps": [], + "path": "/identity", + "sequence": 664, + "wall_monotonic_offset_range_s": 0.00038623809814453125 + }, + { + "delay_finished_wall": 1791832279.578651, + "delay_started_wall": 1791832278.3785973, + "genuine_upstream_elapsed_s": 0.024854457937180996, + "injected_elapsed_s": 1.2000537081621587, + "model_overlaps": [], + "path": "/identity", + "sequence": 665, + "wall_monotonic_offset_range_s": 0.00032401084899902344 + }, + { + "delay_finished_wall": 1791832281.194527, + "delay_started_wall": 1791832279.9924984, + "genuine_upstream_elapsed_s": 0.027741792146116495, + "injected_elapsed_s": 1.2020284999161959, + "model_overlaps": [], + "path": "/identity", + "sequence": 666, + "wall_monotonic_offset_range_s": 0.0002951622009277344 + }, + { + "delay_finished_wall": 1791832282.808212, + "delay_started_wall": 1791832281.6038282, + "genuine_upstream_elapsed_s": 0.033845792058855295, + "injected_elapsed_s": 1.204383792122826, + "model_overlaps": [], + "path": "/identity", + "sequence": 667, + "wall_monotonic_offset_range_s": 0.00036454200744628906 + }, + { + "delay_finished_wall": 1791832284.4161339, + "delay_started_wall": 1791832283.211826, + "genuine_upstream_elapsed_s": 0.03321212506853044, + "injected_elapsed_s": 1.204307832987979, + "model_overlaps": [], + "path": "/identity", + "sequence": 668, + "wall_monotonic_offset_range_s": 0.00027680397033691406 + }, + { + "delay_finished_wall": 1791832286.023186, + "delay_started_wall": 1791832284.8185112, + "genuine_upstream_elapsed_s": 0.031950625125318766, + "injected_elapsed_s": 1.2046747910790145, + "model_overlaps": [], + "path": "/identity", + "sequence": 669, + "wall_monotonic_offset_range_s": 0.0003528594970703125 + }, + { + "delay_finished_wall": 1791832287.63012, + "delay_started_wall": 1791832286.425594, + "genuine_upstream_elapsed_s": 0.025775166926905513, + "injected_elapsed_s": 1.204525833018124, + "model_overlaps": [], + "path": "/identity", + "sequence": 670, + "wall_monotonic_offset_range_s": 0.0003333091735839844 + }, + { + "delay_finished_wall": 1791832289.234438, + "delay_started_wall": 1791832288.0331938, + "genuine_upstream_elapsed_s": 0.023571416968479753, + "injected_elapsed_s": 1.2012440001126379, + "model_overlaps": [], + "path": "/identity", + "sequence": 671, + "wall_monotonic_offset_range_s": 0.00030875205993652344 + }, + { + "delay_finished_wall": 1791832290.857811, + "delay_started_wall": 1791832289.6537929, + "genuine_upstream_elapsed_s": 0.03697133297100663, + "injected_elapsed_s": 1.2040182081982493, + "model_overlaps": [], + "path": "/identity", + "sequence": 672, + "wall_monotonic_offset_range_s": 0.0004439353942871094 + }, + { + "delay_finished_wall": 1791832292.550731, + "delay_started_wall": 1791832291.347129, + "genuine_upstream_elapsed_s": 0.10883808392100036, + "injected_elapsed_s": 1.203601917019114, + "model_overlaps": [], + "path": "/identity", + "sequence": 673, + "wall_monotonic_offset_range_s": 0.0004405975341796875 + }, + { + "delay_finished_wall": 1791832294.067949, + "delay_started_wall": 1791832292.8650882, + "genuine_upstream_elapsed_s": 0.024111542152240872, + "injected_elapsed_s": 1.2028609160333872, + "model_overlaps": [], + "path": "/identity", + "sequence": 674, + "wall_monotonic_offset_range_s": 0.00026679039001464844 + }, + { + "delay_finished_wall": 1791832295.688381, + "delay_started_wall": 1791832294.487985, + "genuine_upstream_elapsed_s": 0.035032999934628606, + "injected_elapsed_s": 1.2003959577996284, + "model_overlaps": [], + "path": "/identity", + "sequence": 675, + "wall_monotonic_offset_range_s": 0.00037360191345214844 + }, + { + "delay_finished_wall": 1791832297.2962801, + "delay_started_wall": 1791832296.0939546, + "genuine_upstream_elapsed_s": 0.03289383416995406, + "injected_elapsed_s": 1.2023255832027644, + "model_overlaps": [], + "path": "/identity", + "sequence": 676, + "wall_monotonic_offset_range_s": 0.0004773139953613281 + }, + { + "delay_finished_wall": 1791832298.916022, + "delay_started_wall": 1791832297.7152755, + "genuine_upstream_elapsed_s": 0.04468645807355642, + "injected_elapsed_s": 1.2007464580237865, + "model_overlaps": [], + "path": "/identity", + "sequence": 677, + "wall_monotonic_offset_range_s": 0.000461578369140625 + }, + { + "delay_finished_wall": 1791832300.50497, + "delay_started_wall": 1791832299.302549, + "genuine_upstream_elapsed_s": 0.024397874949499965, + "injected_elapsed_s": 1.2024210828822106, + "model_overlaps": [], + "path": "/identity", + "sequence": 678, + "wall_monotonic_offset_range_s": 0.0003190040588378906 + }, + { + "delay_finished_wall": 1791832302.12138, + "delay_started_wall": 1791832300.916171, + "genuine_upstream_elapsed_s": 0.0270841249730438, + "injected_elapsed_s": 1.205209042178467, + "model_overlaps": [], + "path": "/identity", + "sequence": 679, + "wall_monotonic_offset_range_s": 0.00034427642822265625 + }, + { + "delay_finished_wall": 1791832303.727721, + "delay_started_wall": 1791832302.5242665, + "genuine_upstream_elapsed_s": 0.025939082959666848, + "injected_elapsed_s": 1.2034545419737697, + "model_overlaps": [], + "path": "/identity", + "sequence": 680, + "wall_monotonic_offset_range_s": 0.00041365623474121094 + }, + { + "delay_finished_wall": 1791832305.343824, + "delay_started_wall": 1791832304.138787, + "genuine_upstream_elapsed_s": 0.03202695888467133, + "injected_elapsed_s": 1.2050369170028716, + "model_overlaps": [], + "path": "/identity", + "sequence": 681, + "wall_monotonic_offset_range_s": 0.00038743019104003906 + }, + { + "delay_finished_wall": 1791832306.948216, + "delay_started_wall": 1791832305.7446063, + "genuine_upstream_elapsed_s": 0.026920791948214173, + "injected_elapsed_s": 1.2036097499076277, + "model_overlaps": [], + "path": "/identity", + "sequence": 682, + "wall_monotonic_offset_range_s": 0.00027108192443847656 + }, + { + "delay_finished_wall": 1791832308.563554, + "delay_started_wall": 1791832307.3598785, + "genuine_upstream_elapsed_s": 0.031036084052175283, + "injected_elapsed_s": 1.2036756249144673, + "model_overlaps": [], + "path": "/identity", + "sequence": 683, + "wall_monotonic_offset_range_s": 0.0003514289855957031 + }, + { + "delay_finished_wall": 1791832310.165736, + "delay_started_wall": 1791832308.9651709, + "genuine_upstream_elapsed_s": 0.024415332823991776, + "injected_elapsed_s": 1.200565000064671, + "model_overlaps": [], + "path": "/identity", + "sequence": 684, + "wall_monotonic_offset_range_s": 0.0003516674041748047 + }, + { + "delay_finished_wall": 1791832311.7797499, + "delay_started_wall": 1791832310.576029, + "genuine_upstream_elapsed_s": 0.02451429096981883, + "injected_elapsed_s": 1.203720834106207, + "model_overlaps": [], + "path": "/identity", + "sequence": 685, + "wall_monotonic_offset_range_s": 0.00028967857360839844 + } + ], + "jobs": [ + { + "both_paths_overlap_model": true, + "final_status": "completed", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "path_coverage": { + "/identity": { + "healthy_injected_reads_overlapping_model": 30, + "model_calls": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "relay_sequences": [ + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 42, + 43, + 44, + 45, + 59, + 60, + 61, + 62, + 63, + 64, + 78, + 79, + 80, + 81, + 96, + 97, + 98, + 99, + 113, + 114, + 115, + 116, + 117 + ] + }, + "/state": { + "healthy_injected_reads_overlapping_model": 33, + "model_calls": [ + 8, + 9, + 10, + 11, + 12, + 13, + 14 + ], + "relay_sequences": [ + 211, + 213, + 215, + 217, + 219, + 234, + 236, + 238, + 240, + 242, + 257, + 259, + 261, + 263, + 265, + 280, + 282, + 284, + 286, + 288, + 303, + 305, + 307, + 309, + 324, + 326, + 328, + 330, + 345, + 347, + 349, + 351, + 353 + ] + } + } + }, + { + "both_paths_overlap_model": true, + "final_status": "completed", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "path_coverage": { + "/identity": { + "healthy_injected_reads_overlapping_model": 9, + "model_calls": [ + 12, + 13 + ], + "relay_sequences": [ + 630, + 631, + 632, + 633, + 634, + 648, + 649, + 650, + 651 + ] + }, + "/state": { + "healthy_injected_reads_overlapping_model": 56, + "model_calls": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "relay_sequences": [ + 373, + 375, + 377, + 379, + 381, + 383, + 398, + 400, + 402, + 404, + 419, + 421, + 423, + 425, + 427, + 429, + 445, + 447, + 449, + 451, + 466, + 468, + 470, + 472, + 489, + 491, + 493, + 495, + 497, + 512, + 514, + 516, + 518, + 520, + 535, + 537, + 539, + 541, + 543, + 545, + 547, + 562, + 564, + 566, + 568, + 583, + 585, + 587, + 589, + 591, + 593, + 608, + 610, + 612, + 614, + 616 + ] + } + } + } + ], + "limits": [ + "This supplementary audit was authored after source freeze; it does not replace the frozen qualifier.", + "Model intervals use provider started_at plus monotonic elapsed_s; delay windows use recorded send time minus measured wait.", + "Wall/monotonic offset spread is retained to expose timing precision limits.", + "Overlap establishes exposure during model planning; it does not prove the cause of the historical SIM11 timeout." + ], + "measured_control_events": [ + { + "intent": "", + "kind": "halt", + "outcome": "reply is uncertain; reconcile exact command without resending", + "seq": 66, + "time": 1791832016.9072719 + }, + { + "intent": "", + "kind": "disconnect", + "outcome": "Transport only; no body reset or replay", + "seq": 67, + "time": 1791832033.026589 + }, + { + "intent": "", + "kind": "reconnect", + "outcome": "No command sent or replayed", + "seq": 68, + "time": 1791832051.478241 + }, + { + "intent": "", + "kind": "resume", + "outcome": "", + "seq": 71, + "time": 1791832069.452853 + } + ], + "measured_cutoff_event_seq": 284, + "measured_cutoff_wall": 1791832270.9544058, + "measured_unexpected_halts": [], + "model_calls": [ + { + "call": 1, + "elapsed_s": 8.888634625123814, + "finished_wall": 1791832146.4737008, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832137.585066 + }, + { + "call": 2, + "elapsed_s": 7.371869457885623, + "finished_wall": 1791832154.8865297, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832147.5146601 + }, + { + "call": 3, + "elapsed_s": 8.43007241608575, + "finished_wall": 1791832164.3083704, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832155.878298 + }, + { + "call": 4, + "elapsed_s": 6.128192666918039, + "finished_wall": 1791832172.0759635, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832165.9477708 + }, + { + "call": 5, + "elapsed_s": 7.361145915929228, + "finished_wall": 1791832180.94438, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832173.583234 + }, + { + "call": 6, + "elapsed_s": 8.747338708955795, + "finished_wall": 1791832191.5603619, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832182.813023 + }, + { + "call": 7, + "elapsed_s": 8.426699750125408, + "finished_wall": 1791832201.4861398, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832193.0594401 + }, + { + "call": 8, + "elapsed_s": 10.435514916898683, + "finished_wall": 1791832213.403819, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832202.9683042 + }, + { + "call": 9, + "elapsed_s": 6.884068874875084, + "finished_wall": 1791832221.844614, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832214.960545 + }, + { + "call": 10, + "elapsed_s": 10.11140904109925, + "finished_wall": 1791832233.665648, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832223.554239 + }, + { + "call": 11, + "elapsed_s": 8.000156666850671, + "finished_wall": 1791832252.1834106, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832244.183254 + }, + { + "call": 12, + "elapsed_s": 7.8165919170714915, + "finished_wall": 1791832261.580144, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832253.763552 + }, + { + "call": 13, + "elapsed_s": 6.307222834089771, + "finished_wall": 1791832269.6300058, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832263.322783 + }, + { + "call": 1, + "elapsed_s": 10.586642124922946, + "finished_wall": 1791831978.080672, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791831967.49403 + }, + { + "call": 2, + "elapsed_s": 6.294448249973357, + "finished_wall": 1791831984.8089693, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791831978.5145211 + }, + { + "call": 3, + "elapsed_s": 9.542235415894538, + "finished_wall": 1791831994.7687895, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791831985.2265542 + }, + { + "call": 4, + "elapsed_s": 6.4462542498949915, + "finished_wall": 1791832001.6932354, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791831995.2469811 + }, + { + "call": 5, + "elapsed_s": 4.764401749940589, + "finished_wall": 1791832007.2908835, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832002.5264819 + }, + { + "call": 6, + "elapsed_s": 8.140898042125627, + "finished_wall": 1791832016.244656, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832008.103758 + }, + { + "call": 7, + "elapsed_s": 8.440171458059922, + "finished_wall": 1791832078.4239416, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832069.9837701 + }, + { + "call": 8, + "elapsed_s": 8.132765874965116, + "finished_wall": 1791832087.3751018, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832079.242336 + }, + { + "call": 9, + "elapsed_s": 7.226740124868229, + "finished_wall": 1791832095.51877, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832088.2920299 + }, + { + "call": 10, + "elapsed_s": 7.37742824992165, + "finished_wall": 1791832103.8689063, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832096.491478 + }, + { + "call": 11, + "elapsed_s": 8.136500083142892, + "finished_wall": 1791832112.922722, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832104.786222 + }, + { + "call": 12, + "elapsed_s": 6.762274875072762, + "finished_wall": 1791832120.609567, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832113.847292 + }, + { + "call": 13, + "elapsed_s": 6.597302458947524, + "finished_wall": 1791832128.1300006, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832121.5326982 + }, + { + "call": 14, + "elapsed_s": 7.210898624965921, + "finished_wall": 1791832136.3729286, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "outcome": "decision", + "process_exit_observed": true, + "started_wall": 1791832129.16203 + } + ], + "passed": true, + "posttrial_handoff_control_events": [ + { + "intent": "", + "kind": "halt", + "outcome": "Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image", + "seq": 285, + "time": 1791832363.512448 + }, + { + "intent": "", + "kind": "halt", + "outcome": "Remote end closed connection without response", + "seq": 287, + "time": 1791832405.32576 + } + ], + "proof_count": 83, + "proof_events_unique": true, + "strengthened_admission_bindings": [ + { + "command_id": "command-accc773656494216b8991d02cab9b603", + "passed": true + }, + { + "command_id": "command-85d8b423ec7c4a53bb1987fb1a62bdf6", + "passed": true + }, + { + "command_id": "command-b93638f4643f4d35b5cde6fde06ed807", + "passed": true + }, + { + "command_id": "command-a44e60b9d8c24bdaa49e479c4b0ef780", + "passed": true + }, + { + "command_id": "command-79dcaf5d02e048449c681748167c446a", + "passed": true + }, + { + "command_id": "command-069d2460341443e69bbcd0b5f39b91f2", + "passed": true + }, + { + "command_id": "command-20fde1f33f97495cade8fce105d16ae4", + "passed": true + }, + { + "command_id": "command-107896fd188d4b72be6d2a6debd2ba0c", + "passed": true + }, + { + "command_id": "command-1bc0e6eb4e064fe1b7b66dfbf750968a", + "passed": true + }, + { + "command_id": "command-70f9b8c19b59452693061139bda6c71b", + "passed": true + }, + { + "command_id": "command-16683e1227d84968879714ddd0556488", + "passed": true + }, + { + "command_id": "command-1fb29328cf0a4c7e800022c949b77f7a", + "passed": true + }, + { + "command_id": "command-f1e1760598fa4cd89339d2d2091f8d1a", + "passed": true + }, + { + "command_id": "command-1a4dc2ad405846ecbdfaed4b2d825f3e", + "passed": true + }, + { + "command_id": "command-55007cfbc1d7410d92d582397af2555b", + "passed": true + }, + { + "command_id": "command-ee7b8dee4444416c98f550c3e5a7c01f", + "passed": true + }, + { + "command_id": "command-77279a97fd4a4ff2aee720c0b7a46c40", + "passed": true + }, + { + "command_id": "command-3211cda07dda4c5c8dd2cc700fdaad98", + "passed": true + }, + { + "command_id": "command-e52c9ef5005a410fb80600b4ad7f947a", + "passed": true + }, + { + "command_id": "command-97245de4fa73480c87503051fc90a8a9", + "passed": true + }, + { + "command_id": "command-5457db2a5bcf4cd3ba1b306e5182ede1", + "passed": true + }, + { + "command_id": "command-d4045c653de542aea3cd3f100603a0dd", + "passed": true + }, + { + "command_id": "command-127c700baa7e4224a9f4d4d1654380fc", + "passed": true + }, + { + "command_id": "command-12d35e26325248a5881960ffcbd97a6f", + "passed": true + }, + { + "command_id": "command-fb95362e732c42c793f505dd7673ea38", + "passed": true + }, + { + "command_id": "command-5365431f8f094a738c04898a662544f5", + "passed": true + }, + { + "command_id": "command-1ca372f4627f44ca820de2e16d58a939", + "passed": true + }, + { + "command_id": "command-8074e0e06a9d46f68b944f8a3949a7d5", + "passed": true + }, + { + "command_id": "command-58c9af8646c94c0b9e453fb32e4622f1", + "passed": true + }, + { + "command_id": "command-706d43a193d349b0abb2a1a2e213670d", + "passed": true + }, + { + "command_id": "command-f01b770705654cf0b746795ef56a5e51", + "passed": true + }, + { + "command_id": "command-01c5b18c0f4848ab83a3a506c6164bd7", + "passed": true + }, + { + "command_id": "command-455161d907e44cc2a0c00c4713404a47", + "passed": true + }, + { + "command_id": "command-c085b10cc40c44539a927aa06c7a4339", + "passed": true + }, + { + "command_id": "command-7c91d1e39cc047049a3c4453e8b35923", + "passed": true + }, + { + "command_id": "command-02d0ee9bb015446e974769918792b02f", + "passed": true + }, + { + "command_id": "command-15941d3c6bb74b9a8916ec43a2fe0e1f", + "passed": true + }, + { + "command_id": "command-f615d864a28e4af88536d43c26a06e7c", + "passed": true + }, + { + "command_id": "command-d11cdb7e2538490784e2e8a2425572b7", + "passed": true + }, + { + "command_id": "command-cdf687139f2e43cab73f3afa8053018d", + "passed": true + }, + { + "command_id": "command-6db96f5e11fc4baebb1607c174a5898f", + "passed": true + }, + { + "command_id": "command-000b1a6737a14842a6b79c23e0a5ca92", + "passed": true + }, + { + "command_id": "command-72de9f33d999438198fc8b176ee89f6d", + "passed": true + }, + { + "command_id": "command-155208c1dd824b43a411bf0d9f879dc9", + "passed": true + }, + { + "command_id": "command-debb71a7f11f45b1b2093c2da309bb26", + "passed": true + }, + { + "command_id": "command-8fe46178c8564d2b8af7b48dd51ceb69", + "passed": true + }, + { + "command_id": "command-1fdd5229845447258a05de892ad29824", + "passed": true + }, + { + "command_id": "command-7e14ebef15814262bf16ee0a417469ea", + "passed": true + }, + { + "command_id": "command-a6931c3bf281480fb0dd090384b20178", + "passed": true + }, + { + "command_id": "command-5a3fb52b0a34409da8c43ce284d498f8", + "passed": true + }, + { + "command_id": "command-6371aeae6cdb432c851d1a095b64f85e", + "passed": true + }, + { + "command_id": "command-020d09130bdf4e10b2e30aed41ee93fd", + "passed": true + }, + { + "command_id": "command-185d0f856fbc4990be03fb5a4d680444", + "passed": true + }, + { + "command_id": "command-271d260ff225464ca18069efe6b89a3f", + "passed": true + }, + { + "command_id": "command-8bc103965b3b4b548f0ab2a4f6529315", + "passed": true + }, + { + "command_id": "command-52b299434a2a4354ae1a0c27f7afda73", + "passed": true + }, + { + "command_id": "command-b50b8172d84a4c2ca69c1b13799c0cd3", + "passed": true + }, + { + "command_id": "command-55878c3e64e7438786d949269a3ca632", + "passed": true + }, + { + "command_id": "command-3c4907bffd1043b7841f4f7a81e14c2e", + "passed": true + }, + { + "command_id": "command-a3d1bf0c87ed4d748bcfddf5acbcdbc8", + "passed": true + }, + { + "command_id": "command-c2820c925b7b43e48231001f02731ba6", + "passed": true + }, + { + "command_id": "command-8a9753d1c9604e3094a1478b421465f0", + "passed": true + }, + { + "command_id": "command-c21a6cfb3b154f799bb67d2695787ef8", + "passed": true + }, + { + "command_id": "command-6d7f70c0e5b14d6494d7eb02930b9d66", + "passed": true + }, + { + "command_id": "command-7d2c4e20bc454be996d99dc7edeea280", + "passed": true + }, + { + "command_id": "command-3352c7fd2fb14ffcaf69c1b27c6c53d9", + "passed": true + }, + { + "command_id": "command-896ce409c627486b9104d8d7415cefd3", + "passed": true + }, + { + "command_id": "command-1875feda0eaf4c058b771536779ccd62", + "passed": true + }, + { + "command_id": "command-844f1072836b419fa30a4c4f4a8697f1", + "passed": true + }, + { + "command_id": "command-7d6435405eaf4824b97108643856b361", + "passed": true + }, + { + "command_id": "command-7408e15ea38244a592d2800662c2b3c8", + "passed": true + }, + { + "command_id": "command-3cdfb3055b044aeeb059afc8731dac9c", + "passed": true + }, + { + "command_id": "command-59ebc979948340c1bceb69a8e01ac2aa", + "passed": true + }, + { + "command_id": "command-7761812fccc94a208c8f3e2dc26c28ec", + "passed": true + }, + { + "command_id": "command-2e37938e1f6a4a63b928572e1cf365af", + "passed": true + }, + { + "command_id": "command-e6cd1a382110409ab381d5fd4c4cc3b0", + "passed": true + }, + { + "command_id": "command-34752e8b30564841a21d087d561a5930", + "passed": true + }, + { + "command_id": "command-c966c8b893db42eb84c5b0616acca391", + "passed": true + }, + { + "command_id": "command-c8ad5019377e44159aef0ee22364b18f", + "passed": true + }, + { + "command_id": "command-10a03ed616ea4d96a26e96ae0973c32b", + "passed": true + }, + { + "command_id": "command-6b6e57d717d249c7811ef4708c6b8667", + "passed": true + }, + { + "command_id": "command-594d54e2793d428bbb42f80713e94ed3", + "passed": true + }, + { + "command_id": "command-bd5377590da74532a8333ac5ca2a72b3", + "passed": true + } + ], + "trace_scope_note": "Append-only journals include later paused handoff administration. Events through the retained final-public snapshot are measured; subsequent events are reported separately.", + "unused_admission_proof_events": [] +} diff --git a/jevdual/results/workbench-health-20261012/review-audit.py b/jevdual/results/workbench-health-20261012/review-audit.py new file mode 100644 index 0000000..0164084 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/review-audit.py @@ -0,0 +1,176 @@ +"""Supplemental post-run, read-only evidence audit; writes only its own result. + +This audit is not the preregistered frozen qualifier. It checks causal coverage +that the frozen qualifier's aggregate delay counter alone cannot establish. +""" +import hashlib +import json +import os +import sys +from pathlib import Path + +sys.dont_write_bytecode = True +ROOT = Path(__file__).resolve().parent +SOURCE_DIR = ROOT.parents[1] +REPO = SOURCE_DIR.parents[1] +sys.path.insert(0, str(SOURCE_DIR)) + + +def read(path): + return json.loads(path.read_bytes()) + + +def sha(content): + return hashlib.sha256(content).hexdigest() + + +def overlap(left_start, left_end, right_start, right_end): + return max(0.0, min(left_end, right_end) - max(left_start, right_start)) + + +def audit(): + frozen = read(ROOT / 'source-freeze.json') + unchanged = all(sha((REPO / name).read_bytes()) == digest for name, digest in frozen['files'].items()) + if not unchanged: + raise RuntimeError('Frozen evidence helpers changed; do not run a changed scorer against this trial') + import score_workbench_health as scorer + # Invoke only the helper functions with no persistence, dispatch or native-state access. + process = read(ROOT / 'process-ledger.json') + final = read(ROOT / 'final-public.json') + identity = read(ROOT / 'identity.json') + records, relay_valid = scorer.relay_records(ROOT) + final_sequence = max(event['seq'] for event in final['activity']) + final_wall = max(event['time'] for event in final['activity']) + all_events = [read(path) for path in sorted((ROOT / 'operator' / 'events').glob('*.json'))] + events = [event for event in all_events if event['seq'] <= final_sequence] + posttrial_events = [event for event in all_events if event['seq'] > final_sequence] + measured_request_count = read(ROOT / 'health-relay' / 'cleanup.json')['request_count'] + records = [record for record in records if record['request']['sequence'] <= measured_request_count] + proofs = scorer.fresh_admissions(records, events, identity) + measured_calls = {job['job_id']: job['call_count'] for job in final['jobs']} + calls = [] + for directory in sorted((ROOT / 'operator' / 'calls').iterdir()): + if not directory.is_dir(): + continue + reservation = read(directory / 'reservation.json') + result = read(directory / 'outcome.json') + if reservation['job_id'] not in measured_calls or reservation['call'] > measured_calls[reservation['job_id']]: + continue + calls.append({'job_id': reservation['job_id'], 'call': reservation['call'], + 'started_wall': result['started_at'], 'finished_wall': result['started_at'] + result['elapsed_s'], + 'elapsed_s': result['elapsed_s'], 'outcome': result['outcome'], + 'process_exit_observed': result['process_exit_observed']}) + delays = [] + for record in records: + request, upstream, result = record['request'], record['upstream'], record['result'] + if not (request['tagged_health'] and request['injected_delay_s'] == 1.2 and upstream and + upstream['http_status'] == 200 and result.get('completed') and result.get('delivered') and + not result.get('delay_interrupted') and result.get('delay_elapsed_s', 0) >= 1.2): + continue + remote = json.loads(record['content']) + healthy = remote == identity if request['path'] == '/identity' else remote.get('identity') == identity and remote.get('state') == 'ready' + if not healthy: + continue + # The delay ends immediately before send/record. Subtracting the measured + # monotonic duration maps the real wait into the recorded wall interval. + ended = result['finished_wall'] + started = ended - result['delay_elapsed_s'] + matches = [{'job_id': call['job_id'], 'call': call['call'], + 'overlap_s': overlap(started, ended, call['started_wall'], call['finished_wall'])} + for call in calls if overlap(started, ended, call['started_wall'], call['finished_wall']) > 0] + offsets = [request['started_wall'] - request['started_monotonic'], + upstream['wall'] - upstream['finished_monotonic'], + result['finished_wall'] - result['finished_monotonic']] + delays.append({'sequence': request['sequence'], 'path': request['path'], + 'delay_started_wall': started, 'delay_finished_wall': ended, + 'injected_elapsed_s': result['delay_elapsed_s'], + 'genuine_upstream_elapsed_s': upstream['upstream_elapsed_s'], + 'wall_monotonic_offset_range_s': max(offsets) - min(offsets), 'model_overlaps': matches}) + jobs = [] + for job in final['jobs']: + per_path = {} + for path in ('/identity', '/state'): + matches = [delay for delay in delays if delay['path'] == path and + any(match['job_id'] == job['job_id'] for match in delay['model_overlaps'])] + per_path[path] = {'healthy_injected_reads_overlapping_model': len(matches), + 'relay_sequences': [delay['sequence'] for delay in matches], + 'model_calls': sorted({match['call'] for delay in matches for match in delay['model_overlaps'] + if match['job_id'] == job['job_id']})} + jobs.append({'job_id': job['job_id'], 'label': job['label'], 'final_status': job['status'], + 'path_coverage': per_path, 'both_paths_overlap_model': all(value['healthy_injected_reads_overlapping_model'] for value in per_path.values())}) + selected_proofs = [proof['proof_event'] for proof in proofs] + selected_reads = [proof['state_read_sequence'] for proof in proofs] + admission_events = [event for event in events if event['kind'] == 'admission_proof'] + unique_proofs = (bool(proofs) and all(proof['passed'] for proof in proofs) and + len(selected_proofs) == len(set(selected_proofs)) and len(selected_reads) == len(set(selected_reads))) + # Tighten the trace check beyond merely finding a matching ready digest: + # each chosen full-state reply must complete, reach its caller, and bind the + # relay request/lease/command identity to the same immutable body. + by_sequence = {record['request']['sequence']: record for record in records} + strengthened = [] + expected_headers = {'x-body-id': identity['body_id'], 'x-adapter-id': identity['adapter_id'], + 'x-source-sha256': identity['source_sha256']} + for proof in proofs: + state = by_sequence.get(proof['state_read_sequence']) + lease = by_sequence.get(proof['lease_sequence']) + command = by_sequence.get(proof['command_sequence']) + ok = bool(proof['passed'] and state and lease and command) + if ok: + command_payload, lease_payload = json.loads(command['payload']), json.loads(lease['payload']) + state_headers = {key.lower(): value for key, value in state['request']['headers'].items()} + command_headers = {key.lower(): value for key, value in command['request']['headers'].items()} + lease_result = json.loads(lease['content']) + ok = bool(state['result'].get('completed') and state['result'].get('delivered') and + lease['result'].get('completed') and lease['result'].get('delivered') and + all(state_headers.get(key) == command_headers.get(key) == value for key, value in expected_headers.items()) and + all(command_payload[key] == identity[key] for key in ('body_id', 'adapter_id', 'source_sha256', 'epoch')) and + command_payload['client_id'] == lease_payload['client_id'] == lease_result['client_id']) + strengthened.append({'command_id': proof['command_id'], 'passed': ok}) + cancelled = [call for call in calls if call['outcome'] == 'cancelled'] + control_kinds = ('pause', 'disconnect', 'reconnect', 'halt', 'resume') + control_events = [event for event in events if event['kind'] in control_kinds] + posttrial_controls = [event for event in posttrial_events if event['kind'] in control_kinds] + steps = {step['name']:step for step in read(ROOT / 'ui-ledger.json')['steps']} + expected_unknown_reason = steps['uncertain']['state']['recovery']['reason'] + unexpected_halts = [event for event in control_events if event['kind'] == 'halt' and event['outcome'] != expected_unknown_reason] + checking = next((step for step in read(ROOT / 'ui-ledger.json')['steps'] if step['name'] == 'healthy_checking'), None) + checking_same_identity = bool(checking and checking['state']['app_id'] == final['app_id'] and + checking['state']['connection']['body_id'] == identity['body_id'] and + checking['state']['active_job_id'] in {job['job_id'] for job in final['jobs']}) + coverage = len(jobs) == 2 and all(job['both_paths_overlap_model'] for job in jobs) + result = {'audit_kind': 'supplemental_post_run_read_only_review', 'frozen_source_commit': frozen['commit'], + 'audit_source_sha256': sha(Path(__file__).read_bytes()), 'frozen_source_unchanged': unchanged, + 'passed': bool(coverage and not cancelled and unique_proofs and all(value['passed'] for value in strengthened) and + checking_same_identity and relay_valid and process['owned_processes_exited'] and not unexpected_halts), + 'both_jobs_both_paths_overlap_actual_model': coverage, 'jobs': jobs, + 'healthy_delayed_reads': delays, 'model_calls': calls, 'cancelled_calls': cancelled, + 'proof_count': len(proofs), 'proof_events_unique': unique_proofs, + 'strengthened_admission_bindings': strengthened, + 'unused_admission_proof_events': [event['seq'] for event in admission_events if event['seq'] not in selected_proofs], + 'healthy_checking_same_application_and_body': checking_same_identity, + 'measured_control_events': control_events, 'measured_unexpected_halts': unexpected_halts, + 'posttrial_handoff_control_events': posttrial_controls, + 'measured_cutoff_event_seq': final_sequence, 'measured_cutoff_wall': final_wall, + 'trace_scope_note': 'Append-only journals include later paused handoff administration. Events through the retained final-public snapshot are measured; subsequent events are reported separately.', + 'limits': ['This supplementary audit was authored after source freeze; it does not replace the frozen qualifier.', + 'Model intervals use provider started_at plus monotonic elapsed_s; delay windows use recorded send time minus measured wait.', + 'Wall/monotonic offset spread is retained to expose timing precision limits.', + 'Overlap establishes exposure during model planning; it does not prove the cause of the historical SIM11 timeout.']} + destination = ROOT / 'review-audit.json' + original = ROOT / 'review-audit-unscoped.json' + if destination.exists() and not original.exists(): + original_fd = os.open(original, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600) + with os.fdopen(original_fd, 'wb') as output: + output.write(destination.read_bytes()) + staged = ROOT / 'review-audit-scoped.json' + fd = os.open(staged, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600) + with os.fdopen(fd, 'w') as output: + json.dump(result, output, sort_keys=True, indent=2, allow_nan=False) + output.write('\n') + os.replace(staged, destination) + print(json.dumps({key: result[key] for key in ('passed', 'both_jobs_both_paths_overlap_actual_model', + 'proof_count', 'proof_events_unique', 'healthy_checking_same_application_and_body')})) + + +if __name__ == '__main__': + audit() diff --git a/jevdual/results/workbench-health-20261012/source-freeze.json b/jevdual/results/workbench-health-20261012/source-freeze.json new file mode 100644 index 0000000..e88bb54 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/source-freeze.json @@ -0,0 +1,33 @@ +{ + "commit": "37ebfdb3054b977149d7b60b46254ddd852b749a", + "files": { + "tools/camera-capture-experiment/capture.py": "3623fcad2a6ec0135af2452d50403bad7c508f80795c0f98417ccc9446a56f7b", + "tools/physical-workcell/agent_bench.py": "e120dbfc9a96ca07fedb15226f27282265203755866210b86d5f856f6e3f5e07", + "tools/physical-workcell/bench.py": "f35b9fdca2c093d4a93bcdb7797ff252f40e7165494e4ee6a957c6d2db5bd4b2", + "tools/physical-workcell/body_client.py": "40388c238192d923888c9852b363314801dcf65c7266aadc8c377d3810aeb33d", + "tools/physical-workcell/body_network.py": "95fd21597bcdd9e982a698859cd1219ae4522062e332c50fea233629dbfb343c", + "tools/physical-workcell/body_protocol.py": "1d24066768105c28b5cf6f4d46458e4e1b9d86cbde45ed6ce466b30da7ff974f", + "tools/physical-workcell/codex-action.schema.json": "e57197e4e73aa4c78145814a460ca77b9c6dc5e49aaf4c91adc0b521b7c3d833", + "tools/physical-workcell/codex-policy.md": "ce947200b2a652e0766b422f3b404bd5095ceb398569341466b2c5f4dd9647bc", + "tools/physical-workcell/codex_policy.py": "40fe73e01d97ee1e5cfdb813650b11edadbea29534784ab10cc1ef4e7f4d5418", + "tools/physical-workcell/episode_cases.py": "c746a6df8f1f9554633266fcd5363b8001f21eb3d334a5e90ffed4b6ad219029", + "tools/physical-workcell/image_guided.py": "572206e18f900776d951b40802d57112a86b22766eb9f7f83bf7a2410328e961", + "tools/physical-workcell/measurement.py": "21900e9297ac15499642cf106b303836b40bb1b19f128f8008ef400a881f7f9e", + "tools/physical-workcell/network_bench_operator.html": "75ca82328967ea65cf3c3f7f7d60c109a4201099ae3a24d3834e0ecf19b4d897", + "tools/physical-workcell/network_bench_operator.py": "9079729ea4e8b56ccdf2a6d187b0c5d79a23a33688748fe55d92d10922500b40", + "tools/physical-workcell/network_fault_proxy.py": "44b0b52f7c213c0f5f93b8997ba72be4e750bc9f1a4f7f6d7b2a8c4f1233b595", + "tools/physical-workcell/network_operator_runtime.py": "001511aa25fef7f1078bce444b9a0f7d0a09d26d4e5fba9e9819ee3ed98cb6b9", + "tools/physical-workcell/order_protocol.py": "d5d9824149e3ed68d15ec4b62e36c406cdc64b8df0cc945ece13f34f13449d5e", + "tools/physical-workcell/qualify_bench.py": "524c537c1b310a0f0ae493acee99a069966a5e7c4b0a783daadf347094db58ef", + "tools/physical-workcell/qualify_network_body.py": "2800cf38afd21b86f8b035c46e994b6f96d966db4ccba1bba703e9e1a22f7c2b", + "tools/physical-workcell/qualify_network_workbench.py": "e5c72acda2ea8fae3658faba907448765df2f1e34e05749fbe85faed28ef003b", + "tools/physical-workcell/qualify_workbench_health.py": "2b73c4b57319dc24afcde062b2782e572fd6abf8d6d3db558133eefc60271e08", + "tools/physical-workcell/record_network_workbench.py": "7604865caa309c7002c01a2384da84eb62d8b22dcd63ab256618c536bc5fedc4", + "tools/physical-workcell/scene.xml": "f411f7632d5df2035c780d26d43e8a066991afe501438daefeedaa68455f251f", + "tools/physical-workcell/score_network_body.py": "d1f7150a5ff23775664b5656fd21379502ba71175487fd7aadb2b51bffcdaf8c", + "tools/physical-workcell/score_network_workbench.py": "67a53586081fe425bd14b0a0fbbf3d7f0fc1e66daccda06765bb88f3d9d4d84c", + "tools/physical-workcell/score_workbench_health.py": "0b5f7a047004f9d566451b88a2c3101403641b0fd0a432da3d93e827d306843a", + "tools/physical-workcell/workbench_link.py": "79571f62c5a9b5fb843a852bc34a2a509b0dc6dc1a6e091fa9f948ab98fae420", + "tools/physical-workcell/workcell.py": "d7034fc6d528c4476aecb3094e7a0b8fd22d3e09b407e056a4a18a8cf1e5b1e2" + } +} diff --git a/jevdual/results/workbench-health-20261012/summary.json b/jevdual/results/workbench-health-20261012/summary.json new file mode 100644 index 0000000..ec4cd7e --- /dev/null +++ b/jevdual/results/workbench-health-20261012/summary.json @@ -0,0 +1,32 @@ +{ + "measured_final_event": { + "intent": "Health inspection 02", + "kind": "rpc_applied", + "outcome": "dispatch: command-bd5377590da74532a8333ac5ca2a72b3", + "seq": 284, + "time": 1791832270.9544058 + }, + "health_passed": true, + "complete_jobs": 2, + "actual_model_calls": 27, + "commands": 83, + "cancelled": [], + "unexpected_halts": [], + "delayed_healthy_reads": 173, + "natural_upstream_long_reads": 0, + "fresh_proof_every_rpc": true, + "jobs": [ + { + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "model_calls": 14, + "reset_generation": 11, + "contact_samples": 3166 + }, + { + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "model_calls": 13, + "reset_generation": 21, + "contact_samples": 3304 + } + ] +} diff --git a/jevdual/results/workbench-health-20261012/ui-ledger.json b/jevdual/results/workbench-health-20261012/ui-ledger.json new file mode 100644 index 0000000..568b4f8 --- /dev/null +++ b/jevdual/results/workbench-health-20261012/ui-ledger.json @@ -0,0 +1,758 @@ +{ + "steps": [ + { + "browser_action": "Observed active image planning with Checking body under tagged 1.2 second reply delay", + "client_commands": 11, + "name": "healthy_checking", + "pending_command_ids": [], + "screenshot": "healthy_checking.png", + "state": { + "active_job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Health read delayed; fresh body proof is required before any command", + "state": "checking" + }, + "current_frame": { + "available": true, + "generation": 3, + "image_url": "/api/frame?generation=3&sha256=abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b" + }, + "jobs": [ + { + "call_count": 4, + "disturbance_test": false, + "error": null, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Retract the pusher left to clear contact before measuring the centered block.", + "measurement": null, + "phase": "prepare", + "reset": null, + "status": "running", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": true, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No uncertain command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791832001.6553578, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t60 checkbox Health inspection 01 Working, Value: 1\n\t\t\t61 checkbox Health inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t62 text Health inspection 01\n\t\t63 text Running\n\t\t16 button Pause, ID: pause\n\t\t64 text A health reply is delayed. Planning can continue; commands require a fresh body check.\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t65 text Checking body\n\t\t\t66 text Health read delayed; fresh body proof is required before any command\n\t\t\t21 button Disconnect, ID: disconnect\n\t\t\t22 button (disabled) Check receipt, ID: reconcile\n\t\t\t23 button (collapsed) Test the simulated connection, Secondary Actions: Expand\n\t\t\t\t24 text Test the simulated connection\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t67 text Last observation \u00b7 health unconfirmed\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t68 text Last captured \u00b7 health unconfirmed \u00b7 generation 2\n\t\t69 text AI IS PLANNING\n\t\t70 text Planning the next move from the latest camera image.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t71 text Pending\n\t\t\t39 text The part\u2019s visible footprint will be measured after its placement is verified." + }, + { + "browser_action": "Lost exactly one dispatch reply in the browser; successor blocked", + "client_commands": 19, + "name": "uncertain", + "pending_command_ids": [ + "command-e52c9ef5005a410fb80600b4ad7f947a" + ], + "screenshot": "uncertain.png", + "state": { + "active_job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Health read delayed; fresh body proof is required before any command", + "state": "checking" + }, + "current_frame": { + "available": true, + "generation": 3, + "image_url": "/api/frame?generation=3&sha256=abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b" + }, + "jobs": [ + { + "call_count": 6, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Move the pusher into the upper bypass lane before crossing to the block's right side.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "resetting", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-e52c9ef5005a410fb80600b4ad7f947a", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791832029.627487, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t87 checkbox Health inspection 01 Needs attention, Value: 1\n\t\t\t88 checkbox Health inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t89 text Health inspection 01\n\t\t90 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t91 text reply is uncertain; reconcile exact command without resending\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t92 text Checking body\n\t\t\t93 text Health read delayed; fresh body proof is required before any command\n\t\t\t21 button Disconnect, ID: disconnect\n\t\t\t22 button Check receipt, ID: reconcile\n\t\t\t66 container\n\t\t\t\t67 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t68 text Test the simulated connection\n\t\t\t\t69 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t70 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t71 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t72 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t94 text No reply fault armed.\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t95 text Last observation \u00b7 health unconfirmed\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t96 text Last captured \u00b7 health unconfirmed \u00b7 generation 3\n\t\t97 text OUTCOME UNCERTAIN\n\t\t98 text The command outcome is uncertain. Reconnect if needed, then check its receipt before continuing.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t99 text Historical result\n\t\t\t79 container measurement-result\n\t\t\t\t100 text 1,726\n\t\t\t\t81 text Orange pixels\n\t\t\t\t82 container\n\t\t\t\t\t101 text 4,794.4\n\t\t\t\t\t84 text mm\u00b2\n\t\t\t\t85 text Apparent footprint\n\t\t\t\t86 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment." + }, + { + "browser_action": "Clicked Disconnect with the exact pending command retained", + "client_commands": 19, + "name": "disconnected", + "pending_command_ids": [ + "command-e52c9ef5005a410fb80600b4ad7f947a" + ], + "screenshot": "disconnected.png", + "state": { + "active_job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Diagnostic link disconnected; cached observations are retained", + "state": "disconnected" + }, + "current_frame": { + "available": true, + "generation": 3, + "image_url": "/api/frame?generation=3&sha256=abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b" + }, + "jobs": [ + { + "call_count": 6, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Move the pusher into the upper bypass lane before crossing to the block's right side.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "resetting", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-e52c9ef5005a410fb80600b4ad7f947a", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791832038.488682, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t87 checkbox Health inspection 01 Needs attention, Value: 1\n\t\t\t88 checkbox Health inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t89 text Health inspection 01\n\t\t90 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t91 text reply is uncertain; reconcile exact command without resending\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t92 text Body disconnected\n\t\t\t93 text Diagnostic link disconnected; cached observations are retained\n\t\t\t21 button Reconnect, ID: disconnect\n\t\t\t22 button (disabled) Check receipt, ID: reconcile\n\t\t\t66 container\n\t\t\t\t67 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t68 text Test the simulated connection\n\t\t\t\t69 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t70 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t71 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t72 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t94 text No reply fault armed.\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t95 text Retained observation \u00b7 body offline\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t96 text Retained \u00b7 offline \u00b7 generation 3\n\t\t97 text DISCONNECTED\n\t\t98 text The body connection is unavailable. The last camera observation is retained.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t99 text Historical result\n\t\t\t79 container measurement-result\n\t\t\t\t100 text 1,726\n\t\t\t\t81 text Orange pixels\n\t\t\t\t82 container\n\t\t\t\t\t101 text 4,794.4\n\t\t\t\t\t84 text mm\u00b2\n\t\t\t\t85 text Apparent footprint\n\t\t\t\t86 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment." + }, + { + "browser_action": "Observed Check receipt disabled offline; no effect or receipt request sent", + "client_commands": 19, + "name": "offline_receipt", + "pending_command_ids": [ + "command-e52c9ef5005a410fb80600b4ad7f947a" + ], + "screenshot": "offline_receipt.png", + "state": { + "active_job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Diagnostic link disconnected; cached observations are retained", + "state": "disconnected" + }, + "current_frame": { + "available": true, + "generation": 3, + "image_url": "/api/frame?generation=3&sha256=abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b" + }, + "jobs": [ + { + "call_count": 6, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Move the pusher into the upper bypass lane before crossing to the block's right side.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "resetting", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-e52c9ef5005a410fb80600b4ad7f947a", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791832047.263253, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t105 checkbox Health inspection 01 Needs attention, Value: 1\n\t\t\t106 checkbox Health inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t107 text Health inspection 01\n\t\t108 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t109 text reply is uncertain; reconcile exact command without resending\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t110 text Body disconnected\n\t\t\t111 text Diagnostic link disconnected; cached observations are retained\n\t\t\t21 button Reconnect, ID: disconnect\n\t\t\t22 button (disabled) Check receipt, ID: reconcile\n\t\t\t66 container\n\t\t\t\t67 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t68 text Test the simulated connection\n\t\t\t\t69 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t70 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t71 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t72 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t112 text No reply fault armed.\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t113 text Retained observation \u00b7 body offline\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t114 text Retained \u00b7 offline \u00b7 generation 3\n\t\t115 text DISCONNECTED\n\t\t116 text The body connection is unavailable. The last camera observation is retained.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t117 text Historical result\n\t\t\t79 container measurement-result\n\t\t\t\t118 text 1,726\n\t\t\t\t81 text Orange pixels\n\t\t\t\t82 container\n\t\t\t\t\t119 text 4,794.4\n\t\t\t\t\t84 text mm\u00b2\n\t\t\t\t85 text Apparent footprint\n\t\t\t\t86 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment." + }, + { + "browser_action": "Clicked Reconnect; same pending command retained and runner still stopped", + "client_commands": 19, + "name": "reconnected", + "pending_command_ids": [ + "command-e52c9ef5005a410fb80600b4ad7f947a" + ], + "screenshot": "reconnected.png", + "state": { + "active_job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 3, + "image_url": "/api/frame?generation=3&sha256=abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b" + }, + "jobs": [ + { + "call_count": 6, + "disturbance_test": false, + "error": "reply is uncertain; reconcile exact command without resending", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Move the pusher into the upper bypass lane before crossing to the block's right side.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "resetting", + "reset": null, + "status": "unknown", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-e52c9ef5005a410fb80600b4ad7f947a", + "operation": "dispatch", + "reason": "reply is uncertain; reconcile exact command without resending", + "state": "uncertain" + }, + "runner_status": "blocked" + }, + "time": 1791832056.7812228, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button (disabled) \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t105 checkbox Health inspection 01 Needs attention, Value: 1\n\t\t\t106 checkbox Health inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t107 text Health inspection 01\n\t\t108 text Needs attention\n\t\t16 button (disabled) Pause, ID: pause\n\t\t109 text reply is uncertain; reconcile exact command without resending\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t110 text Body connected\n\t\t\t111 text Body identity verified by read-only TCP health\n\t\t\t21 button Disconnect, ID: disconnect\n\t\t\t22 button Check receipt, ID: reconcile\n\t\t\t66 container\n\t\t\t\t67 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t68 text Test the simulated connection\n\t\t\t\t69 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t70 button (disabled) Lose next reply, ID: fault-drop\n\t\t\t\t71 button (disabled) Delay next reply, ID: fault-delay\n\t\t\t\t72 button (disabled) Duplicate next command, ID: fault-duplicate\n\t\t\t\t112 text No reply fault armed.\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t113 text Last observation \u00b7 Health inspection 01\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t114 text Captured \u00b7 generation 3\n\t\t115 text OUTCOME UNCERTAIN\n\t\t116 text The command outcome is uncertain. Reconnect if needed, then check its receipt before continuing.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t117 text Recorded\n\t\t\t79 container measurement-result\n\t\t\t\t118 text 1,726\n\t\t\t\t81 text Orange pixels\n\t\t\t\t82 container\n\t\t\t\t\t119 text 4,794.4\n\t\t\t\t\t84 text mm\u00b2\n\t\t\t\t85 text Apparent footprint\n\t\t\t\t86 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment." + }, + { + "browser_action": "Clicked Check receipt; exact result recovered while paused with unchanged command count", + "client_commands": 19, + "name": "recovered", + "pending_command_ids": [], + "screenshot": "recovered.png", + "state": { + "active_job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 3, + "image_url": "/api/frame?generation=3&sha256=abd56127579f6a8c8dd685d44e7d633a4b7f230837d5892d1b0d10b71bbddd4b" + }, + "jobs": [ + { + "call_count": 6, + "disturbance_test": false, + "error": null, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Move the pusher into the upper bypass lane before crossing to the block's right side.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "resetting", + "reset": null, + "status": "paused", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": "command-e52c9ef5005a410fb80600b4ad7f947a", + "operation": "dispatch", + "reason": "Exact historical stage recovered; explicit Resume observes fresh evidence", + "state": "recovered" + }, + "runner_status": "paused" + }, + "time": 1791832066.375594, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t105 checkbox Health inspection 01 Paused, Value: 1\n\t\t\t106 checkbox Health inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t107 text Health inspection 01\n\t\t108 text Paused\n\t\t16 button Resume, ID: pause\n\t\t109 text Receipt recovered. The agent is paused; choose Resume to observe the bench again and continue.\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t110 text Body connected\n\t\t\t111 text Body identity verified by read-only TCP health\n\t\t\t21 button Disconnect, ID: disconnect\n\t\t\t22 button (disabled) Check receipt, ID: reconcile\n\t\t\t66 container\n\t\t\t\t67 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t68 text Test the simulated connection\n\t\t\t\t69 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t70 button Lose next reply, ID: fault-drop\n\t\t\t\t71 button Delay next reply, ID: fault-delay\n\t\t\t\t72 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t112 text No reply fault armed.\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t113 text Last observation \u00b7 Health inspection 01\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t114 text Captured \u00b7 generation 3\n\t\t115 text RECEIPT RECOVERED\n\t\t116 text The exact command receipt was recovered. The agent is paused until you resume.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t117 text Recorded\n\t\t\t79 container measurement-result\n\t\t\t\t118 text 1,726\n\t\t\t\t81 text Orange pixels\n\t\t\t\t82 container\n\t\t\t\t\t119 text 4,794.4\n\t\t\t\t\t84 text mm\u00b2\n\t\t\t\t85 text Apparent footprint\n\t\t\t\t86 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment." + }, + { + "browser_action": "Explicit Resume checks body boot and obtains a fresh camera image", + "client_commands": 20, + "name": "resumed", + "pending_command_ids": [], + "screenshot": "resumed.png", + "state": { + "active_job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Body identity verified by read-only TCP health", + "state": "connected" + }, + "current_frame": { + "available": true, + "generation": 4, + "image_url": "/api/frame?generation=4&sha256=6d7772846a1b09beea21e40b6dbcbfd87a77a3c2bb5158871088d89f9fc03518" + }, + "jobs": [ + { + "call_count": 7, + "disturbance_test": false, + "error": null, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Move the pusher into the upper bypass lane before crossing to the block's right side.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "resetting", + "reset": null, + "status": "running", + "target": "A" + }, + { + "call_count": 0, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "", + "measurement": null, + "phase": null, + "reset": null, + "status": "queued", + "target": "B" + } + ], + "model_request_pending": true, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791832078.293568, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t105 checkbox Health inspection 01 Paused, Value: 1\n\t\t\t106 checkbox Health inspection 02 Queued, Value: 0\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t107 text Health inspection 01\n\t\t108 text Running\n\t\t16 button Pause, ID: pause\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t109 text Body connected\n\t\t\t110 text Current body boot verified for explicit Resume\n\t\t\t21 button Disconnect, ID: disconnect\n\t\t\t22 button (disabled) Check receipt, ID: reconcile\n\t\t\t66 container\n\t\t\t\t67 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t68 text Test the simulated connection\n\t\t\t\t69 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t70 button Lose next reply, ID: fault-drop\n\t\t\t\t71 button Delay next reply, ID: fault-delay\n\t\t\t\t72 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t111 text No reply fault armed.\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t112 text Last observation \u00b7 Health inspection 01\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t113 text Captured \u00b7 generation 3\n\t\t114 text AGENT\n\t\t115 text Move the pusher into the upper bypass lane before crossing to the block's right side.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t116 text Recorded\n\t\t\t79 container measurement-result\n\t\t\t\t117 text 1,726\n\t\t\t\t81 text Orange pixels\n\t\t\t\t82 container\n\t\t\t\t\t118 text 4,794.4\n\t\t\t\t\t84 text mm\u00b2\n\t\t\t\t85 text Apparent footprint\n\t\t\t\t86 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment." + }, + { + "browser_action": "Observed second job still running and AI planning under identity-only health delay", + "client_commands": 83, + "name": "successive_checking", + "pending_command_ids": [], + "screenshot": "second_identity_delay.png", + "state": { + "active_job_id": null, + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Health read delayed; fresh body proof is required before any command", + "state": "checking" + }, + "current_frame": { + "available": true, + "generation": 21, + "image_url": "/api/frame?generation=21&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Finish reset with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 11, + "image_sha256": "e47008c08f81d1ed137d87f021a4273e354a0c3d79e0c9b1da21e6dbeaf28429", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "kind": "finish_reset", + "native_time_s": 22.28199999999853, + "operation_id": "agent-53ec814ec65e409f894ccaf9c1dd2c2a", + "pusher_home_verified": true, + "reset_contact_samples": 3166, + "reset_native_steps": 7940, + "state_sha256": "0de60aca2a69c72c36eb8396ce0c3e420c60000ca6190ec36315207e14c804a4" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "Verify the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 21, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "kind": "finish_reset", + "native_time_s": 43.03000000000662, + "operation_id": "agent-6ec3f611bd9042a5b9a1acc3867b74e7", + "pusher_home_verified": true, + "reset_contact_samples": 3304, + "reset_native_steps": 8106, + "state_sha256": "d3bdf81922c73fc0177d3453905a0376c365e73434d7708da14061adba34ddf7" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791832279.422046, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t125 checkbox Health inspection 01 Completed, Value: 0\n\t\t\t126 checkbox Health inspection 02 Working, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t127 text Health inspection 02\n\t\t128 text Running\n\t\t16 button Pause, ID: pause\n\t\t129 text A health reply is delayed. Planning can continue; commands require a fresh body check.\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t130 text Checking body\n\t\t\t131 text Health read delayed; fresh body proof is required before any command\n\t\t\t21 button Disconnect, ID: disconnect\n\t\t\t22 button (disabled) Check receipt, ID: reconcile\n\t\t\t66 container\n\t\t\t\t67 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t68 text Test the simulated connection\n\t\t\t\t69 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t70 button Lose next reply, ID: fault-drop\n\t\t\t\t71 button Delay next reply, ID: fault-delay\n\t\t\t\t72 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t132 text No reply fault armed.\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t133 text Last observation \u00b7 health unconfirmed\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t134 text Last captured \u00b7 health unconfirmed \u00b7 generation 21\n\t\t135 text AI IS PLANNING\n\t\t136 text Planning the next move from the latest camera image.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t137 text Historical result\n\t\t\t117 container measurement-result\n\t\t\t\t138 text 1,729\n\t\t\t\t119 text Orange pixels\n\t\t\t\t120 container\n\t\t\t\t\t139 text 4,802.8\n\t\t\t\t\t122 text mm\u00b2\n\t\t\t\t123 text Apparent footprint\n\t\t\t\t124 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment." + }, + { + "browser_action": "Both actual image-guided jobs completed their measurement and contact reset", + "client_commands": 83, + "name": "completed", + "pending_command_ids": [], + "screenshot": "completed.png", + "state": { + "active_job_id": null, + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Health read delayed; fresh body proof is required before any command", + "state": "checking" + }, + "current_frame": { + "available": true, + "generation": 21, + "image_url": "/api/frame?generation=21&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Finish reset with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 11, + "image_sha256": "e47008c08f81d1ed137d87f021a4273e354a0c3d79e0c9b1da21e6dbeaf28429", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "kind": "finish_reset", + "native_time_s": 22.28199999999853, + "operation_id": "agent-53ec814ec65e409f894ccaf9c1dd2c2a", + "pusher_home_verified": true, + "reset_contact_samples": 3166, + "reset_native_steps": 7940, + "state_sha256": "0de60aca2a69c72c36eb8396ce0c3e420c60000ca6190ec36315207e14c804a4" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "Verify the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 21, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "kind": "finish_reset", + "native_time_s": 43.03000000000662, + "operation_id": "agent-6ec3f611bd9042a5b9a1acc3867b74e7", + "pusher_home_verified": true, + "reset_contact_samples": 3304, + "reset_native_steps": 8106, + "state_sha256": "d3bdf81922c73fc0177d3453905a0376c365e73434d7708da14061adba34ddf7" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791832296.68832, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t125 checkbox Health inspection 01 Completed, Value: 0\n\t\t\t126 checkbox Health inspection 02 Completed, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t127 text Health inspection 02\n\t\t128 text Running\n\t\t16 button Pause, ID: pause\n\t\t129 text A health reply is delayed. Planning can continue; commands require a fresh body check.\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t130 text Checking body\n\t\t\t131 text Health read delayed; fresh body proof is required before any command\n\t\t\t21 button Disconnect, ID: disconnect\n\t\t\t22 button (disabled) Check receipt, ID: reconcile\n\t\t\t66 container\n\t\t\t\t67 button (expanded) Test the simulated connection, Secondary Actions: Collapse\n\t\t\t\t\t68 text Test the simulated connection\n\t\t\t\t69 text These controls affect the next command reply. Recovery checks its retained receipt and waits for you to resume.\n\t\t\t\t70 button Lose next reply, ID: fault-drop\n\t\t\t\t71 button Delay next reply, ID: fault-delay\n\t\t\t\t72 button Duplicate next command, ID: fault-duplicate\n\t\t\t\t132 text No reply fault armed.\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t133 text Last observation \u00b7 health unconfirmed\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t134 text Last captured \u00b7 health unconfirmed \u00b7 generation 21\n\t\t135 text COMPLETED\n\t\t136 text Measurement recorded and reset verified. The bench is ready for another job.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t137 text Historical result\n\t\t\t117 container measurement-result\n\t\t\t\t138 text 1,729\n\t\t\t\t119 text Orange pixels\n\t\t\t\t120 container\n\t\t\t\t\t139 text 4,802.8\n\t\t\t\t\t122 text mm\u00b2\n\t\t\t\t123 text Apparent footprint\n\t\t\t\t124 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment.\n\t\t\t140 button Repeat job, ID: repeat" + }, + { + "browser_action": "Reloaded the browser; both completed jobs and command count retained", + "client_commands": 83, + "name": "reloaded", + "pending_command_ids": [], + "screenshot": "reloaded.png", + "state": { + "active_job_id": null, + "app_id": "433d80f43f4148ef87d341b6d117396d", + "connection": { + "adapter_id": "20f1c0ad0a0d40f38e1dee2ac094251e", + "body_id": "eea757a5363c43ca81de4a2f78715534", + "epoch": 1, + "fault": null, + "reason": "Health read delayed; fresh body proof is required before any command", + "state": "checking" + }, + "current_frame": { + "available": true, + "generation": 21, + "image_url": "/api/frame?generation=21&sha256=118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa" + }, + "jobs": [ + { + "call_count": 14, + "disturbance_test": false, + "error": null, + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "label": "Health inspection 01", + "last_intent": "Finish reset with the block centered in the home zone and the pusher at its home position.", + "measurement": { + "footprint_area_m2": 0.004794444444444444, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1726 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 11, + "image_sha256": "e47008c08f81d1ed137d87f021a4273e354a0c3d79e0c9b1da21e6dbeaf28429", + "job_id": "6a210963-8657-4adc-8b6b-bfffd52f3743", + "kind": "finish_reset", + "native_time_s": 22.28199999999853, + "operation_id": "agent-53ec814ec65e409f894ccaf9c1dd2c2a", + "pusher_home_verified": true, + "reset_contact_samples": 3166, + "reset_native_steps": 7940, + "state_sha256": "0de60aca2a69c72c36eb8396ce0c3e420c60000ca6190ec36315207e14c804a4" + }, + "status": "completed", + "target": "A" + }, + { + "call_count": 13, + "disturbance_test": false, + "error": null, + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "label": "Health inspection 02", + "last_intent": "Verify the block center is in the home zone and the pusher is at its home position.", + "measurement": { + "footprint_area_m2": 0.004802777777777777, + "method": "simulated_orange_RGB_footprint", + "orange_pixel_count": 1729 + }, + "phase": "completed", + "reset": { + "bench_id": "eea757a5363c43ca81de4a2f78715534", + "block_home_verified": true, + "generation": 21, + "image_sha256": "118bf53bca3344b8d0318c995ebe8b171a2a8bbc09c0ae163d70cc0f1d4aaefa", + "job_id": "18dcf629-14a7-43a8-b47f-ecd98a1a85e1", + "kind": "finish_reset", + "native_time_s": 43.03000000000662, + "operation_id": "agent-6ec3f611bd9042a5b9a1acc3867b74e7", + "pusher_home_verified": true, + "reset_contact_samples": 3304, + "reset_native_steps": 8106, + "state_sha256": "d3bdf81922c73fc0177d3453905a0376c365e73434d7708da14061adba34ddf7" + }, + "status": "completed", + "target": "B" + } + ], + "model_request_pending": false, + "recovery": { + "command_id": null, + "operation": null, + "reason": "No pending command", + "state": "none" + }, + "runner_status": "running" + }, + "time": 1791832310.4273899, + "visible_text": "Browser tab: 4, Title: \"Footwork \u00b7 Network bench\", URL: \"http://127.0.0.1:51377/\".\n1 AXWebArea Footwork \u00b7 Network bench, URL: 127.0.0.1:51377/\n\t2 container\n\t\t3 text Footwork Bench\n\t\t4 text SIMULATION\n\t5 container Jobs\n\t\t6 text WORK QUEUE\n\t\t7 button \uff0b New job, ID: new-job\n\t\t8 container queue\n\t\t\t9 checkbox Health inspection 01 Completed, Value: 0\n\t\t\t10 checkbox Health inspection 02 Completed, Value: 1\n\t11 container\n\t\t12 heading Bench, Value: 1\n\t\t\t13 text Bench\n\t\t14 text Health inspection 02\n\t\t15 text Running\n\t\t16 button Pause, ID: pause\n\t\t17 text A health reply is delayed. Planning can continue; commands require a fresh body check.\n\t\t18 container Description: Body connection, ID: network-card\n\t\t\t19 text Checking body\n\t\t\t20 text Health read delayed; fresh body proof is required before any command\n\t\t\t21 button Disconnect, ID: disconnect\n\t\t\t22 button (disabled) Check receipt, ID: reconcile\n\t\t\t23 button (collapsed) Test the simulated connection, Secondary Actions: Expand\n\t\t\t\t24 text Test the simulated connection\n\t\t25 container Camera observation\n\t\t\t26 text OVERHEAD CAMERA\n\t\t\t27 text Last observation \u00b7 health unconfirmed\n\t\t\t28 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame\n\t\t\t29 text Orange part Blue pusher Green task region\n\t\t\t30 text Last captured \u00b7 health unconfirmed \u00b7 generation 21\n\t\t31 text COMPLETED\n\t\t32 text Measurement recorded and reset verified. The bench is ready for another job.\n\t\t33 container Job progress\n\t\t\t34 text 1 Prepare 2 Measure 3 Reset 4 Ready\n\t\t35 container Measurement\n\t\t\t36 heading Measurement, Value: 2, ID: measurement-heading\n\t\t\t\t37 text Measurement\n\t\t\t38 text Historical result\n\t\t\t39 container measurement-result\n\t\t\t\t40 text 1,729\n\t\t\t\t41 text Orange pixels\n\t\t\t\t42 container\n\t\t\t\t\t43 text 4,802.8\n\t\t\t\t\t44 text mm\u00b2\n\t\t\t\t45 text Apparent footprint\n\t\t\t\t46 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI\u2019s judgment.\n\t\t\t47 button Repeat job, ID: repeat" + } + ] +} diff --git a/jevdual/results/workbench-health-20261012/ui/completed.png b/jevdual/results/workbench-health-20261012/ui/completed.png new file mode 100644 index 0000000000000000000000000000000000000000..98e256c93cba62c1b4cd6d333525f82032e53f9a GIT binary patch literal 47647 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 J!C*fI{|`Kd`fLCI literal 0 HcmV?d00001 diff --git a/jevdual/results/workbench-health-20261012/ui/handoff.txt b/jevdual/results/workbench-health-20261012/ui/handoff.txt new file mode 100644 index 0000000..dd2ae1e --- /dev/null +++ b/jevdual/results/workbench-health-20261012/ui/handoff.txt @@ -0,0 +1,81 @@ +Browser tab: 4, Title: "Footwork · Network bench", URL: "http://127.0.0.1:51377/". +1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ + 2 container + 3 text Footwork Bench + 4 text SIMULATION + 5 container Jobs + 6 text WORK QUEUE + 7 button + New job, ID: new-job + 8 container queue + 9 checkbox Health inspection 01 Completed, Value: 0 + 10 checkbox Health inspection 02 Completed, Value: 1 + 11 container + 12 heading Bench, Value: 1 + 13 text Bench + 14 text Health inspection 02 + 15 text Paused + 16 button Resume, ID: pause + 17 container Description: Body connection, ID: network-card + 18 text Body connected + 19 text Body identity verified by read-only TCP health + 20 button Disconnect, ID: disconnect + 21 button (disabled) Check receipt, ID: reconcile + 22 button (collapsed) Test the simulated connection, Secondary Actions: Expand + 23 text Test the simulated connection + 24 container Camera observation + 25 text OVERHEAD CAMERA + 26 text Last camera observation + 27 image Description: Rendered overhead view of the orange part, blue pusher and green task region, ID: frame + 28 text Orange part Blue pusher Green task region + 29 text Captured · generation 21 + 30 text COMPLETED + 31 text Measurement recorded and reset verified. The bench is ready for another job. + 32 container Job progress + 33 text 1 Prepare 2 Measure 3 Reset 4 Ready + 34 container Measurement + 35 heading Measurement, Value: 2, ID: measurement-heading + 36 text Measurement + 37 text Historical result + 38 container measurement-result + 39 text 1,729 + 40 text Orange pixels + 41 container + 42 text 4,802.8 + 43 text mm² + 44 text Apparent footprint + 45 text Image-based area in the calibrated simulation. This is a recorded measurement, separate from the AI’s judgment. + 46 button Repeat job, ID: repeat + 47 container Activity + 48 heading Activity, Value: 2, ID: activity-heading + 49 text Activity + 50 text 24 events + 51 content list activity + 52 container + 53 text 03:13 PM Agent stopped for review Remote end closed connection without response + 54 container + 55 text 03:12 PM Body restarted 1 -> 2 + 56 container + 57 text 03:12 PM Agent stopped for review Body restarted from boot 1 to 2; check pending receipts and explicitly Resume for a fresh image + 58 container + 59 text 03:11 PM Action receipt checked Health inspection 02 + 60 container + 61 text 03:11 PM Sending a guarded action + 62 container + 63 text 03:11 PM Fresh body check verified The next command uses current body evidence. + 64 container + 65 text 03:11 PM Action proposal accepted Health inspection 02 + 66 container + 67 text 03:11 PM Checking the planned action + 68 container + 69 text 03:11 PM Fresh body check verified The next command uses current body evidence. + 70 container + 71 text 03:11 PM AI planning requested Health inspection 02 + 72 container + 73 text 03:11 PM Camera observation received Health inspection 02 + 74 container + 75 text 03:11 PM Requesting camera observation + 76 button (collapsed) Session details, Secondary Actions: Expand + 77 text Session details + 78 text 27 model requests · Reported tokens: 352,734 input / 4,129 output + +The focused UI element is 1 AXWebArea Footwork · Network bench, URL: 127.0.0.1:51377/ \ No newline at end of file diff --git a/jevdual/results/workbench-health-20261012/ui/healthy_checking.png b/jevdual/results/workbench-health-20261012/ui/healthy_checking.png new file mode 100644 index 0000000000000000000000000000000000000000..855e040018549df39338034c7a7794b75559c858 GIT binary patch literal 39624 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