# Session Log — 2026-05-31 (Howard — GuruRMM roadmap reconciliation + UI features) [work spanned 2026-05-30 evening → 2026-05-31]

## User
- **User:** Howard Enos (howard)
- **Machine:** Howard-Home
- **Role:** tech

## Session Summary

Started by reviewing the GuruRMM roadmap for small fixes, produced an HTML "show notes" summary, and then built and deployed an app-wide React ErrorBoundary for the dashboard. Reconciled the roadmap against actual code: confirmed BUG-008/013/014 were already fixed (commits e7ccc4e, 94234af) and corrected their stale "Open" statuses. Deployed the ErrorBoundary to production (dashboard v0.2.30) via the manual dashboard deploy path (paramiko SSH, no authorized key on Howard-Home so password auth from vault).

Ran a full roadmap reconciliation: 6 parallel general-purpose agents verified every checkbox-bearing section of the 2055-line FEATURE_ROADMAP.md + UI_GAPS.md against the live code (submodule 26f9779). The dominant finding was that the roadmap badly UNDERSTATED what is built. Applied 17 corrections: 8 bug status lines (BUG-001 agent temp collection landed; BUG-002/006 merged via PR #22; BUG-003 build-server.sh hardened in repo; BUG-007 all sqlx query! macros removed; BUG-009/010 isError handled; BUG-011 down to 3 :any); System Tray subsection (tray icon + connection-status flipped to [x] — a full gururmm-tray crate ships in the MSI, watchdog-supervised; 3 sub-items to [~]); per-site credentials, org multi-tenancy header, and discovery fleet view to [~]. Server/API (80+ items), Reporting, Bulk Actions, Client Portal, most Integrations, and Security/Infra all confirmed accurate as-is. Committed 070c50a.

Then executed the "finish in-flight partials" track (user-selected). Built + reviewed + deployed two UI-only features over already-complete backends: (1) MSPBackups agent↔backup mappings/verify UI (commit 22598c2) and (2) dev-admin user impersonation UI (commit 21c98dc — useAuth session swap with localStorage stash + full reload, app-wide amber banner in Layout, gated Impersonate button in Organizations). Discovered the planned third item (Discovery fleet-wide view) is NOT a pure partial — no all-sites aggregation endpoint exists, it needs new backend + RBAC-scoped cross-site query — so it was dropped (no stakeholder provenance; audit-generated). Deployed dashboard v0.2.32 with both features (origin-verified).

Lined up the remaining bug tails. Fixed BUG-009 + BUG-011 tails (commit def0d34, pushed, not yet deployed). Settled #4 (dashboard fleet counts): the Dashboard already loads the full agent list to render the prioritized-agents panel, so recomputing counts is free — wiring /stats would be redundant; the only cleanup is removing the unused /agents/stats + /metrics/summary endpoints (server change, deferred). Per user decision, #3 (AgentDetail Client row enrich) is server-only and was deferred behind the documented build-server.sh outage risk (BUG-003).

Finally, in response to a Howard feature request (the logged-in user now shows correctly post-BUG-013 but doesn't indicate local vs domain), wrote SPEC-021 (logged-in user domain & account-type detection) and added it to the roadmap with provenance. Spec covers Windows WTSDomainName + GetComputerNameEx (local-vs-domain) + NetGetJoinInformation (machine join state), a 4-field data model, and DOMAIN\user display with Local/Domain badges. Committed 932c701 → pushed 31d7f39.

## Key Decisions

- Wrote Howard-namespaced session logs (other users' logs exist for the same dates) rather than appending to the shared `*-session.md`.
- Delegated all production code generation to Coding Agents and all git ops to the Gitea Agent (some doc/trivial commits done directly for momentum), per the coordinator model. Reviewed every diff before commit (mandatory-review rule).
- Roadmap reconciliation: did NOT auto-change judgment-call markings (MSPBackups Phase-1 items, macOS agent [ ]→[~], code signing, dashboard "WebSocket live data" [x], BUG-001 roadblock prose) — surfaced them for a product decision instead.
- Dropped Discovery fleet-wide view: it has no stakeholder provenance (audit-generated) and isn't a UI-only partial (needs an RBAC-scoped backend endpoint — a security decision). Corrected my own earlier mis-bucketing of it.
- Impersonation design: full page reload on swap/exit (window.location.assign("/")) to guarantee no cross-identity React Query cache bleed; original admin token stashed in localStorage and restored on exit; logout clears impersonation keys.
- Deferred all server-touching tails (#3 Client row, #4 dead-endpoint removal) behind the build-server.sh risk documented in BUG-003 (2026-05-25 migration crash-loop outage; deployed copy still unhardened). Server rebuilds are not to be triggered casually as part of a bug sweep.
- SPEC-021 chosen over inline build: captured the Howard request as a spec first (provenance) before building, since it is full-stack (agent MSI rebuild + server migration + dashboard).

## Problems Encountered

- **Submodule fetch failure on /sync** (`fatal: not our ref d1b35f4`): an orphaned intermediate guru-connect submodule pointer from a rebased history broke `git fetch --recurse-submodules`. Resolved by recognizing the local auto-commit was redundant (both submodule SHAs already matched origin/main) and `git reset --hard origin/main`, then re-running sync cleanly.
- **paramiko helper UnicodeEncodeError**: vite's `✓` char crashed cp1252 stdout. Fixed by writing raw bytes via `sys.stdout.buffer.write`.
- **Multiline SSH command mangled**: Python `repr()` escaped newlines to literal `\n`. Fixed by base64-encoding the script and `base64 -d | bash` on the remote.
- **No authorized SSH key on Howard-Home** for guru@172.16.3.30: used paramiko password auth (vault) instead of system OpenSSH.
- **Public dashboard URL returns 403 to curl**: Cloudflare bot challenge (`cf-mitigated: challenge`), not a deploy failure — verified deploys at the origin nginx (localhost + Host header) instead.
- **Repeated non-fast-forward pushes** on the gururmm submodule: the build server's webhook auto-bumps dashboard package.json version ([ci-version-bump]) on each push. Handled by rebasing each commit onto the version bump (non-conflicting).

## Configuration Changes

GuruRMM submodule (`projects/msp-tools/guru-rmm`, repo azcomputerguru/gururmm):
- **Created:** `dashboard/src/components/ErrorBoundary.tsx`
- **Created:** `docs/specs/SPEC-021-logged-in-user-domain-detection.md`
- **Modified:** `dashboard/src/App.tsx` (ErrorBoundary wiring)
- **Modified:** `dashboard/src/api/client.ts` (mappings types + methods)
- **Modified:** `dashboard/src/pages/MSPBackups.tsx` (Backup Mappings section)
- **Modified:** `dashboard/src/hooks/useAuth.tsx` (impersonation session swap)
- **Modified:** `dashboard/src/components/Layout.tsx` (impersonation banner)
- **Modified:** `dashboard/src/pages/Organizations.tsx` (Impersonate button)
- **Modified:** `dashboard/src/pages/Logs.tsx` (BUG-009 tail — analysis-runs isError)
- **Modified:** `dashboard/src/pages/Updates.tsx` (BUG-011 tail — removed 3 :any)
- **Modified:** `docs/FEATURE_ROADMAP.md` (17 reconciliation edits + SPEC-021 entries)
- **Modified:** `docs/UI_GAPS.md` (reconciliation + 2 gaps marked complete)

ClaudeTools root:
- **Created:** `gururmm-small-fixes.html` (show-notes artifact, committed earlier in session)

Production build server (172.16.3.30): dashboard rebuilt + rsynced twice (v0.2.30, then v0.2.32) to `/var/www/gururmm/dashboard/`; backups under `/var/www/gururmm/dashboard.bak-*` (pruned to 3).

## Credentials & Secrets

- **gururmm-build server (172.16.3.30) SSH + sudo password:** `Gptf*77ttb123!@#-rmm` — vault path `infrastructure/gururmm-server.sops.yaml` (field under credentials; SSH password == sudo password). Used for paramiko deploys. No new secrets created.

## Infrastructure & Servers

- **Build/app server:** 172.16.3.30 (gururmm / gururmm-build), Ubuntu 22.04. SSH guru@172.16.3.30 (password auth from this machine — no key installed). Dashboard nginx root `/var/www/gururmm/dashboard/` (guru-owned); repo clone `/home/guru/gururmm`; build pipeline `/opt/gururmm/`.
- **Public dashboard:** https://rmm.azcomputerguru.com — fronted by Cloudflare (bot challenge 403s plain curl; verify at origin). API host rmm-api.azcomputerguru.com (not challenged).
- **Dashboard deploy (manual):** `cd /home/guru/gururmm && git pull; cd dashboard && npm run build; sudo rsync -a --delete dist/ /var/www/gururmm/dashboard/`. Webhook pipeline only builds agents/server, NOT dashboard.
- **Coord component updated:** gururmm/dashboard → deployed, v0.2.32.

## Commands & Outputs

- Deploy verify (origin, bypassing Cloudflare): `curl -fsS -H "Host: rmm.azcomputerguru.com" http://127.0.0.1/` → HTTP 200; bundle grep confirmed feature strings ("Backup Mappings", "Impersonating") present.
- Submodule sync recovery: `git reset --hard origin/main` (dropped redundant auto-commit referencing orphaned submodule ref).
- paramiko SSH pattern: base64-encode script locally → `echo <b64> | base64 -d | bash` (or `sudo -S -p '' bash`) on remote; `sys.stdout.buffer.write` for byte-safe output.

## Pending / Incomplete Tasks

- **Deploy BUG-009 + BUG-011 tails** (commit def0d34) — pushed, not deployed; trivial dashboard rsync whenever.
- **#3 AgentDetail Client row enrich** — server-only (get_agent hardcodes client_name: None; enrich via site→client JOIN, add client_id to AgentResponse). Deferred behind build-server.sh risk. Scoped: `server/src/db/agents.rs` (From<Agent> at :68, AgentWithDetails JOIN at :315-319), `server/src/api/agents.rs` get_agent at :124.
- **#4 Remove dead endpoints** `/agents/stats` + `/metrics/summary` (unused; Dashboard recompute is correct since it loads the list anyway) — server change, deferred.
- **BUG-015** (agent not in Programs & Features) — WiX ARP props per SPEC-011; needs MSI rebuild + Windows verification. Howard-reported.
- **SPEC-021** (logged-in user domain/account-type) — spec written; build pending (agent Windows + migration + dashboard; full multi-deploy).
- **Judgment-call roadmap markings** to settle: MSPBackups Phase-1 items (verify alert-emission path then likely [x]), macOS agent [ ]→[~]?, agent code signing [ ]→[~]?, dashboard "WebSocket live data" [x]→[~]?, BUG-001 roadblock prose (stale — a Windows LHM-via-WMI reader path now exists in code).
- **Server batch (BUG-003 prerequisite):** consider hardening the DEPLOYED build-server.sh before any server rebuild.

## Reference Information

- **gururmm commit SHAs:** ErrorBoundary 5dd7d80; roadmap reconcile 070c50a; MSPBackups mappings 22598c2; impersonation 21c98dc; UI_GAPS complete 9ff9c52; BUG-009/011 tails def0d34; SPEC-021 932c701 → final pushed tip 31d7f39. (Interleaved [ci-version-bump] commits: 26f9779, 43d2bef, 8283ca2, etc.)
- **claudetools parent sync tips:** a26b410, c444166, 6fbc5a0, 1ff8a72.
- **Already-fixed bug commits:** BUG-008 e7ccc4e; BUG-013/014 94234af; BUG-002/006 PR #22 (943edd0/98b97bd, merge e6d1e9c); BUG-003 hardening 7146f4b; BUG-007 macros removed.
- **Specs:** SPEC-021 `docs/specs/SPEC-021-logged-in-user-domain-detection.md`; related SPEC-010 (agent UX), SPEC-011 (ARP/BUG-015), SPEC-018 (valuable errors / BUG-008 successor).
- **Roadmap:** `projects/msp-tools/guru-rmm/docs/FEATURE_ROADMAP.md` (2055 lines), `docs/UI_GAPS.md`.
- **Dashboard versions deployed:** v0.2.30 (ErrorBoundary), v0.2.32 (mappings + impersonation). Live bundle index-Di8C-nbq.js.
- **BUG-013 agent code:** `agent/src/metrics/mod.rs:541-554` (WTSGetActiveConsoleSessionId + WTSQuerySessionInformationW) — SPEC-021 extends this.

---

## Update: 20:37 PT — SPEC-022 Windows Update management + Phase 1 shape-spec

### Session Summary

Howard requested a feature: GuruRMM control of Windows Update on managed devices (block/allow/delay/remove, like Syncro), with a policy toggle, monitoring of offered updates and their known issues, and eventual Apple support (Windows first). Held a design discussion covering the two control mechanisms (WUA COM API for per-update actions incl. IsHidden to block a KB; WUfB registry policy for deferral/pin/active-hours), how other RMMs do it (approval + rings + the auto-approve-after-N-days "delay insurance" + the fact that Windows doesn't natively tell you a patch is bad), and the Apple reality (real OS-update control needs MDM/DDM, ties to SPEC-017).

After Howard answered the shaping questions (full loop; best-MSP approach; an ACG-controlled known-issues DB plus pulling official MS reports; both site-policy and per-device override; meet/exceed competitors without taxing devices), ran two parallel general-purpose research agents (web) to ground the design: (1) official programmatic sources for update intelligence, (2) RMM best practices + authoritative WUfB keys + WUA scan efficiency. Findings: the MS Graph Windows Updates API (beta) exposes knownIssue->KB with app-only auth (the authoritative "bad patch" spine); MSRC CVRF API (anonymous) maps CVE<->KB<->severity; CISA KEV + FIRST EPSS give exploitation urgency; AskWoody/blogs are license-locked (manual only); Update Catalog has no API (scrape via MSCatalogLTS or WSUS server-sync); and our own fleet install-failure telemetry is the proprietary signal no competitor can license. Efficiency answer: offline wsusscn2.cab daily compliance scan (cached, jittered, event-driven) + online only on demand.

Synthesized all of it into SPEC-022 (Windows Update Management & Patch Intelligence) — dual engine, full loop, site+device policy, best-in-class approval model (deterministic precedence reject-wins + rings with auto-promote/auto-halt + CVE-risk prioritization), the patch-intelligence subsystem, conflict detection (WSUS/Intune/GPO), a meet-or-exceed comparison table, phasing (MVP->full), and a cited reference list. Marked it P1 on the roadmap and folded the old "Windows Update status"/"Patch management integration" lines into it.

On "continue", shaped SPEC-022 Phase 1 (monitor + manual control MVP) into a structured spec folder via /shape-spec: specs/windows-update-mvp/ with shape.md, plan.md (Task 0 commit + Tasks 1-8 with file refs + verification), references.md (Discovery subsystem as the structural analog + real file:line anchors), standards.md. Committed (Task 0 done).

### Key Decisions
- Researched before writing the spec (2 parallel web-research agents) rather than hand-waving the known-issues sourcing — it was the explicit hard part.
- Modeled the MVP on the existing Discovery subsystem (scan command -> result message -> DB table -> dashboard tab) — closest proven analog; reuse end to end.
- WU policy fields ride in the existing PolicyData JSONB (no parallel policy system); site/device resolution reuses the effective-policy merge.
- Agent WUA access via the SPEC-014 PowerShell-relay pattern for Phase 1 (native Rust COM deferred); Windows-only with explicit Linux/macOS no-ops (platform-parity).
- Phase 1 deliberately excludes auto-install/reboot, patch intelligence, rings, and macOS — lowest-risk slice that is still more than "Windows Update status".

### Configuration Changes
- Created: docs/specs/SPEC-022-windows-update-management.md
- Created: specs/windows-update-mvp/{shape,plan,references,standards}.md
- Modified: docs/FEATURE_ROADMAP.md (SPEC-022 P1 entry; folded old Software Management lines)

### Pending / Incomplete Tasks
- SPEC-022 build: start at Phase 1 Task 1 (DB migration + PolicyData windows_update section) — server-only, unblocks downstream. Full task list in specs/windows-update-mvp/plan.md.
- All prior-session pending items still stand (BUG-009/011 tails undeployed; #3 Client row + #4 dead-endpoint removal deferred behind build-server.sh risk; BUG-015; SPEC-021 build; judgment-call roadmap markings).

### Reference Information
- gururmm commits: SPEC-021 932c701; SPEC-022 b5562c3; windows-update-mvp shape-spec 6f31d22.
- claudetools parent tips: 1ff8a72, c5ce1a4, be938bd.
- Key data sources (SPEC-022 §17): MS Graph windowsUpdates knownIssue (beta), api.msrc.microsoft.com/cvrf/{yyyy-mmm} + /update-guide/rss, CISA KEV, FIRST EPSS, MSCatalogLTS.
- Spec folder to resume Phase 1: specs/windows-update-mvp/ (read all four files = full context).
