0.20.0
Released 2026-09-29
Added
viv lock exportwritescomposer.lockfromviv.lockthrough the one existing writer, byte-equal on all ten pinned compat projects;--checkreports whether the committedcomposer.lockmatches.viv installin a project withviv.lockand nocomposer.lockgenerates it first and says so; with both present it writes nothing and refuses a divergence with a hint namingviv lock exportandviv lock convert.viv init --lock nativeandviv lock convertmarkcomposer.locklinguist-generated. Aviv.lockrecord now keeps Composer's own package block (raw) and the committime, which is what makes the export exact and the merge rule below decidable; re-runviv lock converton a lock written before this release (#344, #347)viv lock mergeidentifies adev-*record by its commit and, when both branches moved it to different commits, keeps the one with the later commit time and never re-solves that name; equal or missing times are a conflict naming both commits. When the re-solve needs a pinned commit the registry's branch entry no longer describes, viv fetches that commit'scomposer.jsonfrom the package's git source, once per machine (fetching <package> at <sha>on stderr), and uses it in place of the registry head;--offlineerrors naming package and commit (#343, #345)
Research
- Candidate 3.3, a lock that pins commits and merges by record: holds and built. Replayed with the shipped driver over the 52 client merges chapter 1's driver left to a person, 46 finish, 6 do not (three wpackagist plugins that no longer exist, one commit gone upstream, one malformed manifest, one unclassified), none time out; 22 commit fetches on a cold cache, one on a warm one. Chapter 1's floor of 51 unfinished merges in 355 is 6, 1.7% (#331)