Watch
1
0
Fork
You've already forked RedFlag
0

fix: clear selected_version on transition to installed

A version pinned at approval (selected_version) survived the install,
so the next scan compared against the stale pin and plain Approve became
a no-op after the first install. Clear the pin and its metadata source
marker inside the transition tx once the package reaches installed;
subsequent scans track latest available again.
This commit is contained in:
Fimeg 2026-06-11 04:20:20 -04:00
commit 0abff08a9d

View file

@ -597,6 +597,14 @@ func (q *UpdateQueries) transitionStatus(tx *sqlx.Tx, sel statusSelector, to mod
cur.PackageType, cur.PackageName, err)
// Non-fatal: transition already committed, clearance is best-effort.
}
// Clear selected_version so subsequent scans use the latest available,
// not the stale pinned version. Without this, the package stays pinned
// until manual intervention.
if err := clearTargetVersionTx(tx, cur.ID); err != nil {
log.Printf("[WARNING] [server] [updates] clear_target_version_failed pkg=%s/%s error=%v",
cur.PackageType, cur.PackageName, err)
// Non-fatal: transition already committed, clearance is best-effort.
}
}
}
return cur, nil
@ -2010,6 +2018,17 @@ func (q *UpdateQueries) ClearTargetVersion(id uuid.UUID) error {
return err
}
// clearTargetVersionTx is the transactional variant used during status transitions.
func clearTargetVersionTx(tx *sqlx.Tx, id uuid.UUID) error {
_, err := tx.Exec(`
UPDATE current_package_state
SET selected_version = NULL,
metadata = COALESCE(metadata, '{}'::jsonb) - 'selected_version_source',
last_updated_at = NOW()
WHERE id = $1`, id)
return err
}
// NonRestingRow is a minimal projection of current_package_state used by the
// scan-set reconciler (RECONCILE-001). Only the fields needed for set-diff and
// state-machine closure are selected; the full UpdateState columns are not needed.