Skip to content
Implementation guide Fictional demonstration data Review launcher

Final design handoff 0.1.0 · checkpoint 0.1.13 · implementation source

MainsKeeper implementation guide

Start here to implement the selected design: Lattice’s identity and visual language, Datum’s equipment workflows, and the site-first dashboard. This package completes the design scope; it is an editable static prototype and implementation reference, not shipped production software.

Browser verification and screenshots skipped by user request. Visual and browser-interaction acceptance remain unverified.

1. Current decisions and MVP boundary

MainsKeeper monitors UPS condition and site connectivity across Broadwater, Home, Shop and Duplex. The dashboard starts with sites, then collectors, UPSs and powered equipment. UPS-monitoring and site-heartbeat roles are independently configurable. An ordinary sleeping workstation is not an expected always-on site witness.

Monitoring only: no UPS shutdown, outlet switching, equipment reboot, or other equipment-control functions. CLI service administration concerns the collector service, never control of attached equipment.

The installation target is one cohesive collector application followed by dashboard enrollment. macOS, Windows, Fedora/Linux, Raspberry Pi and ESP32 deployment patterns are designed; installers, native services and firmware still need implementation. ESP32 uses its local setup page and a validated adapter/capability model; it does not run the complete NUT stack or support arbitrary UPS hardware.

The existing mockups, tokens and shared CONTRACT.md are the implementation references. Read later correction sections before older foundation text. This guide maps those sources rather than replacing them. Concepts 1–9 and earlier round records are preserved as historical references, not alternative current directions. The proposed authentication flow is Cloudflare Access with GitHub; the static sign-in is simulated.

2. Entry points and source map

Extract either archive and open index.html. For a stable local origin, run python3 -m http.server 8765 --bind 127.0.0.1 from the extracted root, then visit http://127.0.0.1:8765/. No build or dependency installation is required for the static prototype. Use Reset demo before a documented journey.

Dashboard and sites
product/app/index.html — site-first fleet; site.html — evidence and availability; site-setup.html — site configuration.
Onboarding and enrollment
sign-in.html, welcome.html, install.html, enroll.html. Short-code browser approval, role selection, first readings and re-enrollment states.
Equipment and relationships
equipment.html, ups.html, relationships.html. Keep “reads / watches” separate from “powers”.
Incidents and notifications
incidents.html, incident.html, notifications.html, alert-rules.html, maintenance.html.
History and synchronization
history.html — ranges, evidence and coverage; sync.html — backlog, delayed records, clock uncertainty and losses.
Collectors, sources and configuration
collectors.html, collector.html, sources.html, network-source.html, collector-config.html.
CLI and complete state map
product/cli/index.html — proposed command surface and terminal mockups. Review product map, ten journeys and state coverage enumerate the alternate states without implying browser verification.

3. Brand, tokens and components

Brand export guide describes the interlaced-loop mark, wordmarks, lockups, app icons, favicons, clear space and minimum sizes. Editable SVGs remain in product/brand/. Use the existing files and theme variants.

tokens.css owns colors, Sora UI type, DM Mono data type, spacing, radii, focus, elevation and motion. base.css owns base typography and layout primitives; components.css and components.js own shared controls. Start with the component gallery and CONTRACT.md §§1–5. Product fonts and their SIL OFL notices are bundled; historical concepts retain their own fonts and licenses.

Keep both dark and light themes. Sodium denotes selection/focus, never severity. Status combines glyph and word with color. Body type is 16 px; the existing dense-table scale is intentional. Preserve visible focus, semantic labels, 44 px touch targets, reduced motion, nonwrapping numbers/units and full access to truncated data. Contrast figures in the contract are arithmetic token calculations, not visual acceptance.

Responsive intent is 375 / 768 / 1024 / 1440 px: bottom navigation at ≤767, a Menu control at 768–1023, and desktop navigation at ≥1024. Wide charts and tables scroll within their own frames. Keep space for fixed chrome. These rules exist in source and remain visually unverified.

Charts preserve gaps as gaps: separate observed segments, dashed UPS estimates, hollow delayed points with receipt times, hatched missing records and history-arriving intervals, uncertainty brackets and maintenance bands. No interpolation through missing observations. Availability always includes period, coverage, unknown time and exclusions.

4. Entity relationships and shared behavior

