Files
pulse/docs/release-control
rcourtman a4bfca4d32 Serialize Patrol action projection and finalize hung runs
Three gaps remained in how Pulse projects a Patrol investigation's
action and closes its runs.

Projections of one investigation could interleave: the transition
callback, an investigation read and a run's close each read the action
audit and applied it, so one that read an older state could land after
one that read a newer state, and an approval could land between a
run's reconciliation and its finalization. All of them now read and
apply under the investigation's lock, and a close finalizes before it
releases it.

The projection replaced the whole session through Update, so it could
undo run progress the orchestrator saved in between. It now writes
only the changed action and outcome when the store offers SetAction
(aicontracts.InvestigationActionStore), and the reference it writes
carries the broker's canonical result and verification status and the
model's causal attribution, which the audit does not hold.

A run that hung past its limit without closing was recovered by the
stuck-run sweep but never finalized. The sweep now finalizes it with a
copy of its session marked failed, leaving the orchestrator's session
as it is. A later real close is finalized instead, and a refresh no
longer reopens a record that finalization closed.
2026-10-23 22:26:09 +01:00
..