Commit Graph
207 Commits
Author SHA1 Message Date
mokhtar 0cafd770c1 filter: a reload builds the snapshot one source at a time, and the startup pass reloads only when a source changed or was not enforced 2026-10-21 21:41:47 +02:00
mokhtar c2eac8d486 storage: each runtime database connection keeps a page cache sized for its role, read back at open 2026-10-21 21:40:05 +02:00
mokhtar 8f2794533b ci: time limits on the test, test-aarch64, package and container jobs
Gates / frontend (push) Successful in 2m36s
Gates / test (push) Successful in 2m56s
Gates / test-aarch64 (push) Successful in 7m5s
Gates / package (push) Successful in 4m30s
Gates / container (push) Successful in 13s
CI / gates (push) Successful in 14m47s
2026-10-21 21:32:40 +02:00
mokhtar 5a51e2d6b9 tests: a failed server check fails the test instead of hanging it, and the tls idle tests leave the handshake room 2026-10-21 21:32:40 +02:00
mokhtar 4916b01571 filter: store each blocklist name once, flagged exact and subdomains, instead of in two sets per source 2026-10-21 20:49:55 +02:00
mokhtar 2a06239676 ci: use the runner image's node instead of setup-node, which downloaded it again on every run
Site / deploy (push) Successful in 2m39s
Gates / test (push) Successful in 2m59s
Gates / frontend (push) Successful in 3m23s
Gates / test-aarch64 (push) Successful in 7m57s
CI / gates (push) Canceled after 22h20m36s
Gates / package (push) Failing after 53s
Gates / container (push) Canceled after 0s
2026-10-21 18:53:42 +02:00
mokhtar 7e0664250b ci: build nxdns.sh and deploy it as a cloudflare worker with static assets
Gates / test (push) Successful in 2m40s
Site / deploy (push) Failing after 2m17s
Gates / frontend (push) Successful in 2m12s
Gates / test-aarch64 (push) Successful in 8m11s
Gates / package (push) Successful in 5m4s
Gates / container (push) Successful in 19s
CI / gates (push) Successful in 16m18s
2026-10-21 17:31:06 +02:00
mokhtar 93e2683e71 website: nxdns.sh on astro and starlight, with the docs and 0.0.24 screenshots
Gates / frontend (push) Failing after 8m6s
Gates / package (push) Skipped
Gates / container (push) Skipped
Gates / test (push) Successful in 2m38s
Gates / test-aarch64 (push) Successful in 8m52s
CI / gates (push) Failing after 11m33s
2026-10-21 17:03:01 +02:00
mokhtar c21e5a9542 docs: rewrite for people running nxdns; query-history refusals name their remedy and a refused start gives no wrong hints 2026-10-21 17:03:00 +02:00
mokhtar fbc8fd7882 specs: memory budget drops the removed performance page and keeps stack_size, a thp artifact explained the 2 mib stacks 2026-10-21 17:02:03 +02:00
mokhtar 77ae1a189d ci: limit the frontend job to 8 minutes
Gates / container (push) Successful in 17s
CI / gates (push) Successful in 7m14s
Release / guard (push) Successful in 38s
Gates / frontend (push) Successful in 2m30s
Gates / test (push) Successful in 2m38s
Gates / test-aarch64 (push) Successful in 7m43s
Gates / package (push) Successful in 46s
Gates / container (push) Successful in 18s
Release / gates (push) Successful in 11m29s
Release / publish (push) Successful in 5m19s
Gates / test (push) Successful in 2m24s
Gates / test-aarch64 (push) Successful in 7m45s
Gates / frontend (push) Successful in 2m4s
Gates / package (push) Successful in 4m44s
v0.0.24
2026-10-21 13:37:33 +02:00
mokhtar a0d8af3170 build: bump version to 0.0.24
Gates / test (push) Successful in 2m23s
Gates / test-aarch64 (push) Successful in 7m54s
Gates / package (push) Canceled after 0s
Gates / container (push) Canceled after 0s
Gates / frontend (push) Canceled after 1h33m1s
CI / gates (push) Canceled after 1h32m56s
2026-10-21 11:02:17 +02:00
mokhtar 3e8cd0ea88 changelog: date the 0.0.24 section 2026-10-21 11:00:15 +02:00
mokhtar f26ee523c2 admin: tables fit a phone, their first cell carrying the hidden columns, and no positioned label widens the page 2026-10-21 10:21:17 +02:00
mokhtar 9a99890aea build: bump version to 0.0.23
Gates / package (push) Successful in 47s
Gates / container (push) Successful in 11s
Release / gates (push) Successful in 12m3s
Release / publish (push) Successful in 5m25s
Gates / frontend (push) Successful in 2m15s
Gates / test (push) Successful in 2m47s
Gates / test-aarch64 (push) Successful in 8m28s
Gates / package (push) Successful in 6m36s
Gates / container (push) Successful in 16s
CI / gates (push) Successful in 18m14s
Release / guard (push) Successful in 41s
Gates / frontend (push) Successful in 3m5s
Gates / test (push) Successful in 3m19s
Gates / test-aarch64 (push) Successful in 7m45s
v0.0.23
2026-10-20 15:20:37 +02:00
mokhtar 4ad7ad6c32 changelog: date the 0.0.23 section 2026-10-20 15:18:03 +02:00
mokhtar b4ef7b8ed1 website: plan records the approved look, three install tabs and phone screenshots 2026-10-20 14:57:27 +02:00
mokhtar d9d1c1d60d docs: verify-a-release transcripts elide the signing key's email address 2026-10-20 14:57:27 +02:00
mokhtar f35146918b nix: a services.nxdns module that runs the packaged unit in file mode against a configuration the pinned binary accepted 2026-10-20 13:06:43 +02:00
mokhtar aa8c9e28af deploy: the compose file names its own release, and the cut moves it with the version
Gates / frontend (push) Successful in 2m41s
Gates / test (push) Successful in 3m2s
Gates / test-aarch64 (push) Successful in 8m23s
Gates / package (push) Successful in 4m29s
Gates / container (push) Successful in 17s
CI / gates (push) Successful in 16m14s
2026-10-20 11:46:13 +02:00
mokhtar ea9f16a989 admin: the overview's last bucket is drawn as still counting; the query detail names the device as the activity list does 2026-10-20 11:20:16 +02:00
mokhtar 8efe504c51 upstream: an unnamed connect errno fails over, local-resource exchanges are counted, doh faults carry the http status 2026-10-20 10:11:34 +02:00
mokhtar 2697adfa27 website: demo household and the admin screenshots it produced 2026-10-20 09:57:49 +02:00
mokhtar 4ef795a8a9 docs: config examples use cloudflare doh; quad9 doh needs http/2 and answers 505 2026-10-20 09:57:49 +02:00
mokhtar 0385c34ca3 build: bump version to 0.0.22
Gates / package (push) Successful in 7m56s
Gates / frontend (push) Successful in 3m15s
Gates / test (push) Successful in 4m4s
Gates / test-aarch64 (push) Successful in 10m25s
Gates / container (push) Successful in 17s
CI / gates (push) Successful in 22m50s
Release / guard (push) Successful in 38s
Gates / test (push) Successful in 2m22s
Gates / frontend (push) Successful in 2m25s
Gates / test-aarch64 (push) Successful in 7m37s
Gates / package (push) Successful in 50s
Gates / container (push) Successful in 14s
Release / gates (push) Successful in 11m6s
Release / publish (push) Successful in 10m2s
v0.0.22
2026-10-19 23:10:59 +02:00
mokhtar 36e11ca71d metrics: peak gauges for in-flight queries, stream connections and the query log queue 2026-10-19 23:08:58 +02:00
mokhtar 9d2511ee58 specs: memory budget, measured owners and the fix order 2026-10-19 22:48:19 +02:00
mokhtar cab79c75e2 plan: nxdns.sh landing page settled; doq waits on a quic stack, dnscrypt is out 2026-10-19 17:25:44 +02:00
mokhtar 5acfec2bff docs: the reproducibility gate exists since 0.0.17; a fresh rebuild of v0.0.21 matches 2026-10-19 17:25:44 +02:00
mokhtar 534c620695 docs: the install guides ran against the published v0.0.21, no more no-release notes 2026-10-19 17:25:39 +02:00
mokhtar f2dd6ad1c7 build: bump version to 0.0.21
Gates / frontend (push) Successful in 2m1s
Gates / test (push) Successful in 2m25s
Gates / test-aarch64 (push) Successful in 8m19s
Gates / package (push) Successful in 4m22s
Gates / container (push) Successful in 12s
CI / gates (push) Successful in 28m50s
Release / guard (push) Successful in 35s
Gates / frontend (push) Successful in 1m57s
Gates / test (push) Successful in 2m24s
Gates / test-aarch64 (push) Successful in 7m38s
Gates / package (push) Successful in 54s
Gates / container (push) Successful in 18s
Release / gates (push) Successful in 11m18s
Release / publish (push) Successful in 4m56s
v0.0.21
2026-09-12 20:26:58 +02:00
mokhtar 08cdf86ecd upstream: a diagnostics episode follows health, and a peer fault carries its cause
Gates / frontend (push) Successful in 2m5s
Gates / test (push) Successful in 2m43s
Gates / test-aarch64 (push) Successful in 8m19s
Gates / package (push) Successful in 4m21s
Gates / container (push) Successful in 13s
CI / gates (push) Successful in 30m43s
2026-09-12 20:24:49 +02:00
mokhtar 6e9a36903e build: bump version to 0.0.20
Gates / frontend (push) Successful in 1m52s
Gates / test (push) Successful in 2m22s
Gates / test-aarch64 (push) Successful in 8m10s
Gates / package (push) Successful in 4m22s
Gates / container (push) Successful in 10s
CI / gates (push) Successful in 28m22s
Release / guard (push) Successful in 35s
Gates / frontend (push) Successful in 1m53s
Gates / test (push) Successful in 2m20s
Gates / test-aarch64 (push) Successful in 7m26s
Gates / package (push) Successful in 51s
Gates / container (push) Successful in 11s
Release / gates (push) Successful in 10m52s
Release / publish (push) Successful in 4m56s
v0.0.20
2026-09-12 15:10:09 +02:00
mokhtar f6fa43a8b4 filter: blocklist downloads never reuse a pooled connection, the peer closes it between passes
Gates / frontend (push) Successful in 2m3s
Gates / test (push) Successful in 2m34s
Gates / test-aarch64 (push) Successful in 8m20s
Gates / package (push) Successful in 4m20s
Gates / container (push) Successful in 12s
CI / gates (push) Successful in 30m24s
2026-09-12 15:07:55 +02:00
mokhtar f4562cac26 filter: skip the read-only directory test as root, ci's runner ignores mode bits
Gates / frontend (push) Successful in 2m3s
Gates / test (push) Successful in 2m33s
Gates / test-aarch64 (push) Successful in 8m14s
Gates / package (push) Successful in 52s
Gates / container (push) Successful in 14s
CI / gates (push) Successful in 12m0s
Release / guard (push) Successful in 33s
Gates / frontend (push) Successful in 2m36s
Gates / test (push) Successful in 3m47s
Gates / test-aarch64 (push) Successful in 7m24s
Gates / package (push) Successful in 50s
Gates / container (push) Successful in 15s
Release / gates (push) Successful in 12m19s
Release / publish (push) Successful in 6m37s
v0.0.19
2026-09-12 10:43:02 +02:00
mokhtar 250bdca7e7 build: bump version to 0.0.19
Gates / frontend (push) Successful in 1m58s
Gates / test (push) Failing after 2m31s
Gates / test-aarch64 (push) Successful in 8m21s
Gates / package (push) Successful in 4m20s
Gates / container (push) Successful in 10s
CI / gates (push) Failing after 37m36s
2026-09-12 10:01:19 +02:00
mokhtar 63f4f96a48 changelog: date the 0.0.19 section
Gates / frontend (push) Successful in 1m56s
Gates / test (push) Failing after 2m22s
Gates / test-aarch64 (push) Successful in 7m30s
Gates / package (push) Successful in 47s
Gates / container (push) Successful in 9s
CI / gates (push) Failing after 39m22s
2026-09-12 09:59:13 +02:00
mokhtar 52158198cf filter: a failed blocklist download names its phase, cause, status, bytes and elapsed time
Gates / frontend (push) Successful in 2m20s
Gates / test (push) Failing after 2m41s
Gates / test-aarch64 (push) Successful in 8m19s
Gates / package (push) Successful in 4m24s
Gates / container (push) Successful in 16s
CI / gates (push) Failing after 41m33s
2026-09-12 09:58:59 +02:00
mokhtar bf79a22584 docs: renovate's nix manager does not bump a tag ref; the regex manager recipe that does 2026-09-12 00:38:45 +02:00
mokhtar bcd9bce16c build: bump version to 0.0.18
Gates / frontend (push) Successful in 2m34s
Gates / test (push) Successful in 2m39s
Gates / test-aarch64 (push) Successful in 8m16s
Gates / package (push) Successful in 4m21s
Gates / container (push) Successful in 16s
CI / gates (push) Successful in 15m39s
Release / guard (push) Successful in 35s
Gates / frontend (push) Successful in 2m1s
Gates / test (push) Successful in 2m28s
Gates / test-aarch64 (push) Successful in 7m24s
Gates / package (push) Successful in 52s
Gates / container (push) Successful in 11s
Release / gates (push) Successful in 10m59s
Release / publish (push) Successful in 5m11s
v0.0.18
2026-09-09 19:25:08 +02:00
mokhtar 2b790c4c3e changelog: 0.0.18 section 2026-09-09 19:23:07 +02:00
mokhtar 1860ff59f5 admin: the overview pickers fill their wrappers and share a narrow row 2026-09-09 19:04:44 +02:00
mokhtar f168247b33 cut: build the release with the official zig tarball, skip hidden bundle files; re-pin 0.0.17
Gates / frontend (push) Successful in 2m23s
Gates / test (push) Successful in 3m15s
Gates / test-aarch64 (push) Successful in 8m38s
Gates / package (push) Successful in 5m0s
Gates / container (push) Successful in 19s
CI / gates (push) Successful in 17m17s
Release / guard (push) Successful in 37s
Gates / frontend (push) Successful in 2m15s
Gates / test (push) Successful in 2m34s
Gates / test-aarch64 (push) Successful in 7m33s
Gates / package (push) Successful in 51s
Gates / container (push) Successful in 10s
Release / gates (push) Successful in 11m14s
Release / publish (push) Successful in 8m35s
The first 0.0.17 cut (run 687) failed verify-pins in CI for two reasons. The asset generator embedded admin/dist/.src-hash, a freshness stamp that CI's artifact copy does not carry; it now skips dotfiles. And the Arch zig package emits different code than the ziglang.org tarball that CI installs, so the cut downloads the pinned tarball (ZIG_TARBALL_SHA256 in gates.yml, the full digest keys the cache) and builds the release with it. flake.nix is re-pinned to the bytes both now produce.

