← Files Compound EngineeringARCHIVED FILE

skills/ce-pov/scripts/peer-job-runner.py

102 KB · Oct 4, 2026 · 12:33 UTC

↓ Download file

#!/usr/bin/env python3
"""Detached peer-job runner: start/status/wait/result/reap for delegated work.

Some harnesses enforce a hard ceiling on a single shell tool call and kill the
supervising shell mid-run, so no tool call may span a peer worker's runtime.
This runner splits the lifecycle so every call is short and all durable state
lives on disk:

  start   claim a job dir, preflight the worker, detach it into its own
          session (double fork with os.setsid between the forks), print ONLY
          the job id, return fast. The detached process supervises the worker
          and writes ONE atomic terminal record. Also sweeps sibling run roots
          older than 24 hours (best-effort, owner-checked).
  status  print each job's state word without blocking.
  wait    bounded poll (~1s cadence, never longer than --max-secs) that
          returns early once every watched job has settled.
  result  ownership-checked bounded read of a done job's published artifact.
  reap    ask the detached supervisor to terminate the job now; returns fast.
          If the supervisor itself is gone, reap kills the worker tree and
          writes the terminal record itself. Reaping a terminal job is a
          safe no-op.

Job directory (durable state, the source of truth):
  <root>/<skill>/<run-id>/jobs/<job-id>/
    meta.json   identity: skill, run id, label, input digest, start time,
                worker argv, result path (written at start, before detach)
    pid         supervisor pid + worker pid (written by the supervisor before
                start returns; its presence marks "detached"). Platform-
                conditional fields — consumers must use .get(): POSIX adds
                supervisor_pgid; Windows adds job_name (its job object) and
                supervisor_identity / worker_identity (GetProcessTimes guards
                so a recycled pid is not treated as the original process).
    out.log     worker's combined stdout+stderr (byte growth = liveness)
    reason      terminal detail, written before the status rename so the
                status file is always the LAST record to land
    status      exactly one word, published atomically (tmp + os.replace):
                done | failed | timeout | died-without-result

States reported by status/wait:
  running              detached, no terminal record yet
  done                 worker exited 0 (and, when --result-path was declared,
                       the result file exists non-empty)
  failed               nonzero exit, byte-cap kill, or exit 0 without the
                       declared result
  timeout              supervisor idle/hard window fired, or a requested reap
  died-without-result  worker killed by an external signal with no result
                       evidence (or vanished together with its supervisor)
  never-started        meta exists but nothing was ever detached (preflight
                       failure)
  unreadable           an ownership or sanity check failed; content withheld

Supervision (runs inside the detached session, never in a tool call): poll
~2s; liveness is out.log byte growth; idle window with no growth reaps the
worker tree; a hard cap reaps it regardless; byte caps on out.log and the
published result classify as failed with a recorded reason. Reaping is TERM
to the worker's own process group (the worker is started as a session/group
leader), a grace period, then KILL — with a deepest-first tree walk as the
fallback when the group kill is unavailable. The supervisor classifies the
outcome exactly once; when both the worker's internal cap and the
supervisor's window fire, the supervisor's record wins.

Environment overrides (defaults in parentheses):
  CE_PEER_JOBS_ROOT         base dir (/tmp/compound-engineering-<effective-uid>,
                            or $TMPDIR/compound-engineering-<effective-uid> when
                            /tmp cannot host a writable private root, e.g. under
                            a sandbox that only allowlists $TMPDIR)
  CE_WORK_RUNS_ROOT         parent CE Work dir containing all <run-id>/ dirs
  CE_PEER_IDLE_SECS         idle window, no out.log growth (240)
  CE_PEER_HARD_SECS         hard cap on worker wall clock
                            (default: max(1230, CROSS_MODEL_HARD_SECS+30);
                            an explicit value always wins)
  CROSS_MODEL_HARD_SECS     when CE_PEER_HARD_SECS is unset, widens the
                            supervisor hard window (see above)
  CE_PEER_LOG_MAX_BYTES     out.log byte cap (10485760)
  CE_PEER_RESULT_MAX_BYTES  result byte cap, supervise + read (5242880)
  CE_PEER_POLL_SECS         supervisor poll interval (2)
  CE_PEER_GRACE_SECS        TERM-to-KILL grace during reap (5)
  CE_PEER_BASH              Windows: absolute bash.exe for peer workers
                            (preferred over PATH / WSL System32 bash)
  CLAUDE_CODE_GIT_BASH_PATH Claude Code Git Bash path; used on Windows when
                            CE_PEER_BASH is unset (#1268)

Security posture: the job root is a predictable, owner-private directory under
world-shared /tmp. Every read of job state opens the file first (no-follow) and
verifies the descriptor's owner (os.fstat st_uid == os.geteuid, guarded where
geteuid is unavailable) before any content is emitted; a mismatch reports
"unreadable", never content. Reads are bounded by size caps — out.log is never
slurped. Directory/file creation uses 0700/0600 modes, exclusive no-follow
creation, owner/type verification on path components, exact 0700 verification
on the top-level root, and atomic rename for every publish. The worker argv is
exec'd directly (argv list, never a shell); job
ids are minted internally; --skill/--run-id/--label are restricted to
[A-Za-z0-9._-]. Nothing here ever prompts: headless/CI-safe by design.

Platform (#1243): the mechanisms above describe POSIX. Native Windows Python
has no fork/setsid, uid, mode bits, or process groups, so the same contract is
met by win32 equivalents, all behind `sys.platform == "win32"` branches so the
POSIX path is behaviorally unchanged:
  detach    re-invoke this script as a DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP
            child (CREATE_BREAKAWAY_FROM_JOB where the job allows) running the
            internal `__supervise` entrypoint; the pid file is the ack.
  reap      cmd_reap drops a `.reap` marker the supervisor polls for (no directed
            signal to a detached, console-less process).
  teardown  the worker tree lives in a named Job Object -- the real killpg
            analog, since it reaches descendants of an already-exited leader,
            which taskkill /T cannot (it walks parent->child from a LIVE
            parent). Windows releases a named object's name once the last
            handle closes, so a cmd_reap running after the supervisor died
            falls back to a Toolhelp32 snapshot walk; that works because
            Windows never reparents orphans, so a dead pid still appears as
            th32ParentProcessID on its live children. A recycled pid that is
            now this process (or whose GetProcessTimes identity does not
            match the pid file) is not the original leader: sweep stale-PPID
            descendants, do not TerminateProcess the live reused process.
  ownership st_uid == geteuid becomes: the object's owner SID is one this token
            creates objects as (user or default-owner SID), checked on the opened
            handle (GetSecurityInfo) exactly like the POSIX fstat-by-fd check.
  privacy   0700/0600 modes become a hardened ACL (icacls: break inheritance,
            grant only the user + SYSTEM + Administrators — the root-equivalents).
  jobs root defaults under %LOCALAPPDATA%\\compound-engineering-jobs (then the
            user temp dir), owner-private, since there is no shared /tmp.

Pure stdlib. No third-party dependencies.
"""
import argparse
import glob
import json
import os
import re
import shutil
import signal
import stat
import subprocess
import sys
import tempfile
import time

# Identifier charset for --skill/--run-id/--label and bare job refs. The dot is
# allowed (model/date tokens use it) but an all-dot value (".", "..") would be a
# path component that escapes the jobs root, so it is rejected separately below.
SAFE_RE = re.compile(r"^[A-Za-z0-9._-]+$")


def _is_safe_token(value: str) -> bool:
    return bool(SAFE_RE.match(value)) and value.strip(".") != ""


TERMINAL_STATES = ("done", "failed", "timeout", "died-without-result")
IS_WINDOWS = sys.platform == "win32"
_uid_getter = getattr(os, "geteuid", None) or getattr(os, "getuid", None)
_EFFECTIVE_UID = _uid_getter() if _uid_getter is not None else None
if IS_WINDOWS:
    # No geteuid on Windows; the current-user SID is the ownership identity
    # (see the Windows security section below), and the per-user jobs root lives
    # under LOCALAPPDATA (falling back to the user temp dir) with a hardened ACL
    # so R6 has a working default rather than a required override.
    _WIN_ROOT_BASE = os.environ.get("LOCALAPPDATA") or tempfile.gettempdir()
    DEFAULT_ROOT = os.path.join(_WIN_ROOT_BASE, "compound-engineering-jobs")
elif _EFFECTIVE_UID is not None:
    DEFAULT_ROOT = os.path.join("/tmp", f"compound-engineering-{_EFFECTIVE_UID}")
else:
    DEFAULT_ROOT = None
O_NOFOLLOW = getattr(os, "O_NOFOLLOW", 0)
# Windows CPython opens os.open() descriptors in CRT *text* mode by default:
# writes expand \n -> \r\n and reads stop at the first 0x1A (Ctrl-Z EOF), which
# would silently corrupt and truncate a peer's result artifact and desync the
# out.log byte caps from st_size. O_BINARY is 0 on POSIX, so this is a no-op
# there and every os.open below stays byte-exact on both platforms.
O_BINARY = getattr(os, "O_BINARY", 0)
SWEEP_AGE_SECS = 24 * 3600
CLAIM_ATTEMPTS = 16
STATUS_READ_CAP = 256
REASON_READ_CAP = 1024
META_READ_CAP = 64 * 1024

EXIT_CODES_DOC = """\
exit codes:
  0  the command itself succeeded. For status/wait this means the query ran;
     it says nothing about job outcomes — parse stdout (or --json) for states.
     For `result` it means a done job's artifact (or a --path file) was emitted;
     for reap it includes the safe no-op on an already-terminal job.
  1  runtime error (preflight failure, unknown job, detach failure)
  2  usage error; for `result`: the job is still running
  3  for `result`: job settled but not done (failed / timeout /
     died-without-result / never-started), or the result file is missing
  4  the read was refused, so content is never emitted: the ownership check
     failed (job state or result not owned by the current user), or the path
     is there but unreadable (a symlink rejected by O_NOFOLLOW, a non-regular
     file, a byte-cap overrun). Only a genuinely absent file is 3.

environment overrides: CE_PEER_JOBS_ROOT, CE_WORK_RUNS_ROOT, CE_PEER_IDLE_SECS,
CE_PEER_HARD_SECS, CROSS_MODEL_HARD_SECS, CE_PEER_LOG_MAX_BYTES,
CE_PEER_RESULT_MAX_BYTES, CE_PEER_POLL_SECS, CE_PEER_GRACE_SECS (defaults in
the module docstring).
"""


class RunnerError(Exception):
    """Actionable operational error: message to stderr, exit 1."""


class Unreadable(Exception):
    """Job state failed an ownership or sanity check; content withheld."""


# --- configuration -----------------------------------------------------------

# Supervisor hard-window floor: clears the highest cross-model worker default
# (review skills use CROSS_MODEL_HARD_SECS:-1200) so an unset knob still nests
# worker < deadline < runner without orchestrator arithmetic. Grace matches the
# historical prose +30s so a raised knob widens the runner the same way.
_RUNNER_HARD_FLOOR = 1230.0
_RUNNER_HARD_GRACE = 30.0


def _private_root_usable(path: str) -> bool:
    """True when `path` is (or can now be) a directory we own and can write into.

    Creation is the probe: a sandbox that denies writes under /tmp refuses the
    mkdir, and one that lets a pre-existing root stand still fails the access
    check, so both land on the fallback instead of failing at the first job.
    """
    try:
        os.mkdir(path, 0o700)
    except FileExistsError:
        pass
    except OSError:
        return False
    try:
        _check_owned_dir(path)
    except (OSError, RunnerError):
        return False
    return os.access(path, os.W_OK)


def _fallback_root() -> str:
    return os.path.join(os.environ.get("TMPDIR") or "/tmp", f"compound-engineering-{_EFFECTIVE_UID}")


def jobs_root_base() -> str:
    configured = os.environ.get("CE_PEER_JOBS_ROOT")
    if configured:
        return os.path.abspath(configured)
    if DEFAULT_ROOT is None:
        raise RunnerError("effective user ID is unavailable; cannot derive the jobs root")
    if IS_WINDOWS or _private_root_usable(DEFAULT_ROOT):
        return os.path.abspath(DEFAULT_ROOT)
    # Same order and candidates as the skills' shell preamble, so a job started
    # there is found here.
    return os.path.abspath(_fallback_root())


