dfc2e60e1b
Land only the containment-refusal half of R4: the guard every SOR forwarder must pass before it does anything — assert engine != local, or refuse. It moves no traffic, opens no socket, spawns no engine, and builds no SSH chain. - forwarder.py: assert_isolated (raises on local and on any engine off the manifest allow-list), isolation_prefix (docker/multipass exec argv, no host path), ForwarderPlan (construction IS the gate — no plan for local/unknown/ no-container). Allow-list imported from provenance so forwarder and manifest cannot disagree about what counts as isolated. - There is no code path in this module that returns an exec prefix for the host; containment is structural, not a runtime flag. The traffic-moving half of R4 (gate item 1: 3-hop self-traffic e2e delivery + per-hop pcaps across the grid) is deliberately NOT implemented — HELD for a live isolated engine + grid. This guard is fully verifiable offline. Acceptance (gate item 5) green: local/unknown/no-container refused; isolated engine accepted with the correct isolation prefix. Python forwarder suite 12 passed; full SOR Python suite 49 passed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>