a73x

2fd33c91

docs: two comment corrections from re-review; pin makePrivateParent's no-dirname branch

a73x   2026-08-11 12:34

Commit message
docs: two comment corrections from re-review; pin makePrivateParent's no-dirname branch

The readCache doc promised a closed error set it does not deliver
(AccessDenied passes through untranslated, as from Key.load); the key_len
comment understated its own guarantee (the dial-site conversion is by
value, so a drift does not compile). ParseError's name left deliberately
— the writer speaking one Announce* member does not earn a three-site
rename.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

src/handoff.zig
Old New
@@ -16,8 +16,9 @@ pub const deadline_ms: u32 = 2000;
16 16
17 /// The PSK's length in bytes. The same 32 as `quic.Key`, spelled again 17 /// The PSK's length in bytes. The same 32 as `quic.Key`, spelled again
18 /// rather than imported: this module stays free of the C stack, which is 18 /// rather than imported: this module stays free of the C stack, which is
19 /// what lets it test without one. A drift between the two would surface 19 /// what lets it test without one. The conversion at the dial site is by
20 /// as a failed handshake, not as a wrong-looking announce. 20 /// value into `quic.Key`'s fixed-size array, so a drift between the two
21 /// spellings does not compile.
21 pub const key_len = 32; 22 pub const key_len = 32;
22 23
23 /// Where a `muxd endpoint` announce says its listener lives, and the key 24 /// Where a `muxd endpoint` announce says its listener lives, and the key
@@ -206,11 +207,13 @@ pub fn writeCache(path: []const u8, ep: Endpoint) !void {
206 /// read, exactly as `quic.Key.load` refuses a permissive key file: the 207 /// read, exactly as `quic.Key.load` refuses a permissive key file: the
207 /// key is in here, and a cache that anyone can read has cached a 208 /// key is in here, and a cache that anyone can read has cached a
208 /// credential in public. Everything a caller can do about this file is 209 /// credential in public. Everything a caller can do about this file is
209 /// the same — attach cold — so the vocabulary is three errors and no 210 /// the same — attach cold — so this function names three errors:
210 /// more: `CacheMissing` for "no cache yet", `CachePermissive` for one 211 /// `CacheMissing` for "no cache yet", `CachePermissive` for one held
211 /// held wrong, `CacheMalformed` for every way the contents can be 212 /// wrong, `CacheMalformed` for every way the contents can be unusable.
212 /// unusable. Missing stays separate from the other two because it is the 213 /// Missing stays separate from the other two because it is the ordinary
213 /// ordinary first run rather than something to look into. 214 /// first run rather than something to look into. Ordinary filesystem
215 /// failures — an unreadable file, a bad path — pass through
216 /// untranslated, as they do from `quic.Key.load`.
214 pub fn readCache(path: []const u8) !Endpoint { 217 pub fn readCache(path: []const u8) !Endpoint {
215 const f = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) { 218 const f = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) {
216 error.FileNotFound => return error.CacheMissing, 219 error.FileNotFound => return error.CacheMissing,
src/xdg.zig
Old New
@@ -160,6 +160,13 @@ test "hostCachePathFrom: same shape against XDG_CACHE_HOME, and refuses a host w
160 try std.testing.expectError(error.UncacheableHost, hostCachePathFrom(a, "../k", null, "/home/u")); 160 try std.testing.expectError(error.UncacheableHost, hostCachePathFrom(a, "../k", null, "/home/u"));
161 } 161 }
162 162
163 test "makePrivateParent: a path with no directory part is a no-op" {
164 // The branch neither caller's tests reach: nothing to create, nothing
165 // to tighten, and crucially no error — a bare filename must not make
166 // the write that follows it refuse.
167 try makePrivateParent("bare-name-no-dir");
168 }
169
163 test "writeNewKey: creates 0600 with 32 bytes, refuses to overwrite" { 170 test "writeNewKey: creates 0600 with 32 bytes, refuses to overwrite" {
164 const testtmp = @import("testtmp"); 171 const testtmp = @import("testtmp");
165 var tmp = try testtmp.TmpDir.make(); 172 var tmp = try testtmp.TmpDir.make();