Artifact 55aca187a878c14e72cd3796860c2a5192d7df41bc93d23b814107da2dd505ad:
- File
docs/RELEASE-NOTES-0.3.16.md
— part of check-in
[8cfa57ecd3]
at
2026-09-16 07:42:00
on branch trunk
— Release 0.3.16
File index works on submanifest stores; artifact shows S cards; a saved login authenticates a push that names no user. (user: dmestas, size: 5272) [annotate] [blame] [check-ins using]
# zit 0.3.16 zit 0.3.16 makes the file-history index work on a submanifest repository, makes `zit artifact` show a tree check-in's file set, and makes a saved login authenticate the pushes that name no user, autosync included. No artifact, tag namespace, sync message, or on-disk repository format changed. ## The file index on a tree-manifest store (zit#192) 0.3.14 gave `zit log CHECKIN PATH` an index and 0.3.15 made it durable. Neither did anything for a submanifest repository. The change-set capture refused every tree manifest as "unknown at this layer", so on such a store the index recorded the whole log as unknown, was adopted as valid, and answered nothing; a PATH query paid the build and then reconstructed each check-in anyway. The answer was always right. The cost was 39 minutes a query on a pkgsrc mirror, and a forge that warmed the index after every restart spent those minutes for nothing. Trees are now flattened inside the diff step's memo, through the same seam the Repository facade already used, so the untouched diff machinery sees a flat list. A tree that cannot be flattened — a sub-manifest absent, shunned or corrupt — stays unknown, which is the honest degrade the old refusal was protecting and the only case it still covers. | pkgsrc submanifest mirror, 218,444 check-ins | before | after | |---|---|---| | check-ins unknown to the index | 218,048 | **0** | | a PATH query, warm | ~39 min, every time | **1.09s** | | a different path, same index | ~39 min | **1.14s** | | index build | 39 min, never useful | 34.3 min, once | Answers are identical to reconstruction, checked per path. On a 1029-check-in tree store the warm query went from 0.68s to 0.18s; the same history minted flat answers in 0.49s, so a tree store now gets what a flat store gets. The index format bumps to version 3. A version-2 blob built before this change recorded every tree check-in as unknown and would have been adopted as valid forever; it is refused and rebuilt once. The build is proportional to files per check-in rather than files changed, which on a wide tree is real work done once. Making it proportional to what changed is zit#195. The derive-time crosslink feed is deliberately not flattened: it runs on every cold open, and flattening each tree there would move the whole build onto open. A tree stays unknown in that feed, as it always was. ## `zit artifact` renders S cards (zit#194) The card renderer had a lane per card letter and no S lane. A tree check-in carries its entire file set by S cards and no F cards, so it printed as a manifest with no files at all while `ls` on the same hash listed thousands. One lane, in card order; an end-to-end test checks the rendered lines against `--raw`, which always showed them. ## A saved login authenticates a push that names no user (zit#191) `zit push --user U` saves the derived secret at 0600 so a later push needs no password. But the credential resolver returned anonymous the moment `--user` was absent, before consulting what was saved. Autosync invokes the push with no arguments, so a clone whose peer requires a login for writes pulled automatically and never pushed automatically, and logging in changed nothing. With `--user` absent, the saved login now stands in. This is fossil's shape: a remembered login authenticates every later sync. The branch never prompts — there is no operator at a keyboard by definition — so with nothing saved the push is anonymous as before. `push`, `sync` and `config pull` share the one resolver, so all three gain it. `--user ""` still forces an anonymous push, and an explicit `--user` keeps its precedence. The saved login is reused as it stands: after a password change on the peer, pass `--user` again. A unit test pins the resolver: with no `--user` and a login stored, it returns that login without prompting; with nothing stored, or an explicit empty `--user`, the push is anonymous. This makes a no-user push carry the stored login. Whether that push then lands on a *fossil* peer is a separate, pre-existing matter: an authenticated push to fossil is currently refused even for a Setup user whose login the same peer accepts for `config pull`, tracked as zit#196. Against a `zit serve` peer the point is moot — zit's server has no capability model and accepts anonymous writes. ## Compatibility - No on-disk repository or wire format changed; Fossil RFC revision 00 remains the target. - `.zit-cache/finfo` is version 3. A version-2 file is ignored and rebuilt once; the cache is advisory and deleting it is always safe. - A repository holding a saved login now authenticates pushes and syncs that name no user. Pass `--user ""` to push anonymously from such a repository. - No other command or flag changed. `ZIT_FILEINDEX_WALK` now also prints `fileindex-unknown`; it is a diagnostic seam, not a supported interface. ## Qualification `zig build test`, `e2e`, `smoke` (Fossil interop against a real `fossil`), `muscle` (41 differential steps), `git-import-e2e`, `git-export-e2e`, `dst`, and `cross`, plus the three-runner CI battery. Timings are release builds; the pkgsrc figures are from the submanifest mirror in the benchmark corpus and the before figures from the preceding binary on the same store.