fix(rustd): measure the live half of every tracing field, and give both binaries one clock
The last commit named an uninstalled subscriber as the biggest cause of lines reading as unreachable. That was true and it was not sufficient: thirteen lines stayed at zero with the subscriber installed and the code demonstrably running. **`tracing`'s `log` feature makes every field expression compile twice.** sqlx-core and sqlx-postgres request it, Cargo unifies features across the workspace, so it is on for afd_redis too — a crate that never asked for it. The macros then emit each field once for the event and once for a `log` record that never runs when a subscriber is installed, and llvm-cov maps both copies to the same source line and reports the DEAD one. `warn!(x = y.z(), ...)` therefore read as uncovered however many times it ran. Established, not inferred. `lock.rs`'s contention `warn!` showed its opening line at 5 and its own `retry_ms` field at 0 — impossible if the callsite were disabled, and a probe showed it enabled. Replacing the field with a side-effecting expression printed three times in one test while the report still said 0. A standalone crate with the same code and the same `tracing` 0.1.44 / `tracing-core` 0.1.36 reported 5; adding `features = ["log"]` and changing nothing else reported 0. `llvm-cov export --skip-expansions` does not restore it. The fix is a hoist, not an exemption: nineteen call-bearing field expressions move to a `let` above their macro and enter as bare names. The rationale lives once, beside the `tracing` dependency that causes it. Worth stating plainly — **the 100% floor was unreachable through tests alone**, and no amount of test writing would have closed those thirteen lines. **One clock, because the port had already grown two answers.** afd_db carried a private `now_millis` mapping a pre-epoch host to `0`; `clock.zig` returns the negative reading and says why — a silent epoch-0 return corrupts UUIDv7 ordering — so the two binaries answered the same broken host differently while writing the same `audit.schema_migrations` table. §4's JWKS cache would have been the third copy. `afd_core::clock` is now the single reading: `UnixMillis`, a pure `millis_at` beside the clock-reading `now`, and `Clock`/`SystemClock`/ `FixedClock` shaped like the existing `EnvSource`/`ProcessEnv`/`MapEnv`. No date crate — not chrono, not time, not jiff. Every timestamp column is BIGINT, every wire field is i64, and a UUIDv7 carries a 48-bit millisecond field in its own layout, so epoch-milliseconds is already the type three contracts are written in; sqlx maps BIGINT to i64 with no feature flag, so nothing calendar enters the graph. No monotonic reading is exposed either: elapsed time is `Instant` and a deadline is `tokio::time::timeout` (Invariant 4), and omitting the reading is what makes wall-versus-elapsed mixing unwritable. The one Zig caller of the monotonic clock is a deadline loop, which is that shape already. That surfaced a second divergence: the hub's reconnect `jitter()` read the WALL clock for spread. A backward step — an operator correcting drift, an NTP correction — replays the same sub-second nanoseconds and hands two redials the same jitter, reproducing the lockstep the jitter exists to break, at exactly the moment a cluster is most likely to be reconnecting at once. It reads a process-owned `Instant` now. The remaining gap-closing is ordinary work, not measurement: scanner boundaries (a literal at offset zero, `""` inside a quoted identifier, a comment inside a statement, an unclosed `$tag` at end of input), URLs sqlx parses but rejects told apart from wrong schemes, `Migration::for_test` and `Migrator::default` called at runtime, both client construction paths refusing a broken URL by role, the real `ProcessEnv`, and the captured-backtrace rendering on all three error types by the child-process shape afd_core already used. 94.57% → 98.12% lines, 354 tests across both tiers. afd_core and afd_wire join afd_crypto at 100%; afd_redis 94.98% → 97.08%. The forty lines left all need failure injection — a socket that accepts then drops, a killed backend, a server that lies — and each is named in the spec with its route. No number moved. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
K
Kishore Kumar committed
872977d2f3f3e3d17651b62c1cbef139e8b9ef4b
Parent: 168998d