Skip to content

Project

Status

The milestone checklist from the repository, rendered at build time. If it is not ticked here, it is not done.

Living checklist of what exists in this repository. Update it in the same commit as the code it describes. Milestones are defined in the project plan, section 14. Per-tool detail is in FEATURES.md.

Last updated: 2026-09-16.

Milestone summary

MilestoneStateNotes
M0 planning baselineDonePlan v2, research and reuse audit merged in PR #1
M1 foundationDoneData pipeline, site shell, libraries and flagship tools (PR #3), FastAPI skeleton and deployment files (PR #4), image fixes (PRs #5 and #6). Main image runs through commit 2357668 built, smoke tested and published both images; current digests are in deploy/README.md. Nothing is deployed: the Dockhand secrets are not set.
M2 local catalogue and contentDoneThe 24 available local tools, six guides, datasets, API docs and aggregate measurement are merged through PR #22. The full browser journey suite passed with local-tool network assertions.
M3 remote diagnosticsIn progressPublic-destination validation and pinned address selection merged in PR #23. DNS lookup merged in PR #24. DNS compare is implemented in the current branch; Unbound deployment and the rest of the remote tools remain.
M4 TLS full scansNot started
M5 release engineeringNot started

M1 checklist

  • Astro 7 project with the tool registry (55 tools, all planned until wired), page shell (donor layouts, header/footer, theme, global.css with a teal accent), tool layout with slots, command palette, favorites/recents, sitemap filtered to available tools, llms.txt, security.txt, dash-check lint. astro check 0 errors; 72 pages build.
  • Shared packages mac, detect with fixtures (69 tests plus a shard integration test); strict anchored MAC parser replaces the donor's permissive stripping; classification, EUI-64 and link-local derivation, generator, shard lookup client, extraction, identifier detection.
  • IEEE ingestion ported from the donor, snapshot validation, shard build, verification (scripts/, 37 tests; dedupe key widened to registry type plus start so parent blocks under sub-assigned prefixes survive; live snapshot 58,700 records, version 137c777b20c1).
  • FastAPI skeleton (backend/): error envelope, typed request and response models with examples, OpenAPI at /api/openapi.json, security headers, structured access log with route templates, in-memory credit and rate limits keyed on a hashed trusted client IP, /healthz, /api/v1/mac/{address}, /api/v1/mac/bulk, /api/v1/vendors, /api/v1/datasets/current, /api/v1/limits; Python mirrors of the MAC parser, classifier, derivations and extractor verified against shared fixtures that the TypeScript library also runs (150 pytest, 4 parity node tests).
  • Compose and Caddy (deploy/, Dockerfile, docker-compose.yml): Alpine multi-stage image (build stage runs the tests and the dash lint; web on caddy:alpine serving site/dist with hashed-inline-script CSP, cache rules and the security headers; api on python:3-alpine, non-root, read-only), compose with an internal network, health-gated startup and hardened services, host-level Caddyfile example with Cloudflare trusted proxies, Cloudflare cache and rate-limit rules, CI workflows (checks, nightly data refresh, image build with a compose smoke test). Caddy config validated with a real caddy validate and a live run against the built site. Image builds cannot run in the development container (no Docker daemon); CI proves them. docker.yml run 1 on main failed on a missing docs/STATUS.md copy (PR #5), run 2 on the Caddy binary's file capability under cap_drop: ALL (PR #6), and run 3 passed end to end: both images built, non-root check, stack start behind the api health gate, smoke test (12 routes plus the three informational API routes, all as expected), header and CSP hash checks, publish to ghcr.io.
  • Flagship tools wired: inspector, mac-inspector, mac-bulk (panels under site/src/components/tools/, behavior under site/src/scripts/tools/), with 8 Playwright tests including a same-origin network allowlist that proves local tools send nothing.

Exit criterion met: inspector, mac-inspector and mac-bulk work end-to-end in the new design; the three nested-assignment prefixes the old site once got wrong (00-50-C2, 70-B3-D5, 8C-1F-64) are asserted in scripts/verify.mjs, tests/mac/lookup-shards.test.ts and the browser tests.

M2 checklist

  • MAC family local tools: mac-generator, mac-convert, vendor-search (noindex) and datasets. The snapshot build emits a complete local assignment search index and full-record JSON and CSV downloads with SHA-256 checksums and Dataset JSON-LD.
  • Identify extract over text or local files, using packages/detect and the strict MAC extractor shared with Bulk MAC; dedupe, count, sort and compare two sets in a cancellable browser worker.
  • packages/ip strict IPv4/IPv6 parsing, exact CIDR math and 49 active IANA special-purpose prefixes; local subnet-calculator, cidr-tools and the local half of ip-inspector.
  • Local developer utilities: base-convert, timestamp, uuid, encoders, hash, jwt decode and regex with a bounded browser worker.
  • Six launch guides, a datasets landing page with checksums and Dataset JSON-LD, and API documentation reading a checked-in OpenAPI snapshot verified against FastAPI.
  • Aggregate measurement with validated day, tool and event dimensions. Local tool pages retain bounded counters in browser storage without measurement requests; the catalogue submits only those bins to the same-origin coordinator, which sums them in SQLite. A read-only CSV report supports 30, 60 and 90 day review.
  • Browser network assertions for every one of the 24 available local tools, including the measurement journey that proves no tool-page usage request and no input in the later catalogue batch. QR scanning uses a same-origin blob worker and no network fetch for image content.
  • diff: local text and JSON line comparison with unified and side-by-side views, whitespace option, exports and bounded input.
  • password: local random passwords, EFF passphrases and WPA PSK derivation, with generated secret values kept out of network requests and URL state.
  • qr: local generation, image scanning and camera scanning, with a PNG download and no automatic navigation from scanned content.
  • cron: five-field parser and builder, English description and timezone-aware next runs with explicit UTC timestamps.
  • json-tools: bounded JSON formatting, key sorting, query and JSON/YAML/TOML/CSV conversion with local file input.
  • cert-decoder: local PEM, DER, CSR and PKCS#7 decoding, fingerprints, PKCS#8 key match and certificate chain order check.

M3 checklist

  • Public-destination validation with mixed-answer rejection and pinned TLS connections.
  • dns-lookup: bounded record types, resolver selection, AD flag, TTLs and distinct DNS outcomes.
  • dns-compare: eight resolver endpoints from one vantage, value-based answer grouping and visible failures.
  • Deploy local validating Unbound and complete rdap-lookup, ip-lookup and my-ip.
  • Complete HTTP, security header, email authentication and TLS quick diagnostics.

Handoff (2026-09-16)

Where things stand at the end of the last session, for whoever picks the work up next.

  • A paste-ready brief for the next agent is in HANDOFF.md; keep it in step with this section.
  • main holds M0, M1, the M2 MAC family, Extract, IP tools, developer utilities and content (PRs #9 to #14). ci.yml and docker.yml are green on main. The latest published latest and sha-2357668 digests are in deploy/README.md.
  • PR #15 merged aggregate measurement. Its branch CI and image checks passed, including the compose smoke test, response headers and a SQLite write in the non-root API container. backend/metrics-tools.json is exported from the available local tool registry, copied into the web image build stage, packaged in the API wheel and guarded by a Node test.
  • The branch passed 153 Node 22 tests, 31 Chromium journeys, 153 pytest, npm run check (0 errors), npm run check:dashes, npm run build (79 pages), and npm run verify (58,700 assignments). The system Node binary in this development environment lacks TypeScript stripping support, so the unit suite used the npm-distributed Node 22 binary; CI provides standard Node 22.
  • No repository variables are set: PUBLIC_SITE_ORIGIN, PUBLIC_SITE_NAME, PUBLIC_SITE_TAGLINE and PUBLIC_SITE_CONTACT render as empty in CI and fall back to the defaults in site/src/lib/site.ts (Netbench, https://macaddress.app). That is fine until the domain decision.
  • No secrets are set for docker.yml: without DOCKHAND_WEBHOOK_URL and DOCKHAND_WEBHOOK_SECRET the publish still happens to ghcr.io and the deploy step exits 0 with a message. Nothing is deployed anywhere yet.

Next steps, in order

1. Build the M3 DNS and registration tools with controlled resolver behavior. 2. Use pinned public destinations for HTTP and TLS probes, then add the remaining M3 diagnostics.

Conventions that bite: no em or en dashes anywhere in authored text (npm run check:dashes fails the build stage); every site string comes from site/src/lib/site.ts; packages/ use erasable TypeScript only and relative imports carry the .ts extension; local tools may fetch shards under /data/ and nothing else; update this file and docs/FEATURES.md in the same commit as the code.

Known gaps carried into M2

  • API limits are in-memory per process; multi-worker correctness needs the SQLite layer that arrives with the scan queue (M4).
  • Cloudflare IP ranges are embedded in two places (backend/limits.py, deploy/caddy/cloudflare-ranges.caddy), dated 2026-09-15; refresh both together.
  • checkdmarc is pinned to 5.17.1 because 5.17.2+ requires cryptography 48+ while sslyze 6.3.1 caps it below 47; revisit when sslyze lifts the cap.
  • data/meta.json per-registry counts are pre-dedupe (they sum to 58,703) while the snapshot holds 58,700 records; the API reports both. Consider recording post-dedupe counts in the next refresh.
  • GitHub Action majors in the workflows match the donor's; setup-python and upload-artifact could not be verified against the current majors from this container.

Decisions still open (owner)

Domain shortlist; VPS provider and regions; merchant-of-record account; email provider for magic links and alerts; public contact address; timing of the macaddress.app redirect.

Source: docs/STATUS.md on GitHub.