def candidate_jobs_root_bases() -> list:
    """Every root an existing job may live under: the configured root alone, or
    both the /tmp root and the $TMPDIR fallback (deduplicated, primary first).

    Creation uses jobs_root_base(); lookup of an already-started job must not
    depend on which root *this* invocation would create under, because a
    sandboxed session and a later unsandboxed one resolve different roots.
    """
    configured = os.environ.get("CE_PEER_JOBS_ROOT")
    if configured:
        return [os.path.abspath(configured)]
    if DEFAULT_ROOT is None:
        raise RunnerError("effective user ID is unavailable; cannot derive the jobs root")
    bases = [os.path.abspath(DEFAULT_ROOT)]
    if not IS_WINDOWS:
        fallback = os.path.abspath(_fallback_root())
        if fallback not in bases:
            bases.append(fallback)
    return bases


def skill_runs_root(skill: str) -> str:
    if skill == "ce-work" and os.environ.get("CE_WORK_RUNS_ROOT"):
        return os.path.abspath(os.environ["CE_WORK_RUNS_ROOT"])
    return os.path.join(jobs_root_base(), skill)


def candidate_skill_runs_roots(skill: str) -> list:
    if skill == "ce-work" and os.environ.get("CE_WORK_RUNS_ROOT"):
        return [os.path.abspath(os.environ["CE_WORK_RUNS_ROOT"])]
    return [os.path.join(base, skill) for base in candidate_jobs_root_bases()]


def _env_num(name: str, default: float, conv, *, allow_zero: bool = False):
    raw = os.environ.get(name)
    if not raw:
        return default
    try:
        val = conv(raw)
    except ValueError:
        return default
    if allow_zero and val == 0:
        return None
    return val if val > 0 else default


def _derived_hard_default() -> float:
    """Outermost supervisor hard window when CE_PEER_HARD_SECS is unset.

    Reads ambient CROSS_MODEL_HARD_SECS (the runner already forwards os.environ
    to the worker, so a user-set knob is present here). Explicit CE_PEER_HARD_SECS
    still wins via cfg() — ce-work and elevation paths keep their own windows.
    """
    cross = _env_num("CROSS_MODEL_HARD_SECS", 0.0, float)
    return max(_RUNNER_HARD_FLOOR, cross + _RUNNER_HARD_GRACE)


def cfg(skill=None) -> dict:
    return {
        "idle": _env_num("CE_PEER_IDLE_SECS", 240.0, float, allow_zero=skill == "ce-work"),
        "hard": _env_num("CE_PEER_HARD_SECS", _derived_hard_default(), float),
        "log_max": int(_env_num("CE_PEER_LOG_MAX_BYTES", 10 * 1024 * 1024, int)),
        "result_max": int(_env_num("CE_PEER_RESULT_MAX_BYTES", 5 * 1024 * 1024, int)),
        "poll": _env_num("CE_PEER_POLL_SECS", 2.0, float),
        "grace": _env_num("CE_PEER_GRACE_SECS", 5.0, float),
    }


# --- Windows security + process primitives ------------------------------------
#
# POSIX ownership is `fstat().st_uid == geteuid()` plus mode 0700/0600. Windows
# has neither uids nor mode bits, so the equivalent identity is the current
# user's SID: a job dir/file is "ours" when its owner SID is one this process's
# token creates objects as (the user SID or the token's default owner SID -- an
# elevated process defaults new objects to Administrators). A foreign user's
# planted dir carries neither SID and is rejected, exactly as a uid mismatch is
# on POSIX. The DACL is hardened to user+SYSTEM+Administrators (root-equivalents,
# mirroring how root still reaches a 0700 dir) with inheritance broken, so no
# world/Users grant survives. Pure stdlib via ctypes -- no pywin32.

