Captures are produced by
snapshot and iterate — see Capture commands. The commands that read the sets (coverage, multi-coverage, report) are on Coverage commands.The capture layout
Each capture lives under its view’s directory at.sightmap/snapshots/{view}/{stamp}.snap, where {stamp} is a filesystem-safe UTC timestamp in YYYYMMDDTHHMMSSZ form — so lexical order equals chronological order:
.sightmap/snapshots/
{stamp}.snap— the human-readable annotated tree, exactly whatsnapshotprints.{stamp}.snap.tree.json— the raw component tree JSON sibling, written automatically alongside every capture. This is what powers the offline commands (coverage,multi-coverage,sel-check,snapshot-novelty).
A view is a set
Re-snapping never overwrites:snapshot appends to the view’s set, and every set-aware reader operates over the union:
coverageflags a component dead only when it matches 0 of N snaps across the whole set; components present in some captures appear under[Presence]instead.reportrolls each set up to one row — T1/T2 as weighted averages, T3 as the max across captures.multi-coveragefolds each set into one matrix column whose cells are per-component maximums.
The novelty gate
Left unchecked, append-only sets would grow without bound. The novelty gate keeps a capture only when it is structurally new relative to its view’s existing set:- A new component type matched — a component that no existing capture in the set matches, or
- A new orphan slot — an uncovered interactive node identified by its role and nearest stable-attribute ancestor, a deliberately instance-free key.
--force bypasses the gate, and an explicit --out FILE writes exactly there (no set, no gate).
Novelty is corpus-relative: captures are re-matched against the current corpus every time. A capture kept because it had unique orphans stops being novel once you author components covering those orphans — which is exactly what lets snapshot-prune clean up after the fact.
snapshot-novelty
Asks the gate’s question explicitly for a saved capture: does this file add any new component type or orphan slot versus the rest of its view’s set? Use it to understand why a capture was kept, or to check a candidate before committing it.
Flags:
snapshot-prune
The retrospective counterpart to the capture-time gate: re-matches every capture in a view against the current corpus and deletes the ones that are subsumed — removing them does not shrink the union, because their component types and orphan slots all survive in some retained capture. Pruning is conservative: it never chases a minimal cover, never drops a view’s last capture, and collapses two identical captures to one rather than deleting both. Pass a view name, or --all to prune every view with captures.
Flags:
--dry-run to delete the listed captures along with their .snap.tree.json siblings.
migrate-snapshots
Moves legacy flat .snap files (and their .snap.tree.json siblings) from the current directory into the organized per-view structure under .sightmap/snapshots/, where the set-aware commands find them. Each file’s view is inferred from its basename. Run with --dry-run first to see every planned move as an old → new line.
Legacy layouts still parse everywhere in the meantime — coverage, report, and snapshot --all read both forms during a transition — so migration is a one-time tidy-up, not a prerequisite.
Flags:
Typical flow
1
Build the set
Re-snap each view a few times in different configurations — fresh loads, a drawer open, a tab switched. The novelty gate keeps only captures that add a new component type or orphan slot, so just snap freely.
2
Check a candidate when in doubt
Run
sightmap snapshot-novelty FILE.snap to see exactly what a capture adds versus the rest of its set — or why it was skipped.3
Author against the union
Work the coverage loop until every capture is orphan-free. New components retroactively cover the orphan slots that made older captures novel.
4
Prune the redundant captures
Run
sightmap snapshot-prune --dry-run --all, review the plan, then prune. The surviving set’s union is identical — just smaller.