v0.269.1: an installed app keeps the image digest it runs until a guarded Update moves it
gates / gates (push) Successful in 26s
gates / gates (push) Successful in 26s
Found live on 9202 (night 2026-09-24 Part B): the sync rendered the ladder's newest tested digest into a RUNNING app's compose, so the next restart would pull a new image with no backup and no undo. stacks.CarryDigests keeps the running digest for an installed app; a fresh install still takes the tested digest. Red-proofed. 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:
@@ -395,7 +395,14 @@ func (s *Syncer) copyTemplates() (newApps []string, updated []string, err error)
|
||||
s.logger.Printf("[WARN] [sync] Failed to read catalog file %s/%s: %v", appName, filename, rerr)
|
||||
continue
|
||||
}
|
||||
rendered = stacks.RenderWithLadderDigests(srcDir, raw)
|
||||
if s.renderPlanFn != nil && s.renderPlanFn(appName).Deployed {
|
||||
// A DEPLOYED app keeps the digest it runs; only a guarded update moves it (night
|
||||
// 2026-09-24 Part B, live finding). A fresh install takes the ladder's tested digest.
|
||||
current, _ := os.ReadFile(dst)
|
||||
rendered = stacks.CarryDigests(raw, current)
|
||||
} else {
|
||||
rendered = stacks.RenderWithLadderDigests(srcDir, raw)
|
||||
}
|
||||
changed, err = writeIfChanged(rendered, dst)
|
||||
} else {
|
||||
changed, err = copyIfChanged(src, dst)
|
||||
|
||||
Reference in New Issue
Block a user