store: при равной полноте точек побеждает пришедшая доставка
- байтовый порядок канонических форм остался тай-брейком только внутри одной доставки: на живом корпусе он решал 98,8% спорных координат и системно хранил меньшее значение, из-за чего step_count терял род и verify:archive был красным - правило перестало быть коммутативным осознанно, поэтому порядок свёртки приведён к журнальному: проход воркера прекращается на отложенной доставке, а свёртка вне порядка журнала пишет WARN - заведены счётчики PointsHeld и PointsErased — удержание полнотой и единственное направление, в котором правило теряет содержание
This commit is contained in:
@@ -98,6 +98,31 @@ func (s *logSink) count(msg string) int {
|
||||
return n
|
||||
}
|
||||
|
||||
// linesOf отдаёт записи с данным msg РАЗОБРАННЫМИ.
|
||||
//
|
||||
// Разобранными, а не строками: проверка «в логе нет значения точки» обязана
|
||||
// смотреть поля записи, а не сырой буфер — служебное поле `time` содержит доли
|
||||
// секунды, и подстрока вроде «5.1» находится в нём примерно в одном проценте
|
||||
// прогонов (docs/review.md, 2026-08-02).
|
||||
func (s *logSink) linesOf(msg string) []map[string]any {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
var out []map[string]any
|
||||
for _, line := range s.lines {
|
||||
if msgOf(line) != msg {
|
||||
continue
|
||||
}
|
||||
var rec map[string]any
|
||||
if err := json.Unmarshal([]byte(line), &rec); err != nil {
|
||||
continue
|
||||
}
|
||||
delete(rec, "time")
|
||||
out = append(out, rec)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *logSink) dump() string {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
Reference in New Issue
Block a user