if IS_WINDOWS:
    import ctypes
    import msvcrt
    from ctypes import wintypes

    _advapi32 = ctypes.WinDLL("advapi32", use_last_error=True)
    _kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)

    _SE_FILE_OBJECT = 1
    _OWNER_SECURITY_INFORMATION = 0x00000001
    _TOKEN_QUERY = 0x0008
    _TOKEN_USER_CLASS = 1
    _TOKEN_OWNER_CLASS = 4
    _STILL_ACTIVE = 259
    _WAIT_TIMEOUT = 0x00000102
    _PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
    _SYNCHRONIZE = 0x00100000
    # A detached, console-less parent still gives its children a NEW console
    # unless this is set, so every job would flash a window on the user's
    # desktop. Applied to the worker and to every helper tool we shell out to.
    _WIN_NO_WINDOW = getattr(subprocess, "CREATE_NO_WINDOW", 0x08000000)

    def _win_tool(name: str) -> str:
        """Absolute path to a System32 tool. CreateProcess searches the
        application and current directories before System32, so invoking
        `icacls`/`taskkill` by bare name from an untrusted CWD is a binary-
        hijack surface. Falls back to the bare name only if System32 is
        unresolvable, which is strictly better than never running."""
        root = os.environ.get("SystemRoot") or r"C:\Windows"
        candidate = os.path.join(root, "System32", name + ".exe")
        return candidate if os.path.isfile(candidate) else name

    _advapi32.ConvertSidToStringSidW.argtypes = [
        ctypes.c_void_p, ctypes.POINTER(ctypes.c_wchar_p)]
    _advapi32.ConvertSidToStringSidW.restype = wintypes.BOOL
    _advapi32.OpenProcessToken.argtypes = [
        wintypes.HANDLE, wintypes.DWORD, ctypes.POINTER(wintypes.HANDLE)]
    _advapi32.OpenProcessToken.restype = wintypes.BOOL
    _advapi32.GetTokenInformation.argtypes = [
        wintypes.HANDLE, ctypes.c_int, ctypes.c_void_p, wintypes.DWORD,
        ctypes.POINTER(wintypes.DWORD)]
    _advapi32.GetTokenInformation.restype = wintypes.BOOL
    _advapi32.GetSecurityInfo.argtypes = [
        wintypes.HANDLE, ctypes.c_int, wintypes.DWORD,
        ctypes.POINTER(ctypes.c_void_p), ctypes.c_void_p, ctypes.c_void_p,
        ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)]
    _advapi32.GetSecurityInfo.restype = wintypes.DWORD
    _advapi32.GetNamedSecurityInfoW.argtypes = [
        wintypes.LPCWSTR, ctypes.c_int, wintypes.DWORD,
        ctypes.POINTER(ctypes.c_void_p), ctypes.c_void_p, ctypes.c_void_p,
        ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p)]
    _advapi32.GetNamedSecurityInfoW.restype = wintypes.DWORD
    _kernel32.GetCurrentProcess.restype = wintypes.HANDLE
    _kernel32.OpenProcess.argtypes = [
        wintypes.DWORD, wintypes.BOOL, wintypes.DWORD]
    _kernel32.OpenProcess.restype = wintypes.HANDLE
    _kernel32.GetProcessTimes.argtypes = [
        wintypes.HANDLE,
        ctypes.POINTER(wintypes.FILETIME),
        ctypes.POINTER(wintypes.FILETIME),
        ctypes.POINTER(wintypes.FILETIME),
        ctypes.POINTER(wintypes.FILETIME),
    ]
    _kernel32.GetProcessTimes.restype = wintypes.BOOL
    _kernel32.QueryFullProcessImageNameW.argtypes = [
        wintypes.HANDLE, wintypes.DWORD, wintypes.LPWSTR,
        ctypes.POINTER(wintypes.DWORD)]
    _kernel32.QueryFullProcessImageNameW.restype = wintypes.BOOL
    _kernel32.WaitForSingleObject.argtypes = [wintypes.HANDLE, wintypes.DWORD]
    _kernel32.WaitForSingleObject.restype = wintypes.DWORD
    _kernel32.CloseHandle.argtypes = [wintypes.HANDLE]
    _kernel32.CloseHandle.restype = wintypes.BOOL
    _kernel32.LocalFree.argtypes = [wintypes.HGLOBAL]
    _kernel32.LocalFree.restype = wintypes.HGLOBAL
    _kernel32.CreateJobObjectW.argtypes = [ctypes.c_void_p, wintypes.LPCWSTR]
    _kernel32.CreateJobObjectW.restype = wintypes.HANDLE
    _kernel32.OpenJobObjectW.argtypes = [
        wintypes.DWORD, wintypes.BOOL, wintypes.LPCWSTR]
    _kernel32.OpenJobObjectW.restype = wintypes.HANDLE
    _kernel32.AssignProcessToJobObject.argtypes = [
        wintypes.HANDLE, wintypes.HANDLE]
    _kernel32.AssignProcessToJobObject.restype = wintypes.BOOL
    _kernel32.TerminateJobObject.argtypes = [wintypes.HANDLE, wintypes.UINT]
    _kernel32.TerminateJobObject.restype = wintypes.BOOL

    _JOB_OBJECT_TERMINATE = 0x0008
    _PROCESS_TERMINATE = 0x0001
    _PROCESS_SET_QUOTA = 0x0100
    _TH32CS_SNAPPROCESS = 0x00000002
    _TH32CS_SNAPTHREAD = 0x00000004
    _THREAD_SUSPEND_RESUME = 0x0002
    # CreateProcess CREATE_SUSPENDED: primary thread starts frozen so we can
    # AssignProcessToJobObject before any user code (or child spawn) runs.
    _CREATE_SUSPENDED = 0x00000004

    class _PROCESSENTRY32W(ctypes.Structure):
        _fields_ = [
            ("dwSize", wintypes.DWORD),
            ("cntUsage", wintypes.DWORD),
            ("th32ProcessID", wintypes.DWORD),
            ("th32DefaultHeapID", ctypes.POINTER(ctypes.c_ulong)),
            ("th32ModuleID", wintypes.DWORD),
            ("cntThreads", wintypes.DWORD),
            ("th32ParentProcessID", wintypes.DWORD),
            ("pcPriClassBase", ctypes.c_long),
            ("dwFlags", wintypes.DWORD),
            ("szExeFile", ctypes.c_wchar * 260),
        ]

    class _THREADENTRY32(ctypes.Structure):
        _fields_ = [
            ("dwSize", wintypes.DWORD),
            ("cntUsage", wintypes.DWORD),
            ("th32ThreadID", wintypes.DWORD),
            ("th32OwnerProcessID", wintypes.DWORD),
            ("tpBasePri", ctypes.c_long),
            ("tpDeltaPri", ctypes.c_long),
            ("dwFlags", wintypes.DWORD),
        ]

    _kernel32.CreateToolhelp32Snapshot.argtypes = [wintypes.DWORD, wintypes.DWORD]
    _kernel32.CreateToolhelp32Snapshot.restype = ctypes.c_void_p
    _kernel32.Process32FirstW.argtypes = [
        ctypes.c_void_p, ctypes.POINTER(_PROCESSENTRY32W)]
    _kernel32.Process32FirstW.restype = wintypes.BOOL
    _kernel32.Process32NextW.argtypes = [
        ctypes.c_void_p, ctypes.POINTER(_PROCESSENTRY32W)]
    _kernel32.Process32NextW.restype = wintypes.BOOL
    _kernel32.Thread32First.argtypes = [
        ctypes.c_void_p, ctypes.POINTER(_THREADENTRY32)]
    _kernel32.Thread32First.restype = wintypes.BOOL
    _kernel32.Thread32Next.argtypes = [
        ctypes.c_void_p, ctypes.POINTER(_THREADENTRY32)]
    _kernel32.Thread32Next.restype = wintypes.BOOL
    _kernel32.OpenThread.argtypes = [
        wintypes.DWORD, wintypes.BOOL, wintypes.DWORD]
    _kernel32.OpenThread.restype = wintypes.HANDLE
    _kernel32.ResumeThread.argtypes = [wintypes.HANDLE]
    _kernel32.ResumeThread.restype = wintypes.DWORD
    _kernel32.TerminateProcess.argtypes = [wintypes.HANDLE, wintypes.UINT]
    _kernel32.TerminateProcess.restype = wintypes.BOOL

    def _win_process_children_map():
        """th32ParentProcessID -> [child pids] from one Toolhelp snapshot."""
        snap = _kernel32.CreateToolhelp32Snapshot(_TH32CS_SNAPPROCESS, 0)
        if not snap or snap == ctypes.c_void_p(-1).value:
            return {}
        children = {}
        try:
            entry = _PROCESSENTRY32W()
            entry.dwSize = ctypes.sizeof(_PROCESSENTRY32W)
            more = _kernel32.Process32FirstW(snap, ctypes.byref(entry))
            while more:
                children.setdefault(entry.th32ParentProcessID, []).append(
                    entry.th32ProcessID)
                more = _kernel32.Process32NextW(snap, ctypes.byref(entry))
        finally:
            _kernel32.CloseHandle(ctypes.c_void_p(snap))
        return children

    def _win_descendants_deepest_first(root_pid: int, children=None):
        """Children before parents, via a process snapshot. This is the direct
        analog of the POSIX `ps`-based walk and carries the same pid-reuse
        exposure. It works on an EXITED leader because Windows never reparents
        orphans: a dead pid still appears as th32ParentProcessID on its live
        children (unlike POSIX, where orphans are reparented to init)."""
        if children is None:
            children = _win_process_children_map()
        order, queue = [], [root_pid]
        while queue:
            for child in children.get(queue.pop(0), []):
                order.append(child)
                queue.append(child)
        return list(reversed(order))

    def _win_process_identity(pid: int):
        """Creation time plus image path — analog of `ps -o lstart= -o command=`.

        Creation time is the PID-reuse guard: Windows recycles PIDs aggressively,
        and a recycled pid always carries a later FILETIME than the worker we
        recorded. None means unproven (gone or unopenable)."""
        handle = _kernel32.OpenProcess(
            _PROCESS_QUERY_LIMITED_INFORMATION, False, pid)
        if not handle:
            return None
        try:
            created, exited, kernel, user = (wintypes.FILETIME() for _ in range(4))
            if not _kernel32.GetProcessTimes(
                    handle, ctypes.byref(created), ctypes.byref(exited),
                    ctypes.byref(kernel), ctypes.byref(user)):
                return None
            started = (created.dwHighDateTime << 32) | created.dwLowDateTime
            if not started:
                return None
            size = wintypes.DWORD(32768)
            buf = ctypes.create_unicode_buffer(size.value)
            image = (buf.value if _kernel32.QueryFullProcessImageNameW(
                handle, 0, buf, ctypes.byref(size)) else "")
        finally:
            _kernel32.CloseHandle(handle)
        return "{} {}".format(started, image)

    def _win_process_start_time(pid: int):
        handle = _kernel32.OpenProcess(
            _PROCESS_QUERY_LIMITED_INFORMATION, False, pid)
        if not handle:
            return None
        try:
            created, exited, kernel, user = (wintypes.FILETIME() for _ in range(4))
            if not _kernel32.GetProcessTimes(
                    handle, ctypes.byref(created), ctypes.byref(exited),
                    ctypes.byref(kernel), ctypes.byref(user)):
                return None
            started = (created.dwHighDateTime << 32) | created.dwLowDateTime
            return started or None
        finally:
            _kernel32.CloseHandle(handle)

    def _win_process_identity_matches(pid: int, recorded) -> bool:
        if not recorded:
            return True
        current = _win_process_identity(pid)
        return current is not None and current == recorded

    def _win_terminate_pid(pid: int) -> bool:
        if pid <= 0 or pid == os.getpid():
            return False
        handle = _kernel32.OpenProcess(_PROCESS_TERMINATE, False, pid)
        if not handle:
            return False
        try:
            return bool(_kernel32.TerminateProcess(handle, 1))
        finally:
            _kernel32.CloseHandle(handle)

    def _win_job_name(job_dir: str) -> str:
        """A per-job named kernel object. Naming it is what makes this a real
        pgid analog: a DIFFERENT process (cmd_reap, after the supervisor is
        gone) can reopen it by name and terminate the whole tree."""
        return "Local\\ce-peer-job-" + os.path.basename(job_dir.rstrip("\\/"))

    def _win_create_job(name: str):
        """Create the job the worker tree will live in. Deliberately WITHOUT
        JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: like a POSIX process group, the job
        must outlive the supervisor so a dead-supervisor reap still finds a
        live tree to classify and sweep (matching the POSIX lifecycle tests)."""
        handle = _kernel32.CreateJobObjectW(None, name)
        return handle or None

    def _win_assign_to_job(job_handle, pid: int) -> bool:
        proc = _kernel32.OpenProcess(
            _PROCESS_SET_QUOTA | _PROCESS_TERMINATE, False, pid)
        if not proc:
            return False
        try:
            return bool(_kernel32.AssignProcessToJobObject(job_handle, proc))
        finally:
            _kernel32.CloseHandle(proc)

    def _win_resume_process(pid: int) -> bool:
        """Resume every thread of a CREATE_SUSPENDED process. subprocess.Popen
        does not expose hThread from PROCESS_INFORMATION, so walk the thread
        snapshot. CREATE_SUSPENDED only freezes the primary thread; resuming
        all owned threads is still correct and idempotent for running ones."""
        snap = _kernel32.CreateToolhelp32Snapshot(_TH32CS_SNAPTHREAD, 0)
        if not snap or snap == ctypes.c_void_p(-1).value:
            return False
        resumed = False
        try:
            entry = _THREADENTRY32()
            entry.dwSize = ctypes.sizeof(_THREADENTRY32)
            more = _kernel32.Thread32First(snap, ctypes.byref(entry))
            while more:
                if entry.th32OwnerProcessID == pid:
                    handle = _kernel32.OpenThread(
                        _THREAD_SUSPEND_RESUME, False, entry.th32ThreadID)
                    if handle:
                        try:
                            # (DWORD)-1 == failure; 0xFFFFFFFF as unsigned.
                            if _kernel32.ResumeThread(handle) != 0xFFFFFFFF:
                                resumed = True
                        finally:
                            _kernel32.CloseHandle(handle)
                more = _kernel32.Thread32Next(snap, ctypes.byref(entry))
        finally:
            _kernel32.CloseHandle(ctypes.c_void_p(snap))
        return resumed

    def _win_terminate_job(name: str) -> bool:
        """Terminate every process in the named job, whatever the tree shape.
        This is the piece taskkill /T cannot do: it reaches descendants whose
        parent has already exited, because job membership is inherited and
        does not depend on a live parent to walk from."""
        handle = _kernel32.OpenJobObjectW(_JOB_OBJECT_TERMINATE, False, name)
        if not handle:
            return False
        try:
            return bool(_kernel32.TerminateJobObject(handle, 1))
        finally:
            _kernel32.CloseHandle(handle)

    _WIN_IDENTITY_SIDS = None

    def _win_sid_to_string(psid) -> str:
        strp = ctypes.c_wchar_p()
        if not _advapi32.ConvertSidToStringSidW(psid, ctypes.byref(strp)):
            raise OSError(f"ConvertSidToStringSid failed: {ctypes.get_last_error()}")
        try:
            return strp.value
        finally:
            _kernel32.LocalFree(ctypes.cast(strp, wintypes.HGLOBAL))

    def _win_token_sid(token, info_class) -> str:
        size = wintypes.DWORD(0)
        _advapi32.GetTokenInformation(token, info_class, None, 0, ctypes.byref(size))
        buf = (ctypes.c_byte * size.value)()
        if not _advapi32.GetTokenInformation(
            token, info_class, buf, size, ctypes.byref(size)
        ):
            raise OSError(f"GetTokenInformation failed: {ctypes.get_last_error()}")
        # TOKEN_USER / TOKEN_OWNER both begin with a PSID at offset 0.
        sid_ptr = ctypes.cast(buf, ctypes.POINTER(ctypes.c_void_p))[0]
        return _win_sid_to_string(ctypes.c_void_p(sid_ptr))

    def _win_identity_sids() -> frozenset:
        """The SID strings this process's token creates objects as: the user SID
        and the default-owner SID (they differ for an elevated process). Cached;
        an object owned by any of these is treated as ours."""
        global _WIN_IDENTITY_SIDS
        if _WIN_IDENTITY_SIDS is not None:
            return _WIN_IDENTITY_SIDS
        token = wintypes.HANDLE()
        if not _advapi32.OpenProcessToken(
            _kernel32.GetCurrentProcess(), _TOKEN_QUERY, ctypes.byref(token)
        ):
            raise OSError(f"OpenProcessToken failed: {ctypes.get_last_error()}")
        try:
            sids = {
                _win_token_sid(token, _TOKEN_USER_CLASS),
                _win_token_sid(token, _TOKEN_OWNER_CLASS),
            }
        finally:
            _kernel32.CloseHandle(token)
        _WIN_IDENTITY_SIDS = frozenset(s for s in sids if s)
        return _WIN_IDENTITY_SIDS

    def _win_owner_sid(api, target) -> str:
        """Shared GetSecurityInfo / GetNamedSecurityInfoW shape: read the OWNER
        SID into a freshly allocated security descriptor and stringify it. The
        SID points INSIDE that descriptor, so freeing the descriptor is the only
        (and required) cleanup -- never free the SID separately."""
        psid = ctypes.c_void_p()
        psd = ctypes.c_void_p()
        err = api(target, _SE_FILE_OBJECT, _OWNER_SECURITY_INFORMATION,
                  ctypes.byref(psid), None, None, None, ctypes.byref(psd))
        if err != 0:
            raise OSError(f"{api.__name__} failed: {err}")
        try:
            return _win_sid_to_string(psid)
        finally:
            _kernel32.LocalFree(ctypes.cast(psd, wintypes.HGLOBAL))

    def _win_owner_sid_from_handle(handle: int) -> str:
        return _win_owner_sid(_advapi32.GetSecurityInfo, wintypes.HANDLE(handle))

    def _win_owner_sid_from_path(path: str) -> str:
        return _win_owner_sid(_advapi32.GetNamedSecurityInfoW, path)

    def _win_owns_path(path: str) -> bool:
        return _win_owner_sid_from_path(path) in _win_identity_sids()

    def _win_owns_handle(handle: int) -> bool:
        return _win_owner_sid_from_handle(handle) in _win_identity_sids()

    def _win_run_quiet(cmd) -> bool:
        """Fire-and-forget a Windows tool (icacls/taskkill): output suppressed,
        exit status returned but never raised. check=False suppresses a NONZERO
        exit, NOT a missing executable -- Popen still raises FileNotFoundError
        when the tool is absent from PATH, which would otherwise escape the
        supervisor's teardown and turn an already-classified `done` job into
        `failed`. Returns True only when the tool ran and exited 0."""
        try:
            return subprocess.run(
                cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
                check=False, creationflags=_WIN_NO_WINDOW).returncode == 0
        except OSError:
            return False

    def _win_harden_acl(path: str) -> None:
        """Break inheritance and grant only the current user plus the
        root-equivalents (SYSTEM, Administrators), so no world/Users grant
        survives -- the 0700 analog. Best-effort: the owner check and the
        O_EXCL/O_CREAT claim remain the hard gates if icacls is unavailable."""
        sids = _win_identity_sids()
        if not sids:
            return False
        inherit = "(OI)(CI)" if os.path.isdir(path) else ""
        # Grant EVERY identity SID, not an arbitrary one from the set: an
        # elevated token carries two (user + default owner), and picking one
        # nondeterministically could grant the wrong principal.
        grants = []
        for sid in sorted(sids) + ["S-1-5-18", "S-1-5-32-544"]:
            grants += ["/grant:r", f"*{sid}:{inherit}F"]
        return _win_run_quiet([_win_tool("icacls"), path, "/inheritance:r"] + grants)

    def _win_pid_alive(pid: int) -> bool:
        handle = _kernel32.OpenProcess(
            _PROCESS_QUERY_LIMITED_INFORMATION | _SYNCHRONIZE, False, pid)
        if not handle:
            return False
        try:
            return _kernel32.WaitForSingleObject(handle, 0) == _WAIT_TIMEOUT
        finally:
            _kernel32.CloseHandle(handle)

    def _win_kill_tree(
        root_pid: int, grace: float, job_name=None, expected_identity=None,
    ) -> bool:
        """Terminate the worker tree (KTD3). Returns whether the LEADER was
        alive when the kill began -- the reap classification signal -- which is
        independent of how much of the tree we then sweep.

        The job object is the primary mechanism and the true killpg analog: it
        reaches descendants even after the leader has exited. taskkill /T can
        NOT -- it walks parent->child from a live parent, so against an exited
        pid it returns "process not found" and silently leaves grandchildren
        running forever. That is why the sweep is attempted whenever a job name
        exists, regardless of leader liveness.

        No graceful phase: a console-less worker cannot receive taskkill's
        WM_CLOSE (it reports "can only be terminated forcefully"), so the grace
        window was pure latency that also widened the cmd_reap race.

        The job is only reachable by the process that created it: Windows
        releases a named object's NAME once the last handle closes, even while
        member processes keep the object alive (verified: OpenJobObject then
        fails with ERROR_FILE_NOT_FOUND). So a cmd_reap running after the
        supervisor died cannot use it, and falls back to the snapshot walk --
        which is exactly the dead-leader case, hence deepest-first descendants
        BEFORE the leader, and never gated on leader liveness.

        A live pid at root_pid is not automatically the original leader:
        Windows recycles PIDs, and cmd_reap is often the next python.exe after
        the worker exits (the orphan-grandchild smoke). Never terminate this
        process, and never terminate a live pid whose GetProcessTimes identity
        does not match the recorded worker. Stale-PPID orphans still show the
        dead leader as parent. When the pid was reused, the start-time cutoff
        applies only to *direct* children of that pid (the new process's own
        children vs stale-PPID orphans). A pre-reuse child's full subtree is
        still original-tree work, including descendants spawned after reuse."""
        self_pid = os.getpid()
        is_self = root_pid == self_pid
        alive = (not is_self) and _win_pid_alive(root_pid)
        recorded_leader = alive and _win_process_identity_matches(
            root_pid, expected_identity)
        if job_name:
            _win_terminate_job(job_name)
        # Always Toolhelp-sweep after (or without) the job terminate: children
        # that raced outside the job before AssignProcessToJobObject completed
        # are not members, and TerminateJobObject alone would leave them.
        # CREATE_SUSPENDED closes that spawn race; this remains the belt.
        children_map = _win_process_children_map()
        reuse_cutoff = None
        if not recorded_leader and (is_self or alive):
            reuse_cutoff = _win_process_start_time(root_pid)
        if reuse_cutoff is not None:
            def _predates_reuse(pid):
                started = _win_process_start_time(pid)
                return started is None or started < reuse_cutoff
            kill_set = _pre_reuse_descendant_pids(
                root_pid, children_map, _predates_reuse, self_pid)
        else:
            kill_set = None
        for pid in _win_descendants_deepest_first(root_pid, children_map):
            if pid == self_pid:
                continue
            if kill_set is not None and pid not in kill_set:
                continue
            _win_terminate_pid(pid)
        if recorded_leader:
            _win_terminate_pid(root_pid)
        return recorded_leader


