I have a parent and child table as following:
create table parent
(
  identifier serial primary key,
  name text
);
create table ch         
        
As you noticed correctly, you cannot see rows modified in the CTE in the main SELECT. This is documented:
The sub-statements in
WITHare executed concurrently with each other and with the main query. Therefore, when using data-modifying statements inWITH, the order in which the specified updates actually happen is unpredictable. All the statements are executed with the same snapshot (see Chapter 13), so they cannot “see” one another's effects on the target tables. This alleviates the effects of the unpredictability of the actual order of row updates, and means thatRETURNINGdata is the only way to communicate changes between differentWITHsub-statements and the main query.
So you should use RETURNING.
I guess the simplest way would be not to use a function, but to perform json_build_object in the main query and have it operate on the CTEs parents and children.