100 lines
13 KiB
Markdown
100 lines
13 KiB
Markdown
# Session Log — 2026-05-30 (work spanning 2026-05-29 evening → 2026-05-30)
|
|
|
|
## User
|
|
- **User:** Mike Swanson (mike)
|
|
- **Machine:** GURU-5070
|
|
- **Role:** admin
|
|
|
|
## Session Summary
|
|
|
|
The session opened as a GuruRMM feature request ("Mobile device support") and ran through the `/feature-request` flow. After clarifying scope (MDM for phones/tablets **plus** a GuruRMM mobile agent app — treated as one coherent feature), produced `SPEC-017-mobile-device-support.md`. The central technical finding documented: the iOS/Android capability asymmetry — an Android Device Admin app delivers real remote lock/wipe with no server certificate, but a sandboxed iOS App Store app cannot lock/wipe without an MDM enrollment profile (which needs the free Apple MDM Push Certificate). Mike then confirmed ACG now holds **both** Apple certificates (Developer Program + signing, and the MDM Push Certificate), so the spec was updated to mark both iOS phases Apple-cert-unblocked, with the annual MDM-push-cert renewal trap flagged.
|
|
|
|
The bulk of the session was a full GuruConnect (GC) modernization effort. Mike asked whether a `gc-audit` equivalent to `/rmm-audit` existed; it did not, so a `gc-audit` skill was authored, adapted to GC's actual architecture (protobuf wire format, runtime sqlx, Gitea Actions CI, static-HTML+component-library dashboard) rather than copying RMM assumptions. The skill was then run as a dry run: seven parallel/ sequential audit passes on Opus surfaced **three CRITICAL relay-plane auth failures** (any-JWT-joins-any-session, viewer-WS blacklist bypass, JWT-accepted-as-agent-key) plus the dashboard's wire-incompatible "protobuf" decoder, a stubbed deploy step leaving production 57 commits stale, and several HIGH/MEDIUM items. The audit report was committed and the skill was refined (use `.claude/standards/` as the compliance baseline; reconcile all `docs/specs/SPEC-*.md` + `specs/*/plan.md` `[DONE]` markers; tag already-planned findings `[TRACKED]` during a rebuild).
|
|
|
|
Mike then directed a ground-up re-spec. Produced `SPEC-002-v2-modernization-architecture.md` from four locked decisions: greenfield-but-salvage-proven-Rust-cores; native-first with full key fidelity (Win+R / Ctrl+Alt+Del / clipboard) and WebRTC only as a fallback; standalone-first with a versioned `/api/integration/v1/` RMM contract; hardened single-tenant now with a tenancy-ready schema. File transfer (clipboard cut/paste + drag-and-drop, bidirectional) was elevated to a headline differentiator after Mike named it as a favorite ScreenConnect feature. `/shape-spec` then produced `specs/v2-secure-session-core/` (Phase 1).
|
|
|
|
The Phase-1 keystone was implemented end to end across four tasks, each via a Coding Agent (Opus) → mandatory Code Review (Opus) → Gitea Agent commit loop: Task 1 (v2 schema + per-agent `cak_` keys + tenancy-ready columns), Task 2 (auth rebuild deleting the JWT-as-agent-key branch, session-scoped viewer tokens, per-agent key issuance, folding in a pre-existing machine-metadata bug fix), Task 3 (secure relay WS — viewer-token verification with blacklist + session-claim match, agent identity binding, frame caps, input throttle), and Task 4 (in-memory rate limiting + single-use widened support codes). A review-driven authorization-strength fix split viewer tokens into VIEW_ONLY vs CONTROL gated on permission, fully closing CRITICAL #1. Because the dev machine has no Rust toolchain, all code was verified on the build host (172.16.3.30) and confirmed compiling + passing tests (32/32), and the Gitea Actions CI was confirmed green. Every audit CRITICAL and HIGH in the auth/session core is now remediated in code.
|
|
|
|
The session closed with a `/sync` (pulled four of Howard's auto-sync commits) and a radio-show task: set the "promised vs got / best invention" episode to today's date (Saturday 2026-05-30), preserved Howard's Segments 1-2, and expanded the reserved Segment 3 into a topical May-2026 tech-news segment (AI glasses, AI-and-jobs, subscription squeeze, orbital data centers, AI security reality check, gadget hits) using live web research, since the assistant's training only runs to ~Jan 2026.
|
|
|
|
## Key Decisions
|
|
|
|
- **SPEC-017 scope:** treat "mobile device support" as MDM + a GuruRMM mobile agent app together; document the iOS/Android lock-wipe asymmetry rather than over-promising iOS parity.
|
|
- **gc-audit adapted, not copied:** GC uses runtime sqlx (not RMM's macros — and CLAUDE.md's "compile-time checked queries" line is stale), protobuf wire format, Gitea Actions CI, and a static-HTML+component-library dashboard. The skill's passes were rewritten accordingly; Pass B's initial "macros are the GC norm" rule was later corrected to flag new `query!` macros as a `[LOW]` deviation.
|
|
- **GC v2 direction (4 locked decisions):** greenfield-salvage-cores; native-first full key fidelity (WebRTC fallback only); standalone-first + versioned RMM contract; hardened single-tenant with a tenancy-ready (nullable `tenant_id`) schema so Phase 4 flips on isolation with no migration rewrite.
|
|
- **File transfer elevated:** clipboard cut/paste + drag-and-drop (both directions) made a core differentiator with a delayed-render clipboard design, not a deferred panel.
|
|
- **v2 sqlx + repo:** confirmed runtime `sqlx::query()` for v2 (GC already uses it); clean architectural reset in-place in the existing `guru-connect` repo (not a new repo).
|
|
- **Auth-strength (CRITICAL #1):** viewer-token minting gated on permission, and — after review found `view` is held by every default role — split into VIEW_ONLY (gated on `view`, relay refuses input) vs CONTROL (gated on `control`/admin) tokens. This is what actually closed CRITICAL #1.
|
|
- **Codec/transport/cutover:** H.264 default (HEVC opt-in); Phase-2 web viewer on protobuf-over-WSS first (WebRTC later); widened higher-entropy support codes; clean wholesale v1→v2 cutover (no client data to migrate).
|
|
- **Verification path:** with no local Rust toolchain, all Rust was verified by building + testing on the build host (172.16.3.30) and by confirming Gitea Actions CI, rather than trusting self-review.
|
|
- **Radio Segment 3:** built as a "present-day" bookend tying each item back to Segments 1-2; pulled live (web search) because training is stale for a same-day show.
|
|
|
|
## Problems Encountered
|
|
|
|
- **Gitea push failed mid-session** (internal :3000 refused, public 502) — a transient blip; later confirmed reachable and the pending commit had already been swept upstream by auto-sync. No loss.
|
|
- **Explore agent reported two GC docs at the repo root** (`FEATURE_ROADMAP.md`, `ARCHITECTURE_DECISIONS.md`) that actually live under `docs/`; caught and corrected the gc-audit skill's paths before finalizing.
|
|
- **CI red on Tasks 2/3/authz** — but only at the `cargo fmt --all --check` gate, which short-circuits before clippy/build/test, so the code had never actually compiled in CI. Verified on the build host that it compiled + passed; applied the fmt patch + two clippy one-liners (`8a01935`) → CI green.
|
|
- **Task 4 clippy red** — `empty_line_after_doc_comments` (rate_limit.rs) and two dead-code event constants (events.rs); fixed (`2118942`, build-host-verified) → CI green.
|
|
- **Audit authz finding:** Task 2/3's first authz gate used `has_permission("view")`, which is held by every default role, so it didn't actually narrow access; reviewer caught it, leading to the VIEW_ONLY/CONTROL split.
|
|
- **Coord todo POSTs failed twice on an em-dash** ("error parsing the body"); resolved by using ASCII-only text. (Same lesson recurred and was applied.)
|
|
- **No Rust toolchain on GURU-5070** — every Coding Agent could author but not compile; mitigated by build-host verification (172.16.3.30) for each task.
|
|
|
|
## Configuration Changes
|
|
|
|
**`azcomputerguru/guru-connect` (separate repo):**
|
|
- New: `docs/specs/SPEC-002-v2-modernization-architecture.md`, `reports/2026-05-29-gc-audit.md`, `specs/v2-secure-session-core/{plan,shape,references,standards}.md`.
|
|
- New (server): `migrations/004_v2_secure_session_core.sql`, `005_machine_metadata.sql`, `006_widen_support_code.sql`; `src/db/{agent_keys.rs,tenancy.rs}`; `src/auth/agent_keys.rs`; `src/api/machine_keys.rs`.
|
|
- Rebuilt/modified (server): `src/middleware/rate_limit.rs` (+mod.rs), `src/relay/mod.rs`, `src/api/sessions.rs`, `src/auth/{jwt.rs,mod.rs}`, `src/db/{machines,sessions,support_codes,events,users,mod}.rs`, `src/support_codes.rs`, `src/main.rs`, `Cargo.toml` (removed `tower_governor`).
|
|
- Episode/radio: n/a (different repo).
|
|
|
|
**`azcomputerguru/gururmm` (submodule):**
|
|
- New: `docs/specs/SPEC-017-mobile-device-support.md`; `docs/FEATURE_ROADMAP.md` updated (MDM checklist + Asset Location Tracking cross-link to SPEC-017).
|
|
|
|
**`azcomputerguru/claudetools` (this repo):**
|
|
- New: `.claude/skills/gc-audit/SKILL.md` (then refined twice).
|
|
- New memory: `.claude/memory/project_apple_mdm_certs.md`, `.claude/memory/project_guruconnect_v2_direction.md`; `MEMORY.md` index updated.
|
|
- Radio: created `projects/radio-show/episodes/2026-05-30-promised-vs-got-and-inventions/show-prep.md` (expanded, 25KB); `git rm` of `projects/radio-show/episodes/tbd-promised-vs-got-and-inventions/`.
|
|
- This session log.
|
|
|
|
## Credentials & Secrets
|
|
|
|
- No new secrets created.
|
|
- Gitea API token used for CI status checks: SOPS vault `services/gitea.sops.yaml`, field `credentials.api.api-token`.
|
|
- ACG holds both Apple certs as of 2026-05-29 (Developer Program + signing; MDM Push Certificate). **Still to capture:** the exact owning Apple ID and expiry for the MDM Push Certificate (renews annually on the same Apple ID or all enrolled iOS devices break) — see `.claude/memory/project_apple_mdm_certs.md`.
|
|
|
|
## Infrastructure & Servers
|
|
|
|
- **Coordination API:** `http://172.16.3.30:8001/api/coord` (locks, todos) — no auth.
|
|
- **Gitea (internal):** `http://172.16.3.20:3000` (azcomputerguru org). Public: `git.azcomputerguru.com` (NPM/Cloudflare; prefer internal).
|
|
- **GC build/deploy host:** `172.16.3.30` (Linux, Rust toolchain present; GC server runs on `:3002` behind NPM at `connect.azcomputerguru.com`; GC clone at `/home/guru/guru-connect`). Production GC binary was stale (git `1bfd476`, ~2026-01-18) vs submodule HEAD — deploy step is a stub.
|
|
- **Gitea Actions runners (online):** `guruconnect-builder` (ubuntu-latest), `pluto-guruconnect` (windows-msvc, on Pluto 172.16.3.36).
|
|
- GC DB: PostgreSQL on the GC host; v2 migrations 004-006 added (not yet applied to production).
|
|
|
|
## Commands & Outputs
|
|
|
|
- `cargo fmt --all` / `cargo clippy --all-targets --all-features -- -D warnings` / `cargo build --release --target x86_64-unknown-linux-gnu` / `cargo test --release` — run on `172.16.3.30` to verify GC v2 (no local toolchain). Note: must set `CARGO_BUILD_TARGET=x86_64-unknown-linux-gnu` on Linux because the repo `.cargo/config.toml` defaults to `x86_64-pc-windows-msvc`.
|
|
- GC v2 keystone test result on build host: `32 passed; 0 failed`.
|
|
- CI: build-and-test run on `2118942` — build-server, build-agent, security-audit all success.
|
|
- Coord todo POST: requires ASCII-only body (`text`, `created_by_user`, `created_by_machine` required); em-dashes cause "error parsing the body".
|
|
- `git rm -r projects/radio-show/episodes/tbd-promised-vs-got-and-inventions/` — old radio folder removed after writing the dated one.
|
|
|
|
## Pending / Incomplete Tasks
|
|
|
|
- **GC v2 Phase 1 remainder:** Task 5 (attended-mode consent — proto `ConsentRequest`/`ConsentResponse`), Task 6 (native viewer full key fidelity — WH_KEYBOARD_LL hook, scan-code injection, SAS for Ctrl+Alt+Del, clipboard sync), Task 7 (HW H.264 + raw/Zstd fallback). Then Phase 2 (file transfer + dashboard + web viewer), Phase 3 (`/api/integration/v1/` RMM contract), Phase 4 (multi-tenancy switch-on). Source of truth: `specs/v2-secure-session-core/plan.md` + `docs/specs/SPEC-002-*.md`.
|
|
- **Open coord todos (guruconnect):** `9a462965` (revoke viewer tokens on logout), `3c1f372a` (trusted-proxy client-IP keying — NPM-on-loopback collapses clients to 127.0.0.1), `542137df` (multi-instance fail-closed DB single-use gate). Plus two `TODO(audit-events)` comments in `db/events.rs`.
|
|
- **GC v2 deploy:** wire the real `deploy.yml` SSH step (currently a stub) and chain `cargo audit` into release/deploy; v1→v2 cutover after the product-capability tasks.
|
|
- **SPEC-017 mobile:** capture the Apple MDM Push Certificate's owning Apple ID + expiry; provision Google Play/FCM.
|
|
- **Radio:** Mike's "best invention" pick (Segment 2); refresh Segment 3 items if the show slips past 2026-05-30.
|
|
|
|
## Reference Information
|
|
|
|
- **Specs:** `guru-connect/docs/specs/SPEC-002-v2-modernization-architecture.md`, `guru-connect/specs/v2-secure-session-core/`, `guru-connect/specs/native-remote-control/`; `gururmm/docs/specs/SPEC-017-mobile-device-support.md`.
|
|
- **Audit report:** `guru-connect/reports/2026-05-29-gc-audit.md`.
|
|
- **gc-audit skill:** `.claude/skills/gc-audit/SKILL.md`.
|
|
- **Memory:** `.claude/memory/project_apple_mdm_certs.md`, `.claude/memory/project_guruconnect_v2_direction.md`.
|
|
- **Commit SHAs — guru-connect:** `486debf` (audit report), `5c60a10` (SPEC-002), `81e4b99` (shape spec), `fef8111` (T1), `41691bf` (T2), `0f25878` (T3), `a453e79` (authz split), `8a01935` (fmt/clippy), `bfcdbb5` (T4), `2118942` (clippy fix).
|
|
- **Commit SHAs — gururmm:** `417856e` (SPEC-017).
|
|
- **Commit SHAs — claudetools:** `e8ac759`, `df6a2dd`, `e5ccb6a`, `c670471`, `c70cd70` (gc-audit skill).
|
|
- **Coord todos (guruconnect):** done — `faf39fe0`, `c8916c89`; open — `9a462965`, `3c1f372a`, `542137df`.
|
|
- **Radio episode:** `projects/radio-show/episodes/2026-05-30-promised-vs-got-and-inventions/show-prep.md`.
|