I think the correct fix is to change remove_unused_subquery_outputs() so it also checks the WindowClause runConditions in addition to the rel targetlist and baserestrictinfo.
Yes, concur with that. Yesterday I played around with a similar patch which leverages find_window_functions() to locate all the WindowFunc nodes in runCondition expressions and then check if each WindowFunc target entry of the subquery is contained there.
Maybe a better fix is to add a new Bitmapset field to WindowClause and have find_window_run_conditions() record the attno in that field when it appends the new runCondition to the runCondition field. remove_unused_subquery_outputs() can just bms_add_members that field to attrs_used. This just means having to add a field to WindowClause post-beta. Is that going to be a problem?
This is even better if we can keep the attnos somewhere for the window quals that are pushed down to runConditions. Like Tom proposed, maybe PlannerInfo is a more proper place.