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
| Milestone | State | Notes |
|---|---|---|
| M0 planning baseline | Done | Plan v2, research and reuse audit merged in PR #1 |
| M1 foundation | Done | Data 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 content | Done | The 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 diagnostics | In progress | Public-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 scans | Not started | |
| M5 release engineering | Not started |
M1 checklist
- Astro 7 project with the tool registry (55 tools, all planned until wired), page shell (donor layouts, header/footer, theme,
global.csswith a teal accent), tool layout with slots, command palette, favorites/recents, sitemap filtered to available tools,llms.txt,security.txt, dash-check lint.astro check0 errors; 72 pages build. - Shared packages
mac,detectwith 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, version137c777b20c1). - 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;weboncaddy:alpineservingsite/distwith hashed-inline-script CSP, cache rules and the security headers;apionpython: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 realcaddy validateand a live run against the built site. Image builds cannot run in the development container (no Docker daemon); CI proves them.docker.ymlrun 1 onmainfailed on a missingdocs/STATUS.mdcopy (PR #5), run 2 on the Caddy binary's file capability undercap_drop: ALL(PR #6), and run 3 passed end to end: both images built, non-root check, stack start behind theapihealth 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 undersite/src/components/tools/, behavior undersite/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) anddatasets. The snapshot build emits a complete local assignment search index and full-record JSON and CSV downloads with SHA-256 checksums andDatasetJSON-LD. - Identify
extractover text or local files, usingpackages/detectand the strict MAC extractor shared with Bulk MAC; dedupe, count, sort and compare two sets in a cancellable browser worker. packages/ipstrict IPv4/IPv6 parsing, exact CIDR math and 49 active IANA special-purpose prefixes; localsubnet-calculator,cidr-toolsand the local half ofip-inspector.- Local developer utilities:
base-convert,timestamp,uuid,encoders,hash,jwtdecode andregexwith a bounded browser worker. - Six launch guides, a datasets landing page with checksums and
DatasetJSON-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-lookupandmy-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.
mainholds M0, M1, the M2 MAC family, Extract, IP tools, developer utilities and content (PRs #9 to #14).ci.ymlanddocker.ymlare green onmain. The latest publishedlatestandsha-2357668digests are indeploy/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.jsonis 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), andnpm 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_TAGLINEandPUBLIC_SITE_CONTACTrender as empty in CI and fall back to the defaults insite/src/lib/site.ts(Netbench,https://macaddress.app). That is fine until the domain decision. - No secrets are set for
docker.yml: withoutDOCKHAND_WEBHOOK_URLandDOCKHAND_WEBHOOK_SECRETthe 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. checkdmarcis pinned to 5.17.1 because 5.17.2+ requirescryptography48+ whilesslyze6.3.1 caps it below 47; revisit when sslyze lifts the cap.data/meta.jsonper-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-pythonandupload-artifactcould 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.