v0.109.1: re-apply preserves escrow custody + runtime status (live finding)

The QuotaGB hash change triggered a live re-apply that demoted the
escrowed demo to pending and wiped its runtime status. ApplyOffsiteTarget
now carries over EscrowState (custody tracks the preserved repo password,
not the coords) + status fields; fresh guests still land pending.
Red-proofed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
2026-07-10 00:06:06 +02:00
parent f830325ca3
commit ddac21cd91
3 changed files with 72 additions and 0 deletions
+11
View File
@@ -173,6 +173,17 @@ func (m *Manager) ApplyOffsiteTarget(ctx context.Context, tgt *settings.OffboxTa
if err := m.WriteOffboxSecrets(sshKeyPEM, knownHosts); err != nil {
return fmt.Errorf("apply offsite secrets: %w", err)
}
// Re-apply (v0.109.1 live finding): the bridge rebuilds the target from the descriptor, but the
// EXISTING target's custody + runtime status must carry over — EscrowState tracks the REPO PASSWORD
// (preserved by WriteOffboxSecrets above, never rotated by this path), not the target coords; and the
// status fields belong to the runner. Without this, a quota bump demoted an escrowed demo target to
// pending and wiped its history (which would also false-trigger the hub's staleness alert).
if cur := m.settings.GetOffboxTarget(); cur != nil {
tgt.EscrowState = cur.EscrowState
tgt.LastRun, tgt.LastStatus, tgt.LastError = cur.LastRun, cur.LastStatus, cur.LastError
tgt.LastDuration, tgt.LastWarning = cur.LastDuration, cur.LastWarning
tgt.RepoSizeHuman, tgt.RepoSizeBytes, tgt.SnapshotCount = cur.RepoSizeHuman, cur.RepoSizeBytes, cur.SnapshotCount
}
if tgt.EscrowState != "escrowed" {
tgt.EscrowState = "pending"
}