sync milestone-1 spec and api notes with as-built findings

This commit is contained in:
2026-07-31 23:59:40 +02:00
parent b960413ea9
commit bf02f83adc
2 changed files with 46 additions and 10 deletions
+30 -2
View File
@@ -34,6 +34,30 @@ changed most of these APIs.
(compiler suggests the value on first run), plus `.version`, `.paths`, `.dependencies`
(`path`/`url`+`hash`/`lazy`), `.minimum_zig_version`.
## std.process + stdio (found during S1)
- `std.process.args` / `std.process.ArgIterator` **do not exist** in 0.16. Arguments arrive
through main's parameter: `pub fn main(init: std.process.Init) u8 { var args =
init.minimal.args.iterate(); ... }`. `std.process.Init` carries `.io`, `.gpa`, `.arena`,
`.environ_map`, `.preopens`, `.minimal` (`.args`, `.environ`).
See lib/std/process.zig:30 and lib/std/process/Args.zig.
- Console output: `std.Io.File.stdout().writer(io, &buffer)` then use `.interface`
(lib/std/Io/File.zig:91,600). Same shape for stderr.
- Package deps unpack into `zig-pkg/` inside the project root (gitignore it).
- Entropy: `io.random(buf)` (Io.zig:2468). Realtime timestamp: `std.Io.Clock.real.now(io)`
→ `Io.Timestamp` (Io.zig:778). There is NO `io.now(.real)`.
- `std.mem.indexOfScalar` is gone; use `std.mem.findScalar` (mem.zig:1219).
- Conditional imports are impossible: no `@hasImport`, and `@import("root")` in a
`zig test` build resolves to the compiler's test runner, never your tests root.
Integration tests gated on `build_options` therefore live in a separate file with a
runtime `if (!build_options.integration) return error.SkipZigTest;` guard (body stays
semantically analyzed either way — code cannot rot).
- ENVIRONMENT (this dev machine): IPv6 egress is broken — hostname-resolving tests hit
AAAA-first timeouts. Use documented IPv4 literals in live tests, keep SNI on the name.
- `zig fetch` accepts tar.gz/zip etc. but **not .tar.bz2** (no bzip2 decompressor —
src/Package/Fetch.zig ~line 1337). Pin GitHub *source tag* tarballs when a release
asset is bz2-only.
## std.Io (Threaded backend, concurrency)
- `var t = std.Io.Threaded.init(gpa, .{});` — returned by value, must live at a **stable
@@ -59,8 +83,12 @@ changed most of these APIs.
- TCP server: `addr.listen(io, .{ .reuse_address = true })` → `net.Server`;
`srv.accept(io) !Stream`; `srv.deinit(io)`. `Stream.close(io)`, `.shutdown(io, how)`.
Shutdown of the listener makes a blocked accept fail `error.SocketNotListening`.
- TCP client: `addr.connect(io, .{ .timeout = ... })` → `Stream`.
`Io.Timeout = union(enum){ none, duration, deadline }` — **connect only**.
- TCP client: `addr.connect(io, .{ .mode = .stream })` → `Stream`
`ConnectOptions.mode` is REQUIRED (no default, net.zig:332).
`ConnectOptions.timeout` is a LANDMINE in 0.16.0: the Threaded backend panics
"TODO implement netConnectIpPosix with timeout" (Threaded.zig:12077). Never set it.
Bound connects the same way as reads: race the task against a `Clock.Duration.sleep`
via `std.Io.Select` and cancel the loser (see tls_client_integration_test.zig).
- **Stream reads/writes accept no timeout** in 0.16.0 (VTable netRead/netWrite have none;
Operation lacks net stream variants). Bound a TCP/TLS read by running it under
`io.concurrent` and cancelling the future (or shutdown the socket).