Sites, collectors, UPSs and equipment
A site groups collectors, circuits and equipment. Collectors carry site membership, independent roles, availability intent and capabilities. Sources identify local or network UPS adapters; a collector reads a UPS, while a UPS powers equipment. Preserve explicit relationship records instead of inferring them from labels. See CONTRACT.md §§6–8.
One state model
store.js owns prototype actions and localStorage["mk-proto-v1"]. fixture.js composes the active demo/account dataset and selectors. Re-read selectors after actions; do not duplicate page-local entities. Unknown IDs render not-found states. Cross-tab changes prompt reload. See §§12 and 19–22.
Evidence and incidents
Contact loss means the server stopped hearing from a collector; cause remains unknown. Keep UPS communications loss, locally confirmed connectivity failure and observed battery operation distinct. A silent witness while another reports is not site contact loss. First evidence, grace, declaration, acknowledgment, recovery and resolution are separate timestamps. Existing policy resolves after recovery plus five stable minutes; implementation must preserve that behavior unless explicitly revised.
Observation, receipt and replay
Offline records retain observation time and replay after reconnect. Show receipt time, backlog, missing records and uncertain clocks. Historical backfill updates observation-time history without duplicate or obsolete notifications; fresh active evidence remains alertable while backlog drains. UPS runtime estimates are predictions, separate from observed battery duration. Missing values never become zeros, confirmed outages, invented continuity or confirmed battery exhaustion. See §§15 and 18.
Roles, freshness and monitoring gaps
Role changes follow desired → pending → applied at eligible check-in, or fail with a reason. Keep sleeping/revoked/contact-lost gating and persistent stop/resume intervals. Freshness follows reporting cadence. Duration and coverage use exact requested-range intersections; metric sampling is separate. Preserve all short-gap, adjacent-gap, reload, range-clipping and coverage corrections in §§18–22 and state-checks.js.
Network source identity
Use namespace + protocol + normalized host + port + NUT UPS name. Exact duplicates are blocked. A trustworthy serial match at another identity asks for confirmation. A host alone is not identity, and a sleeping collector cannot execute a queued test. See §18.1 and §19; retain deferred duplicate confirmation.

5. CLI, enrollment and configuration ownership

config-contract.js is the single source for MK.cli.grammar, exit codes, platform instructions and configuration ownership. The command table, JSON contract, exit codes and platform table render it. cli-screens.js supplies mockups; build-examples.js generates the 151 bundled text/JSON examples. Example: status JSON. These are implementation contracts, not an installed CLI.

Keep enroll --reenroll, sources discover and sources use. A successful status query exits 0 even when equipment is on battery or stale; condition is in output/JSON. Preserve the existing enroll-expired/denied exit 1 and stalled-queue exit 0 behavior. A future --fail-on option is outside this scope.

Host read-only commands need no elevation. Local changes use the platform policy: macOS/Fedora/Pi use sudo when required; Windows uses an Administrator terminal without sudo; ESP32 has no host CLI. Use MK.cli.platform() and credentialHelp() for paths, secret stores and commands rather than copying Linux instructions everywhere.

Enrollment separates approval, first collector contact and first UPS reading. Waiting, confirmation, approved, expired, denied, offline and re-enrollment presentations remain available. Expired/denied/offline variants are display-only in this prototype; backend transitions are future implementation work.

Dashboard-owned
Site/name, roles, availability expectation, cadence and connectivity targets: desired → pending → applied/failed at check-in. Alert rules apply server-side. Only the documented heartbeat local override is allowed; show desired and effective values.
Local secrets
NUT credentials and SNMP secrets stay on the collector, entered through its platform flow. Dashboard shows Configured / Missing / Rejected and test time, never secret entry or delivery.
Local settings and capabilities
Host storage/logging are local and read-only in the dashboard. ESP32 storage/retention/logging are fixed in firmware. Capabilities are not settings. See the ownership table and CONTRACT.md §§13–14, 18.5.

6. Prototype limitations retained

See historical round-6 limits, round-5 limits and CONTRACT.md §§11, 18.8 for provenance. Historical questions do not request another concept round or gate this handoff. Existing command behavior, fixture endpoint 10.0.30.5, the seven-day prototype range and resolution policy are carried forward as the current baseline.

7. Future implementation work

  1. Choose backend/runtime, durable schemas, account authorization and API boundaries. Preserve entity identities, evidence timestamps, ownership and shared-state behavior; localStorage is only a prototype persistence mechanism.
  2. Implement signed distribution and collector lifecycle for the designed host platforms, dashboard enrollment, secure local credential storage, and capability-specific USB/NUT/SNMP adapters. Validate a constrained ESP32 board/UPS matrix and its real storage budget.
  3. Implement offline buffering, sequence/deduplication, observation-versus-receipt semantics, clock uncertainty, gaps, query ranges, aggregation, incident evaluation and notification delivery. Preserve replay suppression without suppressing new active evidence.
  4. Carry the existing tokens, components, accessibility intent and responsive rules into the application. Remove prototype review controls in the production implementation; retain them in this deliverable for traceability. Product visual/browser acceptance remains a separate unverified implementation obligation, not a prerequisite for this archive.

Decide operational retention, scale, migrations, authorization details, adapter certification and distribution strategy during implementation. Do not silently reinterpret unknown evidence or add equipment control. No browser-tool setup or repeated design correction round is requested by this handoff.

8. Verification and package provenance

The current verification record lists exact commands, fresh source results and inherited evidence. The 0.1.11 record retains 210 state checks, 151 matching CLI exports, 84 syntax checks and 2,531 local references. State/selector and CLI generation results are inherited, not rerun for documentation-only changes. The original 0.1.12 record is retained too.

Fresh checks cover JavaScript syntax, local HTML/CSS references, source preservation, and each packaging helper’s archive validation. No new test framework, browser check or screenshot is included. Packaging commands and source/helper provenance support reproduction.

Checkpoint 0.1.13 is the immutable review/resumption snapshot. Handoff 0.1.0 is the initial final design archive in a separate version series, not product version 1.0. Both contain the same authored payload. The handoff adds _handoff/README.md, a per-file manifest and SHA-256 inventory; the checkpoint adds its changelog. Earlier ZIPs, old generated package metadata, dependencies, caches, credentials and VCS internals are excluded.

Battery Assurance (0.2.2)