The saturated-primary pool test gates its holders on a semaphore instead of sleeps and releases every spawned holder on the way out, so a loaded runner cannot flake it. The package job uploads the payload before the pin check and runs the check when the version or flake.nix changed against the parent. The verify-a-release recipe clones the tag first and builds with the official zig.
v0.0.17
2026-09-08 23:57:07 +02:00
mokhtar d596fd788a build: bump version to 0.0.17
Gates / frontend (push) Successful in 3m10s
Gates / test (push) Failing after 3m36s
Gates / test-aarch64 (push) Successful in 8m46s
Gates / package (push) Failing after 6m15s
Gates / container (push) Skipped
CI / gates (push) Failing after 18m40s
2026-09-08 23:06:52 +02:00
mokhtar f067742adf cut: the pin stage compiles, and zig build test builds the cut binary
Two errors the test build never saw, because the test binary analyses only what the tests reference: `Io.Dir.makePath` does not exist in 0.16.0 (`createDirPath` does), and the tag push passed the optional authorization where the checked token was meant. The test step now depends on the cut compile as well.
2026-09-08 23:04:51 +02:00
mokhtar a4eb749fa7 changelog: 0.0.17 2026-09-08 23:02:33 +02:00
mokhtar 22abcd9b7b release: nix flake with tag-pinned hashes, reproducible tarballs (milestone 40)
flake.nix fetches the release tarballs and carries their SRI hashes in a generated block. The cut tool builds the release locally with the toolchain gates.yml pins, in a normalized nine-variable environment, writes the hashes into flake.nix, and commits it with build.zig.zon as the single bump commit. The package job verifies the pins on the bump commit and the publish job verifies them again on the tag, before anything is uploaded.

