Files
hack-house/cmd_chat/sor/grid.py
T
leetcrypt 6d61c53152 RQ1+RQ2 start-line: live per-cell condition assembler + guarded launcher + Holm ratification
Wire the live per-cell condition assembler (cmd_chat/sor/assembler.py): compose
the existing R1/R4/R5/R6 pieces into a condition-encoding CircuitSpec per frozen
§2 cell, so a cell_id maps to a genuinely distinct, ForwarderPlan-gated
(engine != local) isolated circuit rather than the plain 3-hop control:
  - RQ1 bridge-on / on+padding insert a live bridge hop (+ R1 PADDING stream);
  - RQ2 bridge-/directory-federated genuinely span >= 2 houses
    (federation.select_federated_path, split-knowledge).
Plans only: opens no socket, moves no traffic, stands up no engine.

battery.assembler_dry_check validates on FIXTURES (6/6 cells distinct
fingerprints, all isolation-gated, same (cell,seed) reproduces, RQ1 bridge +
padding arms live, RQ2 federation >= 2 houses); write-once, kept out of any
confirmatory data dir. confirmatory_run preflight now runs it; the --operator-go
path no longer refuses cells as "not wired" — triple-lock + green preflight HOLD
on grid completion, then surface the operator's immutable data-run gate. No
confirmatory cell is ever fabricated.

Start-line instrument-validation gate (cmd_chat/sor/gate.py), grid + containment
pin (grid.py), and the guarded launcher (confirmatory_run.py) land alongside.

Holm: hold family_size = 7, report the 4 RQ1/RQ2 tests -> multipliers 7,6,5,4.
This is the pre-registration, not a deviation (prereg §6 [APPROVAL] size-7 family
+ D6 disclosure in the lead paper); docs/stage-05-holm-clarification.md marked
RATIFIED. RQ3-fold and alpha-split declined.

Containment intact; prereg untouched (SHA f22331a72e...); worktree-only. output/
gitignored (runtime artifacts, never source). Full SOR suite 156 passed. No
confirmatory data collected — the live data run remains the human gate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 20:49:12 -07:00

164 lines
7.1 KiB
Python

