milestone 19: hygiene sweep - dead ecs surface, single-source constants, tls classification, frontend state hazards, docker smoke network fix
This commit is contained in:
@@ -431,6 +431,107 @@ Deleted surface: `parseEcs`/`Ecs`/`EcsError`/`ecs_family_*` (edns.zig), the
|
||||
- [ ] Full suite green: `zig build test -Dintegration`, `npm run test`,
|
||||
`npm run typecheck`, `npm run lint`.
|
||||
|
||||
## Recorded (implementation)
|
||||
|
||||
Accepted deviations and findings from the built milestone.
|
||||
|
||||
### Ruling 1 (S1)
|
||||
|
||||
- The edns.zig test block held six `parseEcs` tests, not nine. A seventh
|
||||
use lived inside "encodeOpt round-trips through record parse and
|
||||
parseOpt", which is not a parseEcs test; its last two lines now compare
|
||||
the found option's bytes directly.
|
||||
- `extendedRcode` stays, with a nuance the ruling's premise missed: the
|
||||
BADVERS production path uses the write-side `splitRcode`; extendedRcode
|
||||
is the read-side verifier whose callers are the two BADVERS wire-format
|
||||
tests (handler.zig, packet.zig). Deleting it would weaken those tests.
|
||||
- The write-fault seam for the rollback test has no exported control
|
||||
surface — the test lives in the same file and needs none.
|
||||
- The ruling-8 doc comment names `local.zig`'s `publish` function instead
|
||||
of a line number, so it cannot go stale.
|
||||
|
||||
### Rulings 3-7 (S2)
|
||||
|
||||
- Ownership amendment: `src/web/metrics.zig` (owned by no session) was
|
||||
granted to S2 mid-flight. Ruling 5's new counter raises the /metrics
|
||||
sample count 29 → 30 (`nxdns_log_lines_truncated_total`); the
|
||||
hard-coded assertion became fully derived
|
||||
(`1 + dns_stat_fields.len + @typeInfo(LoggerCounters)... +
|
||||
@typeInfo(logging.Stats)...`), so a new counter in any of those
|
||||
structs extends the exposition and the assertion together.
|
||||
- Ruling 6 lands asymmetrically, following the ruling body over the
|
||||
stale acceptance bullet: doh_client.zig names eleven members (the two
|
||||
collapsed top-level ones plus the nine `Tls*` members of the unwrapped
|
||||
read-cause set); fetcher.zig names only the two, because it has no
|
||||
cause unwrap and no record-layer member can reach it. Both files carry
|
||||
a comment pointing at the other.
|
||||
- Addition beyond the ruling: an exact switch does not catch a std
|
||||
rename — `error.X` in an expression names a member into existence, so
|
||||
a renamed member leaves the switch compiling and matching nothing.
|
||||
Comptime guards close this for real: doh_client.zig asserts every
|
||||
member of `std.crypto.tls.Client.ReadError` maps to `TlsFailed`, and
|
||||
both files assert the two collapsed names still exist in
|
||||
`std.http.Client.RequestError`.
|
||||
- The ruling's "stashed record-layer cause through the unwrap" test is
|
||||
not constructible: the stub connection is `.plain` on purpose, and a
|
||||
plain connection's stashed error type has no `Tls*` member. The
|
||||
record-layer set is instead tested by an `inline for` over the std
|
||||
error set against `mapError` — all nine members, not one sample.
|
||||
- Ruling 3 behavioral note: queries.zig's client width dropped 64 → 45
|
||||
as directed; a `?client=` filter of 46-64 bytes now returns 400
|
||||
instead of matching nothing. `src/filter/wildcard.zig`'s
|
||||
`max_pattern_len = 253` is a rule-pattern limit, not a logger role,
|
||||
and stays.
|
||||
|
||||
### Rulings 14-20 (S3)
|
||||
|
||||
- Ruling 14: the three `Record<string, unknown>` consumption casts
|
||||
collapse into one documented cast inside `sectionValues` rather than
|
||||
zero — iterating the heterogeneous registry erases the per-section
|
||||
correlation TypeScript needs, and `TlsListenerSettings` (a named
|
||||
interface, no implicit index signature) blocks the assignment route
|
||||
with types.ts off-limits. Four casts before, one after.
|
||||
- Ruling 20: the catch body lives in an exported `swallowMutationError`
|
||||
helper because jsdom never fires `unhandledrejection`, so a rethrow
|
||||
from an async submit handler cannot be asserted directly; the helper
|
||||
is tested directly, mirroring how auth/store.tsx's logout pair is
|
||||
tested.
|
||||
- The refresh store notifies synchronously inside `onSuccess`, one flush
|
||||
before react-query's success dispatch; one pre-existing assertion
|
||||
moved from `getByText` to `await findByText`. The sub-frame transient
|
||||
was judged cheaper than batching through notifyManager.
|
||||
- `lib/queries.ts` imports `features/blocklists/refreshStore.ts` (lib →
|
||||
features) because the spec directs the mutation factory to write the
|
||||
store; recorded as sanctioned layering.
|
||||
- `SourceStatusSection`'s prop is `SourceStatus[] | null` to match the
|
||||
store; BlocklistsPage tests clear the module-level store in
|
||||
`beforeEach`.
|
||||
- Ruling 18: post-m18 there are four other `Promise.all` loaders, not
|
||||
five.
|
||||
|
||||
### Rulings 12, 13 and carry-ins (S4)
|
||||
|
||||
- The undecodable-sibling message reports `decompress.err orelse err`,
|
||||
because `std.Io.Reader` collapses every decode failure into
|
||||
`error.ReadFailed` and stashes the real one.
|
||||
- The Dockerfile keeps its `&&` chain instead of the spec sketch's `;`
|
||||
separators, so any failed step still aborts the layer; the case arms
|
||||
are untouched.
|
||||
- The phase-comment sweep leaves `PLAN.md:605`/`:609` alone — they are
|
||||
the section headings that define Phase 7 and Phase 8, not stale
|
||||
comments.
|
||||
- The orchestrator added the host-fallback sentence to
|
||||
docs/how-to/install-with-docker.md.
|
||||
|
||||
### Residual (named, not fixed)
|
||||
|
||||
`fetcher.zig` hands the collapsed `ReadFailed`/`WriteFailed` to
|
||||
`mapError` with no cause unwrap, so a blocklist download canceled at
|
||||
shutdown returns `error.ReceiveFailed` instead of `error.Canceled` — the
|
||||
class m18 ruling 4 fixed for DoH. Consequence: a wrong source status and
|
||||
a spurious warn line at shutdown. Fixing it needs `req`/`resp` plumbing
|
||||
at four call sites; it deserves its own ruling.
|
||||
|
||||
## Anti-requirements
|
||||
|
||||
- No deletion of `extendedRcode` (m17 gave it a caller) and no deletion of
|
||||
|
||||
Reference in New Issue
Block a user