The tarballs are written by dist_stage (std.tar.Writer, flate gzip) instead of the runner's tar and gzip, and -ffile-prefix-map keeps checkout paths out of the C objects; two checkouts at different absolute paths produce byte-identical archives. nxdns version, /api/version and the admin footer report the version only: the bump commit cannot know its own sha.
2026-09-08 21:45:22 +02:00
mokhtar 3e57f43e08 cut: rerun a flaky release run once, resume after the tag
The v0.0.16 cut pushed the tag and then reported a failure because the release.yml run lost one gate to a timing-flaky test while its guard had passed and its publish job never ran. Rerunning the run by hand published the release; the tool had exited 1 and could not be run again, since a tag on origin meant "derive the next version".

The release stage now classifies a failed run from forge state: retryable when the conclusion is failure, the run is on its first attempt, every commit-status context in a failure state is a gate, and no release is published for the tag. A retryable run is rerun once through the actions API and the same run id is watched again, restarted only once the forge reports a higher run_attempt, so a concluded previous attempt is never read as the result. The rerun decision parses statuses strictly and treats anything it cannot read as terminal. A tag already on origin that peels to HEAD with no published release resumes at the release stage after the origin tag is verified (annotated, tool convention, pinned signing fingerprint). Both decisions are pure, table-tested functions. Spec bullets in specs/release-cut.md.
2026-09-08 01:47:09 +02:00
mokhtar 299d7af99c upstream: overlap attribution test builds its schedule with gates
The test "overlapping exchanges each report the entry that answered that call" failed once on a loaded release runner and passed on rerun. It started two exchanges back to back and relied on a 50 ms failing stall to keep the first in flight until the second arrived; nothing checked that the two calls were ever in flight together, and the failing schedule was never observed.

