SYS.12 / SNAPSHOTS
Snapshots and change
A snapshot is a frozen reading. A change set is what two of them disagree about — and the honest word for what it could not compare.
Where a snapshot came from
Five origins, and only some of them are reproducible.
| Origin | Reproducible? |
|---|---|
| A git commit | yes — the commit identifies the tree |
| A git working tree | no — one developer’s uncommitted state at one moment |
| A GitHub commit | yes |
| An uploaded archive | only as the archive that was uploaded |
| Unknown | the honest answer when nothing established it |
The distinction is kept because a claim about a commit can be checked by anybody with the repository, and a claim about somebody’s working tree cannot be checked by anyone, ever.
The content root hash
Two snapshots with the same root hold the same files with the same contents.
It is derived on the server from the inventory the worker actually ingested — never supplied by a client. Ordering is by code unit rather than locale, because locale ordering varies with the platform and an unreproducible hash reads exactly like data corruption.
Paths are normalised for comparison and stored exactly as ingested — an archive made on one operating system spells an accented filename differently from the way a git host spells it, and comparing the raw strings would report one deletion and one addition for every accented file, on every capture. Case is not folded: two files differing only in case are two files.
The change set
Four statuses, six kinds, and one claim nothing may make without evidence.
| Status | Meaning |
|---|---|
| BASELINE | No comparable base exists. Not a failure |
| COMPLETE | Every file on both sides was accounted for |
| PARTIAL | Some files could not be compared — the counts are a floor |
| UNAVAILABLE | No comparison was possible, with the reason stated |
Kinds are ADDED, MODIFIED, DELETED, RENAMED, UNKNOWN_SECRET and UNKNOWN. A missing row means unchanged — and that is the claim nothing may make without evidence, because a wrongly-unchanged file is invisible and every later step that trusts the set will skip work on it.
What rename detection refuses
Two visible rows beat one invisible mistake.
A rename needs exactly one deleted path and one added path sharing a non-secret content hash. Anything else is left as an addition plus a deletion:
- The hash is shared by more than one file on either side — two empty files moving is the everyday case.
- Either side has no hash, which includes every secret file by design.
- The two paths differ only in case. On a case-insensitive checkout the file was renamed and the archiver spelled it differently are indistinguishable.
Which snapshot it compares against
The immediately preceding ready snapshot in the same lineage. Never simply the newest.
It refuses, with a reason, when the previous snapshot has no files — ingestion never finished, and comparing against it would report every file as added — when the source lineage changed, because an archive and a repository are unrelated trees, and when the recorded manifest algorithm differs.
It deliberately does not walk further back to find an older comparable snapshot. A diff spanning two captures rendered as one is a correct-looking wrong answer, and "changed since snapshot 3" reads exactly like "changed since snapshot 4".