# --- hardened I/O primitives --------------------------------------------------

def _euid():
    return _EFFECTIVE_UID


def _check_owned_dir(path: str, require_private: bool = False) -> None:
    st = os.lstat(path)
    if not stat.S_ISDIR(st.st_mode):
        raise RunnerError(f"{path}: not a real directory (symlink or file planted?)")
    if IS_WINDOWS:
        # SID ownership stands in for st_uid; the hardened ACL (not a mode bit)
        # provides privacy, so there is no separate require_private gate.
        if not _win_owns_path(path):
            raise RunnerError(f"{path}: not owned by the current user")
        return
    euid = _euid()
    if euid is not None and st.st_uid != euid:
        raise RunnerError(f"{path}: not owned by the current user")
    if require_private:
        mode = stat.S_IMODE(st.st_mode)
        if mode != 0o700:
            raise RunnerError(f"{path}: must have mode 0700, found {mode:04o}")


def ensure_owned_dirs(base: str, path: str) -> None:
    """mkdir -p `path` (mode 0700) verifying owner and type on every component
    from `base` down — a planted symlink or foreign dir aborts, never traversed."""
    rel = os.path.relpath(path, base)
    comps = [] if rel == "." else rel.split(os.sep)
    cur = base
    created_base = True
    try:
        os.mkdir(cur, 0o700)
    except FileExistsError:
        created_base = False
    _check_owned_dir(cur)
    if IS_WINDOWS:
        # `icacls /inheritance:r` is destructive and irreversible in a way
        # POSIX's chmod 0700 is not: it permanently drops inherited ACEs. So
        # only re-ACL a root this runner owns -- one we just created, or the
        # managed default (repairing a default left non-private, which is what
        # the POSIX unconditional chmod is for). A pre-existing user-supplied
        # CE_PEER_JOBS_ROOT keeps its ACLs and rests on the owner check.
        default_root = os.path.abspath(DEFAULT_ROOT) if DEFAULT_ROOT else None
        ours = created_base or (
            default_root is not None
            and os.path.normcase(cur) == os.path.normcase(default_root))
        if ours and not _win_harden_acl(cur):
            # Never proceed as if hardened: an unverified root is the one case
            # where the privacy half of the model would silently be missing.
            raise RunnerError(
                f"{cur}: could not harden the jobs-root ACL (icacls failed or "
                "is unavailable); refusing to use a root whose privacy is "
                "unverified"
            )
    else:
        os.chmod(cur, 0o700)
    _check_owned_dir(cur, require_private=True)
    for comp in comps:
        cur = os.path.join(cur, comp)
        created = False
        try:
            os.mkdir(cur, 0o700)
            created = True
        except FileExistsError:
            pass
        if created:
            if IS_WINDOWS:
                _win_harden_acl(cur)
            else:
                os.chmod(cur, 0o700)
        _check_owned_dir(cur)


def read_owned(path: str, cap: int) -> bytes:
    """Open no-follow, verify the OPENED descriptor's owner via fstat, enforce
    the size cap, and return content. Raises Unreadable on any trust failure."""
    fd = os.open(path, os.O_RDONLY | O_NOFOLLOW | O_BINARY)
    try:
        st = os.fstat(fd)
        if IS_WINDOWS:
            # Verify the OPENED handle's owner SID (TOCTOU-safe, like the POSIX
            # fstat-by-fd check) before emitting a byte.
            if not _win_owns_handle(msvcrt.get_osfhandle(fd)):
                raise Unreadable(f"{path}: not owned by the current user; refusing to read")
        else:
            euid = _euid()
            if euid is not None and st.st_uid != euid:
                raise Unreadable(f"{path}: not owned by the current user; refusing to read")
        if not stat.S_ISREG(st.st_mode):
            raise Unreadable(f"{path}: not a regular file")
        if st.st_size > cap:
            raise Unreadable(f"{path}: {st.st_size} bytes exceeds the {cap}-byte read cap")
        chunks = []
        got = 0
        while got <= cap:
            chunk = os.read(fd, 65536)
            if not chunk:
                break
            chunks.append(chunk)
            got += len(chunk)
        if got > cap:
            raise Unreadable(f"{path}: grew past the {cap}-byte read cap during read")
        return b"".join(chunks)
    finally:
        os.close(fd)


def create_exclusive(path: str, data: bytes = b"", mode: int = 0o600) -> None:
    fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | O_NOFOLLOW | O_BINARY, mode)
    try:
        if data:
            os.write(fd, data)
    finally:
        os.close(fd)


def write_atomic(path: str, data: bytes) -> None:
    fd, tmp = tempfile.mkstemp(dir=os.path.dirname(path), prefix=".tmp-")
    try:
        with os.fdopen(fd, "wb") as f:
            f.write(data)
        os.replace(tmp, path)
    except BaseException:
        try:
            os.unlink(tmp)
        except OSError:
            pass
        raise


def write_terminal(job_dir: str, state: str, reason: str, overwrite: bool = True) -> None:
    """Publish the single terminal record. The reason detail lands FIRST so the
    atomic status rename is always the last record; a reason write failure never
    blocks the status."""
    status_path = os.path.join(job_dir, "status")
    if not overwrite and os.path.lexists(status_path):
        return
    try:
        write_atomic(os.path.join(job_dir, "reason"), (reason.rstrip("\n") + "\n").encode())
    except OSError:
        pass
    write_atomic(status_path, (state + "\n").encode())


# --- job identity and resolution ----------------------------------------------

def mint_job_id() -> str:
    return f"{time.strftime('%Y%m%dT%H%M%SZ', time.gmtime())}-{os.urandom(4).hex()}"


def claim_job_dir(jobs_root: str):
    """Atomically claim a fresh job dir: os.mkdir (no -p) fails on collision,
    so the id is regenerated rather than a dir ever being shared."""
    for _ in range(CLAIM_ATTEMPTS):
        job_id = mint_job_id()
        job_dir = os.path.join(jobs_root, job_id)
        try:
            os.mkdir(job_dir, 0o700)
            return job_id, job_dir
        except FileExistsError:
            continue
    raise RunnerError(f"could not claim a unique job dir after {CLAIM_ATTEMPTS} attempts")


def resolve_job_dir(ref: str, skill=None) -> str:
    if os.sep in ref:
        p = os.path.abspath(ref)
        if os.path.isdir(p):
            return p
        raise RunnerError(f"no such job dir: {ref}")
    if not _is_safe_token(ref):
        raise RunnerError(f"invalid job ref: {ref!r}")
    if skill is not None:
        if not _is_safe_token(skill):
            raise RunnerError(f"invalid skill: {skill!r}")
        search_roots = candidate_skill_runs_roots(skill)
        patterns = [os.path.join(root, "*", "jobs", ref) for root in search_roots]
    else:
        search_roots = candidate_jobs_root_bases()
        patterns = [os.path.join(root, "*", "*", "jobs", ref) for root in search_roots]
    matches = sorted({match for pattern in patterns for match in glob.glob(pattern)})
    if not matches:
        raise RunnerError(f"job not found under {', '.join(search_roots)}: {ref}")
    if len(matches) > 1:
        raise RunnerError(f"ambiguous job id {ref}: {len(matches)} matches; pass the job dir path")
    return matches[0]


def job_state(job_dir: str) -> str:
    try:
        _check_owned_dir(job_dir)
    except (RunnerError, OSError):
        return "unreadable"
    try:
        word = read_owned(os.path.join(job_dir, "status"), STATUS_READ_CAP)
        word = word.decode("utf-8", "replace").strip()
        return word if word in TERMINAL_STATES else "unreadable"
    except FileNotFoundError:
        pass
    except (Unreadable, OSError):
        return "unreadable"
    if os.path.lexists(os.path.join(job_dir, "pid")):
        return "running"
    return "never-started"


def job_reason(job_dir: str) -> str:
    """The terminal record's detail line, or "" when unavailable. Decorative
    context for a message; never load-bearing, so every failure reads as ""."""
    try:
        raw = read_owned(os.path.join(job_dir, "reason"), REASON_READ_CAP)
    except (Unreadable, OSError):
        return ""
    return raw.decode("utf-8", "replace").strip()


# --- process-tree control -----------------------------------------------------

def _pid_alive(pid: int) -> bool:
    if IS_WINDOWS:
        return _win_pid_alive(pid)
    try:
        os.kill(pid, 0)
        return True
    except ProcessLookupError:
        return False
    except OSError:
        return True


def _pid_running(pid: int) -> bool:
    """True only for a live process, NOT a <defunct> zombie. os.kill(pid, 0)
    succeeds for a zombie (the process exited but has not been reaped), which
    must not count as a live worker when classifying a reap: a zombie leader
    means the worker is gone (died-without-result), not still running (timeout).
    Falls back to the kill -0 result when process state is unavailable."""
    if IS_WINDOWS:
        # Windows has no <defunct> zombie state -- a terminated process's handle
        # is signaled and OpenProcess-based liveness already reports it dead.
        return _win_pid_alive(pid)
    if not _pid_alive(pid):
        return False
    try:
        out = subprocess.run(
            ["ps", "-o", "state=", "-p", str(pid)],
            capture_output=True, text=True, check=False,
        ).stdout.strip()
    except OSError:
        return True
    if not out:
        return False
    return not out.startswith("Z")


def _kill_quiet(pid: int, sig: int) -> bool:
    try:
        os.kill(pid, sig)
        return True
    except OSError:
        return False


def _killpg_quiet(pgid: int, sig: int) -> bool:
    try:
        os.killpg(pgid, sig)
        return True
    except OSError:
        return False


def _descendants_deepest_first(root_pid: int):
    """Fallback tree enumeration via ps when a process-group kill is not
    available: children die before their parents can respawn or orphan them."""
    try:
        out = subprocess.run(
            ["ps", "-eo", "pid=,ppid="], capture_output=True, text=True, check=False
        ).stdout
    except OSError:
        return []
    children = {}
    for line in out.splitlines():
        parts = line.split()
        if len(parts) != 2:
            continue
        try:
            pid, ppid = int(parts[0]), int(parts[1])
        except ValueError:
            continue
        children.setdefault(ppid, []).append(pid)
    order, queue = [], [root_pid]
    while queue:
        for child in children.get(queue.pop(0), []):
            order.append(child)
            queue.append(child)
    return list(reversed(order))