Two Fake behaviours, hold and hold_fail, wait on a test-owned std.Io.Semaphore and then reply or fail. The test holds both calls inside the first entry, waits on the entry's in_flight count for one and then two, releases the failing call so it fails over while the other is still held, then releases the other. The fake draws its behaviour before it raises in_flight, so a count of one also fixes which call holds which gate. Each gate has a deferred post registered after its task's deferred await, so any early return releases the held call instead of deadlocking. No sleep remains in the test; every assertion is kept. No pool bug was found. Addendum in specs/milestone-31.md.
2026-09-08 01:14:26 +02:00
mokhtar 85b8be50a0 admin: overview redesign, device scope, one formatting contract (milestone 39)
Gates / frontend (push) Successful in 1m57s
Gates / test (push) Successful in 2m34s
Gates / test-aarch64 (push) Successful in 8m9s
Gates / package (push) Successful in 7m14s
Gates / container (push) Successful in 17s
CI / gates (push) Successful in 18m17s
Release / guard (push) Successful in 33s
Gates / test-aarch64 (push) Successful in 7m22s
Gates / container (push) Successful in 11s
Release / gates (push) Successful in 10m35s
Gates / frontend (push) Successful in 2m8s
Gates / test (push) Successful in 2m16s
Gates / package (push) Successful in 44s
Release / publish (push) Successful in 10m4s
The Overview page takes the decided visual language (specs/ui-visual-redesign.md): four centred totals with their Activity links, a smoothed area chart of total and blocked queries with point hover and a tooltip centred beside the point, a stacked client chart in eight distinct hues plus one Other band that is always a series, and a card row with the cache hit rate, the query types as a single-hue ramp ring, and the upstream breakdown. The count axis grows its margin with the widest grouped tick and draws whole-number ticks only.

