authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-10-05 23:40:33-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-10-06 00:27:38-07:00
log0f94ab4eccec40bad42aa31b3adc6dbf9cb50d7a
treeea95927813a7a51c5359b2f6323827d447a081f4
parent8c7f3dfef48f3d2050ce7f0e31b8a1475daf0bce
signature Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU

fix: return the confirmed stamp for replayed Live Share batches

Refresh the stable section image after metadata-only confirmation before caching or acknowledging a duplicate batch. Preserve Committed classification when the refresh fails. fixes #103 Assisted-by: gpt-6.1-sol

1 files changed, 23 insertions(+), 1 deletions(-)

crates/notebook/src/live/share/batch.rs+23-1
...@@ -150,7 +150,18 @@ impl Served {...@@ -150,7 +150,18 @@ impl Served {
150 None => self150 None => self
151 .storage151 .storage
152 .confirm(path, &Stamp::of(&image).expect("section stamp"))152 .confirm(path, &Stamp::of(&image).expect("section stamp"))
153 .map_err(Error::from),153 .map_err(Error::from)
154 .and_then(|()| {
155 image = self.image(path).map_err(|error| CommitError {
156 state: CommitState::Committed,
157 error: match error {
158 Error::Io(error) | Error::RemoteIo(error) => error,
159 Error::Remote(error) => error.error,
160 error => io::Error::other(error),
161 },
162 })?;
163 Ok(())
164 }),
154 };165 };
155 if result.is_ok() {166 if result.is_ok() {
156 self.tell_delta(path, &before, &image, None);167 self.tell_delta(path, &before, &image, None);
...@@ -413,6 +424,17 @@ mod tests {...@@ -413,6 +424,17 @@ mod tests {
413 let repeated = served.batch(&peer, request).unwrap();424 let repeated = served.batch(&peer, request).unwrap();
414 assert!(repeated.failure.is_none(), "{:?}", repeated.failure);425 assert!(repeated.failure.is_none(), "{:?}", repeated.failure);
415 let replayed = std::fs::read(folder.join(path)).unwrap();426 let replayed = std::fs::read(folder.join(path)).unwrap();
427 let confirmed = Stamp::of(&replayed).unwrap();
428 assert_eq!(
429 Stamp::try_from(repeated.stamp.as_ref().unwrap()).unwrap(),
430 confirmed
431 );
432 {
433 let images = served.images.lock().unwrap();
434 let (_, held, image) = images.iter().find(|(held, _, _)| held == path).unwrap();
435 assert_eq!(*held, confirmed);
436 assert_eq!(**image, replayed);
437 }
416 assert_eq!(&replayed[1024..], &committed[1024..]);438 assert_eq!(&replayed[1024..], &committed[1024..]);
417 let replay_arena = Arena::default();439 let replay_arena = Arena::default();
418 let replay = Section::open(&replay_arena, replayed).unwrap();440 let replay = Section::open(&replay_arena, replayed).unwrap();