def _signal_group_or_tree(pid: int, sig: int) -> None:
    """Signal the pid's process group, falling back to a deepest-first tree
    walk when the group kill is unavailable."""
    if not _killpg_quiet(pid, sig):
        for descendant in _descendants_deepest_first(pid):
            _kill_quiet(descendant, sig)
        _kill_quiet(pid, sig)


def _pre_reuse_descendant_pids(root_pid, children, predates_reuse, skip_pid=None):
    """Direct children that predate a recycled leader pid, plus each of those
    children's full subtree.

    Toolhelp still lists the original tree under a dead pid as parent, mixed
    with the new process's own children. The start-time cutoff applies only to
    direct children. A pre-reuse child's later descendants stay original-tree
    work even if they started after the reuse.
    """
    keep = set()
    queue = []
    for child in children.get(root_pid, []):
        if skip_pid is not None and child == skip_pid:
            continue
        if not predates_reuse(child):
            continue
        queue.append(child)
    while queue:
        pid = queue.pop(0)
        if skip_pid is not None and pid == skip_pid:
            continue
        if pid in keep:
            continue
        keep.add(pid)
        queue.extend(children.get(pid, []))
    return keep


def kill_tree(root_pid: int, grace: float, job_name=None, expected_identity=None) -> bool:
    """TERM the pid's process group (workers are started as group leaders),
    falling back to a deepest-first tree walk; grace, then KILL survivors.

    `job_name` is Windows-only (the worker's job object, the pgid analog) and
    is ignored on POSIX, where the pgid is derived from the pid itself.
    `expected_identity` is Windows-only (GetProcessTimes identity recorded at
    start) and is ignored on POSIX."""
    if IS_WINDOWS:
        return _win_kill_tree(root_pid, grace, job_name, expected_identity)
    # Do NOT early-return just because the leader pid is dead: killpg targets
    # the pgid, which persists while any group member lives even after the
    # leader exits, so a dead leader can still front a live group we must sweep.
    # Use _pid_running (zombie-aware), not _pid_alive: a just-exited leader is
    # briefly a <defunct> zombie for which kill -0 still succeeds, and counting
    # that as alive would misclassify the reap as timeout instead of
    # died-without-result (and make the dead-leader sweep test timing-dependent).
    leader_alive = _pid_running(root_pid)
    # Snapshot the descendant set BEFORE any KILL: once the group leader is
    # reaped its children reparent to init and drop out of the tree, so a set
    # enumerated after the kill would miss them and leak orphans.
    survivors = _descendants_deepest_first(root_pid)
    _signal_group_or_tree(root_pid, signal.SIGTERM)
    deadline = time.monotonic() + grace
    while time.monotonic() < deadline:
        if leader_alive and not _pid_alive(root_pid):
            break
        time.sleep(0.1)
    _killpg_quiet(root_pid, signal.SIGKILL)
    for pid in survivors:
        _kill_quiet(pid, signal.SIGKILL)
    _kill_quiet(root_pid, signal.SIGKILL)
    return leader_alive


# --- the supervisor (runs inside the detached session) -------------------------

def classify_exit(rc: int, result_path, conf: dict):
    result_size = None
    if result_path:
        try:
            st = os.lstat(result_path)
            if stat.S_ISREG(st.st_mode) and st.st_size > 0:
                result_size = st.st_size
        except OSError:
            pass
    if result_size is not None and result_size > conf["result_max"]:
        return "failed", (
            f"result exceeded byte cap ({result_size} > {conf['result_max']} bytes)"
        )
    if rc == 0:
        if result_path is None or result_size is not None:
            return "done", "worker exited 0"
        return "failed", "worker exited 0 without publishing a non-empty result"
    if rc < 0:
        if result_size is not None:
            return "done", f"worker killed by signal {-rc} after publishing its result"
        return "died-without-result", (
            f"worker killed by signal {-rc} with no result evidence"
        )
    return "failed", f"worker exited {rc}"


def classify_exit_with_pending_reap(rc: int, result_path, conf: dict, reap_pending: bool):
    """Classify a worker that already exited, optionally under a pending reap.

    When reap is pending (Windows `.reap` or POSIX SIGTERM flag) and the worker
    was killed by the fallback path, classify_exit would record "failed" for a
    non-zero kill exit — prefer timeout. When the worker already completed
    successfully (done + result), keep that: a late reap must not rewrite a
    finished peer run.
    """
    state, reason = classify_exit(rc, result_path, conf)
    if reap_pending and state != "done":
        return "timeout", "reaped on request before completion"
    return state, reason


def _reap_worker(proc, conf: dict, job_name=None) -> None:
    # Deliberately parallel to kill_tree but driven by proc.poll(): an unreaped
    # Popen child is a zombie that os.kill(pid, 0) still reports alive, so the
    # pid-based liveness check would burn the whole grace window.
    if proc.poll() is not None:
        return
    if IS_WINDOWS:
        _win_kill_tree(proc.pid, conf["grace"], job_name)
        try:
            proc.wait(timeout=5)
        except Exception:
            pass
        return
    _signal_group_or_tree(proc.pid, signal.SIGTERM)
    deadline = time.monotonic() + conf["grace"]
    while time.monotonic() < deadline:
        if proc.poll() is not None:
            break
        time.sleep(0.1)
    if proc.poll() is None:
        _killpg_quiet(proc.pid, signal.SIGKILL)
        for pid in _descendants_deepest_first(proc.pid):
            _kill_quiet(pid, signal.SIGKILL)
        try:
            proc.wait(timeout=5)
        except Exception:
            pass


def _reap_requested(flag: dict, job_dir: str) -> bool:
    """POSIX delivers the reap as SIGTERM (sets flag). Windows has no reliable
    directed-signal path to a detached, console-less supervisor, so cmd_reap
    drops a `.reap` marker in the job dir and the loop polls for it."""
    if flag["reap"]:
        return True
    if IS_WINDOWS and os.path.lexists(os.path.join(job_dir, ".reap")):
        return True
    return False


def _interruptible_sleep(secs: float, flag: dict, job_dir: str) -> None:
    end = time.monotonic() + secs
    while time.monotonic() < end:
        # On POSIX _reap_requested reduces to flag["reap"] (the IS_WINDOWS
        # branch never fires), so this is the original signal-driven behavior.
        if _reap_requested(flag, job_dir):
            return
        time.sleep(min(0.1, max(0.01, end - time.monotonic())))


def _is_system32_wsl_bash(path: str) -> bool:
    """True for Windows System32 WSL launchers, including Sysnative aliases."""
    if not path:
        return False
    base = os.path.basename(path).lower()
    if base not in ("bash", "bash.exe", "sh", "sh.exe"):
        return False
    system_root = os.environ.get("SystemRoot") or r"C:\Windows"
    windows_root = os.path.abspath(system_root)
    blocked_parents = {
        os.path.normcase(os.path.join(windows_root, name))
        for name in ("System32", "Sysnative")
    }
    parent = os.path.normcase(os.path.dirname(os.path.abspath(path)))
    return parent in blocked_parents


def _git_bash_well_known_paths():
    """Standard Git for Windows bash.exe locations."""
    pf64 = os.environ.get("ProgramW6432") or ""
    pf = os.environ.get("ProgramFiles") or r"C:\Program Files"
    pf86 = os.environ.get("ProgramFiles(x86)") or r"C:\Program Files (x86)"
    local = os.environ.get("LOCALAPPDATA") or ""
    roots = []
    seen = set()
    for root in (pf64, pf, pf86):
        if not root:
            continue
        key = os.path.normcase(os.path.abspath(root))
        if key in seen:
            continue
        seen.add(key)
        roots.append(root)
    paths = []
    for root in roots:
        paths.extend([
            os.path.join(root, "Git", "bin", "bash.exe"),
            os.path.join(root, "Git", "usr", "bin", "bash.exe"),
        ])
    if local:
        paths.extend([
            os.path.join(local, "Programs", "Git", "bin", "bash.exe"),
            os.path.join(local, "Programs", "Git", "usr", "bin", "bash.exe"),
        ])
    return paths


def _windows_path_shell_candidates():
    """Every bash/sh on PATH in PATH order (not only shutil.which's first hit)."""
    path_env = os.environ.get("PATH") or ""
    names = ("bash.exe", "bash", "sh.exe", "sh")
    found = []
    seen = set()
    for directory in path_env.split(os.pathsep):
        if not directory:
            continue
        for name in names:
            candidate = os.path.join(directory, name)
            try:
                if not os.path.isfile(candidate):
                    continue
            except OSError:
                continue
            key = os.path.normcase(os.path.abspath(candidate))
            if key in seen:
                continue
            seen.add(key)
            found.append(candidate)
    return found


def _env_assignment_token(token: str, allow_option_like: bool = False) -> bool:
    """True for env(1) NAME=value operands (not options or the command)."""
    if (
        not token
        or (token.startswith("-") and not allow_option_like)
        or "=" not in token
    ):
        return False
    return True


def _env_option_advance(tok: str) -> int:
    """How many argv slots an env(1) option occupies (incl. the option itself).

    GNU env options that take a separate operand: -u/--unset, -C/--chdir.
    Attached `--name=value` forms are a single slot.
    Short options may be clustered. No-operand flags (-i/-v and their exact
    long aliases and signal-handling options) advance one slot; -u/-C consume
    the rest of the token as an
    attached operand or the next argv slot. Unsupported options fail closed
    before worker detach.
    (#1292 Codex P2)
    """
    if tok in ("-u", "--unset", "-C", "--chdir"):
        return 2
    if tok.startswith(("--unset=", "--chdir=")):
        return 1
    if tok in ("--ignore-environment", "--debug"):
        return 1
    if tok == "--list-signal-handling" or tok in (
        "--block-signal",
        "--default-signal",
        "--ignore-signal",
    ) or tok.startswith((
        "--block-signal=",
        "--default-signal=",
        "--ignore-signal=",
    )):
        return 1
    if tok == "--null":
        raise RunnerError(
            "env -0/--null cannot be used with a command by native Windows "
            "peer workers; remove the null-output option"
        )
    if not tok.startswith("-"):
        return 1
    if tok.startswith("--"):
        raise RunnerError(
            f"unsupported env long option {tok!r} for native Windows peer "
            "workers; use an exact supported option or pass -- before "
            "option-like assignments"
        )

    cluster = tok[1:]
    for index, option in enumerate(cluster):
        if option in "iv":
            continue
        if option == "0":
            raise RunnerError(
                "env -0/--null cannot be used with a command by native "
                "Windows peer workers; remove the null-output option"
            )
        if option == "S":
            raise RunnerError(
                "env -S/--split-string is unsupported for native Windows "
                "peer workers; pass env assignments and the command as "
                "separate arguments"
            )
        if option in "uC":
            return 1 if index + 1 < len(cluster) else 2
        raise RunnerError(
            f"unsupported env short-option cluster {tok!r} for native "
            "Windows peer workers; pass env options separately"
        )
    return 1


def _env_bash_index(argv):
    """Locate the env(1)-launched bash/sh command, for #1268/#1292 rewriting.

    Matches the production cross-model shape `env VAR=… bash script.sh …`
    (#1268). Operand-taking options (-u/-C and long forms) consume their
    arguments before the command token is sought (#1292). Split-string forms
    fail closed because Python shlex does not match Git env.exe semantics.

    Returns (argv_index, None), or (-1, None) when no bash/sh command is
    present.
    """
    if not argv:
        return -1, None
    if os.path.basename(argv[0]).lower() not in ("env", "env.exe"):
        return -1, None
    i = 1
    options_done = False
    while i < len(argv):
        tok = argv[i]
        if tok in ("-", "--") and not options_done:
            options_done = True
            i += 1
            continue
        if _env_assignment_token(tok, allow_option_like=options_done):
            options_done = True
            i += 1
            continue
        if not options_done and (
            tok in ("-S", "--split-string") or tok.startswith(
                ("-S", "--split-string=")
            )
        ):
            raise RunnerError(
                "env -S/--split-string is unsupported for native Windows "
                "peer workers; pass env assignments and the command as "
                "separate arguments"
            )
        if not options_done and tok.startswith("-"):
            span = _env_option_advance(tok)
            if span > 1 and i + 1 >= len(argv):
                return -1, None
            i += span
            continue
        base = os.path.basename(tok).lower()
        if base in ("bash", "bash.exe", "sh", "sh.exe"):
            return i, None
        return -1, None
    return -1, None


def _windows_path_is_absolute(path: str) -> bool:
    """True for Windows absolute paths (drive letter or path separator)."""
    return os.sep in path or (len(path) >= 2 and path[1] == ":")


