Compressed memory store 104 -> 71 files via four passes: - Syncro: 19 scattered feedback_syncro_* files merged into 3 rule files (api/billing/workflow) + an on-demand feedback_syncro_history.md for incident detail, quotes, and tech/product ID tables. - Four near-duplicate merges: Howard paste-safety, Pluto build server, Howard backend deferral, IX server access (ssh+tailscale). - Per-cluster rule/state/history split applied to GuruConnect (2->1), Dataforth (3->2), Cascades (7->3), GuruRMM (13->3). - New reference_resource_map.md: single auto-loaded cheatsheet for "do I have access to X and how do I connect from this machine?" - MEMORY.md rewritten to match the new layout. Health: broken backlinks 8->7, overlap clusters 12->5, orphans 17->0.
5.9 KiB
name, description, type
| name | description | type |
|---|---|---|
| GuruRMM operational rules — dev ownership, parity, builds, alerts, identify-by-IP, UNC | Six rules for working with GuruRMM. (1) RMM dev is Mike's domain — Howard does NOT code RMM (368/0 commits); GuruScan carve-out is Howard's. (2) Agent parity — Win+Linux+macOS in the same change. (3) Builds go through the Gitea webhook pipeline, never SSH. (4) Skip | feedback |
Technical reference (server / API / user_session / pipeline / agent sandbox): reference_gururmm. Project state + dev principles + pending setup: project_gururmm.
1. RMM dev / bugs / roadmap are Mike's — never route them to Howard
GuruRMM code, bugs, roadmap, and architecture are Mike's domain. Do NOT send RMM dev/bug coord messages to Howard.
Evidence (Mike, 2026-05-26): GuruRMM repo has 368 commits by Mike, 0 by Howard. I had escalated a stale roadmap bug (BUG-001) to Howard via a coord note; Mike corrected: "Howard hasn't done ANY code work on RMM." The /feature-request skill encodes the real model: Howard submits feature requests → Mike does the dev.
How to apply:
- RMM bug / dev / roadmap item → it's Mike's. Since Mike is usually the user, surface to him directly; don't send a coord note (a note to yourself is pointless).
- The broader principle: Howard defers backend / server / agent / DB / infra to Mike by default ("I don't like messing with things"). When wrapping an implementation with follow-up server-side items, note them as "deferred to Mike", not Howard's pending tasks. Don't proactively suggest Howard implement server or agent changes.
GuruScan carve-out (projects/msp-tools/guru-scan/):
- GuruScan IS Howard's project. Coord notes about GuruScan correctly go to Howard.
- Don't conflate GuruScan with GuruRMM because the names rhyme or GuruScan may integrate with RMM.
- Leave GuruScan alone until Howard asks. Don't proactively review, audit, or modify its code — even after a sync pulls in big GuruScan changes (Mike, 2026-05-27, after I offered to review Howard's
GuruScan.psm1refactor unprompted).
See user_howard.
2. Agent parity — Win + Linux + macOS in the same change
"Add feature X to the agent" means all three platforms in the same commit. Delivering Windows-only and leaving Linux/macOS for later is not acceptable — same as not finishing the task (Mike, 2026-05-15).
Apply:
- If the implementation differs by platform, write all three variants.
- If a real implementation isn't feasible on a platform yet, ship a working stub +
// TODO(platform): <os> — <reason>in the same commit. - A silent no-op without a stub and TODO is treated as a bug.
- Full matrix in
.claude/CODING_GUIDELINES.md"GuruRMM Agent — Platform Parity".
3. Builds go through the Gitea webhook pipeline — never SSH manually
Never run build-agents.sh directly via SSH. All builds happen through the normal pipeline (push to main triggers it).
Why: manual runs execute as the SSH user (guru) instead of root, breaking log writes, artifact cleanup, and service restarts.
To trigger a build without a real change: push an empty commit:
git commit --allow-empty -m "chore: trigger build"
4. Skip #bot-alerts for internal infra / build / dev / recon
The /rmm skill says "post a one-line #bot-alert after every dispatch." Mike's clarification (2026-05-29): post a #bot-alert ONLY when the RMM command directly affects a client endpoint or a ticket (remediation, client machine change, ticket-linked work).
For internal infra (Gitea runner install, PLUTO build VM setup), CI/build orchestration, dev tooling, recon/inventory — SKIP the alert. Keeps the channel signal-high; it's a client/ticket activity feed, not a build log.
Apply: before dispatching via /rmm or the API, ask "does this touch a client or a ticket?" If no, do NOT call post-bot-alert.sh. Overrides the skill's blanket "alert after every dispatch" rule. See also reference_pluto_build_server.
5. Identify the agent by IP, don't recon every candidate
When a task names a machine by its external IP (e.g. an auth-failure source from a server log), identify the RMM endpoint by matching that IP — don't dispatch recon to every candidate agent.
Mike pushed back twice 2026-05-30 for probing both Pavon machines to find which had a stray GuruConnect client when the offending external IP was already known. Matching IP is one lookup; reconning all candidates is noisy and slow.
Apply: get the source IP from the relevant server's logs first. Until GuruRMM stores agent IPs natively (todo 7459428e, 2026-05-30 — no local_ip/external_ip fields yet), narrow candidates by site/client first, then have only the candidates report their external IP (Invoke-RestMethod ipify) and match. Once the server stamps external_ip from X-Forwarded-For, query /api/agents directly.
6. UNC paths in user_session need [char]92 — backslash literals get halved
Never use "\\CS-SERVER\..." string literals in PowerShell scripts dispatched via GuruRMM user_session context. The backslash gets halved somewhere in the encoding pipeline, producing \CS-SERVER\... (a local path) instead of the UNC \\CS-SERVER\....
The user_session execution wrapper processes escape sequences in the script text differently than system context, stripping one backslash from \\. system context (offline hive reg query) showed correct \\CS-SERVER output, so the issue is user_session-specific.
Apply: always build UNC paths explicitly when using user_session:
$bs = [char]92
$base = "${bs}${bs}CS-SERVER${bs}homes${bs}Username"
Constructs \\CS-SERVER\homes\Username correctly regardless of context.