81 lines
4.0 KiB
Markdown
81 lines
4.0 KiB
Markdown
# AGENTS.md
|
|
|
|
## Aim
|
|
|
|
nxdns: a self-hosted DNS sinkhole for a household LAN, written in Zig 0.16.0.
|
|
Portfolio-grade public repo. PLAN.md is the source of truth for scope and design;
|
|
specs/ holds per-milestone contracts; specs/research/ holds verified stdlib facts.
|
|
|
|
## Values
|
|
|
|
We intentionally architect this code to be robust, maintainable, pragmatic —
|
|
good craftsmanship and good engineering. We explicitly avoid tech debt, code
|
|
smells, bad architecture decisions, and brittle implementations.
|
|
|
|
What that means in practice:
|
|
|
|
- This is a greenfield project. Breaking changes are allowed. Never keep a bad
|
|
interface for compatibility; fix it at the root.
|
|
- No versioning of scope. A feature is in scope (build it completely) or out of
|
|
scope (do not build it). No "v2 later", no stubs left behind.
|
|
- Fix root causes, not symptoms. Do not iterate on workarounds.
|
|
- Scope is small on purpose: household scale, two targets, few dependencies.
|
|
Do not add generality nobody asked for.
|
|
- Dependencies are liabilities: stdlib first; vendored + pinned C deps
|
|
(sqlite3, mbedTLS) only where the stdlib has nothing.
|
|
- Verify stdlib claims against ../zig at tag 0.16.0 — pre-0.16 knowledge is
|
|
stale (std.Io migration). See specs/research/zig-0.16-api-notes.md.
|
|
- Pure core: dns/, filter/, local/, cache/ take bytes and return bytes — no Io,
|
|
no sockets, no clocks hidden inside.
|
|
- Every failure mode must be visible: no silent drops, no unbounded logs, no
|
|
swallowed errors. Counters + health surfaces over log spam.
|
|
- Tests are runnable acceptance criteria, not decoration. Required CI stays
|
|
deterministic — no network-dependent tests in blocking jobs.
|
|
- Comments state constraints the code cannot show. No narration, no
|
|
commented-out code.
|
|
- Git: GPG-signed commits (`git commit -S`), simple lowercase messages, no
|
|
generated-by footers.
|
|
|
|
## Reading `zig build test` output
|
|
|
|
A fully passing `zig build test` still prints a line like `failed command:
|
|
.../test --cache-dir=... --seed=... --listen=-`, and still exits 0. That line
|
|
is a known upstream zig 0.16.0 labelling defect. It does not mean a test
|
|
failed, and no test binary crashed.
|
|
|
|
The build runner sets a step's `result_failed_command` on every spawn
|
|
(`std/Build/Step/Run.zig:1540`) and never clears it on success. It then prints
|
|
a step's diagnostics whenever the step wrote anything to stderr, explicitly "no
|
|
matter the result" (`compiler/build_runner.zig:1381`), and that printer emits
|
|
the `failed command: ` label unconditionally when the field is set
|
|
(`compiler/build_runner.zig:1515`). Our suite writes to stderr on every run,
|
|
because the tests that cover the warning paths log through the real sink. A
|
|
minimal reproducer with no mbedTLS and no C — one passing test whose body is a
|
|
`std.debug.print` — prints the same label and reports "3/3 steps succeeded;
|
|
1/1 tests passed"; deleting the print removes the label. No upstream issue
|
|
matched a search, so the reference is the 0.16.0 source lines above.
|
|
|
|
Any *other* failure text is real. Trust the summary line: `zig build test`
|
|
exiting non-zero, a `N failed` count, or a panic backtrace all mean a genuine
|
|
failure. Do not filter, wrap, or suppress the runner's output to hide the
|
|
label — that would hide real failures with it.
|
|
|
|
One trap: running a cached test binary by hand with `--listen=-` aborts with
|
|
`internal test runner failure: EndOfStream`. That is not a teardown bug; the
|
|
IPC runner is talking to a closed stdin because no build runner is on the other
|
|
end. Run the binary with no arguments to get the plain stdio report.
|
|
|
|
## Regenerating the contract samples
|
|
|
|
`web/src/lib/contractSamples.gen.ts` is a committed golden of canonicalized
|
|
API responses, byte-compared against the live server by a `-Dintegration`
|
|
test and type-checked by `tsc`. After a deliberate API contract change,
|
|
regenerate it with:
|
|
|
|
```
|
|
zig build test -Dintegration -Dcontract-samples-out="$PWD/web/src/lib/contractSamples.gen.ts"
|
|
```
|
|
|
|
then update `web/src/lib/types.ts` to match and commit both. Never edit the
|
|
generated file by hand.
|