def _prefer_windows_posix_shell(token: str) -> str:
    """Absolute non-WSL bash/sh kept; bare names and System32 go through resolve.

    Explicit absolute paths (portable Git, custom installs) must not be
    substituted by the preferred resolver (#1292 Codex P2). Bare `bash`/`sh`
    and System32 WSL launchers still use `_resolve_windows_posix_shell()`.
    """
    if _windows_path_is_absolute(token):
        path = os.path.abspath(token)
        if not os.path.isfile(path):
            raise RunnerError(
                f"peer worker shell does not exist or is not a regular file: {token}"
            )
        if _is_system32_wsl_bash(path):
            return _resolve_windows_posix_shell()
        return path
    return _resolve_windows_posix_shell()


def _rewrite_windows_env_bash_argv(argv):
    """Rewrite bare bash/sh inside an env-prefixed argv.

    Returns (argv, resolved_shell_or_None). Raises RunnerError when a bash/sh
    token is present but no usable non-WSL shell can be resolved. Absolute
    non-WSL bash tokens are kept unchanged (#1292 P2). Split-string options
    are rejected before detach because their parser semantics are not safely
    reproduced here (#1292).
    """
    idx, split_prefix = _env_bash_index(argv)
    if idx < 0:
        return list(argv), None
    out = list(argv)
    assert split_prefix is None
    shell = _prefer_windows_posix_shell(out[idx])
    if os.path.normcase(os.path.abspath(out[idx])) != os.path.normcase(shell):
        out[idx] = shell
    return out, shell


def _resolve_windows_posix_shell() -> str:
    """Absolute path to a non-WSL POSIX shell for native Windows peer workers.

    Order: CE_PEER_BASH, CLAUDE_CODE_GIT_BASH_PATH, well-known Git Bash
    installs, then every PATH bash/sh excluding System32 WSL. Fail closed when
    nothing usable remains — never select System32\\bash.exe (#1268).
    """
    candidates = []
    for key in ("CE_PEER_BASH", "CLAUDE_CODE_GIT_BASH_PATH"):
        val = (os.environ.get(key) or "").strip()
        if val:
            candidates.append(val)
    candidates.extend(_git_bash_well_known_paths())
    candidates.extend(_windows_path_shell_candidates())

    seen = set()
    for raw in candidates:
        path = os.path.abspath(raw)
        key = os.path.normcase(path)
        if key in seen:
            continue
        seen.add(key)
        if not os.path.isfile(path):
            continue
        if _is_system32_wsl_bash(path):
            continue
        return path

    raise RunnerError(
        "no usable Git Bash (or other non-WSL POSIX shell) for native Windows "
        "peer workers; install Git for Windows or set CE_PEER_BASH / "
        "CLAUDE_CODE_GIT_BASH_PATH to an absolute bash.exe path "
        "(System32\\bash.exe / WSL is not used)"
    )


def _popen_argv(argv):
    """Argv for subprocess.Popen.

    On Windows, CreateProcess does not honor shebang, so a bare *.sh / *.bash
    worker must be launched through bash/sh. Prefer Git Bash over System32
    WSL bash (#1268). Bare `bash`/`sh` prefixes (review skills) and bare
    `bash`/`sh` tokens after `env VAR=…` (cross-model) are rewritten to that
    absolute path. Explicit absolute non-WSL bash/sh paths are kept (#1292 P2).
    meta.json still records the caller argv for authorize-dispatch contracts
    that forbid a shell prefix on ce-work.
    """
    if not IS_WINDOWS or not argv:
        return list(argv)
    head = argv[0]
    base = os.path.basename(head).lower()
    if base in ("env", "env.exe"):
        rewritten, _shell = _rewrite_windows_env_bash_argv(argv)
        return rewritten
    if base in ("bash", "bash.exe", "sh", "sh.exe"):
        shell = _prefer_windows_posix_shell(head)
        if os.path.normcase(os.path.abspath(head)) == os.path.normcase(shell):
            return list(argv)
        return [shell] + list(argv[1:])
    lower = head.lower()
    if not (lower.endswith(".sh") or lower.endswith(".bash")):
        return list(argv)
    shell = _resolve_windows_posix_shell()
    return [shell, head] + list(argv[1:])


def supervise(job_dir: str, argv, result_path, conf: dict, ack_fd: int) -> None:
    """The watchdog around the worker child. Owns liveness (out.log growth),
    the idle/hard windows, byte caps, reap-on-request, and the single terminal
    classification."""
    flag = {"reap": False}

    def on_term(signum, frame):
        flag["reap"] = True

    if not IS_WINDOWS:
        signal.signal(signal.SIGTERM, on_term)
        signal.signal(signal.SIGHUP, signal.SIG_IGN)
    # On Windows there is no SIGHUP and no reliable directed SIGTERM to a
    # detached supervisor; reap arrives via the `.reap` marker polled below.

    acked = False

    def ack():
        nonlocal acked
        if acked:
            return
        acked = True
        # Windows detach has no ack pipe (ack_fd is None): the pid file written
        # just above IS the ack, and the parent polls for it.
        if ack_fd is None:
            return
        try:
            os.write(ack_fd, b"ok")
            os.close(ack_fd)
        except OSError:
            pass

    log_fd = None
    job_name = None
    job_handle = None
    try:
        log_fd = os.open(
            os.path.join(job_dir, "out.log"),
            os.O_WRONLY | os.O_APPEND | O_NOFOLLOW | O_BINARY)
        if IS_WINDOWS:
            # Created BEFORE the worker so the tree can never start outside it.
            # The handle is held for the supervisor's lifetime; the job is what
            # makes teardown reach descendants of an exited leader.
            job_name = _win_job_name(job_dir)
            job_handle = _win_create_job(job_name)
        devnull = os.open(os.devnull, os.O_RDONLY)
        try:
            # Export the interpreter running this supervisor so Windows workers
            # (and any adapter that honors it) do not re-resolve to the Store
            # python3 stub — see resolve-python convention / #1247.
            worker_env = {
                **os.environ,
                "CE_PEER_JOB_ID": os.path.basename(job_dir),
                "CE_PEER_PYTHON": sys.executable,
            }
            popen_kwargs = dict(
                stdin=devnull,
                stdout=log_fd,
                stderr=log_fd,
                env=worker_env,
                close_fds=True,
            )
            if IS_WINDOWS:
                # New process group so the worker's own tree is isolated; reap =
                # job terminate + Toolhelp walk (there is no killpg on Windows).
                # CREATE_NO_WINDOW because the supervisor is console-less, so
                # without it Windows allocates a NEW console per worker and the
                # user sees a window flash for every job. (It is mutually
                # exclusive with DETACHED_PROCESS, which is why the supervisor
                # itself uses DETACHED_PROCESS and only the worker uses this.)
                # CREATE_SUSPENDED: assign to the Job Object before any worker
                # code runs, so early child spawns inherit membership.
                popen_kwargs["creationflags"] = (
                    subprocess.CREATE_NEW_PROCESS_GROUP
                    | _WIN_NO_WINDOW
                    | _CREATE_SUSPENDED)
            else:
                popen_kwargs["start_new_session"] = True  # worker leads its own group
            # Wrap bare *.sh on Windows at spawn time only — meta still has the
            # caller argv (see _popen_argv).
            proc = subprocess.Popen(_popen_argv(argv), **popen_kwargs)
        finally:
            os.close(devnull)
        pid_doc = {
            "supervisor_pid": os.getpid(),
            "worker_pid": proc.pid,
        }
        if IS_WINDOWS:
            sup_ident = _win_process_identity(os.getpid())
            worker_ident = _win_process_identity(proc.pid)
            if sup_ident:
                pid_doc["supervisor_identity"] = sup_ident
            if worker_ident:
                pid_doc["worker_identity"] = worker_ident
            # Assign while still suspended, then resume. Record the job only
            # once the worker is actually a member, so a later reap never trusts
            # a name that owns nothing. If assignment fails (job creation denied,
            # or a nested-job restriction), leave it unset and let teardown fall
            # back to the Toolhelp walk.
            if job_handle is not None and _win_assign_to_job(job_handle, proc.pid):
                pid_doc["job_name"] = job_name
            else:
                job_name = None
            if not _win_resume_process(proc.pid):
                raise RunnerError(
                    f"could not resume suspended Windows worker pid {proc.pid}"
                )
        else:
            # pgid drives POSIX group kills; Windows reaps by job object.
            pid_doc["supervisor_pgid"] = os.getpgid(0)
        # The pid file lands before the parent is acked, so a returned `start`
        # guarantees the detach marker exists (status never mis-reads a fresh
        # job as never-started).
        write_atomic(os.path.join(job_dir, "pid"), (json.dumps(pid_doc) + "\n").encode())
    except Exception as exc:
        write_terminal(job_dir, "failed", f"could not launch worker: {exc}")
        ack()
        return
    ack()

    start_t = time.monotonic()
    last_growth = start_t
    last_size = 0
    while True:
        rc = proc.poll()
        if rc is not None:
            state, reason = classify_exit_with_pending_reap(
                rc, result_path, conf, _reap_requested(flag, job_dir),
            )
            break
        if _reap_requested(flag, job_dir):
            # Classification is fixed BEFORE the kill: even if the worker
            # publishes and exits 0 during the grace window, the supervisor's
            # record wins (R3).
            _reap_worker(proc, conf, job_name)
            state, reason = "timeout", "reaped on request before completion"
            break
        try:
            size = os.fstat(log_fd).st_size
        except OSError:
            size = last_size
        now = time.monotonic()
        if size > last_size:
            last_size, last_growth = size, now
        if size > conf["log_max"]:
            _reap_worker(proc, conf, job_name)
            state, reason = "failed", (
                f"out.log exceeded byte cap ({size} > {conf['log_max']} bytes)"
            )
            break
        if conf["idle"] is not None and now - last_growth >= conf["idle"]:
            _reap_worker(proc, conf, job_name)
            state, reason = "timeout", f"no output for {conf['idle']:g}s (idle window)"
            break
        if now - start_t >= conf["hard"]:
            _reap_worker(proc, conf, job_name)
            state, reason = "timeout", f"hard cap {conf['hard']:g}s exceeded"
            break
        _interruptible_sleep(conf["poll"], flag, job_dir)
    # An externally killed worker can leave group members behind (its shell's
    # children); sweep the group before publishing so no orphan outlives the
    # terminal record. A pgid cannot be recycled while members remain.
    if IS_WINDOWS:
        # Job-object sweep: unlike taskkill this still reaches descendants when
        # the worker leader has already exited, which is the orphan case the
        # POSIX killpg pair below covers.
        _win_kill_tree(proc.pid, min(conf["grace"], 1.0), job_name)
    else:
        _killpg_quiet(proc.pid, signal.SIGTERM)
        _killpg_quiet(proc.pid, signal.SIGKILL)
    write_terminal(job_dir, state, reason)


def detach_supervisor(job_dir: str, argv, result_path, conf: dict) -> bool:
    """setsid double-fork. The grandchild (new session, stdio on /dev/null,
    reparented to init) runs the supervisor; the parent returns once the
    supervisor acks that the pid file exists."""
    if IS_WINDOWS:
        return detach_supervisor_windows(job_dir, argv, result_path, conf)
    sys.stdout.flush()
    sys.stderr.flush()
    read_fd, write_fd = os.pipe()
    pid1 = os.fork()
    if pid1 == 0:
        os.close(read_fd)
        os.setsid()
        if os.fork() > 0:
            os._exit(0)
        rc = 0
        try:
            devnull = os.open(os.devnull, os.O_RDWR)
            os.dup2(devnull, 0)
            os.dup2(devnull, 1)
            os.dup2(devnull, 2)
            if devnull > 2:
                os.close(devnull)
            supervise(job_dir, argv, result_path, conf, write_fd)
        except BaseException:
            rc = 1
            try:
                write_terminal(
                    job_dir, "failed", "supervisor crashed before classification",
                    overwrite=False,
                )
            except BaseException:
                pass
        os._exit(rc)
    os.close(write_fd)
    os.waitpid(pid1, 0)
    ack = b""
    try:
        while len(ack) < 2:
            chunk = os.read(read_fd, 2 - len(ack))
            if not chunk:
                break
            ack += chunk
    finally:
        os.close(read_fd)
    return ack == b"ok"


