While I don't have a fix for the root issue, I did have a chance to create a lint for LOGBOOK duplicates, as you suggested.
It can be found here:
https://github.com/jeffkowalski/prelude/commit/f44b6041730469ba2094849b60d301cd94a5bed1#diff-3de035eea502a119bcdd40f4adc3d6108d4f337f827358cb2361623525682042R1199-R1251

Also below:

  (defun jeff/org-logbook-retrieve-timestamps (beg end)
    "Retrieve timestamp of all state-change entries between BEG and END."
    (save-excursion
      (let* ((reversed org-log-states-order-reversed)
             (search (if reversed 're-search-forward 're-search-backward))
             (limit (if reversed end (point)))
             (re (format
                  "^[ \t]*-[ \t]+\\(?:State \"%s\"\s+from\s+\"%s\".*%s%s\\)"
                  org-todo-regexp
                  org-todo-regexp
                  org-ts-regexp-inactive
                  (let ((value (cdr (assq 'done org-log-note-headings))))
                    (if (not value) ""
                      (concat "\\|"
                              (org-replace-escapes
                               (regexp-quote value)
                               `(("%d" . ,org-ts-regexp-inactive)
                                 ("%D" . ,org-ts-regexp)
                                 ("%s" . "\"\\S-+\"")
                                 ("%S" . "\"\\S-+\"")
                                 ("%t" . ,org-ts-regexp-inactive)
                                 ("%T" . ,org-ts-regexp)
                                 ("%u" . ".*?")
                                 ("%U" . ".*?"))))))))
             log-entries)
        (goto-char (if reversed beg end))
        (while (funcall search re limit t)
          (push (match-string-no-properties 3) log-entries))
        log-entries)))

  (defun org-lint-duplicate-logbook-timestamps (ast)
    "Report LOGBOOK entries with duplicate timestamp"
    (org-element-map ast 'drawer
      (lambda (d)
        (when (equal (org-element-property :drawer-name d) "LOGBOOK")
          (let* ((beg (org-element-property :contents-begin d))
                 (end (org-element-property :contents-end d))
                 (orig (jeff/org-logbook-retrieve-timestamps beg end))
                 (uniq (cl-remove-duplicates
                        orig
                        :test (lambda (x y) (or (null y) (equal x y)))
                        :from-end t))
                 (diff (- (length orig) (length uniq))))
            (unless (zerop diff)
              (list (org-element-property :begin d)
                    (format "LOGBOOK has %d entries with duplicate timestamp" diff))))))))

  (add-to-list 'org-lint--checkers
               (make-org-lint-checker
                :name 'duplicate-logbook-timestamps
                :description "Report LOGBOOK entries with duplicate timestamp"
                :categories '(properties)))


On Thu, Jun 17, 2021 at 6:16 AM Gustavo Barros <gusbrs.2016@gmail.com> wrote:
Thanks for confirming and for the habits info.  So that's what was
happening with my consistency graphs.  I had indeed been noticing they
felt "off", but I eventually reverted to 9.4.4 because of the duplicate
entries and forgot about it.  It seems then that this got solved for me
not by the reverting itself but by me removing the duplicate entries in
the LOGBOOK.

Would clocking reports be affected too? (I'm not personally an user of
clocking, so I don't really know).

Perhaps a "lint" for LOGBOOK duplicates would be a good idea alongside
with the fix, so that people could go about fixing their data with a
little more convenience?

Best regards,
Gustavo.