Docs: guides in the indexes, the stalest-kind rule, and the changelog
Some checks failed
CI / backend (push) Has been cancelled
CI / naming (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / migrations-mysql (push) Has been cancelled

Guides was shipped without an entry in PLUGINS.md or START-HERE, so a site
adopting the product had no way to find out it exists.

BACKUP-KINDS.md described a host's badge as coming from the most recently
confirmed kind. It has not worked that way since the fleet report was reworked:
the freshest revision per (host, kind) is taken, and then the STALEST of those
kinds decides, because reporting the freshest would let a healthy NTLARS backup
mask a part-marker capture that stopped a month ago. Stalest among kinds that
can be JUDGED - a kind never confirmed is unmeasurable, not stale, and treating
it as the worst value made a host with a working backup show no badge at all.

The backups row also still advertised UDC and CMM kinds that do not exist.

api-inventory, openapi.json and PROJECT-MAP regenerated.
This commit is contained in:
cproudlock
2026-08-26 15:06:20 -04:00
parent a9289ee670
commit 90c3c3102b
7 changed files with 971 additions and 4 deletions

View File

@@ -74,7 +74,7 @@ they would have to go and look up.
| Field | Meaning |
|-------|---------|
| `backupkind` | Which kind was most recently confirmed. `null` = no backup at all. |
| `backupkind` | The kind the verdict is about - the STALEST measurable one, not the freshest. `null` = no backup at all. |
| `backuplastseen` | When it was last CONFIRMED still current (ISO). Tooltip only. |
| `backupcollectedat` | When the config was last CAPTURED (ISO). Only moves on a real change. Tooltip only. |
| `backupok` | `true` good, `false` stale, `null` nothing to judge. |
@@ -86,6 +86,32 @@ backup taken 12 Aug 5:20 PM is still current."* - the first date proves the
check is running, the second says what is actually stored. Collapsing them was
what made a healthy machine look neglected.
### A host with several kinds is judged by its WORST one
A marker bay runs both an NTLARS backup and a part-marker backup. Reporting the
freshest of them would let a healthy kind mask a dead one: the part-marker
capture could stop for a month and the host would stay green on the strength of
its NTLARS row. So the row is reduced twice - the freshest revision per
`(host, kind)`, and then the **stalest** of those kinds decides the verdict.
Stalest **among kinds that can be judged**. A kind whose newest revision has
never been confirmed - `lastseenat` NULL, which means a backfilled row or one
written before the column existed - is not stale, it is UNMEASURABLE, and it
must not win the comparison. Treating NULL as the worst value looked right and
was wrong: a host with a healthy NTLARS backup plus one never-confirmed row
showed NO BADGE at all, because the verdict for an unconfirmed kind is `None`.
A working backup rendering as nothing is the one outcome the badge must never
produce. When EVERY kind is unmeasurable the host still reports which kind it
has, with a `null` verdict and no badge.
This is the same rule `staleness.py` applies per chain: a chain becomes
measurable the first time its PC posts, and says nothing until then.
Known consequence: a device retired from a PC leaves its last revision behind,
so that host stays stale until the revision is pruned. That is the honest
failure direction - it complains about a backup that genuinely is not running
any more, rather than going quiet about one.
`backupok` is deliberately **tri-state**. `null` means there is no revision for
that host, or the check is disabled - and it renders as no badge, never green.
"Never seen" must not read as healthy.