def detach_supervisor_windows(job_dir: str, argv, result_path, conf: dict) -> bool:
    """Windows detach: there is no fork/setsid, so re-invoke this script as a
    fresh DETACHED_PROCESS running the internal `__supervise` entrypoint. The
    spawn spec travels through an owner-private file in the job dir; the parent
    returns once the supervisor has left its ack marker (the pid file, or a
    terminal status if the worker could not launch). CREATE_BREAKAWAY_FROM_JOB
    is the analog of setsid's reparent-to-init: it lets the supervisor outlive a
    launching harness that runs inside a kill-on-close Job Object, falling back
    when the job forbids breakaway."""
    spec = {"argv": list(argv), "result_path": result_path, "conf": conf}
    create_exclusive(
        os.path.join(job_dir, ".spawn.json"),
        (json.dumps(spec) + "\n").encode(),
    )
    cmd = [sys.executable, os.path.abspath(__file__), "__supervise", job_dir]
    base_flags = subprocess.DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP
    devnull = os.open(os.devnull, os.O_RDWR)
    proc = None
    try:
        for flags in (base_flags | subprocess.CREATE_BREAKAWAY_FROM_JOB, base_flags):
            try:
                proc = subprocess.Popen(
                    cmd,
                    stdin=devnull, stdout=devnull, stderr=devnull,
                    close_fds=True, creationflags=flags,
                )
                break
            except OSError:
                proc = None
        if proc is None:
            return False
    finally:
        os.close(devnull)

    pid_path = os.path.join(job_dir, "pid")
    status_path = os.path.join(job_dir, "status")
    deadline = time.monotonic() + 15.0
    while time.monotonic() < deadline:
        if os.path.lexists(pid_path) or os.path.lexists(status_path):
            return True
        if proc.poll() is not None:
            # Supervisor process exited without leaving a marker: detach failed.
            return os.path.lexists(pid_path) or os.path.lexists(status_path)
        time.sleep(0.05)
    # Deadline with the supervisor still running. Do not abandon it: reporting
    # a detach failure while leaving a live, unreachable supervisor/worker pair
    # behind is exactly the orphan this runner exists to prevent. The snapshot
    # walk reaches the worker as the supervisor's child.
    try:
        if proc.poll() is None:
            _win_kill_tree(proc.pid, 0.0)
    except Exception:
        pass
    return False


def _win_supervise_from_spec(job_dir: str) -> int:
    """Internal `__supervise` entrypoint: the detached Windows supervisor. Drops
    its console-less std handles onto NUL, reads the owner-checked spawn spec,
    and runs the shared supervisor loop with a file-based (not fd) ack."""
    rc = 0
    # Redundant with detach_supervisor_windows, which already binds this
    # process's stdio to NUL via Popen -- kept deliberately so the entrypoint is
    # self-contained: a supervisor is long-lived, and any future/manual
    # invocation that inherited a real pipe could block forever once it filled.
    try:
        devnull = os.open(os.devnull, os.O_RDWR)
        for fd in (0, 1, 2):
            try:
                os.dup2(devnull, fd)
            except OSError:
                pass
        if devnull > 2:
            os.close(devnull)
    except OSError:
        pass
    try:
        _check_owned_dir(job_dir)
        spec = json.loads(read_owned(os.path.join(job_dir, ".spawn.json"), META_READ_CAP))
        argv = spec["argv"]
        result_path = spec.get("result_path")
        conf = spec["conf"]
        try:
            os.unlink(os.path.join(job_dir, ".spawn.json"))
        except OSError:
            pass
        supervise(job_dir, argv, result_path, conf, None)
    except BaseException:
        rc = 1
        try:
            write_terminal(
                job_dir, "failed", "supervisor crashed before classification",
                overwrite=False,
            )
        except BaseException:
            pass
    return rc


# --- subcommands ---------------------------------------------------------------

def sweep_stale_runs(skill_dir: str, keep: str) -> None:
    """Best-effort retention (R14): remove sibling run roots older than 24h.
    Owner-checked via lstat; never raises, never touches the current run."""
    try:
        entries = list(os.scandir(skill_dir))
    except OSError:
        return
    now = time.time()
    euid = _euid()
    keep_abs = os.path.abspath(keep)
    for entry in entries:
        if os.path.abspath(entry.path) == keep_abs:
            continue
        try:
            st = entry.stat(follow_symlinks=False)
        except OSError:
            continue
        if not stat.S_ISDIR(st.st_mode):
            continue
        if IS_WINDOWS:
            try:
                if not _win_owns_path(entry.path):
                    continue
            except OSError:
                continue
        elif euid is not None and st.st_uid != euid:
            continue
        if now - st.st_mtime <= SWEEP_AGE_SECS:
            continue
        shutil.rmtree(entry.path, ignore_errors=True)


def _require_detach_support() -> None:
    """Detached peer jobs need a supported detach path: os.fork/os.setsid on
    POSIX, or the native Windows DETACHED_PROCESS path (#1243). Checked first,
    before jobs_root_base()/geteuid, so an unsupported host fails with this clear
    message instead of jobs_root_base()'s unrelated "effective user ID is
    unavailable" error or an AttributeError mid-detach. Native Windows is now
    supported; only a non-win32 Python missing fork/setsid (some embedded
    builds) is rejected here."""
    if IS_WINDOWS:
        return
    if not hasattr(os, "fork") or not hasattr(os, "setsid"):
        raise RunnerError(
            "detached peer jobs require os.fork/os.setsid on this platform; no "
            "job was started. Run under a POSIX Python, or on native Windows use "
            "a Windows Python 3 build (see "
            "EveryInc/compound-engineering-plugin#1243)."
        )


def cmd_start(args, worker_argv) -> int:
    _require_detach_support()
    for flag, value in (("--skill", args.skill), ("--run-id", args.run_id)):
        if not _is_safe_token(value):
            raise RunnerError(f"{flag} must match [A-Za-z0-9._-]+ and not be all dots (got {value!r})")
    if args.label is not None and not _is_safe_token(args.label):
        raise RunnerError(f"--label must match [A-Za-z0-9._-]+ and not be all dots (got {args.label!r})")
    if not worker_argv:
        raise RunnerError("no worker argv; place it after `--`")

    base = jobs_root_base()
    skill_dir = skill_runs_root(args.skill)
    run_dir = os.path.join(skill_dir, args.run_id)
    jobs_root = os.path.join(run_dir, "jobs")
    ensure_owned_dirs(skill_dir if skill_dir != os.path.join(base, args.skill) else base, jobs_root)
    if not args.no_sweep:
        sweep_stale_runs(skill_dir, keep=run_dir)

    job_id, job_dir = claim_job_dir(jobs_root)
    result_path = os.path.abspath(args.result_path) if args.result_path else None

    argv0 = worker_argv[0]
    problem = None
    windows_posix_shell = None
    base0 = os.path.basename(argv0).lower()
    if IS_WINDOWS and base0 in ("bash", "bash.exe", "sh", "sh.exe"):
        # Prefer Git Bash over PATH/System32 WSL before meta + detach (#1268).
        # Keep an explicit absolute non-WSL bash (portable Git) (#1292 P2).
        try:
            resolved = _prefer_windows_posix_shell(argv0)
            windows_posix_shell = resolved
        except RunnerError as exc:
            problem = str(exc)
            resolved = argv0
    elif IS_WINDOWS and base0 in ("env", "env.exe"):
        # Production cross-model: env VAR=… bash script.sh — rewrite bash
        # before detach so env cannot PATH-resolve System32 WSL (#1268).
        if os.sep in argv0 or (len(argv0) >= 2 and argv0[1] == ":"):
            resolved = os.path.abspath(argv0)
            if not os.path.isfile(resolved):
                problem = "does not exist or is not a regular file"
        else:
            resolved = shutil.which(argv0)
            if resolved is None:
                problem = "was not found on PATH"
                resolved = argv0
        try:
            rewritten, shell = _rewrite_windows_env_bash_argv(list(worker_argv))
            if shell is not None:
                windows_posix_shell = shell
                worker_argv = rewritten
        except RunnerError as exc:
            problem = str(exc) if problem is None else f"{problem}; {exc}"
    elif os.sep in argv0 or (IS_WINDOWS and len(argv0) >= 2 and argv0[1] == ":"):
        resolved = os.path.abspath(argv0)
        if not os.path.isfile(resolved):
            problem = "does not exist or is not a regular file"
        elif IS_WINDOWS and resolved.lower().endswith((".sh", ".bash")):
            # CreateProcess cannot run shebang scripts; _popen_argv wraps with
            # Git Bash. Require that shell now so start fails closed, not after
            # detach. Skip the X_OK check — Windows often marks .sh non-exec.
            try:
                windows_posix_shell = _resolve_windows_posix_shell()
            except RunnerError as exc:
                problem = str(exc)
        elif not os.access(resolved, os.X_OK):
            problem = "is not executable"
    else:
        resolved = shutil.which(argv0)
        if resolved is None:
            problem = "was not found on PATH"
            resolved = argv0
        elif IS_WINDOWS and resolved.lower().endswith((".sh", ".bash")):
            try:
                windows_posix_shell = _resolve_windows_posix_shell()
            except RunnerError as exc:
                problem = str(exc)
        elif IS_WINDOWS and os.path.basename(resolved).lower() in (
            "bash", "bash.exe", "sh", "sh.exe",
        ):
            # which() may have returned System32 WSL — rewrite now.
            try:
                resolved = _resolve_windows_posix_shell()
                windows_posix_shell = resolved
            except RunnerError as exc:
                problem = str(exc)
    argv = [resolved] + list(worker_argv[1:])

    conf = cfg(args.skill)
    meta = {
        "job_id": job_id,
        "skill": args.skill,
        "run_id": args.run_id,
        "label": args.label,
        "input_digest": args.input_digest,
        "started_at": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        "worker_argv": argv,
        "result_path": result_path,
        "sweep_enabled": not args.no_sweep,
        "supervision": conf,
    }
    if windows_posix_shell:
        meta["windows_posix_shell"] = windows_posix_shell
    try:
        create_exclusive(
            os.path.join(job_dir, "meta.json"),
            (json.dumps(meta, indent=2) + "\n").encode(),
        )
    except OSError as exc:
        raise RunnerError(f"cannot write job metadata for {job_id}: {exc}")

    if problem is not None:
        raise RunnerError(
            f"preflight failed for job {job_id}: worker {argv0!r} {problem}; "
            f"nothing was detached (job left never-started at {job_dir})"
        )
    try:
        create_exclusive(os.path.join(job_dir, "out.log"))
    except OSError as exc:
        raise RunnerError(
            f"preflight failed for job {job_id}: job dir not writable ({exc}); "
            "nothing was detached"
        )

    if not detach_supervisor(job_dir, argv, result_path, conf):
        raise RunnerError(
            f"detach failed for job {job_id}: supervisor did not acknowledge; "
            f"inspect {job_dir}"
        )
    print(job_id)
    return 0


def _emit_states(rows, as_json: bool) -> None:
    if as_json:
        print(json.dumps(
            [{"ref": r, "job_dir": d, "state": s} for r, d, s in rows]
        ))
    elif len(rows) == 1:
        print(rows[0][2])
    else:
        for ref, _, state in rows:
            print(f"{ref}\t{state}")


def cmd_status(args) -> int:
    rows = []
    for ref in args.jobs:
        job_dir = resolve_job_dir(ref, args.skill)
        rows.append((ref, job_dir, job_state(job_dir)))
    _emit_states(rows, args.json)
    return 0


def cmd_wait(args) -> int:
    dirs = [(ref, resolve_job_dir(ref, args.skill)) for ref in args.jobs]
    deadline = time.monotonic() + max(0.0, args.max_secs)
    rows = [(ref, d, "running") for ref, d in dirs]
    while True:
        # Settled states are final; only still-running jobs get re-read.
        rows = [
            (ref, d, state if state != "running" else job_state(d))
            for ref, d, state in rows
        ]
        if all(state != "running" for _, _, state in rows):
            break
        remaining = deadline - time.monotonic()
        if remaining <= 0:
            break
        time.sleep(min(1.0, remaining))
    _emit_states(rows, args.json)
    return 0


def _emit_bytes(data: bytes) -> None:
    buffer = getattr(sys.stdout, "buffer", None)
    if buffer is not None:
        buffer.write(data)
        buffer.flush()
    else:
        sys.stdout.write(data.decode("utf-8", "replace"))


