pub(crate) fn task_endings(messages: &[Message]) -> HashMap<String, TaskEnding>Expand description
Every task ending the conversation holds, by the call each names.
Both carriers, because the CLI writes the same notice two ways: an
attachment row the scan hoists into a queued_command block, and a
user row whose content string is the XML.
A pre-pass, and that is the point of it. The ending is frequently not in its call’s turn: the notice row opens a turn of its own, and a delivery, a peer message or a person’s next prompt can sit between the two, so a fold that read them in one pass could only see the endings that happened to follow their call closely. A pre-pass reads the whole conversation once, keyed by call, so the walk reads the answer wherever it needs it.
The last ending naming a call wins, the only rule that reads a repeated ending as the newer word rather than the older. It is load-bearing rather than hypothetical: ten of this machine’s calls carry two notices. Nine of those pairs are the restart case, completed first and stopped second - written once a restart found no completion record - and one runs the other way, so the rule is what decides between them rather than the order the CLI happens to write.