Skip to content

fix(distribute): read current bytes as current before a lagging files: receipt as an edit - #192

Merged
arcaven merged 2 commits into
mainfrom
build/sideshow/190-files-case-order
Oct 8, 2026
Merged

arcaven merged 2 commits into
mainfrom
build/sideshow/190-files-case-order

Conversation

@arcaven

@arcaven arcaven commented Oct 8, 2026

Copy link
Copy Markdown
Member

A files: artifact whose receipt lags its bytes, because a run wrote the new version and died before the registry saved or because the user applied the update by hand, was reported as "modified since sideshow wrote it" on every run and could never be updated again. This tests "bytes equal the pack's" before "bytes differ from the receipt", so that state reads as already current and the receipt moves to the new sha.

The same order the #189 review asked for rules. A files: artifact has no marker, so the order is narrower here: a file with no receipt stays user-authored even when its bytes equal the pack's, because equal bytes prove only equality and a user's own copy must never be adopted into management.

Refs: sideshow#190

Order in distributeFile: no receipt (user-authored, skip, nothing recorded); then bytes equal to the pack with a known receipt (already current, receipt recorded as the pack's sha); then bytes differ from the receipt (modified, edit kept, receipt kept).

Known limit, now in a comment and not fixed here: a first write whose registry save fails leaves no receipt, so that file reads as user-authored from then on. That is safe, and deleting the file takes the pack's version.

Acceptance:

  • the receipt holds the old sha and the disk holds the new bytes: "already current", the receipt moves to the new sha, and an edit after it skips as modified; a dry run says the same and asks to record nothing (red before the fix)
  • no receipt and bytes equal to the pack: still user-authored, nothing recorded, on a dry run and a real run (a guard that passes on arrival)

Commits: (1) tests, red; (2) the reorder and the comment.

Blast radius: the order of two branches in distributeFile.

Mutants, each compiles and fails a test:

  • the old order (the current-bytes case only when the receipt equals the bytes): killed by TestFiles_ALaggingReceiptWithCurrentBytesIsMovedNotReadAsAnEdit
  • a file with no receipt and bytes equal to the pack is adopted: killed by TestFiles_NoReceiptAndBytesEqualToThePackIsStillUserAuthored

@arcavenai arcavenai left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. A files: artifact whose receipt lags its bytes now reads as current and takes the next pack update, instead of reading as an edit forever. A file with no receipt still stays the user's even when its bytes match the pack.

The reproducer from #191, end to end. I wrote v2's bytes into a.cfg under its v1 receipt, then installed v2, reading the registry after each run. At 3776d96 every run said modified since sideshow wrote it and the receipt stayed at the v1 sha. At 683e972:

  • --dry-run says already current and leaves the receipt at the v1 sha;
  • the real run says already current and moves the receipt to the v2 sha;
  • the next run is unchanged;
  • an edit after that reads modified ... on two runs, with the receipt and the edit kept.

No receipt, equal bytes. A user-authored a.cfg holding exactly the pack's bytes reads user-authored on a dry run, then on three real runs across a v2 bump. It gains no receipt and is never written.

Nothing else moved. My #191 files: rows (sibling recreated, edit plus sibling, edit plus bump, dry run, removed and re-added, user-authored, unedited bump) match 3776d96 line for line. The only change is the reproducer row. My #189 rules rows match 8736668 line for line.

The write path. It is reached only with a known receipt that equals the bytes on disk while those bytes differ from the pack's. An edit cannot reach it with or without a receipt; a file with no receipt never gets past the first case.

Red, and mutants. At cca9cc8, TestFiles_ALaggingReceiptWithCurrentBytesIsMovedNotReadAsAnEdit fails for the stated reason: it reads modified and keeps the old sha. The no-receipt guard passes there, as stated. Head passes the full suite and two runs of -count=20. Each of these mutants fails a test:

  • the two named mutants;
  • my #189 old-order mutant, applied here by moving the current-bytes case back after the modified case;
  • the current case not recording;
  • the current case recording under a dry run;
  • the current case keeping the old receipt;
  • the edited case removed.

The comment. The known-limit comment at the !known branch says a first write whose registry save fails leaves no receipt, so the file reads as user-authored from then on, and that deleting it takes the pack's version. That matches the no-receipt run above and the absent-file path, which creates.

CI on 683e972 passes.

Seat: reviewer / reviewer

@arcaven
arcaven marked this pull request as ready for review October 8, 2026 11:38
@arcaven
arcaven merged commit 3cd4e2d into main Oct 8, 2026
10 checks passed
@arcaven
arcaven deleted the build/sideshow/190-files-case-order branch October 8, 2026 11:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants