
# 1 · Network identity and duplicates (demo, broadwater-lan / home-lan)
PASS sites carry network namespaces
PASS identity key = namespace|protocol|host|port|upsName
PASS SNMP identity has no UPS name and default port 161
PASS host alone is not an identity (incomplete; legacy duplicateOf({host}) → null)
PASS loopback is per machine (namespace host:bw-pi-01)
PASS (a) rackups on 192.168.1.20 in broadwater-lan: draft created
PASS (a) rackups test success · CyberPower OR1500LCDRM1U
PASS (a) rackups selected → monitoring with first readings
PASS (a) deskups on the same server is a different identity → draft created
PASS (a) deskups generic serial "000000000000" is untrustworthy and decides nothing
PASS (a) deskups selected → second UPS asset
PASS (a) same identity again → hard duplicate "Already monitored by bw-pi-01 as BW NUT rack UPS"
PASS (a) another draft with the same identity is a hard duplicate too
PASS (b) home-lan 192.168.1.20 rackups allowed (different namespace)
PASS (b) it is a different physical UPS (Eaton 5P 1550, G355K12345), no duplicate
PASS (b) selected → monitoring
PASS (c) 10.0.20.15 from bw-pi-01 → "Already monitored by bw-pi-01 as BW Office UPS" (blocked)
PASS (c) 10.0.20.15 from another Broadwater collector (bw-pi-02) → blocked, same namespace
PASS (c) 10.0.20.15 from home-lan is a different identity → no duplicate; nothing answers there (unreachable)
PASS soft: 10.0.20.16 card reports BW Rack UPS serial → "Possibly the same UPS as BW Rack UPS (serial match) — confirm"
PASS soft: selectSource asks for confirmation (never a hard block)
PASS soft: proceeds with {confirmDuplicate:true}
PASS untrustworthy serials rejected: "" "0" "000000000" "UNKNOWN" "Default" "123456789" "AAAAAAA" "AB12" "000000000000"
PASS real serials trusted (CRMA2231045, G355K12345)
PASS serial match with inconsistent vendor/model is ignored
PASS collector.networkNamespace overrides the site namespace
PASS 10.0.30.5:3493 duplex-rack in duplex-lan → success (CLI example)
PASS 192.168.1.99 → unreachable
PASS 192.168.1.22 office → rejected (credentials)
PASS 192.168.1.26 → unsupported (partial)
PASS home-lan 192.168.1.20 has no "deskups" → unreachable with the server’s UPS list
PASS ESP32 probes cannot add network sources

# 2a · Gating on home-laptop (demo · macOS ordinary workstation, connectivity-only, asleep since 13:05)
PASS home-laptop starts asleep, UPS role off
PASS configure NUT home-lan 192.168.1.20 rackups while asleep → saved as draft
PASS credential instruction is macOS: sudo mainskeeper sources auth <source>
PASS test while asleep → unavailable, queued, never success
PASS reason: "home-laptop is asleep — test will run when it reports"
PASS selectSource while asleep → saved "Configured — waiting for collector", no UPS asset
PASS enable UPS role → desired on, pending (asleep)
PASS checkIn while asleep → not reporting, role stays pending
PASS source state while asleep: Configured (gate: collector + role)
PASS reconnect → reporting again; demo clock advanced past 15:22:00 (15:22:30)
PASS check-in at reconnect applied the UPS role (applied ≥ reconnect)
PASS seeded reporting_interval 120 s (pending since 13:20) applied at the check-in
PASS queued test ran at the check-in → success
PASS test now succeeds (≥ reconnect time)
PASS select → monitoring
PASS first readings recorded at/after reconnect (15:22:57 ≥ 15:22:30)
PASS first-readings event timestamp ≥ reconnect
PASS UPS reading On schedule (120 s cadence applied)

# 2b · Gating on an account-dataset connectivity-only collector (first run)
PASS account site namespace "<slug>-lan" = cabin-lan
PASS approve WDJB-MJHT → studio-mbp, ordinary workstation, connectivity only, reporting
PASS NUT 192.168.1.20 rackups on the simulated LAN → test success (collector reports; role not needed to test)
PASS select with UPS role off → saved "Configured — waiting for UPS role", no UPS asset, no readings
PASS source state = waiting-for-role
PASS role desired on → pending until check-in
PASS check-in applies the role and starts monitoring automatically
PASS first readings ≥ role-applied time (15:22:57 ≥ 15:22:30)
PASS workstation goes to sleep (review aid) → asleep; UPS last known, not current
PASS test while asleep → unavailable (queued) with reason
PASS select while asleep → saved "Configured — waiting for collector"
PASS recordReadings while asleep records nothing (gated)
PASS reconnect → queued test runs, the waiting source starts monitoring; first reading ≥ reconnect
PASS the first UPS resumes after reconnect; the sleep gap is not back-filled
PASS account virtual clock advanced (now 15:24:00)

# 2c · Witness down: nothing after 15:04:12 from home-studio or Office Desk UPS
PASS no readings, heartbeats, events, series points, power states or probe results after 15:04:12
PASS Office Desk UPS last reading 15:04:12, last known
PASS freshness: Stale · last known 15:04 (collector not reporting)
PASS home-esp32-garage reporting → site reachable (collector failure), never Office Desk power
PASS control: default scenario Office Desk UPS keeps reporting

# 3 · History inclusion rule and unknown propagation
PASS 15:00–15:22 excludes yesterday’s Duplex episode (INC-0409)
PASS 15:00–15:22 excludes this morning’s Home 06:42 event
PASS 15:00–15:22 excludes the Duplex 14:03–14:30 episode and 13:41–14:30 probe interval
PASS 15:00–15:22 includes the ongoing BW Rack episode and the 14:54–15:02:06 probe interval
PASS point rule: from ≤ t ≤ to (boundaries inclusive)
PASS interval without endAt and not ongoing = point (no implicit "until now")
PASS eventsFor uses the same rule
PASS yesterday 21:00–21:40 Duplex includes INC-0409 episode
PASS replayed 14:03 record keeps observation-time placement (in 14:00–14:10, not in 15:15–15:20)
PASS series: no Office Desk point after 15:04:12
PASS series: gap 15:04:12–15:22 "No records — collector not reporting"
PASS power lane: utility ends 15:04:12, UNKNOWN to 15:22
PASS hourly aggregate 15:00: coverage reduced (not filled) with the unknown label
PASS aggregate carries minute-precision unknown span to now
PASS UPS availability: ≥ 17 unknown minutes, counted as unknown (not up/down)
PASS UPS availability 15:00–15:22 (exact): 4.2 min observed on utility, 17.8 min unknown
PASS Home site 15:00–15:22: probe results unknown after 15:04 (coverage < 1)
PASS history() lists the unknown span for the selected UPS

# 4 · Freshness vs configured cadence
PASS 30 s: 42 s On schedule (g 30 s; ≤ 60)
PASS 30 s: 61–90 s Overdue, 91 s Stale
PASS 600 s: g = 300 s; 420 s On schedule; ≤ 900 On schedule
PASS 600 s: 901–1500 Overdue, 1501 Stale
PASS old thresholds gone: 300 s at a 600 s cadence is On schedule (was Stale after 300 s)
PASS interval clamped to 10–600 s
PASS contact lost → Stale · last known
PASS absolute age shown separately ("read 42 s ago")
PASS fixture: BW Office UPS (SNMP, 600 s) On schedule at 420 s
PASS JSON ups[].freshness = {state, ageSeconds, expectedIntervalSeconds, allowanceSeconds}
PASS legacy staleness()/readingStaleness() use the source interval
PASS BW Office series: no value filled after the last report (awaiting next report)
PASS heartbeat 30 s: On time ≤ 60 s, Late > 60 s, Contact lost > 300 s
PASS heartbeat 300 s: Late > 600 s, Contact lost after 900 s (3H)
PASS policy legend has no ≤ 60 s / ≤ 5 min reading thresholds
PASS bw-pi-01 effective heartbeat = 15 s local override

