import io, sys
root = sys.argv[1]
CR = bytes([13]); LF = bytes([10]); CRLF = CR + LF; APOS = bytes([39])
def edit(path, old, new):
    p = root + '/' + path
    raw = io.open(p, 'rb').read()
    crlf = CRLF in raw
    d = raw.replace(CRLF, LF) if crlf else raw
    n = d.count(old)
    assert n == 1, f'{path}: anchor count {n}'
    out = d.replace(old, new, 1)
    if crlf:
        out = out.replace(LF, CRLF)
    io.open(p, 'wb').write(out)
    print(f'{path}: 1 replacement, working copy CRLF={crlf} preserved')
old_title = b'title = "Every Brain reply-wait loop shares one deadline computed after its send and before its loop; unrelated frames cannot renew the call budget. The unbounded read_event convenience API is removed and all callers use read_event_until with an explicit deadline. Whole carriers retain their existing None budget. STREAM LOOPS (serve_*_feed, the attach serve loop) are not reply-waits and never take a per-call budget: their deadline is an explicit None, and any future silence bound on them is per read, never per call."'
new_title = b'title = "Every ordinary Brain RPC reply-wait loop shares ONE fixed deadline computed after its send and before its loop; unrelated frames cannot renew the call budget. WAN stream reply-waits (crates/spt-daemon/src/wan.rs, six sites) are a SEPARATE contract, REQ-WAN-REPLY-BOUND: a progress policy whose budget is renewed only by data on the matching stream, so unrelated frames renew neither kind of wait. The unbounded read_event convenience API is removed and all callers use read_event_until with an explicit deadline. Whole carriers retain their existing None budget. STREAM LOOPS (serve_*_feed, the attach serve loop) are not reply-waits and never take a per-call budget: their deadline is an explicit None, and any future silence bound on them is per read, never per call. The six WAN reply-waits are excluded from the static fixed-deadline audit by record; their renewal behaviour is not certified by that audit."'
edit('traceable-reqs.toml', old_title, new_title)
old_kh = LF.join([
    b'`xtask check` also includes it. Predicate tests use synthetic Rust text, while',
    b'runtime recovery remains covered by separate pump-deadline integration cells.',
    b'',
])
add_kh = LF.join([
    b'The six WAN stream reply-waits in `wan.rs` follow `REQ-WAN-REPLY-BOUND` (a budget',
    b'renewed only by data on the matching stream) and are EXCLUDED from the audit' + APOS + b's',
    b'fixed-deadline policy controls by record: a tokenizer cannot prove that a guarded',
    b're-arm is the only renewal, and a false assurance is worse than a named exclusion.',
    b'The exclusion does not imply the renewal behaviour is tested (register follow-up).',
    b'',
])
edit('docs/KNOWN-HAZARDS.md', old_kh, old_kh + add_kh)
