My experience was that this was not the case. Basically the CTE was materialized and the variables were resolved as part of PREPARE, so each invocation got the same values. I couldn't find the blurb I'd read previously but I did a little digging today and it looks like maybe NOT MATERIALIZED would fix the problem?
Fortunately the records are locked, so a second query will pick them up. Still sad tho.
Prepared statements work fine with CTEs.