from pathlib import Path
import os
os.chdir(r"C:\Users\decid\Documents\projects\spt-core\.worktrees\ws272-w0")
p = Path(".github/ci/ws272-w0.py")
s = p.read_bytes().decode("utf-8")
assert s.count("\r\n") > 200
s = s.replace("\r\n", "\n")

def swap(old, new, count=1):
    global s
    assert s.count(old) == count, (old[:50], s.count(old))
    s = s.replace(old, new)

# 1. doc-comment: the lock guards the POOL at the worktree level
swap('''The output dir is claimed like a pool (a held lock file inside it): a second
driver aimed at the same dir is REFUSED with OUTPUT_DIR_HELD naming the holder.
Mechanism this guards (W0, 2026-09-06): stopping a LOCAL ssh does not stop its
remote `bash -lc` (no tty, no SIGHUP) — an orphan chain re-ran this driver into
the same dir and pool beside the intended one, two suites interleaved one
nextest.raw (two Summary lines), and the gater voided the window. Two writers
to one evidence dir is never evidence.
"""''',
'''SAME-LANE POOL SERIALIZATION IS THE INVARIANT: one driver at a time per
worktree, whatever its output dir. Every --run holds the lane lock
<worktree>/.spt/driver.lock (beside the target/ pool it guards) for its whole
life; a second driver in the same worktree is REFUSED with POOL_HELD naming the
holder pid. An output-dir lock would not do: two drivers with different output
dirs still share the worktree, target/ and the default docs port, which is the
shape that bit. Mechanism this guards (W0, 2026-09-06): stopping a LOCAL ssh
does not stop its remote `bash -lc` (no tty, no SIGHUP) — an orphan chain
re-ran this driver beside the intended one, two suites interleaved one
nextest.raw (two Summary lines), and the gater voided the window.
"""''')

# 2. the claim: worktree-level
swap('''def claim_output(output):
    """Hold an exclusive lock on <output>/.driver.lock for this process's life.

    Returns the open handle (keep it alive) or None when another live driver
    holds it; the refusal names the holder pid recorded inside the lock file.
    A dead holder releases the OS lock with its process, so no stale-lock
    sweeping is needed — the lock, not the file's existence, is the claim.
    """
    path = output / ".driver.lock"
    handle = open(path, "a+", encoding="utf-8")''',
'''def claim_pool(root):
    """Hold the lane lock <root>/.spt/driver.lock for this process's life.

    Returns the open handle (keep it alive) or None when another live driver
    holds it; the refusal names the holder pid recorded inside the lock file.
    A dead holder releases the OS lock with its process, so no stale-lock
    sweeping is needed — the lock, not the file's existence, is the claim.
    """
    path = Path(root) / ".spt" / "driver.lock"
    path.parent.mkdir(parents=True, exist_ok=True)
    handle = open(path, "a+", encoding="utf-8")''')
swap('''        print(f"OUTPUT_DIR_HELD: {output} is driven by pid {holder}; refusing a second writer", flush=True)
        return None''',
'''        print(f"POOL_HELD: {root} is driven by pid {holder}; same-lane pool "
              "serialization is the invariant — refusing a second driver", flush=True)
        return None''')

# 3. CLI: --probe-lock DIR (the self-test's second writer, and a hand check)
swap('''    modes.add_argument("--run", action="store_true")''',
'''    modes.add_argument("--run", action="store_true")
    modes.add_argument("--probe-lock", metavar="WORKTREE",
                       help="take and release the lane lock once; exit 4 with POOL_HELD if held")''')
swap('''    if args.preflight_only:
        return 0 if preflight() else 2''',
'''    if args.preflight_only:
        return 0 if preflight() else 2
    if args.probe_lock:
        probe = claim_pool(Path(args.probe_lock))
        if probe is None:
            return 4
        probe.close()
        return 0''')
swap('''    root = Path(__file__).resolve().parents[2]
    output = args.output.resolve() if args.output else root / ".spt" / "ws272-w0-gate"
    output.mkdir(parents=True, exist_ok=True)
    lock = claim_output(output)
    if lock is None:
        return 4''',
'''    root = Path(__file__).resolve().parents[2]
    lane_lock = claim_pool(root)  # held until this process exits
    if lane_lock is None:
        return 4
    output = args.output.resolve() if args.output else root / ".spt" / "ws272-w0-gate"
    output.mkdir(parents=True, exist_ok=True)''')

# 4. self-test: second writer via --probe-lock, then free after release
start = s.index("    import tempfile\n    with tempfile.TemporaryDirectory() as tmp:")
end = s.index('        print("PASS output-dir claim: second writer refused while the first lives")\n') + len('        print("PASS output-dir claim: second writer refused while the first lives")\n')
s = s[:start] + '''    import tempfile
    with tempfile.TemporaryDirectory() as tmp:
        first = claim_pool(Path(tmp))
        if first is None:
            raise AssertionError("lane lock: first claim refused")
        probe = [sys.executable, str(Path(__file__).resolve()), "--probe-lock", tmp]
        held = subprocess.run(probe, capture_output=True, text=True)
        if held.returncode != 4 or "POOL_HELD" not in held.stdout:
            raise AssertionError(f"lane lock: second driver not refused: rc={held.returncode} "
                                 f"out={held.stdout!r} err={held.stderr!r}")
        first.close()
        freed = subprocess.run(probe, capture_output=True, text=True)
        if freed.returncode != 0:
            raise AssertionError(f"lane lock: not released with its holder: rc={freed.returncode} err={freed.stderr!r}")
        print("PASS lane lock: second driver refused while the holder lives, free once it exits")
''' + s[end:]

p.write_bytes(s.replace("\n", "\r\n").encode("utf-8"))
print("driver lock reworked to worktree level")
