mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-27 05:57:27 +00:00
b329730e6b
A rebuild applies canonical-ID successions to the store, which moves the predecessor's operator row to the successor, before it publishes the registry generation that lists the successor. For the length of the rebuild the previous generation keeps serving the old ID, and the planner, the Patrol broker and both dispatch gates read the row of that ID. The row had gone, so a lock the operator set did not refuse an action planned or dispatched against it. Every kind of succession reaches this window: pin-driven, Proxmox guest eras, and the host and Docker reporter eras. GetResourceOperatorState now follows the recorded successions when an ID holds no row, in both stores, through one walker. It answers as the ID the chain ends on would, with that row's remediation block alone, so a lock the operator lifted on the successor stays lifted, a chain that loops ends, and nothing is written. The SQLite walk is one transaction, because a succession that commits between two of its statements can move the lock onto an ID the walk has already passed. Delaying the move was rejected: later steps of the same rebuild read the store, and plans already issued against the old ID would not be protected. Seven tests that used a missing read to prove a row had moved now read the rows directly. An operator edit to the retired ID inside the window still does not reach the successor; the contract names it as a limit.