{
  "_schema": "Every entry records 1 deliberate difference between a vendored file and the pristine pin in UPSTREAM-MANIFEST.json. Required fields per entry: file, symbol, reason, pre, post, post_sha256, post_lines. The pre field carries the exact pristine line or block, so a test can reconstruct the pre change behaviour in a scratch copy and observe the defect present, which is the only way a fix is proven rather than asserted. The post_sha256 is the sha256 of the whole file after the change, and the integrity guard accepts that hash in place of the pinned one for exactly the files listed here. The post_bytes is the byte length of the whole file after the change, carried for the same reason: an oracle that reads the shipped file to learn its own expected length is self referential. The post_lines is the newline count of the whole file after the change, and the integrity guard accepts it in place of the pinned line count for the same files, because a line count arm without the same exception the hash arm has would report a defect on a correct write.",
  "_agreement_rule": "A divergence is recorded per SITE, so several entries may name 1 file. Every entry naming a given file describes the state of that file after ALL of this plan's changes land in 1 commit, so every entry naming a given file MUST carry the same post_sha256 and the same post_lines. Without that rule the hash check is unfalsifiable, because a file carrying 2 different post hashes matches whichever entry the reader happened to pick.",
  "_reconstruction_rule": "Each entry's pre and post block occurs EXACTLY ONCE in the pristine file and exactly once in the shipped file respectively, and the 3 blocks are disjoint contiguous regions, so replacing every post block with its pre block reconstructs the pristine file byte for byte regardless of the order the entries are applied in. tests/fleet-divergence.test.cjs performs that reconstruction and asserts its sha256 equals the pristine pin, which is what makes the ledger provably COMPLETE rather than merely present.",
  "_rule": "A vendored file whose recomputed hash stops matching UPSTREAM-MANIFEST.json without a matching entry in this array is a defect, not an update. The integrity guard fails on it.",
  "pinned_manifest": "UPSTREAM-MANIFEST.json",
  "divergences": [
    {
      "id": "DIV-01",
      "file": "bin/ratchet-exec",
      "symbol": "_supervise",
      "upstream_lines": "319-369",
      "phase": "18",
      "reason": "Unbounded retention of untrusted child output. _supervise appended every chunk the child wrote and returned the whole join with nothing bounding it, so a child that writes without stopping grows the supervisor until the machine gives up: a denial of service against the operator, not against the child. Both callers slice the last 200000 bytes the moment they receive it, so the retained prefix had no consumer at all. The retained output is now a bounded tail of 4000000 bytes, an order of magnitude above that slice, so any child under the cap returns byte identical output and only the unbounded case changes. Eviction is from the front, so the tail the callers read is exactly the tail they read before. Threat T-18-09.",
      "pre": "def _supervise(proc, deadline):\n    \"\"\"Non-blocking wall-clock supervision of an untrusted child. Returns (reaped, out_bytes).\n    NEVER blocks on a read a child could hold open — a partial line with no newline, or a bg child\n    keeping the stdout pipe open, both defeated a blocking readline()/read() and starved the timeout\n    check. Reads are non-blocking, gated by select against the remaining budget; on timeout the whole\n    GROUP is SIGTERM'd then SIGKILL'd. Shared by run_card (agents) and guarded_suite (PR gate) so the\n    two supervision loops can never drift apart again.\"\"\"\n    import select\n    fd = proc.stdout.fileno()\n    os.set_blocking(fd, False)\n    outbuf = []\n    reaped = None\n    eof = False\n    def _drain():                       # read whatever is buffered, without waiting for EOF\n        try:\n            while True:\n                chunk = os.read(fd, 65536)\n                if not chunk:\n                    break\n                outbuf.append(chunk)\n        except (BlockingIOError, OSError):\n            pass\n    while True:\n        remaining = deadline - time.time()\n        if remaining <= 0:              # wall-clock cap: SIGTERM the GROUP, then SIGKILL\n            reaped = \"timeout\"\n            try:\n                os.killpg(proc.pid, signal.SIGTERM)\n                time.sleep(5)\n                if proc.poll() is None:\n                    os.killpg(proc.pid, signal.SIGKILL)\n            except OSError:\n                pass\n            break\n        if proc.poll() is not None:     # exited — drain buffered output, never wait on a held pipe\n            if not eof:\n                _drain()\n            break\n        if eof:\n            time.sleep(min(0.2, remaining)); continue\n        r, _, _ = select.select([fd], [], [], min(1.0, remaining))\n        if r:\n            try:\n                chunk = os.read(fd, 65536)\n            except (BlockingIOError, OSError):\n                chunk = None\n            if chunk == b\"\":\n                eof = True\n            elif chunk:\n                outbuf.append(chunk)\n    return reaped, b\"\".join(outbuf)\n",
      "post": "_OUT_CAP = 4_000_000   # bytes of child output retained; both callers slice only the last 200_000\n\ndef _supervise(proc, deadline):\n    \"\"\"Non-blocking wall-clock supervision of an untrusted child. Returns (reaped, out_bytes).\n    NEVER blocks on a read a child could hold open — a partial line with no newline, or a bg child\n    keeping the stdout pipe open, both defeated a blocking readline()/read() and starved the timeout\n    check. Reads are non-blocking, gated by select against the remaining budget; on timeout the whole\n    GROUP is SIGTERM'd then SIGKILL'd. Shared by run_card (agents) and guarded_suite (PR gate) so the\n    two supervision loops can never drift apart again.\n\n    FERROX DIV-01 (phase 18): the retained output is BOUNDED to a tail of _OUT_CAP bytes. Upstream\n    appended every chunk an untrusted child wrote and returned the whole join with nothing bounding\n    it, so a child that writes without stopping grows this supervisor until the machine gives up —\n    a denial of service against the OPERATOR, not against the child. Both callers already slice\n    raw[-200_000:] the moment they get it, so the retained prefix had no consumer whatsoever. The\n    cap sits an order of magnitude above that slice, so any child under it returns byte-identical\n    output and only the unbounded case changes. Dropping is from the FRONT: the tail the callers\n    actually read is exactly the tail they read before.\"\"\"\n    import select\n    fd = proc.stdout.fileno()\n    os.set_blocking(fd, False)\n    outbuf = []\n    kept = 0\n    reaped = None\n    eof = False\n    def _keep(chunk):                   # bounded ring: evict from the FRONT, never from the tail\n        nonlocal kept\n        outbuf.append(chunk)\n        kept += len(chunk)\n        while kept > _OUT_CAP:\n            over = kept - _OUT_CAP\n            if len(outbuf[0]) <= over:\n                kept -= len(outbuf.pop(0))\n            else:\n                outbuf[0] = outbuf[0][over:]\n                kept -= over\n    def _drain():                       # read whatever is buffered, without waiting for EOF\n        try:\n            while True:\n                chunk = os.read(fd, 65536)\n                if not chunk:\n                    break\n                _keep(chunk)\n        except (BlockingIOError, OSError):\n            pass\n    while True:\n        remaining = deadline - time.time()\n        if remaining <= 0:              # wall-clock cap: SIGTERM the GROUP, then SIGKILL\n            reaped = \"timeout\"\n            try:\n                os.killpg(proc.pid, signal.SIGTERM)\n                time.sleep(5)\n                if proc.poll() is None:\n                    os.killpg(proc.pid, signal.SIGKILL)\n            except OSError:\n                pass\n            break\n        if proc.poll() is not None:     # exited — drain buffered output, never wait on a held pipe\n            if not eof:\n                _drain()\n            break\n        if eof:\n            time.sleep(min(0.2, remaining)); continue\n        r, _, _ = select.select([fd], [], [], min(1.0, remaining))\n        if r:\n            try:\n                chunk = os.read(fd, 65536)\n            except (BlockingIOError, OSError):\n                chunk = None\n            if chunk == b\"\":\n                eof = True\n            elif chunk:\n                _keep(chunk)\n    return reaped, b\"\".join(outbuf)\n",
      "post_sha256": "4ae757eff6d5b211636718f066897973d6e804263a5d6f88e20defe70210147c",
      "post_lines": 1308,
      "post_bytes": 81228
    },
    {
      "id": "DIV-02",
      "file": "bin/ratchet-exec",
      "symbol": "_git, _containment_audit",
      "upstream_lines": "88-90",
      "phase": "18",
      "reason": "The containment audit crashed before the restore. _git delegated to the kernel's K.git, whose run() passes text=True with no errors argument and therefore decodes strictly, so a single path that is not valid in the ambient encoding raised UnicodeDecodeError out of _status_z and out of _changed_paths. In run_card that call sits before the .git tamper check and before any restore, and in guarded_suite it sits before the unconditional restore, so 1 undecodable filename aborted the audit with the tree unrestored and an injected hook still live in the CANONICAL hooks directory, which _hooks_dir resolves through rev-parse --git-path hooks for a linked worktree. The sandbox now reads git as bytes and decodes with the surrogate escape handler, which never raises AND round trips, so every downstream on disk lookup still hits the real file. The replace handler is deliberately not used: it yields a string that no longer resolves on disk, which would turn a loud crash into a silently missed symlink escape in _escapes. The second half of this fix is _containment_audit, added in the same block, which runs the whole audit behind a guard and fails closed so no other throw can skip the restore either; its 2 call sites are inside the DIV-03 block because DIV-03 rewrites both callers wholesale, and reversing all 3 entries reproduces the pristine bytes. Threat T-18-10.",
      "pre": "_SAFE = [\"-c\", \"core.hooksPath=/dev/null\", \"-c\", \"core.fsmonitor=false\"]\ndef _git(wt, *args):\n    return K.git(wt, *(_SAFE + list(args)))\n",
      "post": "_SAFE = [\"-c\", \"core.hooksPath=/dev/null\", \"-c\", \"core.fsmonitor=false\"]\ndef _git(wt, *args, timeout=45):\n    \"\"\"FERROX DIV-02 (phase 18), half 1 of 2. Read git's output as BYTES and decode it with the\n    SURROGATE ESCAPE handler, instead of routing through the kernel's K.git, whose run() passes\n    text=True with no errors argument and therefore decodes STRICTLY.\n\n    The defect that fixes: one path that is not valid in the ambient encoding made _status_z raise\n    UnicodeDecodeError, which propagated out of _changed_paths. In run_card that call sits BEFORE\n    the .git-tamper check and before any restore, and in guarded_suite it sits before the\n    unconditional restore, so a single undecodable filename aborted the containment audit with the\n    tree unrestored and an injected hook still live. _hooks_dir resolves `rev-parse --git-path\n    hooks`, which for a linked worktree is the CANONICAL repository's hooks directory, so that hook\n    then fires on the next canonical git operation.\n\n    The REPLACE handler is deliberately NOT used. It yields a string that no longer resolves on\n    disk, so os.path.islink / os.path.realpath in _escapes would look up a name that does not\n    exist and walk a symlink escape straight through as clean: a loud crash traded for a silent\n    miss. surrogateescape never raises AND round-trips, so os.fsencode of the decoded name is the\n    original byte sequence and every downstream on-disk lookup still hits the real file. The\n    docstring on _status_z already argues this exact point about C-quoted names.\n\n    Same (rc, stdout, stderr) contract as K.git, including the rstrip-only on stdout, because a\n    leading space is significant in porcelain output (' M file').\"\"\"\n    argv = [\"git\", \"-C\", wt, *_SAFE, *args]\n    try:\n        r = subprocess.run(argv, capture_output=True, timeout=timeout)\n    except subprocess.TimeoutExpired:\n        return 124, \"\", f\"timeout after {timeout}s\"\n    except (FileNotFoundError, OSError) as e:\n        return 127, \"\", str(e)\n    return (r.returncode,\n            r.stdout.decode(\"utf-8\", \"surrogateescape\").rstrip(\"\\n\"),\n            r.stderr.decode(\"utf-8\", \"surrogateescape\").strip())\n\ndef _containment_audit(wt, snap, refs0=None):\n    \"\"\"FERROX DIV-02 (phase 18), half 2 of 2: defence in depth behind the lenient decode above.\n    Upstream ran the containment audit INLINE, with no try, immediately before the restore, so any\n    throw from inside it skipped the restore entirely. The strict decode was the known way to make\n    that happen; this makes the ordering safe against every other way. Fails CLOSED: an audit that\n    could not complete is itself reported as a violation, so the run is rejected and restored\n    rather than reported clean.\n\n    Call sites are inside the guarded_suite and run_card blocks, which DIV-03 rewrites wholesale;\n    reversing all 3 ledger entries reproduces the pristine bytes. Returns a dict rather than a\n    tuple because the 2 callers compose violations differently: guarded_suite folds in ref tamper,\n    run_card folds in the grant manifest.\"\"\"\n    out = {\"changed\": [], \"escapes\": [], \"meta_tampered\": False, \"ref_tampered\": [], \"error\": None}\n    try:\n        out[\"changed\"] = _changed_paths(wt, snap)\n        out[\"escapes\"] = _escapes(wt, out[\"changed\"])\n        out[\"meta_tampered\"] = _git_meta(wt) != snap[\"meta\"]\n        if refs0 is not None:\n            out[\"ref_tampered\"] = _ref_tamper(refs0, _refs(wt))\n    except Exception as e:   # noqa: BLE001 — deliberately broad: the restore below must always run\n        out[\"error\"] = \"<containment audit failed: %s: %s>\" % (type(e).__name__, e)\n    return out\n",
      "post_sha256": "4ae757eff6d5b211636718f066897973d6e804263a5d6f88e20defe70210147c",
      "post_lines": 1308,
      "post_bytes": 81228
    },
    {
      "id": "DIV-03",
      "file": "bin/ratchet-exec",
      "symbol": "guarded_suite, run_card",
      "upstream_lines": "400-1052",
      "phase": "18",
      "reason": "Untrusted code executed against the canonical git directory. Both untrusted paths ran with cwd inside a LINKED worktree, whose .git is a file pointing at the canonical common gitdir, so the child could write the canonical repository's hooks, config and refs directly. Upstream detected and reverted that, which is not containment: the window is live while the child runs, the revert can fail, and restore-failed is a real upstream verdict. run_card is the worse half and the one phase 19 executes, because PROFILES launches claude -p --dangerously-skip-permissions, codex exec -s workspace-write and gemini --skip-trust, and because _refs is never called from run_card at all, so that path had no ref containment whatsoever. Both paths now execute against a throwaway clone that owns its own git directory, built with --no-hardlinks and no --shared so it shares no object file and no alternates, with every local head and tag replicated so the ref containment surface is preserved, with the origin remote removed so the child cannot push back into the card tree, and with user.name and user.email carried across so the child can still commit. The gate suite needs no transfer because upstream already discarded every suite write. The agent path transfers back only on a containment accepted verdict, clean or failed-checks, which is exactly the set of runs upstream left in the worktree; every other verdict drops the clone and leaves the card tree byte identical. The scope is deliberately the 2 functions that execute untrusted code and NOT the card lifecycle, because converting the card tree would additionally change 6 sites in the kernel whose gc and reap paths archive a branch with git bundle create against the canonical repository, so the branch would live only in the clone and archive before delete would silently bundle nothing, which is a data loss path. This block also carries the 2 call sites of _containment_audit from DIV-02, and the 15 selftest mock stimuli that cd to a hardcoded card tree path, which now cd to RATCHET_WORKTREE instead. The engine already exported that variable into the lane at the spawn site, and upstream's linked worktree and the isolation clone are both correct values of it, so the 33 upstream cases stay behavioural and location agnostic and all 33 still pass. The region is contiguous, which is why swarm is carried through it unchanged. Threat T-18-08.",
      "pre": "def guarded_suite(wt, cmd, timeout=600):\n    \"\"\"Run an UNTRUSTED contributor command `cmd` (a shell string) inside worktree `wt` under the\n    same governed sandbox spine as run_card, so a PR gate can execute a repo's test suite without\n    handing it the operator's shell. Guarantees:\n      • allowlisted clean_env — no GH_TOKEN / *_API_KEY / AWS_* to exfiltrate (the suite sees only\n        PATH/HOME-class vars);\n      • own process group + wall-clock cap (SIGTERM→SIGKILL on the GROUP) enforced by a NON-BLOCKING\n        supervision loop — a bg child holding the stdout pipe, or a partial-line-then-stall, can no\n        longer starve the timeout check — then a group sweep so a non-detached child can't write\n        after we stop watching;\n      • the worktree is SNAPSHOTTED first and hard-RESTORED after — the suite's writes are a\n        throwaway, and, critically, an injected .git hook / core.fsmonitor command is reverted so\n        our subsequent (shared-gitdir) git calls in the canonical repo can't be hijacked;\n      • REFS are snapshotted too and any create/move/delete is a VIOLATION and is reverted — a suite\n        cannot move the canonical mainline onto its own head to blind a later diff or poison the repo;\n      • .git config/hooks tamper and symlink/realpath escapes out of the worktree are flagged as\n        containment VIOLATIONS (never legitimate suite behaviour).\n    Unlike run_card this does NOT reject ordinary in-worktree writes — a test suite legitimately\n    writes artifacts, and the tree is discarded. The gate signal is: exited 0, not reaped, no\n    containment violation. HONEST BOUNDARY is identical to run_card's (setsid-detached children and\n    absolute-path writes outside the worktree need OS sandboxing — deferred, BUILD-PLAN-V2 §9).\n    Returns {ok, rc, reaped, duration_s, violations, restore_ok, stream_tail}.\"\"\"\n    snap = _snapshot(wt)\n    refs0 = _refs(wt)\n    env = K.clean_env({\"RATCHET_GATE\": \"1\", \"RATCHET_WORKTREE\": wt})\n    argv = [\"bash\", \"-lc\", cmd]\n    t0 = time.time()\n    try:\n        # BYTES (no text=True): the shared non-blocking supervisor reads the raw fd and decodes later.\n        proc = subprocess.Popen(argv, cwd=wt, env=env, start_new_session=True,\n                                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\n    except (FileNotFoundError, OSError) as e:\n        return {\"ok\": False, \"rc\": 127, \"reaped\": None, \"duration_s\": 0.0,\n                \"violations\": [\"spawn-failed: %s\" % e], \"restore_ok\": _restore(wt, snap),\n                \"stream_tail\": \"\"}\n    reaped, raw = _supervise(proc, t0 + timeout)\n    rc = proc.wait()\n    try:\n        os.killpg(proc.pid, signal.SIGKILL)  # sweep the group before we inspect / restore the tree\n        time.sleep(0.2)\n    except OSError:\n        pass\n    dur = round(time.time() - t0, 1)\n    stream = raw[-200_000:].decode(\"utf-8\", \"replace\")\n    # containment audit BEFORE restore: .git tamper, ref tamper, and realpath/symlink escapes are\n    # never legitimate suite behaviour.\n    changed = _changed_paths(wt, snap)\n    escapes = _escapes(wt, changed)\n    meta_tampered = _git_meta(wt) != snap[\"meta\"]\n    ref_tampered = _ref_tamper(refs0, _refs(wt))   # moved/deleted pre-existing refs (creates ignored)\n    violations = list(dict.fromkeys(\n        escapes\n        + ([\"<.git config/hooks tampered>\"] if meta_tampered else [])\n        + ([\"<git refs moved/deleted: %s>\" % \", \".join(ref_tampered[:3])] if ref_tampered else [])))\n    # ALWAYS restore: drops the throwaway suite writes, reverts any injected hook/config, and puts\n    # every moved/deleted ref back — so the canonical repo (shared common gitdir) is safe AND unpoisoned.\n    restore_ok = _restore(wt, snap)\n    if ref_tampered:\n        _restore_refs(wt, refs0, ref_tampered)\n    ok = (rc == 0) and (reaped is None) and (not violations)\n    return {\"ok\": ok, \"rc\": rc, \"reaped\": reaped, \"duration_s\": dur, \"violations\": violations,\n            \"restore_ok\": restore_ok, \"stream_tail\": K.redact(stream)[-2000:]}\n\ndef run_card(args):\n    pos = [a for a in args if not a.startswith(\"-\")]\n    if not pos:\n        print(\"usage: ratchet-exec run <work-id> [--cli claude|codex|gemini|mock] [--timeout <s>] [--grant <glob,...>]\"); return 1\n    work_id = pos[0]\n    # lane selection (v2 dispatch): explicit --cli wins; otherwise the capability-detected\n    # preference hierarchy — chosen flat-rate sub-CLI, else Wayland Core through Flux, else refuse.\n    if \"--cli\" in args:\n        cli = args[args.index(\"--cli\") + 1]\n    else:\n        cli, why = K.default_dispatch()\n        if cli is None:\n            print(f\"exec: no agent available — {why}. Run `ratchet init` to detect + install one.\"); return 2\n        print(f\"exec: no --cli given; dispatching to '{cli}' — {why}\")\n    timeout = int(args[args.index(\"--timeout\") + 1]) if \"--timeout\" in args else 900\n    extra = args[args.index(\"--prompt-extra\") + 1] if \"--prompt-extra\" in args else \"\"\n    # WRITE-manifest scope: --grant \"src/**,tests/**\" overrides the card's own grant field.\n    # None = ungoverned (permissive, flagged). The repo index (wave 2) computes grant per card.\n    # exec-owned flags are read from positions that are NOT the value of another flag, so an\n    # untrusted --prompt-extra payload can't smuggle in a governance flag (e.g. --no-auto-grant).\n    payload_idx = {args.index(\"--prompt-extra\") + 1} if \"--prompt-extra\" in args else set()\n    own_flags = {a for i, a in enumerate(args) if a.startswith(\"--\") and i not in payload_idx}\n    grant, grant_source = None, \"none\"\n    if \"--grant\" in args:\n        grant = [g for g in args[args.index(\"--grant\") + 1].split(\",\") if g.strip()]\n        grant_source = \"explicit-cli\"\n    m = K.load_manifest()\n    cfg, _, _ = K.config_load()\n    if cli in cfg.get(\"deny_list\", []):\n        print(f\"exec: REFUSE — '{cli}' is on the config deny-list\"); return 2\n    card = next((c for c in K.state_load(K.CARDS, {\"cards\": []})[\"cards\"]\n                 if c[\"work_id\"] == work_id and c[\"status\"] == \"open\"), None)\n    if card is None:\n        print(f\"exec: no OPEN card {work_id} — ratchet take first (cards are the only doorway)\"); return 2\n    wt = K.expand(card[\"worktree\"])\n    if not os.path.isdir(wt):\n        print(f\"exec: card {work_id} worktree missing ({wt}) — ratchet reconcile\"); return 2\n    r = m[\"repos\"][card[\"repo\"]]\n    if grant is None and card.get(\"grant\"):\n        grant = card[\"grant\"]; grant_source = \"explicit-card\"\n    if grant is None and \"--no-auto-grant\" not in own_flags and re.fullmatch(r\"[A-Za-z0-9]+\", work_id):\n        # ask the repo index to scope the lane (loose coupling: a tolerated subprocess). We do NOT\n        # trust its output: the returned globs are VALIDATED at this boundary (_valid_autogrant) —\n        # a bad/changed index can't turn an ungoverned run into a wide 'governed' one. Run with a\n        # SCRUBBED env so an ambient PYTHONPATH/LD_PRELOAD can't change what the helper computes.\n        idx_bin = os.path.join(HERE, \"ratchet-index\")\n        if os.path.exists(idx_bin):\n            senv = {k: v for k, v in os.environ.items()\n                    if k in (\"PATH\", \"HOME\", \"WL_HOME\", \"WL_MANIFEST\", \"WL_INSTANCE\", \"RATCHET_HOME\")}\n            outcome = \"helper-absent\"\n            try:\n                gp = subprocess.run([sys.executable, idx_bin, \"grant\", work_id], env=senv,\n                                    capture_output=True, text=True, timeout=30)\n                if gp.returncode != 0:\n                    outcome = f\"rc={gp.returncode}\"\n                else:\n                    auto = json.loads(gp.stdout or \"{}\").get(\"grant\")\n                    if auto is None:\n                        outcome = \"no-confident-scope\"\n                    elif _valid_autogrant(auto):\n                        grant, grant_source, outcome = auto, \"auto-index\", \"scoped\"\n                        print(f\"exec: auto-scoped lane from repo index → {grant}\")\n                    else:\n                        outcome = \"rejected-invalid-grant\"  # stays ungoverned+flagged, never widened\n            except subprocess.TimeoutExpired:\n                outcome = \"timeout-30s\"\n            except (ValueError, OSError, subprocess.SubprocessError):\n                outcome = \"error\"\n            if outcome != \"scoped\":\n                print(f\"exec: no auto-grant ({outcome}) — lane ungoverned (permissive, flagged)\")\n\n    # brief → file (recorded, hashed)\n    import hashlib\n    brief = build_brief(m, card, r)\n    bdir = os.path.join(K.WL_HOME, \"state\", \"recordings\", work_id)\n    os.makedirs(bdir, exist_ok=True)\n    bpath = os.path.join(bdir, f\"brief-{int(time.time())}.md\")\n    open(bpath, \"w\").write(K.redact(brief))\n    bhash = hashlib.sha1(brief.encode()).hexdigest()[:12]\n    prompt = (f\"Read the work brief at {bpath} and complete that card's work in the current \"\n              f\"directory (your isolated worktree). Follow its rules exactly. {extra}\").strip()\n\n    # spawn in own process group with an ALLOWLISTED env (security-council CRITICAL): the old\n    # blocklist stripped FLUX_/RATCHET_BREAK/WL_BREAK but LEAKED GH_TOKEN, *_API_KEY, AWS_* etc.\n    # to an untrusted agent. clean_env() passes only PATH/HOME-class vars + RATCHET_* identity —\n    # the agent has no secret to exfiltrate. The provider CLI reads its OWN auth from its own\n    # config dir, not our env, so this doesn't break claude/codex/gemini.\n    env = K.clean_env({\"RATCHET_CARD\": work_id, \"RATCHET_WORKTREE\": wt, \"RATCHET_AGENT\": f\"exec-{cli}\"})\n    if cli == \"mock\" and os.environ.get(\"RATCHET_MOCK_CMD\"):\n        env[\"RATCHET_MOCK_CMD\"] = os.environ[\"RATCHET_MOCK_CMD\"]  # test adapter only\n    if cli == \"mock\":\n        argv = [\"bash\", \"-lc\", env.get(\"RATCHET_MOCK_CMD\", \"true\")]\n    elif cli in PROFILES:\n        argv = PROFILES[cli] + [prompt]\n    else:\n        print(f\"exec: unknown CLI profile '{cli}'\"); return 1\n\n    # SANDBOX: snapshot the worktree before the agent touches it — every bad exit restores to here\n    snap = _snapshot(wt)\n\n    t0 = time.time()\n    try:\n        # BYTES: the shared non-blocking supervisor (_supervise) can't be starved by a partial line\n        # or a bg child holding the pipe — the same hardening guarded_suite uses (one loop, both paths).\n        proc = subprocess.Popen(argv, cwd=wt, env=env, start_new_session=True,\n                                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\n    except FileNotFoundError:\n        print(f\"exec: CLI '{cli}' not installed\"); return 2\n    # lane identity goes on the record FIRST — kernel kill/pause/resume verbs act on this\n    K.record(work_id, {\"event\": \"exec_spawn\", \"cli\": cli, \"pid\": proc.pid,\n                       \"pid_start\": K.pid_start(proc.pid), \"brief_hash\": bhash, \"timeout_s\": timeout,\n                       \"cost_basis\": \"ADVISORY — oracle wiring lands with councils (E2); wall-clock is the enforced cap\"})\n    reaped, raw = _supervise(proc, t0 + timeout)   # non-blocking wall-clock cap; SIGTERM→SIGKILL the group\n    rc = proc.wait()\n    # sweep the process GROUP before we inspect the tree: a non-detached background child\n    # (`sh -c 'sleep 2; echo pwn > x' &`) would otherwise write AFTER our checks. A setsid-detached\n    # child escapes its group and this sweep — that residual is the OS-sandbox boundary (deferred).\n    try:\n        os.killpg(proc.pid, signal.SIGKILL)\n        time.sleep(0.2)  # let the group die before _changed_paths reads the tree\n    except OSError:\n        pass\n    dur = round(time.time() - t0, 1)\n    stream = raw[-200_000:].decode(\"utf-8\", \"replace\")\n    spath = os.path.join(bdir, f\"stream-{int(t0)}.log\")\n    open(spath, \"w\").write(K.redact(stream))  # redaction-before-capture, same as the kernel\n\n    # evidence: what actually changed in the tree (ground truth, never the agent's self-report).\n    # _git (hooks/fsmonitor neutralized) because this is our FIRST git call after an untrusted run.\n    rcd, dirty, _ = _git(wt, \"status\", \"--porcelain\")\n    K.record(work_id, {\"event\": \"exec_exit\", \"cli\": cli, \"rc\": rc, \"reaped\": reaped,\n                       \"duration_s\": dur, \"dirty_files\": len(dirty.splitlines()) if dirty else 0})\n\n    verdict = \"failed\"\n    checks = {}\n    governed = grant is not None\n    grant_violations = []\n    restore_ok = True\n    def _reject(reason, msg):\n        nonlocal verdict, grant_violations, restore_ok\n        ok = _restore(wt, snap)\n        restore_ok = restore_ok and ok\n        grant_violations = reason\n        verdict = \"restore-failed\" if not ok else \"grant-violation\"\n        tail = \"; worktree restored, nothing lands\" if ok else \"; RESTORE FAILED — worktree may be dirty, ratchet reconcile\"\n        print(f\"exec: {msg}{tail}; stream: {spath}\")\n    if reaped:\n        restore_ok = _restore(wt, snap)  # a timed-out agent leaves NOTHING behind — tree restored\n        verdict = \"reaped\" if restore_ok else \"restore-failed\"\n        print(f\"exec: REAPED ({reaped}) after {dur}s — \"\n              + (\"worktree restored to snapshot\" if restore_ok else \"RESTORE FAILED — ratchet reconcile\")\n              + f\"; stream: {spath}\")\n    elif rc != 0:\n        restore_ok = _restore(wt, snap)\n        verdict = \"failed\" if restore_ok else \"restore-failed\"\n        print(f\"exec: agent exited {rc} after {dur}s — \"\n              + (\"worktree restored to snapshot\" if restore_ok else \"RESTORE FAILED — ratchet reconcile\")\n              + f\"; stream: {spath}\")\n    else:\n        # WRITE-manifest: did the agent stay inside its lane? A single out-of-lane write rejects the\n        # WHOLE run. Containment breaks (symlink/realpath escape) and the .git config/hooks RCE\n        # surface are violations REGARDLESS of grant — they are never legitimate agent behaviour.\n        changed = _changed_paths(wt, snap)\n        escapes = _escapes(wt, changed)\n        meta_tampered = _git_meta(wt) != snap[\"meta\"]\n        if grant is not None:\n            grant_violations = _ungranted(changed, grant)\n        violations = list(dict.fromkeys(\n            grant_violations + escapes + ([\"<.git config/hooks tampered>\"] if meta_tampered else [])))\n        if violations:\n            _reject(violations, f\"REJECTED — out-of-lane write {violations[:5]}\"\n                    + (\" …\" if len(violations) > 5 else \"\"))\n        else:\n            # deterministic post-checks — the same gates a human faces, run early\n            rc_d = subprocess.run([sys.executable, os.path.join(HERE, \"ratchet\"), \"doctor\",\n                                   card[\"repo\"], \"--offline\"], capture_output=True, text=True).returncode\n            checks[\"doctor\"] = rc_d\n            rc_c = K.corpus_run(card[\"repo\"], wt)\n            checks[\"corpus\"] = rc_c\n            verdict = \"clean\" if rc_d in (0, 3) and rc_c == 0 else \"failed-checks\"\n    # recent_commits reflects the FINAL tree — after a restore the agent's commits are gone\n    rchf, headf, _ = _git(wt, \"log\", \"--oneline\", \"-5\")\n    delivery = {\"schema_version\": 1, \"card\": work_id, \"cli\": cli, \"verdict\": verdict, \"rc\": rc,\n                \"reaped\": reaped, \"duration_s\": dur, \"brief_hash\": bhash, \"checks\": checks,\n                \"governed\": governed, \"grant\": grant, \"grant_source\": grant_source,\n                \"grant_violations\": grant_violations,\n                \"restore_ok\": restore_ok,\n                \"snapshot_head\": (snap[\"head\"] or \"none\")[:12], \"stream\": spath,\n                \"recent_commits\": headf.splitlines() if rchf == 0 else [],\n                \"next\": f\"ratchet land {wt}\" if verdict == \"clean\" else \"fix or ratchet reconcile\"}\n    dpath = os.path.join(bdir, f\"delivery-{int(t0)}.json\")\n    json.dump(K.redact(delivery), open(dpath, \"w\"), indent=1)\n    K.record(work_id, {\"event\": \"exec_delivery\", \"verdict\": verdict, \"artifact\": dpath})\n    lane = f\"governed ({len(grant)} glob{'s' if len(grant) != 1 else ''})\" if governed else \"UNGOVERNED — whole worktree\"\n    print(f\"exec: verdict {verdict} · lane {lane} · delivery artifact {dpath}\")\n    if verdict == \"clean\":\n        print(f\"  next: ratchet land {wt}   (the agent cannot run this — deliver-through-gate only)\")\n    return 0 if verdict == \"clean\" else 2\n\ndef swarm(args):\n    \"\"\"E4, scoped per §7: dispatch N cards across adapters in PARALLEL LANES. Each lane is a\n    fresh `ratchet-exec run` process — same supervision, same isolation, same gates. Cards\n    already pin their own worktrees (take), so brief and tree describe the same reality.\n    A failed lane halts nothing else; it reports, suggests the debug card, and exits nonzero.\"\"\"\n    if \"--cards\" not in args:\n        print(\"usage: ratchet-exec swarm --cards <id1,id2,...> [--clis <c1,c2>] [--max <n>]\"); return 1\n    cards = args[args.index(\"--cards\") + 1].split(\",\")\n    clis = (args[args.index(\"--clis\") + 1].split(\",\")) if \"--clis\" in args else [\"claude\"]\n    maxp = int(args[args.index(\"--max\") + 1]) if \"--max\" in args else 3\n    timeout = args[args.index(\"--timeout\") + 1] if \"--timeout\" in args else \"900\"\n    me = os.path.abspath(__file__)\n    lanes, results = [], {}\n    queue = [(wid, clis[i % len(clis)]) for i, wid in enumerate(cards)]\n    print(f\"swarm: {len(queue)} card(s) across {len(clis)} adapter(s), {maxp} lane(s) max\")\n    lane_dir = os.path.join(K.WL_HOME, \"state\", \"recordings\")\n    while queue or lanes:\n        while queue and len(lanes) < maxp:\n            wid, cli = queue.pop(0)\n            # lane output goes to a FILE, not a pipe: a lane chattier than the 64KB pipe\n            # buffer blocked before exit while the parent polled forever (final-audit BLOCKER)\n            os.makedirs(os.path.join(lane_dir, wid), exist_ok=True)\n            lpath = os.path.join(lane_dir, wid, f\"lane-{int(time.time())}.log\")\n            lf = open(lpath, \"w\")\n            p = subprocess.Popen([sys.executable, me, \"run\", wid, \"--cli\", cli, \"--timeout\", timeout],\n                                 stdout=lf, stderr=subprocess.STDOUT, text=True)\n            lanes.append((wid, cli, p, lf, lpath))\n            print(f\"swarm: lane up — {wid} on {cli} (log {lpath})\")\n        for wid, cli, p, lf, lpath in lanes[:]:\n            if p.poll() is None:\n                continue\n            lf.close()\n            try:\n                out = open(lpath).read()\n            except OSError:\n                out = \"\"\n            results[wid] = {\"cli\": cli, \"rc\": p.returncode, \"tail\": out[-160:].strip()}\n            lanes.remove((wid, cli, p, lf, lpath))\n            print(f\"swarm: lane down — {wid} ({'clean' if p.returncode == 0 else f'rc {p.returncode}'})\")\n        time.sleep(0.3)\n    failed = {w: r for w, r in results.items() if r[\"rc\"] != 0}\n    print(f\"\\nswarm: {len(results) - len(failed)}/{len(results)} lanes clean\")\n    for w, r in failed.items():\n        print(f\"  FAILED {w} on {r['cli']} (rc {r['rc']}) — debug it as its own card:\")\n        print(f\"    ratchet take debug-{w[:6]} --repo <repo> --title 'debug swarm failure {w}'\")\n    for w, r in results.items():\n        if r[\"rc\"] == 0:\n            print(f\"  CLEAN  {w} — delivery artifact recorded; land it: see `ratchet inbox`\")\n    return 0 if not failed else 2\n\ndef selftest(args):\n    \"\"\"Mock-adapter proofs. No network, no models — the supervision loop itself is the target.\"\"\"\n    import tempfile\n    results = []\n    with tempfile.TemporaryDirectory(prefix=\"rexec-st-\") as tmp:\n        # sandbox workspace: upstream + repo + card, mirroring the kernel's own selftest rig\n        up = os.path.join(tmp, \"up.git\"); seed = os.path.join(tmp, \"seed\")\n        K.run([\"git\", \"init\", \"-q\", \"--bare\", up]); K.run([\"git\", \"init\", \"-q\", \"-b\", \"main\", seed])\n        K.run([\"git\", \"-C\", seed, \"config\", \"user.email\", \"t@t\"]); K.run([\"git\", \"-C\", seed, \"config\", \"user.name\", \"t\"])\n        open(os.path.join(seed, \"f.txt\"), \"w\").write(\"x\")\n        os.makedirs(os.path.join(seed, \"billing\"))\n        open(os.path.join(seed, \"billing\", \"invoice.py\"), \"w\").write(\"def invoice():\\n    return 1\\n\")  # auto-grant target\n        K.run([\"git\", \"-C\", seed, \"add\", \".\"]); K.run([\"git\", \"-C\", seed, \"commit\", \"-qm\", \"c0\"])\n        K.run([\"git\", \"-C\", seed, \"remote\", \"add\", \"origin\", up]); K.run([\"git\", \"-C\", seed, \"push\", \"-q\", \"origin\", \"main\"])\n        clone = os.path.join(tmp, \"clone\"); K.run([\"git\", \"clone\", \"-q\", up, clone])\n        K.run([\"git\", \"-C\", clone, \"config\", \"user.email\", \"t@t\"]); K.run([\"git\", \"-C\", clone, \"config\", \"user.name\", \"t\"])\n        mpath = os.path.join(tmp, \"m.json\"); home = os.path.join(tmp, \"home\")\n        os.makedirs(os.path.join(home, \"state\"), exist_ok=True)\n        json.dump({\"schema_version\": 1, \"min_wl_plane\": \"0\", \"repos\": {\"sb\": {\n            \"path\": clone, \"mainline\": \"main\", \"fetch_remote\": \"origin\", \"push_remote\": \"origin\",\n            \"gh_login\": \"t\", \"forbidden_push\": [], \"remotes\": {\"origin\": up},\n            \"worktree_root\": os.path.join(tmp, \"wts\")}},\n            \"noise_paths\": [], \"archive_dir\": os.path.join(tmp, \"arc\"),\n            \"fetch_ttl_seconds\": 300, \"sync_warn_behind\": 1, \"sync_red_behind\": 50}, open(mpath, \"w\"))\n        env = dict(os.environ, WL_HOME=home, WL_MANIFEST=mpath, WL_INSTANCE=\"rexec-st\")\n        kern = os.path.join(HERE, \"ratchet\"); me = os.path.abspath(__file__)\n        import signal\n        class _R:\n            __slots__ = (\"returncode\", \"stdout\", \"stderr\")\n        def sh(*a, extra=None, t=120):\n            # Capture to a FILE in a new session, wait on the DIRECT child, then killpg the group. A mock\n            # lane under test can leave a detached/bg child that inherits the output stream; with\n            # capture_output=True (a pipe) communicate() would then block past the timeout — a\n            # nondeterministic CI deadlock that hangs this whole companion (and the kernel waiting on it).\n            # A file has no write-end to hold; p.wait returns when the lane itself exits; killpg reaps the\n            # rest. Deterministic regardless of what a lane leaks.\n            with tempfile.TemporaryFile(mode=\"w+\") as tf:\n                p = subprocess.Popen([sys.executable, *a], env={**env, **(extra or {})},\n                                     stdout=tf, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL,\n                                     start_new_session=True)\n                try:\n                    rc = p.wait(timeout=t)\n                except subprocess.TimeoutExpired:\n                    rc = 124\n                finally:\n                    try:\n                        os.killpg(os.getpgid(p.pid), signal.SIGKILL)\n                    except (ProcessLookupError, PermissionError, OSError):\n                        pass\n                    try:\n                        p.wait(timeout=10)\n                    except subprocess.TimeoutExpired:\n                        pass\n                tf.seek(0); out = tf.read()\n            r = _R(); r.returncode = rc; r.stdout = out; r.stderr = \"\"\n            return r\n        sh(kern, \"take\", \"exec-proof\", \"--repo\", \"sb\", \"--title\", \"exec proof\")\n        cards = json.load(open(os.path.join(home, \"state\", \"workcards.json\")))[\"cards\"]\n        wid = next(c[\"work_id\"] for c in cards if c[\"slug\"] == \"exec-proof\")\n        pre = open(os.path.join(home, \"state\", \"workcards.json\")).read()\n\n        # 1. failing agent ⇒ card state UNCHANGED (the E1 exit criterion)\n        r1 = sh(me, \"run\", wid, \"--cli\", \"mock\", extra={\"RATCHET_MOCK_CMD\": \"echo boom; exit 1\"})\n        post = open(os.path.join(home, \"state\", \"workcards.json\")).read()\n        results.append((\"EXEC failing agent leaves card state UNCHANGED\",\n                        r1.returncode == 2 and json.loads(pre)[\"cards\"] == json.loads(post)[\"cards\"],\n                        r1.stdout[-90:]))\n        # 2. timeout ⇒ reaped, no partial deliver\n        r2 = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--timeout\", \"2\",\n                extra={\"RATCHET_MOCK_CMD\": \"sleep 30\"}, t=180)\n        results.append((\"EXEC wall-clock cap reaps the lane\",\n                        r2.returncode == 2 and \"REAPED\" in r2.stdout, r2.stdout[-90:]))\n        # 2b. partial-line-then-stall must NOT starve the cap (the run_card twin-loop hardening)\n        r2p = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--timeout\", \"2\",\n                 extra={\"RATCHET_MOCK_CMD\": \"printf partial-no-newline; sleep 30\"}, t=60)\n        results.append((\"EXEC wall-clock cap reaps a partial-line-then-stall lane (no readline starvation)\",\n                        r2p.returncode == 2 and \"REAPED\" in r2p.stdout, r2p.stdout[-90:]))\n        # 3. clean pass ⇒ delivery artifact, verdict clean, NEXT points at the land gate\n        wtp = os.path.join(tmp, \"wts\", \"wt-exec-proof\")\n        r3 = sh(me, \"run\", wid, \"--cli\", \"mock\",\n                extra={\"RATCHET_MOCK_CMD\":\n                       f\"cd {wtp} && echo work > done.txt && git add . && git commit -qm 'feat: work' && echo done\"})\n        deliv = [f for f in os.listdir(os.path.join(home, \"state\", \"recordings\", wid)) if f.startswith(\"delivery\")]\n        dj = json.load(open(os.path.join(home, \"state\", \"recordings\", wid, sorted(deliv)[-1]))) if deliv else {}\n        results.append((\"EXEC clean pass delivers THROUGH the gate (never lands)\",\n                        r3.returncode == 0 and dj.get(\"verdict\") == \"clean\" and \"ratchet land\" in dj.get(\"next\", \"\"),\n                        f\"verdict={dj.get('verdict')}\"))\n        # 3b. GUARDED_SUITE — the PR-gate sandbox primitive (ratchet-maintain routes its untrusted\n        # contributor suite through this). Reproduced-failure proofs, called as a library:\n        os.environ[\"GH_TOKEN\"] = \"ghp_\" + \"z\" * 36\n        try:\n            gs = guarded_suite(wtp, 'test -z \"$GH_TOKEN\"', timeout=30)\n            results.append((\"GUARDED suite cannot see GH_TOKEN (clean_env allowlist)\",\n                            gs[\"ok\"] and gs[\"rc\"] == 0, str(gs)[-90:]))\n            gs2 = guarded_suite(wtp, 'test -n \"$GH_TOKEN\"', timeout=30)\n            results.append((\"GUARDED control: a suite that REQUIRES the secret fails\",\n                            (not gs2[\"ok\"]) and gs2[\"rc\"] != 0, str(gs2)[-90:]))\n        finally:\n            os.environ.pop(\"GH_TOKEN\", None)\n        gst = guarded_suite(wtp, \"sleep 30\", timeout=2)\n        results.append((\"GUARDED hung (silent) suite is reaped, not ok\",\n                        gst[\"reaped\"] == \"timeout\" and not gst[\"ok\"] and gst[\"duration_s\"] < 12, str(gst)[-90:]))\n        # the timeout must NOT be starvable by output — a partial line then a stall\n        gsp = guarded_suite(wtp, \"printf partial-no-newline; sleep 30\", timeout=2)\n        results.append((\"GUARDED partial-line-then-stall is still reaped (no readline starvation)\",\n                        gsp[\"reaped\"] == \"timeout\" and gsp[\"duration_s\"] < 12, str(gsp)[-90:]))\n        # a non-detached bg child holding the stdout pipe open must NOT make us wait for it\n        gsw = guarded_suite(wtp, \"sleep 999999 & echo parent-done\", timeout=30)\n        results.append((\"GUARDED bg child holding the pipe does not stall the supervision loop\",\n                        gsw[\"duration_s\"] < 12, str(gsw)[-90:]))\n        # bg child write to a path OUTSIDE the worktree — restore cannot mask an absolute-path write,\n        # so its absence proves the GROUP SWEEP killed the child before its delayed write (not restore)\n        _bgpath = os.path.join(tmp, \"BG_PWN_OUTSIDE.txt\")\n        guarded_suite(wtp, \"sh -c 'sleep 3; echo pwn > %s' &\" % _bgpath, timeout=30)\n        results.append((\"GUARDED non-detached bg child is swept before it can write (outside wt)\",\n                        not os.path.exists(_bgpath), _bgpath))\n        gsh = guarded_suite(wtp, 'HD=$(git rev-parse --git-path hooks) && mkdir -p \"$HD\" && '\n                            \"printf '#!/bin/sh\\\\necho PWN\\\\n' > \\\"$HD/pre-commit\\\" && chmod +x \\\"$HD/pre-commit\\\"\",\n                            timeout=30)\n        _hp = os.path.join(_hooks_dir(wtp) or wtp, \"pre-commit\")\n        _hookgone = (not os.path.exists(_hp)) or (\"PWN\" not in open(_hp).read())\n        results.append((\"GUARDED .git hook injection is flagged + reverted (RCE surface)\",\n                        (not gsh[\"ok\"]) and bool(gsh[\"violations\"]) and _hookgone, str(gsh)[-90:]))\n        # ref tamper: MOVING/DELETING a pre-existing ref in the SHARED gitdir (what defeated the scan —\n        # mainline moved onto the PR head) is a violation + reverted. CREATING a ref is intentionally\n        # IGNORED so a concurrent gate's fresh branch in the same gitdir is never clobbered.\n        _git(wtp, \"update-ref\", \"refs/heads/victim\", \"HEAD\")   # a pre-existing ref at wt's own HEAD\n        _pre_refs = _refs(wtp)\n        gsr = guarded_suite(wtp, \"git update-ref -d refs/heads/victim\", timeout=30)\n        _post_refs = _refs(wtp)\n        results.append((\"GUARDED deleting a pre-existing ref is a violation + reverted\",\n                        (not gsr[\"ok\"]) and bool(gsr[\"violations\"]) and _post_refs == _pre_refs, str(gsr)[-90:]))\n        gsc = guarded_suite(wtp, \"git update-ref refs/heads/peer HEAD\", timeout=30)\n        results.append((\"GUARDED a CREATED ref is not flagged (concurrency-safe: no concurrent-gate clobber)\",\n                        not gsc[\"violations\"], str(gsc)[-90:]))\n        _git(wtp, \"update-ref\", \"-d\", \"refs/heads/peer\")\n        _git(wtp, \"update-ref\", \"-d\", \"refs/heads/victim\")\n        gse = guarded_suite(wtp, \"ln -s /etc/passwd ESCAPE_LINK\", timeout=30)\n        results.append((\"GUARDED symlink escape out of the worktree is a violation\",\n                        (not gse[\"ok\"]) and bool(gse[\"violations\"]), str(gse)[-90:]))\n        # 4. captured stream is REDACTED (a leaking agent cannot poison the recording)\n        sh(me, \"run\", wid, \"--cli\", \"mock\",\n           extra={\"RATCHET_MOCK_CMD\": \"echo api_key = 'sk-\" + \"z\" * 24 + \"'; exit 1\"})\n        rdir = os.path.join(home, \"state\", \"recordings\", wid)\n        streams = \"\".join(open(os.path.join(rdir, f)).read() for f in os.listdir(rdir) if f.startswith(\"stream\"))\n        results.append((\"EXEC captured streams are redacted before disk\",\n                        \"sk-zzzz\" not in streams and \"[REDACTED\" in streams, streams[-60:]))\n        # 5. deny-list refusal (config is policy, exec obeys it)\n        json.dump({\"schema_version\": 1, \"deny_list\": [\"mock\"]}, open(os.path.join(home, \"state\", \"config.json\"), \"w\"))\n        r5 = sh(me, \"run\", wid, \"--cli\", \"mock\", extra={\"RATCHET_MOCK_CMD\": \"true\"})\n        results.append((\"EXEC honors the config deny-list\", r5.returncode == 2 and \"deny-list\" in r5.stdout, r5.stdout[-70:]))\n        os.remove(os.path.join(home, \"state\", \"config.json\"))\n        # 5b. SECRET NON-LEAK (security-council CRITICAL): a secret in the parent env must NOT\n        # reach the agent — the mock echoes $GH_TOKEN and it must come back empty/redacted\n        r5s = sh(me, \"run\", wid, \"--cli\", \"mock\",\n                 extra={\"RATCHET_MOCK_CMD\": \"echo TOKEN_IS=[$GH_TOKEN] KEY=[$OPENAI_API_KEY]; exit 1\",\n                        \"GH_TOKEN\": \"ghp_\" + \"z\" * 30, \"OPENAI_API_KEY\": \"sk-\" + \"z\" * 30})\n        rdir = os.path.join(home, \"state\", \"recordings\", wid)\n        streams = \"\".join(open(os.path.join(rdir, f)).read() for f in os.listdir(rdir) if f.startswith(\"stream\"))\n        results.append((\"EXEC agent env is allowlisted — parent secrets never reach the lane\",\n                        \"TOKEN_IS=[]\" in streams and \"KEY=[]\" in streams and \"ghp_zzzz\" not in streams,\n                        \"leak check\"))\n        # SANDBOX 1 — grant VIOLATION: a write outside the lane rejects the whole run, hard-restores\n        # the worktree (the forbidden file is gone), and leaves the card byte-identical\n        wtp = os.path.join(tmp, \"wts\", \"wt-exec-proof\")\n        preg = open(os.path.join(home, \"state\", \"workcards.json\")).read()\n        rg = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"allowed.txt\",\n                extra={\"RATCHET_MOCK_CMD\":\n                       f\"cd {wtp} && echo bad > forbidden.txt && git add . && git commit -qm 'x' && echo done\"})\n        postg = open(os.path.join(home, \"state\", \"workcards.json\")).read()\n        results.append((\"SANDBOX grant violation rejects the run + restores the worktree\",\n                        rg.returncode == 2 and \"REJECTED\" in rg.stdout\n                        and not os.path.exists(os.path.join(wtp, \"forbidden.txt\"))\n                        and json.loads(preg)[\"cards\"] == json.loads(postg)[\"cards\"],\n                        rg.stdout[-90:]))\n        # SANDBOX 2 — an in-lane write passes and the delivery is stamped governed, zero violations\n        rgi = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*.txt\",\n                 extra={\"RATCHET_MOCK_CMD\":\n                        f\"cd {wtp} && echo good >> ingrant.txt && git add . && git commit -qm 'y' && echo done\"})\n        rdir = os.path.join(home, \"state\", \"recordings\", wid)\n        deliv = sorted(f for f in os.listdir(rdir) if f.startswith(\"delivery\"))\n        dj2 = json.load(open(os.path.join(rdir, deliv[-1]))) if deliv else {}\n        results.append((\"SANDBOX in-lane write passes + delivery marked governed\",\n                        rgi.returncode == 0 and dj2.get(\"verdict\") == \"clean\"\n                        and dj2.get(\"governed\") is True and dj2.get(\"grant_violations\") == [],\n                        f\"verdict={dj2.get('verdict')} governed={dj2.get('governed')}\"))\n        # SANDBOX 3 — a timed-out lane leaves NOTHING behind: its partial write is gone after reap\n        rt = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--timeout\", \"2\",\n                extra={\"RATCHET_MOCK_CMD\": f\"cd {wtp} && echo partial > partial.txt && sleep 30\"}, t=180)\n        results.append((\"SANDBOX reap hard-restores the worktree to snapshot\",\n                        rt.returncode == 2 and \"REAPED\" in rt.stdout\n                        and not os.path.exists(os.path.join(wtp, \"partial.txt\")), rt.stdout[-90:]))\n        # DISPATCH — no --cli + no agent on PATH ⇒ the capability hierarchy refuses honestly\n        # (points at `ratchet init`), it does not crash or silently pick a missing binary\n        emptybin = os.path.join(tmp, \"emptybin\"); os.makedirs(emptybin, exist_ok=True)\n        rnd = sh(me, \"run\", wid, extra={\"PATH\": emptybin})\n        results.append((\"DISPATCH no --cli + no agent available refuses cleanly\",\n                        rnd.returncode == 2 and \"no agent available\" in rnd.stdout, rnd.stdout[-90:]))\n        # AUTO-GRANT — with a repo index present, a card with a confident scope auto-scopes the lane\n        # (no --grant given): exec asks ratchet-index and governs the run against the derived globs.\n        idx_bin = os.path.join(HERE, \"ratchet-index\")\n        if os.path.exists(idx_bin):\n            sh(idx_bin, \"build\", \"sb\")\n            sh(kern, \"take\", \"billing-fix\", \"--repo\", \"sb\", \"--title\", \"fix the billing invoice\")\n            cag = json.load(open(os.path.join(home, \"state\", \"workcards.json\")))[\"cards\"]\n            wag = next(c[\"work_id\"] for c in cag if c[\"slug\"] == \"billing-fix\")\n            wtag = os.path.join(tmp, \"wts\", \"wt-billing-fix\")\n            rag = sh(me, \"run\", wag, \"--cli\", \"mock\",  # NO --grant → index scopes it\n                     extra={\"RATCHET_MOCK_CMD\": f\"cd {wtag} && echo w > billing/new.py && git add . && git commit -qm x && echo done\"})\n            rd = os.path.join(home, \"state\", \"recordings\", wag)\n            dag = json.load(open(os.path.join(rd, sorted(f for f in os.listdir(rd) if f.startswith(\"delivery\"))[-1])))\n            results.append((\"AUTO-GRANT: repo index scopes the lane when no --grant is given\",\n                            rag.returncode == 0 and dag.get(\"governed\") is True\n                            and dag.get(\"grant\") and \"billing/**\" in dag[\"grant\"]\n                            and dag.get(\"grant_source\") == \"auto-index\" and \"auto-scoped\" in rag.stdout,\n                            f\"grant={dag.get('grant')} src={dag.get('grant_source')}\"))\n            # cross-audit: exec VALIDATES the index's output — a wide/escaping glob is never trusted\n            results.append((\"AUTO-GRANT validates index globs (rejects **, absolute, ..)\",\n                            _valid_autogrant([\"billing/**\"]) and not _valid_autogrant([\"**\"])\n                            and not _valid_autogrant([\"/etc/**\"]) and not _valid_autogrant([\"../x/**\"])\n                            and not _valid_autogrant(\"billing/**\") and not _valid_autogrant([]), \"\"))\n            # cross-audit: a --no-auto-grant smuggled in the agent PAYLOAD does not disable governance\n            rpl = sh(me, \"run\", wag, \"--cli\", \"mock\", \"--prompt-extra\", \"--no-auto-grant\",\n                     extra={\"RATCHET_MOCK_CMD\": f\"cd {wtag} && echo w >> billing/new.py && git add . && git commit -qm y && echo done\"})\n            dp = json.load(open(os.path.join(rd, sorted(f for f in os.listdir(rd) if f.startswith(\"delivery\"))[-1])))\n            results.append((\"AUTO-GRANT: --no-auto-grant in the payload can't disable governance\",\n                            dp.get(\"grant_source\") == \"auto-index\", f\"src={dp.get('grant_source')}\"))\n        # ── wave-1 cross-audit hardening proofs (each pins a confirmed council finding) ──\n        # AUDIT-1 · .git hooks RCE surface: injecting a hook into the RESOLVED hooks dir (the common\n        # gitdir — a worktree's .git is a file) is a violation even under a matching grant, and the\n        # injected hook is stripped on restore. The agent locates it exactly as git does.\n        hooksdir = os.path.join(clone, \".git\", \"hooks\")\n        rga = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",\n                 extra={\"RATCHET_MOCK_CMD\":\n                        f\"cd {wtp} && HD=$(git rev-parse --git-path hooks) && mkdir -p \\\"$HD\\\" && \"\n                        \"printf '#!/bin/sh\\\\necho HOOKPWN\\\\n' > \\\"$HD/pre-commit\\\" && chmod +x \\\"$HD/pre-commit\\\" && echo done\"})\n        hp = os.path.join(hooksdir, \"pre-commit\")\n        hookbody = open(hp).read() if os.path.exists(hp) else \"\"\n        results.append((\"AUDIT .git hooks tamper is rejected + reverted (added or overwritten)\",\n                        rga.returncode == 2 and \"REJECTED\" in rga.stdout and \"HOOKPWN\" not in hookbody,\n                        rga.stdout[-90:]))\n        # AUDIT-2 · symlink escape: an in-grant symlink pointing outside the worktree is a violation\n        outside = os.path.join(tmp, \"outside_target\"); open(outside, \"w\").write(\"host\")\n        rsy = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"cd {wtp} && ln -s {outside} escape && echo done\"})\n        results.append((\"AUDIT symlink escaping the worktree is a violation\",\n                        rsy.returncode == 2 and \"REJECTED\" in rsy.stdout\n                        and not os.path.islink(os.path.join(wtp, \"escape\"))\n                        and open(outside).read() == \"host\",  # external target untouched\n                        rsy.stdout[-90:]))\n        # AUDIT-2b · non-ASCII filename must NOT defeat containment: default git C-quotes such a name\n        # (`\"caf\\303\\251_escape\"`) so a literal-string parse would look up a name that doesn't exist\n        # and pass the symlink escape through as `clean`. -z parsing hits the REAL file. Same escape,\n        # café name: rejected AND removed on restore.\n        outside2 = os.path.join(tmp, \"outside_target2\"); open(outside2, \"w\").write(\"host2\")\n        nm = \"café_escape\"\n        r2b = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"cd {wtp} && ln -s {outside2} '{nm}' && echo done\"})\n        results.append((\"AUDIT non-ASCII symlink escape is a violation + restored (quotePath bypass closed)\",\n                        r2b.returncode == 2 and \"REJECTED\" in r2b.stdout\n                        and not os.path.islink(os.path.join(wtp, nm))\n                        and not os.path.exists(os.path.join(wtp, nm))\n                        and open(outside2).read() == \"host2\",\n                        r2b.stdout[-90:]))\n        # AUDIT-3 · rename bypass: `git mv` of a forbidden file counts the SOURCE, not just the dest\n        sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",  # seed a tracked forbidden.py in-lane\n           extra={\"RATCHET_MOCK_CMD\": f\"cd {wtp} && echo x > forbidden.py && git add . && git commit -qm seed && echo done\"})\n        rmv = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"allowed.py\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"cd {wtp} && git mv forbidden.py allowed.py && git commit -qm mv && echo done\"})\n        results.append((\"AUDIT rename counts the vacated source path (git mv bypass closed)\",\n                        rmv.returncode == 2 and \"REJECTED\" in rmv.stdout\n                        and os.path.exists(os.path.join(wtp, \"forbidden.py\")),  # restored\n                        rmv.stdout[-90:]))\n        # AUDIT-4 · history evasion: add-then-remove nets to zero in a plain diff but is in history\n        rhx = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"keep.txt\",\n                 extra={\"RATCHET_MOCK_CMD\":\n                        f\"cd {wtp} && echo s > secret.txt && git add . && git commit -qm add && \"\n                        f\"git rm -q secret.txt && git commit -qm del && echo done\"})\n        results.append((\"AUDIT add-then-remove (net-zero diff) is still caught via history\",\n                        rhx.returncode == 2 and \"REJECTED\" in rhx.stdout, rhx.stdout[-90:]))\n        # AUDIT-5 · pre-run UNTRACKED file is preserved across a failed run (clean -fd would nuke it)\n        keep = os.path.join(wtp, \"user_local.txt\"); open(keep, \"w\").write(\"mine\")\n        rpr = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--timeout\", \"2\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"cd {wtp} && echo junk > agent_tmp.txt && sleep 30\"}, t=180)\n        results.append((\"AUDIT pre-run untracked file survives restore; agent's is removed\",\n                        \"REAPED\" in rpr.stdout and os.path.exists(keep)\n                        and open(keep).read() == \"mine\"\n                        and not os.path.exists(os.path.join(wtp, \"agent_tmp.txt\")), rpr.stdout[-90:]))\n        os.remove(keep)  # tidy so it doesn't pollute later proofs\n        # AUDIT-6 · .git/config tamper: injecting core.hooksPath into the local config is DETECTED\n        # (run rejected) AND the config file is reverted byte-for-byte on restore. A pre-seeded\n        # multi-valued key must survive the restore (byte-restore preserves it; a semantic git-config\n        # rewrite would not — that fidelity concern was why this was deferred).\n        cfgp = os.path.join(clone, \".git\", \"config\")\n        subprocess.run([\"git\", \"-C\", clone, \"config\", \"--add\", \"ratchet.canary\", \"one\"], check=True)\n        subprocess.run([\"git\", \"-C\", clone, \"config\", \"--add\", \"ratchet.canary\", \"two\"], check=True)\n        cfg_before = open(cfgp).read()\n        rcf = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"cd {wtp} && git config --add core.hooksPath /tmp/evilhooks && echo done\"})\n        cfg_after = open(cfgp).read()\n        results.append((\"AUDIT .git/config tamper is rejected + reverted byte-for-byte (multi-valued keys kept)\",\n                        rcf.returncode == 2 and \"REJECTED\" in rcf.stdout\n                        and \"evilhooks\" not in cfg_after and cfg_after == cfg_before\n                        and cfg_after.count(\"canary\") >= 2,\n                        rcf.stdout[-90:]))\n        subprocess.run([\"git\", \"-C\", clone, \"config\", \"--unset-all\", \"ratchet.canary\"],\n                       stderr=subprocess.DEVNULL)  # tidy so it doesn't pollute later proofs\n        # 6. E4 swarm: two parallel mock lanes — one clean, one failing; report names both,\n        # neither corrupts state, and the failure suggests its debug card\n        sh(kern, \"take\", \"sw-a\", \"--repo\", \"sb\", \"--title\", \"swarm a\")\n        sh(kern, \"take\", \"sw-b\", \"--repo\", \"sb\", \"--title\", \"swarm b\")\n        cards2 = json.load(open(os.path.join(home, \"state\", \"workcards.json\")))[\"cards\"]\n        wa = next(c[\"work_id\"] for c in cards2 if c[\"slug\"] == \"sw-a\")\n        wb = next(c[\"work_id\"] for c in cards2 if c[\"slug\"] == \"sw-b\")\n        wta = os.path.join(tmp, \"wts\", \"wt-sw-a\")\n        mock = (f\"if [ \\\"$RATCHET_CARD\\\" = \\\"{wa}\\\" ]; then cd {wta} && echo w > w.txt && git add . \"\n                f\"&& git commit -qm 'feat: swarm work' && exit 0; else sleep 1; exit 1; fi\")\n        r6 = sh(me, \"swarm\", \"--cards\", f\"{wa},{wb}\", \"--clis\", \"mock,mock\", \"--timeout\", \"60\",\n                extra={\"RATCHET_MOCK_CMD\": mock}, t=300)\n        cards3 = json.load(open(os.path.join(home, \"state\", \"workcards.json\")))[\"cards\"]\n        both_open = all(c[\"status\"] == \"open\" for c in cards3 if c[\"slug\"] in (\"sw-a\", \"sw-b\"))\n        results.append((\"SWARM runs parallel lanes; failure isolated + debug card suggested\",\n                        r6.returncode == 2 and \"1/2 lanes clean\" in r6.stdout\n                        and f\"FAILED {wb}\" in r6.stdout and \"debug-\" in r6.stdout and both_open,\n                        r6.stdout[-140:]))\n        # 7. a lane NOISIER than the pipe buffer must not deadlock the swarm (final-audit\n        # BLOCKER: stdout=PIPE read only after exit blocked chatty children forever)\n        try:\n            r7 = sh(me, \"swarm\", \"--cards\", wb, \"--clis\", \"mock\", \"--timeout\", \"120\",\n                    extra={\"RATCHET_MOCK_CMD\": \"seq 1 8000 | sed 's/^/noise padding line number /'\"}, t=240)\n            ok7 = r7.returncode == 0 and \"1/1 lanes clean\" in r7.stdout\n            det7 = r7.stdout[-90:]\n        except subprocess.TimeoutExpired:\n            ok7, det7 = False, \"DEADLOCKED — pipe-buffer hang reproduced\"\n        results.append((\"SWARM survives a lane noisier than the pipe buffer\", ok7, det7))\n\n    passed = sum(1 for _, okv, _ in results if okv)\n    for label, okv, detail in results:\n        print(f\"  {'OK  ' if okv else 'FAIL'}  {label}\" + (\"\" if okv else f\" — {detail}\"))\n    print(f\"\\n  ratchet-exec selftest: {passed}/{len(results)}\")\n    return 0 if passed == len(results) else 2\n",
      "post": "# ── FERROX DIV-03 (phase 18): untrusted code never shares the canonical git directory ────────\n# Upstream ran BOTH untrusted paths with cwd inside a LINKED worktree. A linked worktree's .git is\n# a FILE pointing at the canonical common gitdir, so the child could write the canonical\n# repository's hooks, config and refs directly. Upstream detected that and reverted it — hooks at\n# _snapshot/_restore, refs at _refs/_ref_tamper/_restore_refs, the tree at _restore. Detect and\n# revert is not containment: the window is live while the child runs, the revert itself can fail,\n# and `restore-failed` is a real upstream verdict. Worse, _refs is only ever called by\n# guarded_suite; run_card, the path that runs an AI agent CLI, has no ref containment at all.\n#\n# So both paths now execute against a THROWAWAY CLONE that owns its own git directory. The scope\n# is deliberately the 2 functions that execute untrusted code and NOT the card lifecycle:\n# converting the card tree itself would additionally change 6 sites in the kernel, and its gc and\n# reap paths archive a branch with `git bundle create` against the CANONICAL repository, so after\n# such a conversion the branch would live only in the clone and archive-before-delete would\n# silently bundle nothing. That is a data loss path. The isolation goes where the untrusted\n# process runs.\n#\n# The gate suite needs no transfer at all: upstream already discards every suite write. The agent\n# path transfers back ONLY on a containment-accepted verdict, which is exactly the set of runs\n# upstream left in the worktree.\n\ndef _mirror_tree(src, dst):\n    \"\"\"Copy every working-file entry of src over dst and delete dst entries src does not have,\n    skipping any entry named .git at every level. Symlinks are copied AS symlinks and never\n    followed, so a pre-run symlink stays a symlink and _escapes still sees it as one.\"\"\"\n    import shutil\n    def _entries(d):\n        try:\n            return {n for n in os.listdir(d) if n != \".git\"}\n        except OSError:\n            return set()\n    def _drop(p):\n        try:\n            if os.path.islink(p) or not os.path.isdir(p):\n                os.remove(p)\n            else:\n                shutil.rmtree(p, ignore_errors=True)\n        except OSError:\n            pass\n    s_names, d_names = _entries(src), _entries(dst)\n    for name in d_names - s_names:\n        _drop(os.path.join(dst, name))\n    for name in s_names:\n        sp, dp = os.path.join(src, name), os.path.join(dst, name)\n        try:\n            if os.path.islink(sp):\n                if os.path.lexists(dp):\n                    _drop(dp)\n                os.symlink(os.readlink(sp), dp)\n            elif os.path.isdir(sp):\n                if os.path.lexists(dp) and (os.path.islink(dp) or not os.path.isdir(dp)):\n                    _drop(dp)\n                os.makedirs(dp, exist_ok=True)\n                _mirror_tree(sp, dp)\n            else:\n                if os.path.lexists(dp) and os.path.isdir(dp) and not os.path.islink(dp):\n                    _drop(dp)\n                shutil.copy2(sp, dp, follow_symlinks=False)\n        except OSError:\n            pass\n    return True\n\ndef _isolated_clone(wt, tag):\n    \"\"\"Build the throwaway clone. --no-hardlinks and no --shared, so it shares no object file and\n    no alternates with the canonical repository; its .git is a real directory, so its hooks, config\n    and refs are its own. Every local head and tag is replicated with update-ref, because a plain\n    clone materialises only the checked-out branch and the ref containment surface would otherwise\n    be empty. The origin remote points back AT the card tree, so it is REMOVED: leaving it would\n    hand the child `git push origin` straight into the canonical repository. user.name and\n    user.email are carried across so the child can still commit. Returns the path, or None.\"\"\"\n    parent = os.path.dirname(os.path.abspath(wt.rstrip(os.sep))) or os.path.abspath(os.sep)\n    dst = os.path.join(parent, \".ratchet-iso-%s-%d-%d\" % (tag, os.getpid(), int(time.time() * 1000) % 1000000))\n    if os.path.exists(dst):\n        return None\n    rc, _, _ = K.run([\"git\", \"clone\", \"--no-hardlinks\", \"-q\", wt, dst], timeout=600)\n    if rc != 0 or not os.path.isdir(os.path.join(dst, \".git\")):\n        return None\n    head_ref = None\n    rcs, sref, _ = _git(dst, \"symbolic-ref\", \"-q\", \"HEAD\")\n    if rcs == 0:\n        head_ref = sref.strip() or None\n    rcf, refs, _ = _git(wt, \"for-each-ref\", \"--format=%(objectname) %(refname)\", \"refs/heads\", \"refs/tags\")\n    if rcf == 0:\n        for ln in refs.splitlines():\n            p = ln.split(\" \", 1)\n            if len(p) == 2 and p[1] != head_ref:\n                _git(dst, \"update-ref\", p[1], p[0])\n    _git(dst, \"remote\", \"remove\", \"origin\")\n    for key in (\"user.name\", \"user.email\"):\n        rcv, val, _ = _git(wt, \"config\", \"--get\", key)\n        if rcv == 0 and val.strip():\n            _git(dst, \"config\", key, val.strip())\n    _mirror_tree(wt, dst)\n    return dst\n\ndef _drop_clone(iso):\n    \"\"\"Delete the throwaway clone. Runs on EVERY exit path, accepted or rejected.\"\"\"\n    import shutil\n    if iso and os.path.isdir(iso):\n        shutil.rmtree(iso, ignore_errors=True)\n\ndef _transfer_back(wt, iso):\n    \"\"\"Move the card branch onto the clone's HEAD and mirror the clone's working files over the\n    card tree. Runs ONLY after the containment audit accepted the run. The commit is fetched into\n    a PRIVATE per-process ref first, so a failed fetch can never leave the card branch half moved,\n    and the ref is dropped again immediately (refs/ratchet/* is a COMMON ref namespace, so it is\n    keyed by pid rather than fixed, unlike _snapshot's own pin).\"\"\"\n    xref = \"refs/ratchet/xfer-%d\" % os.getpid()\n    rcf, _, _ = _git(wt, \"fetch\", \"--no-tags\", \"-q\", iso, \"+HEAD:\" + xref)\n    if rcf != 0:\n        return False\n    rcr, _, _ = _git(wt, \"reset\", \"--hard\", \"-q\", xref)\n    _git(wt, \"update-ref\", \"-d\", xref)\n    if rcr != 0:\n        return False\n    _mirror_tree(iso, wt)\n    return True\n\ndef guarded_suite(wt, cmd, timeout=600):\n    \"\"\"Run an UNTRUSTED contributor command `cmd` (a shell string) against worktree `wt` under the\n    same governed sandbox spine as run_card, so a PR gate can execute a repo's test suite without\n    handing it the operator's shell. Guarantees:\n      • FERROX DIV-03: the command executes inside a THROWAWAY CLONE of `wt` that owns its own git\n        directory, so the canonical repository's hooks, config and refs are not reachable at all\n        rather than reachable-and-reverted. The clone is snapshotted, audited and restored exactly\n        as the worktree used to be, and then deleted; upstream already discarded every suite write,\n        so nothing is transferred back and the gate signal is unchanged;\n      • allowlisted clean_env — no GH_TOKEN / *_API_KEY / AWS_* to exfiltrate (the suite sees only\n        PATH/HOME-class vars);\n      • own process group + wall-clock cap (SIGTERM→SIGKILL on the GROUP) enforced by a NON-BLOCKING\n        supervision loop — a bg child holding the stdout pipe, or a partial-line-then-stall, can no\n        longer starve the timeout check — then a group sweep so a non-detached child can't write\n        after we stop watching;\n      • the clone is SNAPSHOTTED first and hard-RESTORED after — the suite's writes are a\n        throwaway, and an injected .git hook / core.fsmonitor command is reverted as well as\n        contained, so the restore path stays exercised rather than becoming dead code;\n      • REFS are snapshotted too and any move/delete is a VIOLATION and is reverted — a suite\n        cannot move a mainline ref onto its own head to blind a later diff or poison the repo;\n      • .git config/hooks tamper and symlink/realpath escapes out of the tree are flagged as\n        containment VIOLATIONS (never legitimate suite behaviour).\n    Unlike run_card this does NOT reject ordinary in-worktree writes — a test suite legitimately\n    writes artifacts, and the tree is discarded. The gate signal is: exited 0, not reaped, no\n    containment violation. HONEST BOUNDARY is identical to run_card's (setsid-detached children and\n    absolute-path writes outside the clone need OS sandboxing — deferred, BUILD-PLAN-V2 §9).\n    Returns {ok, rc, reaped, duration_s, violations, restore_ok, stream_tail}.\"\"\"\n    iso = _isolated_clone(wt, \"gate\")\n    if iso is None:\n        return {\"ok\": False, \"rc\": 127, \"reaped\": None, \"duration_s\": 0.0,\n                \"violations\": [\"<isolation clone failed: refusing to run untrusted code against the canonical git directory>\"],\n                \"restore_ok\": True, \"stream_tail\": \"\"}\n    try:\n        snap = _snapshot(iso)\n        refs0 = _refs(iso)\n        env = K.clean_env({\"RATCHET_GATE\": \"1\", \"RATCHET_WORKTREE\": iso})\n        argv = [\"bash\", \"-lc\", cmd]\n        t0 = time.time()\n        try:\n            # BYTES (no text=True): the shared non-blocking supervisor reads the raw fd and decodes later.\n            proc = subprocess.Popen(argv, cwd=iso, env=env, start_new_session=True,\n                                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\n        except (FileNotFoundError, OSError) as e:\n            return {\"ok\": False, \"rc\": 127, \"reaped\": None, \"duration_s\": 0.0,\n                    \"violations\": [\"spawn-failed: %s\" % e], \"restore_ok\": _restore(iso, snap),\n                    \"stream_tail\": \"\"}\n        reaped, raw = _supervise(proc, t0 + timeout)\n        rc = proc.wait()\n        try:\n            os.killpg(proc.pid, signal.SIGKILL)  # sweep the group before we inspect / restore the tree\n            time.sleep(0.2)\n        except OSError:\n            pass\n        dur = round(time.time() - t0, 1)\n        stream = raw[-200_000:].decode(\"utf-8\", \"replace\")\n        # containment audit BEFORE restore: .git tamper, ref tamper, and realpath/symlink escapes are\n        # never legitimate suite behaviour. DIV-02: the audit cannot throw past the restore below.\n        audit = _containment_audit(iso, snap, refs0)\n        ref_tampered = audit[\"ref_tampered\"]\n        violations = list(dict.fromkeys(\n            ([audit[\"error\"]] if audit[\"error\"] else [])\n            + audit[\"escapes\"]\n            + ([\"<.git config/hooks tampered>\"] if audit[\"meta_tampered\"] else [])\n            + ([\"<git refs moved/deleted: %s>\" % \", \".join(ref_tampered[:3])] if ref_tampered else [])))\n        # ALWAYS restore: drops the throwaway suite writes, reverts any injected hook/config, and puts\n        # every moved/deleted ref back. The clone is then deleted, so the canonical repository was\n        # never reachable in the first place — restore is now the second line, not the only one.\n        restore_ok = _restore(iso, snap)\n        if ref_tampered:\n            _restore_refs(iso, refs0, ref_tampered)\n        ok = (rc == 0) and (reaped is None) and (not violations)\n        return {\"ok\": ok, \"rc\": rc, \"reaped\": reaped, \"duration_s\": dur, \"violations\": violations,\n                \"restore_ok\": restore_ok, \"stream_tail\": K.redact(stream)[-2000:]}\n    finally:\n        _drop_clone(iso)\n\ndef run_card(args):\n    pos = [a for a in args if not a.startswith(\"-\")]\n    if not pos:\n        print(\"usage: ratchet-exec run <work-id> [--cli claude|codex|gemini|mock] [--timeout <s>] [--grant <glob,...>]\"); return 1\n    work_id = pos[0]\n    # lane selection (v2 dispatch): explicit --cli wins; otherwise the capability-detected\n    # preference hierarchy — chosen flat-rate sub-CLI, else Wayland Core through Flux, else refuse.\n    if \"--cli\" in args:\n        cli = args[args.index(\"--cli\") + 1]\n    else:\n        cli, why = K.default_dispatch()\n        if cli is None:\n            print(f\"exec: no agent available — {why}. Run `ratchet init` to detect + install one.\"); return 2\n        print(f\"exec: no --cli given; dispatching to '{cli}' — {why}\")\n    timeout = int(args[args.index(\"--timeout\") + 1]) if \"--timeout\" in args else 900\n    extra = args[args.index(\"--prompt-extra\") + 1] if \"--prompt-extra\" in args else \"\"\n    # WRITE-manifest scope: --grant \"src/**,tests/**\" overrides the card's own grant field.\n    # None = ungoverned (permissive, flagged). The repo index (wave 2) computes grant per card.\n    # exec-owned flags are read from positions that are NOT the value of another flag, so an\n    # untrusted --prompt-extra payload can't smuggle in a governance flag (e.g. --no-auto-grant).\n    payload_idx = {args.index(\"--prompt-extra\") + 1} if \"--prompt-extra\" in args else set()\n    own_flags = {a for i, a in enumerate(args) if a.startswith(\"--\") and i not in payload_idx}\n    grant, grant_source = None, \"none\"\n    if \"--grant\" in args:\n        grant = [g for g in args[args.index(\"--grant\") + 1].split(\",\") if g.strip()]\n        grant_source = \"explicit-cli\"\n    m = K.load_manifest()\n    cfg, _, _ = K.config_load()\n    if cli in cfg.get(\"deny_list\", []):\n        print(f\"exec: REFUSE — '{cli}' is on the config deny-list\"); return 2\n    card = next((c for c in K.state_load(K.CARDS, {\"cards\": []})[\"cards\"]\n                 if c[\"work_id\"] == work_id and c[\"status\"] == \"open\"), None)\n    if card is None:\n        print(f\"exec: no OPEN card {work_id} — ratchet take first (cards are the only doorway)\"); return 2\n    wt = K.expand(card[\"worktree\"])\n    if not os.path.isdir(wt):\n        print(f\"exec: card {work_id} worktree missing ({wt}) — ratchet reconcile\"); return 2\n    r = m[\"repos\"][card[\"repo\"]]\n    if grant is None and card.get(\"grant\"):\n        grant = card[\"grant\"]; grant_source = \"explicit-card\"\n    if grant is None and \"--no-auto-grant\" not in own_flags and re.fullmatch(r\"[A-Za-z0-9]+\", work_id):\n        # ask the repo index to scope the lane (loose coupling: a tolerated subprocess). We do NOT\n        # trust its output: the returned globs are VALIDATED at this boundary (_valid_autogrant) —\n        # a bad/changed index can't turn an ungoverned run into a wide 'governed' one. Run with a\n        # SCRUBBED env so an ambient PYTHONPATH/LD_PRELOAD can't change what the helper computes.\n        idx_bin = os.path.join(HERE, \"ratchet-index\")\n        if os.path.exists(idx_bin):\n            senv = {k: v for k, v in os.environ.items()\n                    if k in (\"PATH\", \"HOME\", \"WL_HOME\", \"WL_MANIFEST\", \"WL_INSTANCE\", \"RATCHET_HOME\")}\n            outcome = \"helper-absent\"\n            try:\n                gp = subprocess.run([sys.executable, idx_bin, \"grant\", work_id], env=senv,\n                                    capture_output=True, text=True, timeout=30)\n                if gp.returncode != 0:\n                    outcome = f\"rc={gp.returncode}\"\n                else:\n                    auto = json.loads(gp.stdout or \"{}\").get(\"grant\")\n                    if auto is None:\n                        outcome = \"no-confident-scope\"\n                    elif _valid_autogrant(auto):\n                        grant, grant_source, outcome = auto, \"auto-index\", \"scoped\"\n                        print(f\"exec: auto-scoped lane from repo index → {grant}\")\n                    else:\n                        outcome = \"rejected-invalid-grant\"  # stays ungoverned+flagged, never widened\n            except subprocess.TimeoutExpired:\n                outcome = \"timeout-30s\"\n            except (ValueError, OSError, subprocess.SubprocessError):\n                outcome = \"error\"\n            if outcome != \"scoped\":\n                print(f\"exec: no auto-grant ({outcome}) — lane ungoverned (permissive, flagged)\")\n\n    # brief → file (recorded, hashed)\n    import hashlib\n    brief = build_brief(m, card, r)\n    bdir = os.path.join(K.WL_HOME, \"state\", \"recordings\", work_id)\n    os.makedirs(bdir, exist_ok=True)\n    bpath = os.path.join(bdir, f\"brief-{int(time.time())}.md\")\n    open(bpath, \"w\").write(K.redact(brief))\n    bhash = hashlib.sha1(brief.encode()).hexdigest()[:12]\n    prompt = (f\"Read the work brief at {bpath} and complete that card's work in the current \"\n              f\"directory (your isolated worktree). Follow its rules exactly. {extra}\").strip()\n\n    # spawn in own process group with an ALLOWLISTED env (security-council CRITICAL): the old\n    # blocklist stripped FLUX_/RATCHET_BREAK/WL_BREAK but LEAKED GH_TOKEN, *_API_KEY, AWS_* etc.\n    # to an untrusted agent. clean_env() passes only PATH/HOME-class vars + RATCHET_* identity —\n    # the agent has no secret to exfiltrate. The provider CLI reads its OWN auth from its own\n    # config dir, not our env, so this doesn't break claude/codex/gemini.\n    env = K.clean_env({\"RATCHET_CARD\": work_id, \"RATCHET_WORKTREE\": wt, \"RATCHET_AGENT\": f\"exec-{cli}\"})\n    if cli == \"mock\" and os.environ.get(\"RATCHET_MOCK_CMD\"):\n        env[\"RATCHET_MOCK_CMD\"] = os.environ[\"RATCHET_MOCK_CMD\"]  # test adapter only\n    if cli == \"mock\":\n        argv = [\"bash\", \"-lc\", env.get(\"RATCHET_MOCK_CMD\", \"true\")]\n    elif cli in PROFILES:\n        argv = PROFILES[cli] + [prompt]\n    else:\n        print(f\"exec: unknown CLI profile '{cli}'\"); return 1\n\n    # SANDBOX: FERROX DIV-03 — the agent NEVER runs inside the linked worktree, whose .git is a\n    # file pointing at the CANONICAL common gitdir. It runs inside a throwaway clone that owns its\n    # own git directory, and the clone is snapshotted before the agent touches it exactly as the\n    # worktree used to be, so every bad exit still restores to here. Nothing reaches the card tree\n    # until the containment audit has accepted the run.\n    iso = _isolated_clone(wt, \"run\")\n    if iso is None:\n        print(f\"exec: could not build the isolation clone beside {wt} — refusing to run an \"\n              \"untrusted agent against the canonical git directory\"); return 2\n    env[\"RATCHET_WORKTREE\"] = iso   # the lane's worktree IS the clone; the brief's rules bind to it\n    snap = _snapshot(iso)\n\n    try:\n        t0 = time.time()\n        try:\n            # BYTES: the shared non-blocking supervisor (_supervise) can't be starved by a partial line\n            # or a bg child holding the pipe — the same hardening guarded_suite uses (one loop, both paths).\n            proc = subprocess.Popen(argv, cwd=iso, env=env, start_new_session=True,\n                                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\n        except FileNotFoundError:\n            print(f\"exec: CLI '{cli}' not installed\"); return 2\n        # lane identity goes on the record FIRST — kernel kill/pause/resume verbs act on this\n        K.record(work_id, {\"event\": \"exec_spawn\", \"cli\": cli, \"pid\": proc.pid,\n                           \"pid_start\": K.pid_start(proc.pid), \"brief_hash\": bhash, \"timeout_s\": timeout,\n                           \"cost_basis\": \"ADVISORY — oracle wiring lands with councils (E2); wall-clock is the enforced cap\"})\n        reaped, raw = _supervise(proc, t0 + timeout)   # non-blocking wall-clock cap; SIGTERM→SIGKILL the group\n        rc = proc.wait()\n        # sweep the process GROUP before we inspect the tree: a non-detached background child\n        # (`sh -c 'sleep 2; echo pwn > x' &`) would otherwise write AFTER our checks. A setsid-detached\n        # child escapes its group and this sweep — that residual is the OS-sandbox boundary (deferred).\n        try:\n            os.killpg(proc.pid, signal.SIGKILL)\n            time.sleep(0.2)  # let the group die before _changed_paths reads the tree\n        except OSError:\n            pass\n        dur = round(time.time() - t0, 1)\n        stream = raw[-200_000:].decode(\"utf-8\", \"replace\")\n        spath = os.path.join(bdir, f\"stream-{int(t0)}.log\")\n        open(spath, \"w\").write(K.redact(stream))  # redaction-before-capture, same as the kernel\n\n        # evidence: what actually changed in the CLONE (ground truth, never the agent's self-report).\n        # _git (hooks/fsmonitor neutralized, DIV-02 lenient decode) because this is our FIRST git call\n        # after an untrusted run.\n        rcd, dirty, _ = _git(iso, \"status\", \"--porcelain\")\n        K.record(work_id, {\"event\": \"exec_exit\", \"cli\": cli, \"rc\": rc, \"reaped\": reaped,\n                           \"duration_s\": dur, \"dirty_files\": len(dirty.splitlines()) if dirty else 0})\n\n        verdict = \"failed\"\n        checks = {}\n        governed = grant is not None\n        grant_violations = []\n        restore_ok = True\n        def _reject(reason, msg):\n            nonlocal verdict, grant_violations, restore_ok\n            ok = _restore(iso, snap)\n            restore_ok = restore_ok and ok\n            grant_violations = reason\n            verdict = \"restore-failed\" if not ok else \"grant-violation\"\n            tail = \"; worktree restored, nothing lands\" if ok else \"; RESTORE FAILED — worktree may be dirty, ratchet reconcile\"\n            print(f\"exec: {msg}{tail}; stream: {spath}\")\n        if reaped:\n            restore_ok = _restore(iso, snap)  # a timed-out agent leaves NOTHING behind — tree restored\n            verdict = \"reaped\" if restore_ok else \"restore-failed\"\n            print(f\"exec: REAPED ({reaped}) after {dur}s — \"\n                  + (\"worktree restored to snapshot\" if restore_ok else \"RESTORE FAILED — ratchet reconcile\")\n                  + f\"; stream: {spath}\")\n        elif rc != 0:\n            restore_ok = _restore(iso, snap)\n            verdict = \"failed\" if restore_ok else \"restore-failed\"\n            print(f\"exec: agent exited {rc} after {dur}s — \"\n                  + (\"worktree restored to snapshot\" if restore_ok else \"RESTORE FAILED — ratchet reconcile\")\n                  + f\"; stream: {spath}\")\n        else:\n            # WRITE-manifest: did the agent stay inside its lane? A single out-of-lane write rejects the\n            # WHOLE run. Containment breaks (symlink/realpath escape) and the .git config/hooks RCE\n            # surface are violations REGARDLESS of grant — they are never legitimate agent behaviour.\n            # DIV-02: this is the audit that used to raise UnicodeDecodeError before the .git-tamper\n            # check and before any restore, leaving an injected hook live in the CANONICAL hooks dir.\n            audit = _containment_audit(iso, snap)\n            changed = audit[\"changed\"]\n            if grant is not None:\n                grant_violations = _ungranted(changed, grant)\n            violations = list(dict.fromkeys(\n                ([audit[\"error\"]] if audit[\"error\"] else [])\n                + grant_violations + audit[\"escapes\"]\n                + ([\"<.git config/hooks tampered>\"] if audit[\"meta_tampered\"] else [])))\n            if violations:\n                _reject(violations, f\"REJECTED — out-of-lane write {violations[:5]}\"\n                        + (\" …\" if len(violations) > 5 else \"\"))\n            else:\n                # deterministic post-checks — the same gates a human faces, run early. They read the\n                # CLONE, because that is where the agent's work is until the transfer below.\n                rc_d = subprocess.run([sys.executable, os.path.join(HERE, \"ratchet\"), \"doctor\",\n                                       card[\"repo\"], \"--offline\"], capture_output=True, text=True).returncode\n                checks[\"doctor\"] = rc_d\n                rc_c = K.corpus_run(card[\"repo\"], iso)\n                checks[\"corpus\"] = rc_c\n                verdict = \"clean\" if rc_d in (0, 3) and rc_c == 0 else \"failed-checks\"\n        # FERROX DIV-03 step 4: the agent's work reaches the card tree ONLY here, and only after the\n        # containment audit accepted the run. `clean` and `failed-checks` are exactly the 2 verdicts\n        # upstream left in the worktree; every other verdict restored it, and here the clone is\n        # dropped instead, which is strictly stronger because the card tree was never written to.\n        transfer_ok = None\n        if verdict in (\"clean\", \"failed-checks\"):\n            transfer_ok = _transfer_back(wt, iso)\n            if not transfer_ok:\n                verdict = \"restore-failed\"\n                print(f\"exec: TRANSFER FAILED from the isolation clone into {wt} — nothing landed; \"\n                      \"ratchet reconcile\")\n        # recent_commits reflects the FINAL tree — after a restore the agent's commits are gone, and\n        # after an accepted transfer the card tree carries them\n        rchf, headf, _ = _git(wt, \"log\", \"--oneline\", \"-5\")\n        delivery = {\"schema_version\": 1, \"card\": work_id, \"cli\": cli, \"verdict\": verdict, \"rc\": rc,\n                    \"reaped\": reaped, \"duration_s\": dur, \"brief_hash\": bhash, \"checks\": checks,\n                    \"governed\": governed, \"grant\": grant, \"grant_source\": grant_source,\n                    \"grant_violations\": grant_violations,\n                    \"restore_ok\": restore_ok, \"isolated\": True, \"transfer_ok\": transfer_ok,\n                    \"snapshot_head\": (snap[\"head\"] or \"none\")[:12], \"stream\": spath,\n                    \"recent_commits\": headf.splitlines() if rchf == 0 else [],\n                    \"next\": f\"ratchet land {wt}\" if verdict == \"clean\" else \"fix or ratchet reconcile\"}\n        dpath = os.path.join(bdir, f\"delivery-{int(t0)}.json\")\n        json.dump(K.redact(delivery), open(dpath, \"w\"), indent=1)\n        K.record(work_id, {\"event\": \"exec_delivery\", \"verdict\": verdict, \"artifact\": dpath})\n        lane = f\"governed ({len(grant)} glob{'s' if len(grant) != 1 else ''})\" if governed else \"UNGOVERNED — whole worktree\"\n        print(f\"exec: verdict {verdict} · lane {lane} · delivery artifact {dpath}\")\n        if verdict == \"clean\":\n            print(f\"  next: ratchet land {wt}   (the agent cannot run this — deliver-through-gate only)\")\n        return 0 if verdict == \"clean\" else 2\n    finally:\n        _drop_clone(iso)\n\ndef swarm(args):\n    \"\"\"E4, scoped per §7: dispatch N cards across adapters in PARALLEL LANES. Each lane is a\n    fresh `ratchet-exec run` process — same supervision, same isolation, same gates. Cards\n    already pin their own worktrees (take), so brief and tree describe the same reality.\n    A failed lane halts nothing else; it reports, suggests the debug card, and exits nonzero.\"\"\"\n    if \"--cards\" not in args:\n        print(\"usage: ratchet-exec swarm --cards <id1,id2,...> [--clis <c1,c2>] [--max <n>]\"); return 1\n    cards = args[args.index(\"--cards\") + 1].split(\",\")\n    clis = (args[args.index(\"--clis\") + 1].split(\",\")) if \"--clis\" in args else [\"claude\"]\n    maxp = int(args[args.index(\"--max\") + 1]) if \"--max\" in args else 3\n    timeout = args[args.index(\"--timeout\") + 1] if \"--timeout\" in args else \"900\"\n    me = os.path.abspath(__file__)\n    lanes, results = [], {}\n    queue = [(wid, clis[i % len(clis)]) for i, wid in enumerate(cards)]\n    print(f\"swarm: {len(queue)} card(s) across {len(clis)} adapter(s), {maxp} lane(s) max\")\n    lane_dir = os.path.join(K.WL_HOME, \"state\", \"recordings\")\n    while queue or lanes:\n        while queue and len(lanes) < maxp:\n            wid, cli = queue.pop(0)\n            # lane output goes to a FILE, not a pipe: a lane chattier than the 64KB pipe\n            # buffer blocked before exit while the parent polled forever (final-audit BLOCKER)\n            os.makedirs(os.path.join(lane_dir, wid), exist_ok=True)\n            lpath = os.path.join(lane_dir, wid, f\"lane-{int(time.time())}.log\")\n            lf = open(lpath, \"w\")\n            p = subprocess.Popen([sys.executable, me, \"run\", wid, \"--cli\", cli, \"--timeout\", timeout],\n                                 stdout=lf, stderr=subprocess.STDOUT, text=True)\n            lanes.append((wid, cli, p, lf, lpath))\n            print(f\"swarm: lane up — {wid} on {cli} (log {lpath})\")\n        for wid, cli, p, lf, lpath in lanes[:]:\n            if p.poll() is None:\n                continue\n            lf.close()\n            try:\n                out = open(lpath).read()\n            except OSError:\n                out = \"\"\n            results[wid] = {\"cli\": cli, \"rc\": p.returncode, \"tail\": out[-160:].strip()}\n            lanes.remove((wid, cli, p, lf, lpath))\n            print(f\"swarm: lane down — {wid} ({'clean' if p.returncode == 0 else f'rc {p.returncode}'})\")\n        time.sleep(0.3)\n    failed = {w: r for w, r in results.items() if r[\"rc\"] != 0}\n    print(f\"\\nswarm: {len(results) - len(failed)}/{len(results)} lanes clean\")\n    for w, r in failed.items():\n        print(f\"  FAILED {w} on {r['cli']} (rc {r['rc']}) — debug it as its own card:\")\n        print(f\"    ratchet take debug-{w[:6]} --repo <repo> --title 'debug swarm failure {w}'\")\n    for w, r in results.items():\n        if r[\"rc\"] == 0:\n            print(f\"  CLEAN  {w} — delivery artifact recorded; land it: see `ratchet inbox`\")\n    return 0 if not failed else 2\n\ndef selftest(args):\n    \"\"\"Mock-adapter proofs. No network, no models — the supervision loop itself is the target.\"\"\"\n    import tempfile\n    results = []\n    # FERROX DIV-03: the mock stimuli cd to the lane's OWN worktree, which the engine exports\n    # as RATCHET_WORKTREE, rather than to a hardcoded card tree path. Upstream's linked\n    # worktree and the isolation clone are both correct values of that variable, so every case\n    # below stays behavioural and location agnostic under either workspace strategy.\n    CDW = 'cd \"$RATCHET_WORKTREE\"'\n    with tempfile.TemporaryDirectory(prefix=\"rexec-st-\") as tmp:\n        # sandbox workspace: upstream + repo + card, mirroring the kernel's own selftest rig\n        up = os.path.join(tmp, \"up.git\"); seed = os.path.join(tmp, \"seed\")\n        K.run([\"git\", \"init\", \"-q\", \"--bare\", up]); K.run([\"git\", \"init\", \"-q\", \"-b\", \"main\", seed])\n        K.run([\"git\", \"-C\", seed, \"config\", \"user.email\", \"t@t\"]); K.run([\"git\", \"-C\", seed, \"config\", \"user.name\", \"t\"])\n        open(os.path.join(seed, \"f.txt\"), \"w\").write(\"x\")\n        os.makedirs(os.path.join(seed, \"billing\"))\n        open(os.path.join(seed, \"billing\", \"invoice.py\"), \"w\").write(\"def invoice():\\n    return 1\\n\")  # auto-grant target\n        K.run([\"git\", \"-C\", seed, \"add\", \".\"]); K.run([\"git\", \"-C\", seed, \"commit\", \"-qm\", \"c0\"])\n        K.run([\"git\", \"-C\", seed, \"remote\", \"add\", \"origin\", up]); K.run([\"git\", \"-C\", seed, \"push\", \"-q\", \"origin\", \"main\"])\n        clone = os.path.join(tmp, \"clone\"); K.run([\"git\", \"clone\", \"-q\", up, clone])\n        K.run([\"git\", \"-C\", clone, \"config\", \"user.email\", \"t@t\"]); K.run([\"git\", \"-C\", clone, \"config\", \"user.name\", \"t\"])\n        mpath = os.path.join(tmp, \"m.json\"); home = os.path.join(tmp, \"home\")\n        os.makedirs(os.path.join(home, \"state\"), exist_ok=True)\n        json.dump({\"schema_version\": 1, \"min_wl_plane\": \"0\", \"repos\": {\"sb\": {\n            \"path\": clone, \"mainline\": \"main\", \"fetch_remote\": \"origin\", \"push_remote\": \"origin\",\n            \"gh_login\": \"t\", \"forbidden_push\": [], \"remotes\": {\"origin\": up},\n            \"worktree_root\": os.path.join(tmp, \"wts\")}},\n            \"noise_paths\": [], \"archive_dir\": os.path.join(tmp, \"arc\"),\n            \"fetch_ttl_seconds\": 300, \"sync_warn_behind\": 1, \"sync_red_behind\": 50}, open(mpath, \"w\"))\n        env = dict(os.environ, WL_HOME=home, WL_MANIFEST=mpath, WL_INSTANCE=\"rexec-st\")\n        kern = os.path.join(HERE, \"ratchet\"); me = os.path.abspath(__file__)\n        import signal\n        class _R:\n            __slots__ = (\"returncode\", \"stdout\", \"stderr\")\n        def sh(*a, extra=None, t=120):\n            # Capture to a FILE in a new session, wait on the DIRECT child, then killpg the group. A mock\n            # lane under test can leave a detached/bg child that inherits the output stream; with\n            # capture_output=True (a pipe) communicate() would then block past the timeout — a\n            # nondeterministic CI deadlock that hangs this whole companion (and the kernel waiting on it).\n            # A file has no write-end to hold; p.wait returns when the lane itself exits; killpg reaps the\n            # rest. Deterministic regardless of what a lane leaks.\n            with tempfile.TemporaryFile(mode=\"w+\") as tf:\n                p = subprocess.Popen([sys.executable, *a], env={**env, **(extra or {})},\n                                     stdout=tf, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL,\n                                     start_new_session=True)\n                try:\n                    rc = p.wait(timeout=t)\n                except subprocess.TimeoutExpired:\n                    rc = 124\n                finally:\n                    try:\n                        os.killpg(os.getpgid(p.pid), signal.SIGKILL)\n                    except (ProcessLookupError, PermissionError, OSError):\n                        pass\n                    try:\n                        p.wait(timeout=10)\n                    except subprocess.TimeoutExpired:\n                        pass\n                tf.seek(0); out = tf.read()\n            r = _R(); r.returncode = rc; r.stdout = out; r.stderr = \"\"\n            return r\n        sh(kern, \"take\", \"exec-proof\", \"--repo\", \"sb\", \"--title\", \"exec proof\")\n        cards = json.load(open(os.path.join(home, \"state\", \"workcards.json\")))[\"cards\"]\n        wid = next(c[\"work_id\"] for c in cards if c[\"slug\"] == \"exec-proof\")\n        pre = open(os.path.join(home, \"state\", \"workcards.json\")).read()\n\n        # 1. failing agent ⇒ card state UNCHANGED (the E1 exit criterion)\n        r1 = sh(me, \"run\", wid, \"--cli\", \"mock\", extra={\"RATCHET_MOCK_CMD\": \"echo boom; exit 1\"})\n        post = open(os.path.join(home, \"state\", \"workcards.json\")).read()\n        results.append((\"EXEC failing agent leaves card state UNCHANGED\",\n                        r1.returncode == 2 and json.loads(pre)[\"cards\"] == json.loads(post)[\"cards\"],\n                        r1.stdout[-90:]))\n        # 2. timeout ⇒ reaped, no partial deliver\n        r2 = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--timeout\", \"2\",\n                extra={\"RATCHET_MOCK_CMD\": \"sleep 30\"}, t=180)\n        results.append((\"EXEC wall-clock cap reaps the lane\",\n                        r2.returncode == 2 and \"REAPED\" in r2.stdout, r2.stdout[-90:]))\n        # 2b. partial-line-then-stall must NOT starve the cap (the run_card twin-loop hardening)\n        r2p = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--timeout\", \"2\",\n                 extra={\"RATCHET_MOCK_CMD\": \"printf partial-no-newline; sleep 30\"}, t=60)\n        results.append((\"EXEC wall-clock cap reaps a partial-line-then-stall lane (no readline starvation)\",\n                        r2p.returncode == 2 and \"REAPED\" in r2p.stdout, r2p.stdout[-90:]))\n        # 3. clean pass ⇒ delivery artifact, verdict clean, NEXT points at the land gate\n        wtp = os.path.join(tmp, \"wts\", \"wt-exec-proof\")\n        r3 = sh(me, \"run\", wid, \"--cli\", \"mock\",\n                extra={\"RATCHET_MOCK_CMD\":\n                       f\"{CDW} && echo work > done.txt && git add . && git commit -qm 'feat: work' && echo done\"})\n        deliv = [f for f in os.listdir(os.path.join(home, \"state\", \"recordings\", wid)) if f.startswith(\"delivery\")]\n        dj = json.load(open(os.path.join(home, \"state\", \"recordings\", wid, sorted(deliv)[-1]))) if deliv else {}\n        results.append((\"EXEC clean pass delivers THROUGH the gate (never lands)\",\n                        r3.returncode == 0 and dj.get(\"verdict\") == \"clean\" and \"ratchet land\" in dj.get(\"next\", \"\"),\n                        f\"verdict={dj.get('verdict')}\"))\n        # 3b. GUARDED_SUITE — the PR-gate sandbox primitive (ratchet-maintain routes its untrusted\n        # contributor suite through this). Reproduced-failure proofs, called as a library:\n        os.environ[\"GH_TOKEN\"] = \"ghp_\" + \"z\" * 36\n        try:\n            gs = guarded_suite(wtp, 'test -z \"$GH_TOKEN\"', timeout=30)\n            results.append((\"GUARDED suite cannot see GH_TOKEN (clean_env allowlist)\",\n                            gs[\"ok\"] and gs[\"rc\"] == 0, str(gs)[-90:]))\n            gs2 = guarded_suite(wtp, 'test -n \"$GH_TOKEN\"', timeout=30)\n            results.append((\"GUARDED control: a suite that REQUIRES the secret fails\",\n                            (not gs2[\"ok\"]) and gs2[\"rc\"] != 0, str(gs2)[-90:]))\n        finally:\n            os.environ.pop(\"GH_TOKEN\", None)\n        gst = guarded_suite(wtp, \"sleep 30\", timeout=2)\n        results.append((\"GUARDED hung (silent) suite is reaped, not ok\",\n                        gst[\"reaped\"] == \"timeout\" and not gst[\"ok\"] and gst[\"duration_s\"] < 12, str(gst)[-90:]))\n        # the timeout must NOT be starvable by output — a partial line then a stall\n        gsp = guarded_suite(wtp, \"printf partial-no-newline; sleep 30\", timeout=2)\n        results.append((\"GUARDED partial-line-then-stall is still reaped (no readline starvation)\",\n                        gsp[\"reaped\"] == \"timeout\" and gsp[\"duration_s\"] < 12, str(gsp)[-90:]))\n        # a non-detached bg child holding the stdout pipe open must NOT make us wait for it\n        gsw = guarded_suite(wtp, \"sleep 999999 & echo parent-done\", timeout=30)\n        results.append((\"GUARDED bg child holding the pipe does not stall the supervision loop\",\n                        gsw[\"duration_s\"] < 12, str(gsw)[-90:]))\n        # bg child write to a path OUTSIDE the worktree — restore cannot mask an absolute-path write,\n        # so its absence proves the GROUP SWEEP killed the child before its delayed write (not restore)\n        _bgpath = os.path.join(tmp, \"BG_PWN_OUTSIDE.txt\")\n        guarded_suite(wtp, \"sh -c 'sleep 3; echo pwn > %s' &\" % _bgpath, timeout=30)\n        results.append((\"GUARDED non-detached bg child is swept before it can write (outside wt)\",\n                        not os.path.exists(_bgpath), _bgpath))\n        gsh = guarded_suite(wtp, 'HD=$(git rev-parse --git-path hooks) && mkdir -p \"$HD\" && '\n                            \"printf '#!/bin/sh\\\\necho PWN\\\\n' > \\\"$HD/pre-commit\\\" && chmod +x \\\"$HD/pre-commit\\\"\",\n                            timeout=30)\n        _hp = os.path.join(_hooks_dir(wtp) or wtp, \"pre-commit\")\n        _hookgone = (not os.path.exists(_hp)) or (\"PWN\" not in open(_hp).read())\n        results.append((\"GUARDED .git hook injection is flagged + reverted (RCE surface)\",\n                        (not gsh[\"ok\"]) and bool(gsh[\"violations\"]) and _hookgone, str(gsh)[-90:]))\n        # ref tamper: MOVING/DELETING a pre-existing ref in the SHARED gitdir (what defeated the scan —\n        # mainline moved onto the PR head) is a violation + reverted. CREATING a ref is intentionally\n        # IGNORED so a concurrent gate's fresh branch in the same gitdir is never clobbered.\n        _git(wtp, \"update-ref\", \"refs/heads/victim\", \"HEAD\")   # a pre-existing ref at wt's own HEAD\n        _pre_refs = _refs(wtp)\n        gsr = guarded_suite(wtp, \"git update-ref -d refs/heads/victim\", timeout=30)\n        _post_refs = _refs(wtp)\n        results.append((\"GUARDED deleting a pre-existing ref is a violation + reverted\",\n                        (not gsr[\"ok\"]) and bool(gsr[\"violations\"]) and _post_refs == _pre_refs, str(gsr)[-90:]))\n        gsc = guarded_suite(wtp, \"git update-ref refs/heads/peer HEAD\", timeout=30)\n        results.append((\"GUARDED a CREATED ref is not flagged (concurrency-safe: no concurrent-gate clobber)\",\n                        not gsc[\"violations\"], str(gsc)[-90:]))\n        _git(wtp, \"update-ref\", \"-d\", \"refs/heads/peer\")\n        _git(wtp, \"update-ref\", \"-d\", \"refs/heads/victim\")\n        gse = guarded_suite(wtp, \"ln -s /etc/passwd ESCAPE_LINK\", timeout=30)\n        results.append((\"GUARDED symlink escape out of the worktree is a violation\",\n                        (not gse[\"ok\"]) and bool(gse[\"violations\"]), str(gse)[-90:]))\n        # 4. captured stream is REDACTED (a leaking agent cannot poison the recording)\n        sh(me, \"run\", wid, \"--cli\", \"mock\",\n           extra={\"RATCHET_MOCK_CMD\": \"echo api_key = 'sk-\" + \"z\" * 24 + \"'; exit 1\"})\n        rdir = os.path.join(home, \"state\", \"recordings\", wid)\n        streams = \"\".join(open(os.path.join(rdir, f)).read() for f in os.listdir(rdir) if f.startswith(\"stream\"))\n        results.append((\"EXEC captured streams are redacted before disk\",\n                        \"sk-zzzz\" not in streams and \"[REDACTED\" in streams, streams[-60:]))\n        # 5. deny-list refusal (config is policy, exec obeys it)\n        json.dump({\"schema_version\": 1, \"deny_list\": [\"mock\"]}, open(os.path.join(home, \"state\", \"config.json\"), \"w\"))\n        r5 = sh(me, \"run\", wid, \"--cli\", \"mock\", extra={\"RATCHET_MOCK_CMD\": \"true\"})\n        results.append((\"EXEC honors the config deny-list\", r5.returncode == 2 and \"deny-list\" in r5.stdout, r5.stdout[-70:]))\n        os.remove(os.path.join(home, \"state\", \"config.json\"))\n        # 5b. SECRET NON-LEAK (security-council CRITICAL): a secret in the parent env must NOT\n        # reach the agent — the mock echoes $GH_TOKEN and it must come back empty/redacted\n        r5s = sh(me, \"run\", wid, \"--cli\", \"mock\",\n                 extra={\"RATCHET_MOCK_CMD\": \"echo TOKEN_IS=[$GH_TOKEN] KEY=[$OPENAI_API_KEY]; exit 1\",\n                        \"GH_TOKEN\": \"ghp_\" + \"z\" * 30, \"OPENAI_API_KEY\": \"sk-\" + \"z\" * 30})\n        rdir = os.path.join(home, \"state\", \"recordings\", wid)\n        streams = \"\".join(open(os.path.join(rdir, f)).read() for f in os.listdir(rdir) if f.startswith(\"stream\"))\n        results.append((\"EXEC agent env is allowlisted — parent secrets never reach the lane\",\n                        \"TOKEN_IS=[]\" in streams and \"KEY=[]\" in streams and \"ghp_zzzz\" not in streams,\n                        \"leak check\"))\n        # SANDBOX 1 — grant VIOLATION: a write outside the lane rejects the whole run, hard-restores\n        # the worktree (the forbidden file is gone), and leaves the card byte-identical\n        wtp = os.path.join(tmp, \"wts\", \"wt-exec-proof\")\n        preg = open(os.path.join(home, \"state\", \"workcards.json\")).read()\n        rg = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"allowed.txt\",\n                extra={\"RATCHET_MOCK_CMD\":\n                       f\"{CDW} && echo bad > forbidden.txt && git add . && git commit -qm 'x' && echo done\"})\n        postg = open(os.path.join(home, \"state\", \"workcards.json\")).read()\n        results.append((\"SANDBOX grant violation rejects the run + restores the worktree\",\n                        rg.returncode == 2 and \"REJECTED\" in rg.stdout\n                        and not os.path.exists(os.path.join(wtp, \"forbidden.txt\"))\n                        and json.loads(preg)[\"cards\"] == json.loads(postg)[\"cards\"],\n                        rg.stdout[-90:]))\n        # SANDBOX 2 — an in-lane write passes and the delivery is stamped governed, zero violations\n        rgi = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*.txt\",\n                 extra={\"RATCHET_MOCK_CMD\":\n                        f\"{CDW} && echo good >> ingrant.txt && git add . && git commit -qm 'y' && echo done\"})\n        rdir = os.path.join(home, \"state\", \"recordings\", wid)\n        deliv = sorted(f for f in os.listdir(rdir) if f.startswith(\"delivery\"))\n        dj2 = json.load(open(os.path.join(rdir, deliv[-1]))) if deliv else {}\n        results.append((\"SANDBOX in-lane write passes + delivery marked governed\",\n                        rgi.returncode == 0 and dj2.get(\"verdict\") == \"clean\"\n                        and dj2.get(\"governed\") is True and dj2.get(\"grant_violations\") == [],\n                        f\"verdict={dj2.get('verdict')} governed={dj2.get('governed')}\"))\n        # SANDBOX 3 — a timed-out lane leaves NOTHING behind: its partial write is gone after reap\n        rt = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--timeout\", \"2\",\n                extra={\"RATCHET_MOCK_CMD\": f\"{CDW} && echo partial > partial.txt && sleep 30\"}, t=180)\n        results.append((\"SANDBOX reap hard-restores the worktree to snapshot\",\n                        rt.returncode == 2 and \"REAPED\" in rt.stdout\n                        and not os.path.exists(os.path.join(wtp, \"partial.txt\")), rt.stdout[-90:]))\n        # DISPATCH — no --cli + no agent on PATH ⇒ the capability hierarchy refuses honestly\n        # (points at `ratchet init`), it does not crash or silently pick a missing binary\n        emptybin = os.path.join(tmp, \"emptybin\"); os.makedirs(emptybin, exist_ok=True)\n        rnd = sh(me, \"run\", wid, extra={\"PATH\": emptybin})\n        results.append((\"DISPATCH no --cli + no agent available refuses cleanly\",\n                        rnd.returncode == 2 and \"no agent available\" in rnd.stdout, rnd.stdout[-90:]))\n        # AUTO-GRANT — with a repo index present, a card with a confident scope auto-scopes the lane\n        # (no --grant given): exec asks ratchet-index and governs the run against the derived globs.\n        idx_bin = os.path.join(HERE, \"ratchet-index\")\n        if os.path.exists(idx_bin):\n            sh(idx_bin, \"build\", \"sb\")\n            sh(kern, \"take\", \"billing-fix\", \"--repo\", \"sb\", \"--title\", \"fix the billing invoice\")\n            cag = json.load(open(os.path.join(home, \"state\", \"workcards.json\")))[\"cards\"]\n            wag = next(c[\"work_id\"] for c in cag if c[\"slug\"] == \"billing-fix\")\n            wtag = os.path.join(tmp, \"wts\", \"wt-billing-fix\")\n            rag = sh(me, \"run\", wag, \"--cli\", \"mock\",  # NO --grant → index scopes it\n                     extra={\"RATCHET_MOCK_CMD\": f\"{CDW} && echo w > billing/new.py && git add . && git commit -qm x && echo done\"})\n            rd = os.path.join(home, \"state\", \"recordings\", wag)\n            dag = json.load(open(os.path.join(rd, sorted(f for f in os.listdir(rd) if f.startswith(\"delivery\"))[-1])))\n            results.append((\"AUTO-GRANT: repo index scopes the lane when no --grant is given\",\n                            rag.returncode == 0 and dag.get(\"governed\") is True\n                            and dag.get(\"grant\") and \"billing/**\" in dag[\"grant\"]\n                            and dag.get(\"grant_source\") == \"auto-index\" and \"auto-scoped\" in rag.stdout,\n                            f\"grant={dag.get('grant')} src={dag.get('grant_source')}\"))\n            # cross-audit: exec VALIDATES the index's output — a wide/escaping glob is never trusted\n            results.append((\"AUTO-GRANT validates index globs (rejects **, absolute, ..)\",\n                            _valid_autogrant([\"billing/**\"]) and not _valid_autogrant([\"**\"])\n                            and not _valid_autogrant([\"/etc/**\"]) and not _valid_autogrant([\"../x/**\"])\n                            and not _valid_autogrant(\"billing/**\") and not _valid_autogrant([]), \"\"))\n            # cross-audit: a --no-auto-grant smuggled in the agent PAYLOAD does not disable governance\n            rpl = sh(me, \"run\", wag, \"--cli\", \"mock\", \"--prompt-extra\", \"--no-auto-grant\",\n                     extra={\"RATCHET_MOCK_CMD\": f\"{CDW} && echo w >> billing/new.py && git add . && git commit -qm y && echo done\"})\n            dp = json.load(open(os.path.join(rd, sorted(f for f in os.listdir(rd) if f.startswith(\"delivery\"))[-1])))\n            results.append((\"AUTO-GRANT: --no-auto-grant in the payload can't disable governance\",\n                            dp.get(\"grant_source\") == \"auto-index\", f\"src={dp.get('grant_source')}\"))\n        # ── wave-1 cross-audit hardening proofs (each pins a confirmed council finding) ──\n        # AUDIT-1 · .git hooks RCE surface: injecting a hook into the RESOLVED hooks dir (the common\n        # gitdir — a worktree's .git is a file) is a violation even under a matching grant, and the\n        # injected hook is stripped on restore. The agent locates it exactly as git does.\n        hooksdir = os.path.join(clone, \".git\", \"hooks\")\n        rga = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",\n                 extra={\"RATCHET_MOCK_CMD\":\n                        f\"{CDW} && HD=$(git rev-parse --git-path hooks) && mkdir -p \\\"$HD\\\" && \"\n                        \"printf '#!/bin/sh\\\\necho HOOKPWN\\\\n' > \\\"$HD/pre-commit\\\" && chmod +x \\\"$HD/pre-commit\\\" && echo done\"})\n        hp = os.path.join(hooksdir, \"pre-commit\")\n        hookbody = open(hp).read() if os.path.exists(hp) else \"\"\n        results.append((\"AUDIT .git hooks tamper is rejected + reverted (added or overwritten)\",\n                        rga.returncode == 2 and \"REJECTED\" in rga.stdout and \"HOOKPWN\" not in hookbody,\n                        rga.stdout[-90:]))\n        # AUDIT-2 · symlink escape: an in-grant symlink pointing outside the worktree is a violation\n        outside = os.path.join(tmp, \"outside_target\"); open(outside, \"w\").write(\"host\")\n        rsy = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"{CDW} && ln -s {outside} escape && echo done\"})\n        results.append((\"AUDIT symlink escaping the worktree is a violation\",\n                        rsy.returncode == 2 and \"REJECTED\" in rsy.stdout\n                        and not os.path.islink(os.path.join(wtp, \"escape\"))\n                        and open(outside).read() == \"host\",  # external target untouched\n                        rsy.stdout[-90:]))\n        # AUDIT-2b · non-ASCII filename must NOT defeat containment: default git C-quotes such a name\n        # (`\"caf\\303\\251_escape\"`) so a literal-string parse would look up a name that doesn't exist\n        # and pass the symlink escape through as `clean`. -z parsing hits the REAL file. Same escape,\n        # café name: rejected AND removed on restore.\n        outside2 = os.path.join(tmp, \"outside_target2\"); open(outside2, \"w\").write(\"host2\")\n        nm = \"café_escape\"\n        r2b = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"{CDW} && ln -s {outside2} '{nm}' && echo done\"})\n        results.append((\"AUDIT non-ASCII symlink escape is a violation + restored (quotePath bypass closed)\",\n                        r2b.returncode == 2 and \"REJECTED\" in r2b.stdout\n                        and not os.path.islink(os.path.join(wtp, nm))\n                        and not os.path.exists(os.path.join(wtp, nm))\n                        and open(outside2).read() == \"host2\",\n                        r2b.stdout[-90:]))\n        # AUDIT-3 · rename bypass: `git mv` of a forbidden file counts the SOURCE, not just the dest\n        sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",  # seed a tracked forbidden.py in-lane\n           extra={\"RATCHET_MOCK_CMD\": f\"{CDW} && echo x > forbidden.py && git add . && git commit -qm seed && echo done\"})\n        rmv = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"allowed.py\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"{CDW} && git mv forbidden.py allowed.py && git commit -qm mv && echo done\"})\n        results.append((\"AUDIT rename counts the vacated source path (git mv bypass closed)\",\n                        rmv.returncode == 2 and \"REJECTED\" in rmv.stdout\n                        and os.path.exists(os.path.join(wtp, \"forbidden.py\")),  # restored\n                        rmv.stdout[-90:]))\n        # AUDIT-4 · history evasion: add-then-remove nets to zero in a plain diff but is in history\n        rhx = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"keep.txt\",\n                 extra={\"RATCHET_MOCK_CMD\":\n                        f\"{CDW} && echo s > secret.txt && git add . && git commit -qm add && \"\n                        f\"git rm -q secret.txt && git commit -qm del && echo done\"})\n        results.append((\"AUDIT add-then-remove (net-zero diff) is still caught via history\",\n                        rhx.returncode == 2 and \"REJECTED\" in rhx.stdout, rhx.stdout[-90:]))\n        # AUDIT-5 · pre-run UNTRACKED file is preserved across a failed run (clean -fd would nuke it)\n        keep = os.path.join(wtp, \"user_local.txt\"); open(keep, \"w\").write(\"mine\")\n        rpr = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--timeout\", \"2\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"{CDW} && echo junk > agent_tmp.txt && sleep 30\"}, t=180)\n        results.append((\"AUDIT pre-run untracked file survives restore; agent's is removed\",\n                        \"REAPED\" in rpr.stdout and os.path.exists(keep)\n                        and open(keep).read() == \"mine\"\n                        and not os.path.exists(os.path.join(wtp, \"agent_tmp.txt\")), rpr.stdout[-90:]))\n        os.remove(keep)  # tidy so it doesn't pollute later proofs\n        # AUDIT-6 · .git/config tamper: injecting core.hooksPath into the local config is DETECTED\n        # (run rejected) AND the config file is reverted byte-for-byte on restore. A pre-seeded\n        # multi-valued key must survive the restore (byte-restore preserves it; a semantic git-config\n        # rewrite would not — that fidelity concern was why this was deferred).\n        cfgp = os.path.join(clone, \".git\", \"config\")\n        subprocess.run([\"git\", \"-C\", clone, \"config\", \"--add\", \"ratchet.canary\", \"one\"], check=True)\n        subprocess.run([\"git\", \"-C\", clone, \"config\", \"--add\", \"ratchet.canary\", \"two\"], check=True)\n        cfg_before = open(cfgp).read()\n        rcf = sh(me, \"run\", wid, \"--cli\", \"mock\", \"--grant\", \"*\",\n                 extra={\"RATCHET_MOCK_CMD\": f\"{CDW} && git config --add core.hooksPath /tmp/evilhooks && echo done\"})\n        cfg_after = open(cfgp).read()\n        results.append((\"AUDIT .git/config tamper is rejected + reverted byte-for-byte (multi-valued keys kept)\",\n                        rcf.returncode == 2 and \"REJECTED\" in rcf.stdout\n                        and \"evilhooks\" not in cfg_after and cfg_after == cfg_before\n                        and cfg_after.count(\"canary\") >= 2,\n                        rcf.stdout[-90:]))\n        subprocess.run([\"git\", \"-C\", clone, \"config\", \"--unset-all\", \"ratchet.canary\"],\n                       stderr=subprocess.DEVNULL)  # tidy so it doesn't pollute later proofs\n        # 6. E4 swarm: two parallel mock lanes — one clean, one failing; report names both,\n        # neither corrupts state, and the failure suggests its debug card\n        sh(kern, \"take\", \"sw-a\", \"--repo\", \"sb\", \"--title\", \"swarm a\")\n        sh(kern, \"take\", \"sw-b\", \"--repo\", \"sb\", \"--title\", \"swarm b\")\n        cards2 = json.load(open(os.path.join(home, \"state\", \"workcards.json\")))[\"cards\"]\n        wa = next(c[\"work_id\"] for c in cards2 if c[\"slug\"] == \"sw-a\")\n        wb = next(c[\"work_id\"] for c in cards2 if c[\"slug\"] == \"sw-b\")\n        wta = os.path.join(tmp, \"wts\", \"wt-sw-a\")\n        mock = (f\"if [ \\\"$RATCHET_CARD\\\" = \\\"{wa}\\\" ]; then {CDW} && echo w > w.txt && git add . \"\n                f\"&& git commit -qm 'feat: swarm work' && exit 0; else sleep 1; exit 1; fi\")\n        r6 = sh(me, \"swarm\", \"--cards\", f\"{wa},{wb}\", \"--clis\", \"mock,mock\", \"--timeout\", \"60\",\n                extra={\"RATCHET_MOCK_CMD\": mock}, t=300)\n        cards3 = json.load(open(os.path.join(home, \"state\", \"workcards.json\")))[\"cards\"]\n        both_open = all(c[\"status\"] == \"open\" for c in cards3 if c[\"slug\"] in (\"sw-a\", \"sw-b\"))\n        results.append((\"SWARM runs parallel lanes; failure isolated + debug card suggested\",\n                        r6.returncode == 2 and \"1/2 lanes clean\" in r6.stdout\n                        and f\"FAILED {wb}\" in r6.stdout and \"debug-\" in r6.stdout and both_open,\n                        r6.stdout[-140:]))\n        # 7. a lane NOISIER than the pipe buffer must not deadlock the swarm (final-audit\n        # BLOCKER: stdout=PIPE read only after exit blocked chatty children forever)\n        try:\n            r7 = sh(me, \"swarm\", \"--cards\", wb, \"--clis\", \"mock\", \"--timeout\", \"120\",\n                    extra={\"RATCHET_MOCK_CMD\": \"seq 1 8000 | sed 's/^/noise padding line number /'\"}, t=240)\n            ok7 = r7.returncode == 0 and \"1/1 lanes clean\" in r7.stdout\n            det7 = r7.stdout[-90:]\n        except subprocess.TimeoutExpired:\n            ok7, det7 = False, \"DEADLOCKED — pipe-buffer hang reproduced\"\n        results.append((\"SWARM survives a lane noisier than the pipe buffer\", ok7, det7))\n\n    passed = sum(1 for _, okv, _ in results if okv)\n    for label, okv, detail in results:\n        print(f\"  {'OK  ' if okv else 'FAIL'}  {label}\" + (\"\" if okv else f\" — {detail}\"))\n    print(f\"\\n  ratchet-exec selftest: {passed}/{len(results)}\")\n    return 0 if passed == len(results) else 2\n",
      "post_sha256": "4ae757eff6d5b211636718f066897973d6e804263a5d6f88e20defe70210147c",
      "post_lines": 1308,
      "post_bytes": 81228
    }
  ]
}
