@@ -278,7 +278,10 @@ final class LiveTailViewModel {
278278 let toIndex = columnOrder.firstIndex(of: targetColumn),
279279 fromIndex != toIndex else { return }
280280 let item = columnOrder.remove(at: fromIndex)
281− columnOrder.insert(item, at: toIndex)
281+ // Removing an element before the target shifts the target down by one, so
282+ // inserting at the original `toIndex` would land the column past its target.
283+ let adjusted = fromIndex < toIndex ? toIndex - 1 : toIndex
284+ columnOrder.insert(item, at: adjusted)
282285 saveColumnConfig()
283286 }
284287
@@ -569,7 +572,11 @@ final class LiveTailViewModel {
569572 case .int(let i):
570573 hashNumberBits(Double(i).bitPattern, h0: &h0, h1: &h1)
571574 case .double(let d):
572− hashNumberBits((d.isNaN ? Double.nan : d).bitPattern, h0: &h0, h1: &h1)
575+ // Canonicalize NaN (so all NaNs fold together) AND signed zero: JSONValue
576+ // equality treats `-0.0 == 0.0`, but their raw bit patterns differ, which
577+ // would otherwise let an identical record slip past dedup as a phantom row.
578+ let canonical: Double = d.isNaN ? .nan : (d == 0 ? 0.0 : d)
579+ hashNumberBits(canonical.bitPattern, h0: &h0, h1: &h1)
573580 case .string(let s):
574581 h0 = (h0 ^ 0x04) &* 1099511628211
575582 h1 = (h1 ^ 0x04) &* 6700417
@@ -632,14 +639,16 @@ final class LiveTailViewModel {
632639 }
633640
634641 if parts.isEmpty {
642+ // Filter to scalars BEFORE taking the prefix — otherwise three leading
643+ // non-scalar fields (alphabetically) would yield an empty summary even
644+ // when scalar fields exist later in the record.
635645 let scalarFields = record
636646 .filter { $0.key != "p_timestamp" && $0.key != "p_tags" && $0.key != "p_metadata" }
647+ .filter { $0.value.isScalar }
637648 .sorted { $0.key < $1.key }
638649 .prefix(3)
639650 for (key, value) in scalarFields {
640− if value.isScalar {
641− parts.append("\(key)=\(value.displayString)")
642− }
651+ parts.append("\(key)=\(value.displayString)")
643652 }
644653 }
645654