package host import ( "context" "github.com/carlosframework/platform/internal/hostclaim" execlease "github.com/carlosframework/platform/internal/hostexec" ) // completedRelocationDischarge is claim ask C10's CC9 discharge, rev 4 of // its text with rev 4.2's sentence (region HA rulings 56, 66 and 70; Astra // rounds 3 and 4). It is keyed by the persisted participation binding (the // slot's, or after a restart the .hostexec record's), never by a captured // observation: when the claim now serves on the binding's box, its holder // is still the stopped probe session the serving op records as completed // for exactly the binding's op and incarnation, and root's completed // writer-session receipt for it is in this box's guard journal and // verifies, the session is stopped with root's evidence and the // participation is discharged. Nothing is stopped again. It runs first in // every cleanup path, the slot's close and clearUntracked alike. done // false with no error falls through to main's cleanup unchanged. Any // error, a failed claim read or an unreadable completion record included, // is (true, err), and the caller also stops on any error: the cleanup // fails, nothing is stopped, and the next pass retries (rev 4.2). Region // HA never releases the row's hold or the activator fence before this has // succeeded (ruling 66), so no serving admission can move the holder off // the probe session first. func (a ClaimAssembly) completedRelocationDischarge(ctx context.Context, binding execlease.Binding) (done bool, err error) { if binding.Host == "" || binding.Op == "" || binding.Box == "" { return false, nil } now, err := hostclaim.Read(ctx, a.Claims, binding.Host) if err != nil { // Rev 4.2 (Astra round 4): a failed read never falls through to // ordinary cleanup, whose serving-shaped stop would replace the // completed probe's active fence (BeginFence) and make the first // serving wake's handover refuse for good. The cleanup fails and // is retried on the next pass, with nothing stopped. return true, err } if now.Absent || now.Claim == nil || now.Claim.Holder == nil { return false, nil } h := relocationCompletedHandover{Guard: a.Guard, Box: binding.Box} record, ok, err := h.completedPrior(now) if err != nil { // A completion record that cannot be read is not "no completion" // (absence is never evidence): the same rule as a failed read. return true, err } if !ok || record.Op != binding.Op || now.Claim.Holder.Incarnation != binding.Incarnation { return false, nil } r, err := h.receipt(ctx, now) if err != nil { return true, err } return true, verifyRetirementReceipt(ctx, r) }