Files
nmon/docs/milestones

nmon build milestones

The build follows the six gated milestones in docs/spec/spec.md. Each milestone has its own document here. It is written before any code for that milestone and its Gate log is filled in when the gate passes. A milestone is done only when:

  1. make lint is clean: maintainability is a hard rule (docs/MAINTAINABILITY.md), and every gate script runs lint first,
  2. every acceptance line it closes (from build-detail.md) has a test that passes,
  3. make test (go test -race ./...) and make test-integration pass,
  4. its gate command (make gate-mN) passes when run by the supervisor, and
  5. the tree is committed and tagged mN.
# Milestone Gate Doc Status
M1 Skeleton and fixtures nmon serve polls the counters fixture and /api/v1/query returns rising ifHCInOctets M1 passed, tagged m1
M2 Discovery and profiles every fixture's expect.yaml passes, including v1 and v3, and the PDU budget holds M2 passed, tagged m2
M3 Graphs and UI a port's in/out graph renders at 1 h, 24 h and 30 d from the counters fixture M3 in progress (web UI done on mock data)
M4 Alerting stopping a parent fixture sends one notification naming it and its children M4 in progress (WP2 rules and WP3 notify done)
M5 Push ingest, rollup, checks a replayed Proxmox sample shows under its node and a 2 y query hits the 1 h tier M5 planned
M6 Auth and ops a viewer gets 403 on PUT and the 2,000-device loadtest cycle finishes under 40 s M6 planned
M7 gNMI streaming after v1; not built in this run — out of scope

How the work is run

  • Supervisor (Claude Opus): writes these docs, splits each milestone into work packages (WPs), reviews every diff, runs every gate command itself, commits and tags.
  • Implementers (Claude Sonnet sub-agents): one WP each. WPs in different internal/ packages run in parallel. Shared files (go.mod, cmd/nmon/*.go wiring, openapi.json, Makefile) are changed only by the supervisor or by the single WP that owns them in that milestone.

Departures from the spec are recorded in docs/DEVIATIONS.md.

Rules every WP follows (from "Decisions that don't move")

  • Maintainability is a hard rule. Follow docs/MAINTAINABILITY.md: zero golangci-lint and ESLint findings in your packages, the function, complexity and file-size limits, and the layering rules. Every WP brief cites it.

  • One static binary, CGO_ENABLED=0. No raw SQL outside internal/store.

  • The 60 s poll path talks only to devices (SNMP, ICMP) and the local hot store.

  • Metric labels on SNMP series: device=<slug>, plus iface=<ULID> on interface series. Nothing else.

  • Every port is polled, up or down. Only the profile's exclude_ifname patterns drop a port.

  • Rollups store rates, never raw counters.

  • IPv6 first: every network path works on v6 and v4; tests default to ::1.

  • Time comes from internal/clock. No time.Now()/time.Sleep in logic that a test must control.

  • Tests never need real hardware. Fixtures are .snmprec files served by internal/simagent.

Deferred (revisit after v1 milestones)

  • Deployment playbook: install layout (binary, /usr/share/nmon/mibs sidecar, systemd unit granting port 162, key file location), TLS/ACME or proxy setup, IdP configuration, backups, and upgrades. Raised by the user on 2026-10-22; deliberately postponed.

Review artifacts

  • From M3 on, each UI milestone's gate captures Playwright screenshots of every page into docs/screenshots/<milestone>/ for the user to review.