def _report_absent_artifact(target: str, args) -> int:
    """An absent --path artifact is an outcome, not a read error: a peer that
    skipped its gate exits 0 and writes nothing, so the file is legitimately
    missing on the most common fold-in path. Name that outcome, and when the
    caller also passed the job id, name the job's state -- otherwise "still
    running" and "ran, produced nothing" arrive as one errno the caller cannot
    act on. Each outcome keeps the exit code the job-result contract already
    assigns it, so a trust or lookup failure never reads as the routine skip:
    2 running, 4 ownership, 1 unknown job, 3 settled with no artifact."""
    sys.stderr.write(f"peer-job-runner: no artifact at {target}\n")
    if not args.job:
        return 3
    try:
        job_dir = resolve_job_dir(args.job, args.skill)
    except RunnerError as exc:
        sys.stderr.write(f"peer-job-runner: {exc}\n")
        return 1
    state = job_state(job_dir)
    if state == "unreadable":
        # Do not read `reason` here: job_dir already failed its owner check, and
        # O_NOFOLLOW guards only the final component, so a swapped directory
        # could redirect that read.
        sys.stderr.write(
            f"peer-job-runner: job state unreadable (ownership or corruption): {job_dir}\n"
        )
        return 4
    if state == "running":
        sys.stderr.write(f"peer-job-runner: job {args.job} is still running\n")
        return 2
    reason = job_reason(job_dir)
    sys.stderr.write(
        f"peer-job-runner: job {args.job}: {state}" + (f" ({reason})" if reason else "") + "\n"
    )
    return 3


def cmd_result(args) -> int:
    if not getattr(args, "path", None) and not args.job:
        sys.stderr.write("peer-job-runner: result needs a job id or --path FILE\n")
        return 2
    if getattr(args, "path", None):
        # Verified read of an arbitrary artifact: same fd-ownership check and
        # bounded read as job results. Exists because fold-in filenames can embed
        # values unknown at start time (so no --result-path was declared), yet the
        # consumer must never read a predictable /tmp path unchecked.
        target = os.path.abspath(args.path)
        try:
            data = read_owned(target, cfg()["result_max"])
        except Unreadable as exc:
            sys.stderr.write(f"peer-job-runner: unreadable: {exc}\n")
            return 4
        except FileNotFoundError:
            return _report_absent_artifact(target, args)
        except OSError as exc:
            # Only a genuine ENOENT is "the peer produced nothing". Every other
            # read failure means the path is there but was refused -- a planted
            # symlink rejected by O_NOFOLLOW is the case this guard exists for --
            # so it takes the trust-failure code, never the routine one.
            sys.stderr.write(f"peer-job-runner: refused to read {target}: {exc}\n")
            return 4
        _emit_bytes(data)
        return 0
    job_dir = resolve_job_dir(args.job, args.skill)
    state = job_state(job_dir)
    if state == "unreadable":
        sys.stderr.write(
            f"peer-job-runner: job state unreadable (ownership or corruption): {job_dir}\n"
        )
        return 4
    if state == "running":
        sys.stderr.write("peer-job-runner: running\n")
        return 2
    if state != "done":
        sys.stderr.write(f"peer-job-runner: {state}\n")
        return 3
    conf = cfg()
    try:
        meta = json.loads(read_owned(os.path.join(job_dir, "meta.json"), META_READ_CAP))
    except Unreadable as exc:
        sys.stderr.write(f"peer-job-runner: unreadable: {exc}\n")
        return 4
    except (OSError, ValueError) as exc:
        sys.stderr.write(f"peer-job-runner: cannot read job metadata: {exc}\n")
        return 4
    result_path = meta.get("result_path") if isinstance(meta, dict) else None
    if not result_path:
        sys.stderr.write("peer-job-runner: job declared no result path; nothing to emit\n")
        return 0
    try:
        data = read_owned(result_path, conf["result_max"])
    except Unreadable as exc:
        sys.stderr.write(f"peer-job-runner: unreadable: {exc}\n")
        return 4
    except OSError as exc:
        sys.stderr.write(f"peer-job-runner: result missing or unreadable: {exc}\n")
        return 3
    _emit_bytes(data)
    return 0


def cmd_reap(args) -> int:
    job_dir = resolve_job_dir(args.job, args.skill)
    state = job_state(job_dir)
    if state in TERMINAL_STATES or state == "never-started":
        return 0
    if state == "unreadable":
        sys.stderr.write(
            f"peer-job-runner: job state unreadable (ownership or corruption): {job_dir}\n"
        )
        return 4
    conf = cfg()
    pid_doc = None
    try:
        pid_doc = json.loads(read_owned(os.path.join(job_dir, "pid"), META_READ_CAP))
    except (Unreadable, OSError, ValueError):
        pid_doc = None
    if not isinstance(pid_doc, dict):
        pid_doc = {}
    sup_pid = pid_doc.get("supervisor_pid")
    sup_pgid = pid_doc.get("supervisor_pgid")
    worker_pid = pid_doc.get("worker_pid")
    # Windows-only: the worker tree's job object. Named precisely so this
    # process -- which never held the supervisor's handle -- can reopen and
    # terminate the tree even after the worker leader has exited.
    job_name = pid_doc.get("job_name")
    worker_identity = pid_doc.get("worker_identity")
    supervisor_identity = pid_doc.get("supervisor_identity")

    supervisor_ours = (
        isinstance(sup_pid, int)
        and not (IS_WINDOWS and sup_pid == os.getpid())
        and _pid_alive(sup_pid)
        and (
            not IS_WINDOWS
            or _win_process_identity_matches(sup_pid, supervisor_identity)
        )
    )
    if supervisor_ours:
        # The supervisor owns TERM-grace-KILL and the terminal classification.
        # POSIX signals it (SIGTERM to the group or pid); Windows drops the
        # `.reap` marker the supervisor's loop polls for.
        if IS_WINDOWS:
            try:
                with open(os.path.join(job_dir, ".reap"), "w") as f:
                    f.write("reap\n")
                signaled = True
            except OSError:
                signaled = False
        else:
            signaled = (isinstance(sup_pgid, int) and _killpg_quiet(sup_pgid, signal.SIGTERM)) \
                or _kill_quiet(sup_pid, signal.SIGTERM)
        if signaled:
            # kill -0 is true for a zombie, so confirm the classification landed
            # rather than trusting the signal; fall through to self-cleanup if not.
            # Windows: the supervisor only notices `.reap` on its next poll tick
            # (default 2s), so min(grace, 1.0) alone is shorter than one poll and
            # races into the fallback self-classify path.
            wait_budget = min(conf["grace"], 1.0)
            if IS_WINDOWS:
                wait_budget = max(wait_budget, conf["poll"] + 0.25)
            deadline = time.monotonic() + wait_budget
            while time.monotonic() < deadline:
                if job_state(job_dir) in TERMINAL_STATES:
                    return 0
                time.sleep(0.05)

    # Supervisor gone: perform the tree kill and classification ourselves,
    # with a short grace so reap still returns quickly. Sweep whenever we have a
    # worker pid, NOT only when its leader is still alive: a child can survive in
    # the worker's process group after the leader exits, and kill_tree targets
    # the pgid precisely so that orphan is swept instead of leaked. Guarding this
    # on _pid_alive would re-defeat kill_tree's dead-leader-safe path. kill_tree
    # returns whether the leader was alive, which is the reap classification.
    worker_leader_alive = False
    if isinstance(worker_pid, int):
        worker_leader_alive = kill_tree(
            worker_pid, min(conf["grace"], 1.0), job_name, worker_identity)
    # A worker can publish its declared result and exit before this fallback runs
    # (e.g. the supervisor died mid-run, then the worker completed cleanly). Honor
    # that result instead of discarding it as died-without-result: read the
    # declared result_path and classify from the artifact, mirroring
    # classify_exit. Only with no usable result do we fall back to timeout (leader
    # was alive) / died-without-result (leader gone).
    result_path = None
    try:
        meta = json.loads(read_owned(os.path.join(job_dir, "meta.json"), META_READ_CAP))
        result_path = meta.get("result_path") if isinstance(meta, dict) else None
    except (Unreadable, OSError, ValueError):
        result_path = None
    result_size = None
    if result_path:
        try:
            st = os.lstat(result_path)
            if stat.S_ISREG(st.st_mode) and st.st_size > 0:
                result_size = st.st_size
        except OSError:
            pass
    if result_size is not None and result_size > conf["result_max"]:
        word, reason = "failed", (
            f"result exceeded byte cap ({result_size} > {conf['result_max']} bytes)"
        )
    elif result_size is not None:
        word, reason = "done", "worker published its result before reap (supervisor was gone)"
    elif worker_leader_alive:
        word, reason = "timeout", (
            "reaped by request; supervisor was gone, worker tree killed by reap"
        )
    else:
        word, reason = "died-without-result", (
            "supervisor and worker both gone without a terminal record"
        )
    write_terminal(job_dir, word, reason, overwrite=False)
    return 0


# --- CLI -----------------------------------------------------------------------

def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="peer-job-runner.py",
        description=(
            "Detached, supervised job lifecycle for delegated peer work: "
            "no call here ever spans the worker's runtime."
        ),
        epilog=EXIT_CODES_DOC,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    sub = parser.add_subparsers(dest="cmd", required=True)

    p_start = sub.add_parser(
        "start",
        help="claim a job, preflight, detach the worker, print the job id",
    )
    p_start.add_argument("--skill", required=True)
    p_start.add_argument("--run-id", required=True, dest="run_id")
    p_start.add_argument("--label", default=None)
    p_start.add_argument("--input-digest", default=None, dest="input_digest")
    p_start.add_argument(
        "--result-path", default=None, dest="result_path",
        help="worker's expected result file; done then requires it non-empty",
    )
    p_start.add_argument(
        "--no-sweep", action="store_true",
        help="retain old sibling run roots (ce-work durable recovery)",
    )

    p_status = sub.add_parser("status", help="print each job's state word")
    p_status.add_argument("--skill", default=None, help="limit job-id lookup to this skill")
    p_status.add_argument("--json", action="store_true")
    p_status.add_argument("jobs", nargs="+", help="job ids or job dir paths")

    p_wait = sub.add_parser(
        "wait", help="bounded poll until all watched jobs settle (or the cap)"
    )
    p_wait.add_argument("--skill", default=None, help="limit job-id lookup to this skill")
    p_wait.add_argument("--max-secs", type=float, default=30.0, dest="max_secs")
    p_wait.add_argument("--json", action="store_true")
    p_wait.add_argument("jobs", nargs="+", help="job ids or job dir paths")

    p_result = sub.add_parser(
        "result",
        help="emit a done job's artifact (exit: 0 done, 2 running, 3 other, 4 unreadable)",
    )
    p_result.add_argument("--skill", default=None, help="limit job-id lookup to this skill")
    p_result.add_argument("job", nargs="?", default=None)
    p_result.add_argument(
        "--path",
        default=None,
        help=(
            "ownership-checked bounded read of this file instead of a job's "
            "declared result; pass the job id too so an absent file reports "
            "that job's state"
        ),
    )

    p_reap = sub.add_parser(
        "reap", help="terminate a running job now; no-op if already terminal"
    )
    p_reap.add_argument("--skill", default=None, help="limit job-id lookup to this skill")
    p_reap.add_argument("job")
    return parser


def main(argv) -> int:
    # Internal Windows detach re-invocation (not a user-facing subcommand): the
    # detached supervisor process runs `__supervise <job_dir>`. Gated on
    # IS_WINDOWS so POSIX keeps its previous behavior exactly (argparse usage
    # error), and so a non-win32 Python without geteuid -- where the ownership
    # checks degrade -- can never be steered into exec'ing argv from a planted
    # .spawn.json. Only the Windows detach path ever emits this argv.
    if IS_WINDOWS and argv and argv[0] == "__supervise":
        if len(argv) < 2:
            return 2
        return _win_supervise_from_spec(argv[1])
    worker_argv = []
    if "--" in argv:
        split = argv.index("--")
        argv, worker_argv = argv[:split], argv[split + 1:]
    args = build_parser().parse_args(argv)
    try:
        if args.cmd == "start":
            return cmd_start(args, worker_argv)
        if args.cmd == "status":
            return cmd_status(args)
        if args.cmd == "wait":
            return cmd_wait(args)
        if args.cmd == "result":
            return cmd_result(args)
        if args.cmd == "reap":
            return cmd_reap(args)
        return 2
    except RunnerError as exc:
        sys.stderr.write(f"peer-job-runner: {exc}\n")
        return 1
    except Unreadable as exc:
        sys.stderr.write(f"peer-job-runner: unreadable: {exc}\n")
        return 4


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))

SHA-256: aac862a60af97eb4b9da6c90a1c688d27618ccb830ea5b1ee816b2ae653bfb0a