"""Grid inventory + containment pin for the RQ1+RQ2 confirmatory battery.
Pins the node-role → device mapping for the lab grid (2 phones + laptop) and
probes, at call time, which devices are SSH-reachable and which can host an
**isolated engine** (docker). Writes an auditable ``device-map.json``.
Containment note (load-bearing): every SOR forwarder/hop runs inside an isolated
engine (docker container), never on a phone or the host directly. The physical
phones are *distribution* options for where those isolated containers live; the
operator-blessed fallback for the confirmatory RQ1/RQ2 path is isolated docker
containers co-located on the docker host (as used for gate item 1). So the grid
being partly degraded does not by itself collapse the topology — but any inability
to honour the §2 topology / §6 matched-N with isolated nodes is a STOP-and-flag.
"""
from __future__ import annotations
import json
import shutil
import subprocess
from dataclasses import asdict, dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Dict, List, Optional
@dataclass(frozen=True)
class Device:
"""A pinned grid device and the house-role it plays in the confirmatory design."""
name: str # ssh alias / stable id
kind: str # "phone" | "laptop"
arch: str # "aarch64" | "x86_64"
can_host_engine: bool # can run an isolated docker engine locally?
house_role: str # design role (e.g. "house-A host / hop pool")
# Pinned inventory (lab-only, all ours — CLAUDE.md §Containment). tril + fp6 are
# the two phones; laptop is the x86_64 docker host. Only devices that can host an
# isolated docker engine may run a forwarder; phones without docker are consent
# endpoints / distribution targets, never a bare host forwarder.
GRID_INVENTORY: List[Device] = [
Device("laptop", "laptop", "x86_64", True, "house-A docker host + hop pool"),
Device("fp6", "phone", "aarch64", False, "house-B consenting node (phone)"),
Device("tril", "phone", "aarch64", False, "house-C consenting node (Termux, no docker)"),
]
def _probe_ssh(alias: str, timeout: int = 8) -> bool:
"""Best-effort SSH reachability probe (BatchMode, short timeout). Never raises."""
try:
r = subprocess.run(
["ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=5",
"-o", "StrictHostKeyChecking=accept-new", alias, "true"],
capture_output=True, timeout=timeout,
)
return r.returncode == 0
except Exception: # noqa: BLE001
return False
def _probe_remote_docker(alias: str, timeout: int = 12) -> bool:
"""Best-effort probe of an isolated docker engine on a remote device. Never raises."""
try:
r = subprocess.run(
["ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=5",
"-o", "StrictHostKeyChecking=accept-new", alias,
"docker version --format '{{.Server.Version}}'"],
capture_output=True, timeout=timeout,
)
return r.returncode == 0 and bool(r.stdout.strip())
except Exception: # noqa: BLE001
return False
def _probe_local_docker() -> Optional[str]:
"""Local docker server version if a daemon is up, else None. Never raises."""
if shutil.which("docker") is None:
return None
try:
r = subprocess.run(["docker", "version", "--format", "{{.Server.Version}}"],
capture_output=True, timeout=12)
return r.stdout.decode().strip() if r.returncode == 0 else None
except Exception: # noqa: BLE001
return None
def probe_grid() -> Dict[str, Any]:
"""Probe reachability + isolated-engine availability across the pinned grid.
Pure I/O, no traffic, no forwarder — a connectivity/capability snapshot only."""
local_docker = _probe_local_docker()
devices: List[Dict[str, Any]] = []
for d in GRID_INVENTORY:
reachable = _probe_ssh(d.name)
# An isolated engine is available on this device if it is the local docker
# host (laptop here) or a reachable device advertising a docker daemon.
if d.name == "laptop":
engine_ok = local_docker is not None
engine_ver = local_docker
elif reachable and d.can_host_engine:
engine_ok = _probe_remote_docker(d.name)
engine_ver = "remote-docker" if engine_ok else None
else:
engine_ok = False
engine_ver = None
devices.append({
**asdict(d),
"ssh_reachable": reachable,
"isolated_engine_available": engine_ok,
"engine_version": engine_ver,
})
return {"local_docker_version": local_docker, "devices": devices}
def write_device_map(out_dir: Path) -> Dict[str, Any]:
"""Write ``device-map.json`` (write-once) pinning the node-role→device map and
the current reachability/engine snapshot, plus a containment + matched-N
assessment. Returns the document."""
out_dir = Path(out_dir)
out_dir.mkdir(parents=True, exist_ok=True)
snap = probe_grid()
engine_hosts = [d for d in snap["devices"] if d["isolated_engine_available"]]
reachable = [d for d in snap["devices"] if d["ssh_reachable"]]
down = [d["name"] for d in snap["devices"] if not d["ssh_reachable"]]
# RQ1/RQ2 hops run as isolated docker containers; a single docker host can
# host >=3 distinct containerised nodes (operator-blessed, gate item 1). So
# the topology/matched-N is honourable iff at least one isolated engine exists.
topology_honourable = len(engine_hosts) >= 1
doc = {
"schema": "sor-device-map/1",
"scope": "RQ1+RQ2 lead-paper grid pin (CLAUDE.md §Containment)",
"generated_utc": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
"local_docker_version": snap["local_docker_version"],
"devices": snap["devices"],
"reachable_count": len(reachable),
"isolated_engine_host_count": len(engine_hosts),
"degraded": bool(down),
"devices_down": down,
"topology_matchedN_honourable": topology_honourable,
"containment": {
"hops_run_in": "isolated docker containers only (never a phone/host forwarder)",
"external_target": "none",
"live_vm_churn_on_rq1_rq2": "none (RQ1/RQ2 use no churn; churn_schedule_id=none)",
"self_traffic_only": True,
},
"matched_N_note": (
"RQ1/RQ2 isolated hops are containerised on the docker host (>=3 distinct "
"containers = distinct nodes). Physical-phone distribution is optional; the "
"confirmatory matched-N (single-house N = federated total consenting nodes) is "
"pinned from the containerised node count at run time and recorded per manifest."
),
"assessment": (
"GO on isolated docker host" if topology_honourable
else "STOP: no isolated engine available — topology/matched-N cannot be honoured"
),
}
path = out_dir / "device-map.json"
if not path.exists():
path.write_text(json.dumps(doc, indent=2, sort_keys=True) + "\n", encoding="utf-8")
doc["_report_path"] = str(path)
return doc