# 5 · Platform-specific instructions
PASS Windows: no sudo; elevated terminal note
PASS Windows: C:\ProgramData\MainsKeeper\collector.toml · DPAPI LocalMachine · Event Viewer logs
PASS cmdFor('sources auth', {platform:'windows'}) has no sudo
PASS ESP32: no host CLI, elevate → null, setup page
PASS cmdFor on ESP32 → line null + setup-page note
PASS ESP32 credential help → local setup page (http://home-esp32-garage.local)
PASS macOS: sudo · /Library/Application Support/MainsKeeper/collector.toml · Keychain · /Library/Logs/MainsKeeper/
PASS macOS credential help: sudo mainskeeper sources auth src-x · Keychain item "MainsKeeper source src-x"
PASS Pi/Fedora: sudo · /etc/mainskeeper/collector.toml · secrets.d 0600 · journalctl -u mainskeeperd
PASS platformFor: bw-pi-01 pi · home-studio macos · home-esp32-garage esp32
PASS effective(bw-pi-01, snmp_v3_secrets).command = sudo mainskeeper sources auth src-bw-office-snmp
PASS contractFor(ESP32): secrets on the setup page; local keys fixed in firmware
PASS contractFor(macOS): local keys at /Library/Application Support/MainsKeeper/collector.toml with sudo
PASS Windows collector den-win-01 approved (account)
PASS contractFor(Windows): ProgramData path, no sudo; secrets DPAPI; elevated terminal
PASS addNetworkSource on Windows: authCommand without sudo
PASS credential error on Windows names the elevated terminal, no sudo

# 6 · UPS role on → off → on: effective monitoring governs observation (demo, bw-pi-01)
PASS NUT deskups on bw-pi-01 is monitored (first readings)
PASS roles → connectivity-only applied at check-in
PASS after +5 min: created UPS last reading frozen at or before the role change (15:22:27)
PASS created UPS: comm last-known, monitoring disabled, status not current
PASS fixture UPSs on bw-pi-01 (BW Rack, BW Office) also stop at the role change — no refreshed timestamps
PASS freshness: "Monitoring disabled · last known" (not On schedule), JSON state stale + monitoring disabled
PASS source: Monitoring disabled — UPS role off
PASS power lane: disabled (unknown) from the last reading to now — no current utility power
PASS series: no point after the last reading; gap "No records — UPS monitoring disabled"
PASS observations(): no UPS reading after the role change
PASS history(): disabled span listed as unknown
PASS availability: disabled minutes counted as unknown, not utility
PASS recordReadings refuses while the role is off (gated: role)
PASS re-enable pending: still disabled, last reading unchanged
PASS check-in applies the role, then a NEW reading resumes monitoring (resumed: bw-rack-ups, bw-office-ups, apc-back-ups-rs-1500)
PASS intervening gap preserved: 15:22:27–15:27:57 (last reading → first new reading)
PASS power lane: disabled span carved between observed spans; observed again after the new reading
PASS fixture BW Rack UPS resumes too, gap kept
PASS events: "Readings resumed" recorded for the created UPS

# 7 · Deferred activation: identify → reconcile → confirm before monitoring (demo, bw-pi-01, SNMP 10.0.20.16)
PASS test while disconnected: unavailable + queued (never success)
PASS select while disconnected: choice saved (waiting-for-collector)
PASS reconnect: queued test runs and succeeds
PASS reconnect does NOT activate: blocked on confirm-duplicate (possible BW Rack UPS)
PASS source identified at check-in (vendor, model, serial read from the endpoint)
PASS no UPS asset created; no unidentified UPS; no default 100 % charge
PASS source state: Identified — confirm possible duplicate (with the match reason)
PASS pending choice preserved while confirmation is outstanding (useRequested + name)
PASS a later check-in still waits for confirmation (never activates by itself)
PASS confirm → activates with the saved name and the identified model
PASS readings come from the identified device (no invented values)
PASS immediate path: untested → not-tested
PASS immediate path: identification runs before Use and the same confirm-duplicate applies
PASS identified device without a charge value: charge stays null ("Not reported"), never 100

# R1 · First run: createSite → approveEnrollment → selectSource → readings persisted
PASS approve BKTN-XRWP → garage-pi-02 with one discovered USB source
PASS select → UPS with first readings
PASS persisted in localStorage["mk-proto-v1"] (account: site, collector, UPS with readings)
PASS fleet counts: 1 of 1 expected collectors reporting · 1 of 1 UPSs communicating
PASS history before monitoring = Not monitored yet (unknown)

# R2 · Acknowledgment propagation via selectors
PASS acknowledge INC-0413 → one record
PASS visible in incident and ups-comms-lost datasets
PASS second acknowledge returns the existing record
PASS fleet counts include the acknowledgment

# R3 · INC-0412 restoration steps
PASS restored: clock 15:32, utility restored 15:31:00, recovered, acknowledged by jp
PASS restored: BW Rack power lane battery 15:09–15:31 then utility
PASS resolved: 15:36:00 after 5 min stable (clock 15:37)
PASS alert clears the walkthrough

# R4 · CLI examples: file count and credential-guard-safe names
PASS product/cli/examples has ≥ 121 files (found 151)
PASS no file name trips the credential guard ((credential|secret|passw|token|auth|apikey|api-key|private|\.pem$|\.key$|\.env$) + cli GUARD_RE credential|secret|token|auth|password|key)

# 8 · Monitoring gaps keep stable boundaries across later readings, repeated cycles and reloads (demo, bw-pi-01 deskups)
PASS cycle 1: gap 15:22:27–15:27:57 (last reading before off → first reading after on)
PASS a later normal reading does not move the closed gap (still 15:22:27–15:27:57)
PASS power lane carries the same single gap
PASS cycle 2: both gaps kept, first unchanged (15:22:27–15:27:57, 15:33:27–15:38:57)
PASS power lanes show both gaps with the same boundaries as the series
PASS history().unknown lists both gaps
PASS availability counts both gaps as unknown, exactly (11 min for 11 min of gaps), sums consistent
PASS hourly aggregate: both gaps carried with exact boundaries; the current hour's unknown minutes include them exactly
PASS more readings after cycle 2 move neither gap
PASS fixture BW Rack UPS (same collector) keeps its own two gaps, identical in series and lanes (15:22:26–15:27:57, 15:33:26–15:38:57)
PASS after a reload (new store instance from localStorage) both gaps are identical

# 9 · Exact monitoring-gap intervals: every gap kept in series, lanes, history, aggregate and availability (demo, bw-pi-01)
PASS A: series gap is exactly 15:22:27–15:22:57 (was empty on the minute grid)
PASS A: power lanes, history().unknown and the hourly aggregate carry the identical gap
PASS A: no chart segment bridges the gap and no point lies inside it
PASS A: 24 h availability counts exactly 0.5 min disabled-unknown; text is not "No unknown time"
PASS A: 24 h availability parts sum to the range (1440 min)
PASS A: current hourly bucket includes the 0.5 min gap in its unknown minutes
PASS A: clipped 15:22–15:23 → 0.5 min unknown, 0.5 min observed, coverage 50.0 %, identical in every selector
PASS display rounding only: fmt.minutes 0.5 → "30 s", 17.8 → "17.8 min", 4.2 → "4.2 min", 0.004 → "< 1 s"; fmt.duration 17.8 min → "18 min"
PASS A: fixture BW Rack UPS (same collector) keeps its own short gap 15:22:26–15:22:57, identical across selectors
PASS A: BW Rack UPS availability counts the exact sub-minute gap (0.5167 min), not "No unknown time"
PASS B: series keeps both gaps 15:22:27–15:28:27 and 15:28:42–15:34:12 (0.1.9 lost the second)
PASS B: power lanes, history().unknown and the hourly aggregate carry the identical two gaps
PASS B: segments split at both gaps; no point inside either gap
PASS B: the 15 s observed interval stays observed (utility lane 15:28:27–15:28:42) with no invented series points
PASS B: 24 h availability counts exactly 11.5 min disabled-unknown (6 min + 5.5 min)
PASS B: availability, series and aggregate agree on the disabled time
PASS B: clipped 15:25–15:30 → gaps 15:25:00–15:28:27 and 15:28:42–15:30:00 in every selector
PASS B: clipped 15:25–15:30 → 4.75 min unknown, 0.25 min observed, coverage 5.0 % (series 285 s, bucket 4.75 min)
PASS B: 15:28:30–15:28:40 is exactly 10 s, zero unknown, 100% coverage in aggregate, series and availability
PASS B: 15:25:15–15:30:15 is exactly 5 min, 4.75 min unknown, 5% coverage across selectors
PASS B: aggregate power shares and pending share use the exact requested duration
PASS B: 10 s wholly inside a gap is exactly 10 s unknown and 0% coverage
PASS B: exact aggregate clipping also holds for bw-rack-ups
PASS B: exact aggregate clipping also holds for apc-back-ups-rs-1500
PASS B: per-hour duration intersections sum to 30.5 min, with 15 s in the first bucket
PASS B: fixture BW Rack UPS keeps both of its gaps 15:22:26–15:28:27, 15:28:41–15:34:12, identical across selectors and in availability
PASS B: later readings move neither gap
PASS B: a third short cycle adds a third gap and keeps the first two unchanged (15:22:27–15:28:27, 15:28:42–15:34:12, 15:37:27–15:37:57)
PASS B: after a reload (new store instance from localStorage) all gaps and the exact unknown minutes are identical
PASS B: after reload both fractional ranges keep exact aggregate duration, unknown time and coverage

PASS · 210 passed · 0 failed
