What healing does
On every conversation read, two functions run: _heal_incomplete_turns and _cleanup_dangling_parent_ids.
Reconstruction
Walk the JSONL, find any user message with no completed assistant child, accumulate the streaming deltas (keyed by pippa.user_msg_id), write a synthesized assistant row to SQLite. Timestamp it at user.created_at + 1µs, not at heal-time — so ORDER BY created_at produces the natural chain.
Normalization
Cleanup any parent_id that doesn't reference an existing message, re-parent it to the previous message in created_at order. This kills the ghost-branch mechanism at its root — removing the dangling references entirely so no future placeholder can match against them.
Why on every read
Healing runs idempotently on every GET. There's no separate 'repair' button anymore. The cost is low (it's reading the JSONL anyway), and it means corrupted state from any past version of any client can never reach the screen.