import io

p = 'crates/spt/src/api/delivery.rs'
s = io.open(p, encoding='utf-8').read()

old = "use spt_store::perch::{self, ParentHint, EDGE_ECHO_SENTINEL, IDLE_SENTINEL};"
new = "use spt_store::perch::{self, ParentHint, EDGE_ECHO_SENTINEL, IDLE_SENTINEL, TURN_ECHO_SENTINEL};"
assert s.count(old) == 1
s = s.replace(old, new)

# ── the idle arm now arms the WORK-DRIVEN sentinel ──
old = '''            stamp_transition(id, true, was_idle);
            if !no_gate {
                let _ = std::fs::write(sentinel_path(id, EDGE_ECHO_SENTINEL), "");
            }'''
new = '''            stamp_transition(id, true, was_idle);
            if !no_gate {
                // The WORK-DRIVEN arm (releases#113 fork 1). This call is the
                // adapter's turn-end report, so it arms the turn sentinel — the
                // one the pulse age-gates — and NEVER the edge sentinel, whose
                // fires are ungated. Writing one file from one writer class is
                // what makes an idle report structurally unable to downgrade an
                // armed attention-change fire into an aged one.
                //
                // The ARMING is unconditional, exactly as before: the published
                // contract is that reporting idle arms the gate, and that stays
                // true. What changed is the FIRE, which now waits for age.
                // [impl->REQ-ECHO-IDLE-AGE-GATE]
                let _ = std::fs::write(sentinel_path(id, TURN_ECHO_SENTINEL), "");
            }'''
assert s.count(old) == 1
s = s.replace(old, new)

io.open(p, 'w', encoding='utf-8', newline='\n').write(s)
print('ok')
