Repository navigation
Description
#158 asked for the rename's handoff stamp to be hardened and for "broader four-file crash recovery" to be assessed separately. This issue is that separate assessment. No issue tracked it until now.
What #212 made atomic, and what it did not
Atomic now: the Rule 3 RENAMED from … stamp. rename-lane writes the stamped copy to an exclusive mktemp file beside the handoff, in its resolved directory, copies the handoff's mode onto it with cp -p, and replaces the handoff with mv -f. A SIGKILL or power loss at any point leaves the handoff whole: either the old bytes or the stamped bytes, never a truncated file. cleanup removes the temporary file on handled exits.
Still not crash-atomic: the rename itself. Its four moves are separate filesystem operations, made in this order:
- the object log is moved to
lanes/log/<new>.mdand theRENAMEDline is appended; - the handoff is moved and stamped;
- a row is appended to
lanes/aliases.tsv; - the register row is rewritten.
They become one change only at the commit. rename_undo restores them on a handled failure (exit or INT/TERM), but a SIGKILL or power loss runs no trap. A crash between two moves therefore leaves the checkout half-renamed: for example, the log already under <new> while the row still says <old>. A second rename-lane cannot finish that state, because its own refusal reads the moved log as another lane's ("lane '' has no row and this checkout already carries … an object log under that name"). Recovery is by hand.
rename_undo's own restores are also in-place redirects: cat snapshot > target for the log, the handoff, the alias table and the register. A crash during a rollback can therefore truncate any of them. The register's redirect is deliberate, because of the symlink hazard in lanes-edit.sh's header (a redirect follows the ~/projects/<estate>/LANES.md link where mv would detach it), so any answer for the register has to keep following that link.
A fix has to decide how a crashed rename is detected and finished or undone on the next run. One option is an intent record written before the first move, which a later rename-lane or lane-start reads. That decision is the scope here. It does not extend to more single-file atomicity.
A rolled-back MOVED handoff loses its mode (found in #212's review, also on main)
When a rename that moved the handoff rolls back, rename_undo runs rm -f "$RL_H_NEW" and then cat -- "$RL_SNAP/handoff" > "$RL_H_OLD". That creates a new file at the default umask mode, so a 0640 handoff comes back as 0644. The object log's restore (rm -f "$RL_LOG_NEW", then cat … > "$RL_LOG_OLD") follows the same shape. The bytes are restored exactly; the mode is not. f87fd5a behaves the same way.
A stale sentence that is fenced for another branch
docs/README-lanes.md:~4202–4206 still says "Legacy lane rename is an explicit publication exception … Its existing four-file transaction uses EXIT rollback, including stamp write failures; it is not crash atomic across those files." After #212 the stamp is no longer an exception to atomic publication; only the four-file rename is still not crash-atomic. That region (README-lanes.md from ~:3830 on) is reserved for lane openRepoTools-3's unpublished branch feat/triad-lane-tooling, so #212 left it alone. #212 corrected the same claim in skills/handoff/SKILL.md.
Filed by lane openRepoTools-4 from the review of #212.
🤖 Generated with Claude Code
Activity
Say in the handoff skill that rename's stamp is now atomic and the fo…
Publish rename-lane's Rule 3 handoff stamp through a same-directory t…