backups: a revision chain belongs to a PC, not just a machine

Dedup compared a posted config against the latest revision for the ASSET,
which is only correct when a machine number means one PC. Several PCs share one
here: the part markers on 0613, 0615 and WJPRT are separate devices, differing
by COM port, filed under one machine number. Each marker's post therefore
differed from whichever marker had posted last, nothing ever deduped, and the
table grew by one row per PC per collection cycle.

A chain is now (asset, kind, source hostname). An unchanged config is a no-op
again, and each PC keeps its own history against the machine. NULL sources -
rows written before the column was populated, and hand-loaded ones - form their
own chain via IS NULL; `column == None` never matches in SQL, so without that
those rows would have re-posted forever.

Two consumers assumed the old key and are fixed with it. Retention pruned per
asset, so a busy marker's revisions could evict a quiet marker's only backup;
it now prunes each chain separately, protecting the newest and oldest of each.
The revision diff compared against the previous revision on the machine, which
across two markers reported one device's COM port as a change on the other; it
now compares within the source's own chain.

scripts/collapse_duplicate_backup_revisions.py cleans up what the old rule
wrote. It removes only a revision whose hash repeats the one before it in the
same chain - rows the fixed code would never have written - and keeps every
genuine change, every chain's newest and oldest, and every source. Dry run by
default. Its --report mode explains what grew each chain, which separates a
legitimately shared machine number from two PCs wrongly carrying the same one,
and from a value inside the config that changes on its own.
This commit is contained in:
cproudlock
2026-08-10 15:02:38 -04:00
parent 5108ba8aaa
commit d429c882b4
6 changed files with 376 additions and 16 deletions

View File

@@ -21,6 +21,17 @@ ADR-007 and ADR-002.
number now identifies the machine only. A new PC takes its hostname as its
asset number, which is what the existing data already does, and an existing
PC's asset number is never overwritten.
- Configuration backups piled up duplicate revisions on any machine number
reported by more than one PC. A posted config was compared against the latest
revision for the machine, so where several PCs share a number - the part
markers do, and their configs differ by COM port - each PC's post differed
from whichever PC posted last, nothing deduped, and the table grew by a row
per PC per collection cycle. A backup chain is now per source PC, so an
unchanged config is a no-op again and each PC keeps its own history against
the machine it belongs to. Retention prunes each chain separately, so a busy
PC's revisions can no longer push out a quiet PC's only backup, and the
revision diff compares against the same PC's previous revision rather than
another PC's.
- A backup export containing a value with an empty right-hand side (`Name=`)
failed to parse, and with it the whole file, so that machine could never be
backed up. The form is not strictly legal but occurs in real exports. It is