v0.275.0: a backup's data and its version travel together (R-696, 07 §6.6, D4 option A); R-695, R-691, R-694
gates / gates (push) Successful in 23s
gates / gates (push) Successful in 23s
The unit's data files are stamped with the versions that wrote them; the capture keeps the definition the data belongs to; a restore never starts data under another version's definition (unit restores refuse a mismatch; the off-site restore writes the snapshot's definition); every tier's time is its data's; the conversion-copy release needs a dump on the new engine. File-browser sync single-flight + no empty kept folder (R-695); the kept view joins the folder's owning group, language switch resyncs (R-691); a restore-generated login is not shown as the password (R-694). Red-proofs in felhom.eu/documentation/audits/version-travel-2026-09-26/. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -234,3 +234,27 @@ func loadMetadataFile(path string) (Metadata, error) {
|
||||
}
|
||||
return LoadProbeMetadata(tmp), nil // R-670
|
||||
}
|
||||
|
||||
// RestoredVersionPosition says where an app stands after a restore brought it back at an older version
|
||||
// (v0.275.0, `07` §6.6, the page's first sentence): behind — its pin is not the catalog's; climbable — a
|
||||
// tested ladder step leads on from its pin, so the automatic leg climbs it (legCandidate refuses an app
|
||||
// older than the ladder, LegSkipOlderThanLadder, and a template with no ladder, LegSkipNoTestRecord).
|
||||
// Digests are ignored on both sides: this is about versions, not about which bytes a tag names today.
|
||||
func (m *Manager) RestoredVersionPosition(name string) (behind, climbable bool) {
|
||||
st, ok := m.GetStack(name)
|
||||
if !ok || st.AppConfig == nil || len(st.AppConfig.PinnedImages) == 0 || len(st.CatalogImages) == 0 {
|
||||
return false, false
|
||||
}
|
||||
strip := func(in map[string]string) map[string]string {
|
||||
out := make(map[string]string, len(in))
|
||||
for k, v := range in {
|
||||
out[k] = StripDigest(v)
|
||||
}
|
||||
return out
|
||||
}
|
||||
if sameRefs(strip(st.AppConfig.PinnedImages), strip(st.CatalogImages)) {
|
||||
return false, false
|
||||
}
|
||||
tpl := filepath.Dir(m.CatalogTemplatePath(name, "docker-compose.yml"))
|
||||
return true, ladderStepsLeft(tpl, st.AppConfig.PinnedImages) > 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user