Artifact 04f0cf4ce689f5423c781201936b3c49c93bb6de5ebc6972496b98f6a7c76938:
- File
docs/RELEASE-NOTES-0.3.22.md
— part of check-in
[d75c7a741d]
at
2026-09-18 01:52:14
on branch trunk
— Release 0.3.22
clone and pull authenticate; a private repository is readable. (user: dmestas, size: 3550) [annotate] [blame] [check-ins using]
zit 0.3.22
zit 0.3.22 reads a private repository. clone and pull authenticate the
way push and sync already did, and a clone learns to sign its login the
way fossil's does.
No artifact, tag namespace, sync message, or on-disk repository format
changed. Two verbs gained --user and --password; a user@ in a remote
URL now counts for every verb that syncs.
clone and pull send a login card
Only push and sync derived a shared secret and signed a login card.
clone and pull sent nothing, so a private repository on a forge that
gates reads was unreadable by the account that owned it. The forge's answer
to an anonymous read of a private repository is a deliberate 404, since a
403 would confirm the repository exists, so the operator saw "not found" for
a repository they administer, with nothing pointing at credentials. A stored
login from an earlier push sat on disk while the next pull read anonymously.
The login is now resolved the same way for all four verbs, in this order:
--user, the user@ component of the remote URL (given or saved), then the
login a previous authenticated round stored in the repository. None of the
three means anonymous, as before. The password comes from --password,
$ZIT_PASSWORD, or a no-echo prompt on a terminal; a stored login needs
none. A freshly derived secret is stored only after the peer accepted it.
A clone signs from round one, after a refusal
A clone cannot sign its first request: the shared secret is derived from the project code, and the project code is what the first reply teaches. fossil's client therefore sends no login on a clone's first round, and its server, refusing an anonymous read, still answers with the project code and an error card. The fossil client discards that error on round zero, derives the secret from the code it was just taught, and sends the clone card again with a login.
zit's clone now does the same. It holds the name and password until the
round-zero reply names the project code, then signs every later round. A
refused round zero that taught the project code is the retry point rather
than a failure; a refused round zero with no login to retry with is still
the failure it was, reported as the peer's words. The login the peer
accepted is stored in the new repository, so the next pull or push from
that clone authenticates without being told.
Verification
- Parser tests for
--userand--passwordonpullandclone, and for theuser@extraction, which never yields a URL password. - Sync-core tests: a clone with a pending login sends no round-zero card and a login card on the next round; a refused anonymous round zero that taught the project code is retried with the login, and without a login it aborts.
- A new fossil interop smoke scenario: a fossil repository with read
stripped from
nobodyandanonymousrefuses an anonymous zit clone, serves one with--user, and a barezit pullfrom that clone reuses the stored login. Seventeen scenarios now run against a real fossil.
Compatibility
- No on-disk repository or wire format changed; Fossil RFC revision 00 remains the target.
- A repository that stores a login is written owner-only, as a push already did.
- Anonymous clone and pull behave exactly as before when no user is given,
no
user@is in the URL, and no login is stored.
Qualification
zig fmt --check, zig build test, e2e, smoke, muscle,
git-import-e2e, git-export-e2e, dst, and cross, plus the
three-runner CI battery.