d = r'C:/Users/decid/AppData/Local/Temp/claude/C--Users-decid-Documents-projects-spt-core/29212dec-e8e9-45d8-865e-c24e5432a269/scratchpad/'
s = open(d + 'mutate3.py', 'rb').read().decode('utf-8')
nl = '\r\n' if '\r\n' in s else '\n'
JT = "crates/spt-store/src/jsonltail.rs"
add = r'''    ("2c-1 line count from a second read", TW,
     b"    if raw_lines != records.len() {\r\n        let _ = crate::jsonltail::rewrite_at(&file, &records);",
     b"    let raw_lines = std::fs::read_to_string(&file).map(|s| s.lines().filter(|l| !l.trim().is_empty()).count()).unwrap_or(0);\r\n    if raw_lines != records.len() {\r\n        let _ = crate::jsonltail::rewrite_at(&file, &records);",
     "-p spt-store --lib", "a_concurrent_append_after_the_read_survives"),
    ("2c-2 a failed rewrite returns before the append", TW,
     b"        let _ = crate::jsonltail::rewrite_at(&file, &records);",
     b"        crate::jsonltail::rewrite_at(&file, &records)?;",
     "-p spt-store --lib", "a_failed_rewrite_still_records_the_warning"),
    ("2c-3 reader stops at the first non-UTF-8 line", JT,
     b"    let rows = raw_lines(&bytes)\r\n",
     b"    let rows = raw_lines(&bytes)\r\n        .take_while(|l| std::str::from_utf8(l).is_ok())\r\n",
     "-p spt-store --lib", "a_torn_non_utf8_line_costs_only_itself"),
    ("2c-4 out-of-shape session kept raw", TW,
     b"receipt_session.filter(|s| is_session_id_shape(s)).map(str::to_string),",
     b"receipt_session.map(str::to_string),",
     "-p spt-store --lib", "an_out_of_shape_session_records_as_unbound"),
]
'''.replace('\n', nl)
marker = ']' + nl + 'env ='
assert s.count(marker) == 1, s.count(marker)
s = s.replace(marker, add + 'env =', 1)
s = s.replace("WAN = 'crates/spt-daemon/src/wan.rs'", "WAN = 'crates/spt-daemon/src/wan.rs'" + nl + "JT = 'crates/spt-store/src/jsonltail.rs'", 1)
open(d + 'mutate4.py', 'wb').write(s.encode('utf-8'))
import ast; ast.parse(s)
print('mutate4 ok', s.count('("'))