GET /api/overview takes a client parameter; the scoped read uses idx_query_log_ts and the cache keeps scoped slots. The device selector beside the period selector is URL state, so a scoped view is a link, and the tile links carry the scope into Activity. The route reduces a pasted IPv6 scope to the RFC 5952 spelling the logger stores, mapped addresses included, and drops anything that is not an address. A failed device list says so under the selector with a retry.

All measured quantities go through admin/src/lib/format.ts: grouped counts, two-decimal percentages, one-decimal rates, durations as the two largest nonzero units. Identifiers, configured values and preset labels render as written; the module header states that scope. A sweep test refuses toFixed, toLocaleString, Intl.NumberFormat and padStart anywhere else.

Chrome: one 4px radius from the metrics constants, shared Card with a prominent title and a one-line description on every panel, the settings form sections on the same card with a floated legend, the sidebar grouped into Monitoring and System with a status block (protection, queries per minute on Overview, uptime), keyboard-focusable table scroll wrappers, and the accent darkened to 5.43:1 on its wash.

Not built: the spec's ranked-list primitive, which has no consumer and no API rows. Codex reviewed sessions B to D over five rounds (thirty-three findings fixed, thirteen rejected as non-quantities); the owner skipped a sixth round.

Claude-Session: https://claude.ai/code/session_01VTgx3a1zz1R78o4K55kkwR
v0.0.16
2026-09-07 23:11:50 +02:00