Files
claudetools/.claude/skills/rmm-audit/SKILL.md
Mike Swanson 5ead5d4dee sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-19 17:56:56
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-19 17:56:56
2026-05-19 17:57:02 -07:00

405 lines
14 KiB
Markdown

---
name: rmm-audit
description: |
Periodic end-to-end verification of the GuruRMM codebase. Runs 5 parallel audit
passes: (1) API/route inventory cross-reference, (2) UI coverage and gap update,
(3) Rust code quality and standards compliance, (4) TypeScript/frontend quality,
(5) security and data integrity. Produces a timestamped audit report and updates
the living docs (UI_GAPS.md, FEATURE_ROADMAP.md). Takes 10-20 minutes.
Invoke explicitly only — no auto-trigger. Use /rmm-audit for a full audit.
Optional arg: --pass=<name> to run a single pass (api, ui, rust, ts, security).
---
# GuruRMM End-to-End Audit
Periodic full-stack sanity check. Read-only by default — findings are written to a
report file and living docs are updated. No code is changed.
---
## Execution Overview
```
Phase 0: Context load (coordinator reads key files)
Phase 1: Spawn 4 parallel audit agents
Phase 2: Collect findings, aggregate, score
Phase 3: Write report + update living docs
Phase 4: Present summary to user
```
The audit is orchestrated here (Claude coordinator). All heavy passes run in
parallel subagents. Each agent returns structured findings; the coordinator
aggregates and writes the final report.
---
## Phase 0: Context Load (Coordinator Reads These)
Before spawning agents, read these yourself:
1. `projects/msp-tools/guru-rmm/CONTEXT.md` — project overview and current state
2. `projects/msp-tools/guru-rmm/docs/UI_GAPS.md` — living gap tracker (may be stale)
3. `projects/msp-tools/guru-rmm/docs/FEATURE_ROADMAP.md` — planned features
4. `.claude/CODING_GUIDELINES.md` — development standards
Capture from `server/src/api/mod.rs` the complete route list (all `.route(...)` calls).
This becomes the **authority route list** passed to both the API and UI audit agents.
---
## Phase 1: Parallel Audit Agents
Spawn all four agents simultaneously in a single message. Each agent receives the
full context it needs inline — do not assume they share context.
---
### Agent A — API Coverage & Route Inventory
**Goal:** Find server endpoints with no dashboard UI exposure, and dashboard API
client functions calling non-existent or mismatched server routes.
**Instructions for agent:**
1. Read `server/src/api/mod.rs` in full — extract every `.route(path, method)` into
a list grouped by resource (agents, clients, sites, policies, etc.).
2. Read `dashboard/src/api/client.ts` — extract every API function and the URL path
it calls.
3. Cross-reference:
- Server routes with no client.ts function → **ORPHANED ROUTE** (dead code or
intentionally backend-only — distinguish by context)
- Client.ts functions whose URL doesn't match any server route → **BROKEN CALL**
- Server routes that exist but the client uses a different HTTP method → **METHOD MISMATCH**
4. Read `dashboard/src/App.tsx` (or wherever routes are defined) — list all frontend
pages and their paths.
5. For each API resource group, assess whether a UI page exposes the major CRUD
operations. Flag any resource that has full CRUD on the server but only partial
or no UI.
6. Return structured findings: `[SEVERITY] Description — file:line`.
---
### Agent B — Rust Code Quality & Standards
**Goal:** Find violations of the established Rust coding standards and common quality
issues across the server codebase.
**Instructions for agent:**
Read `.claude/CODING_GUIDELINES.md` first to know the rules. Then check:
**Compliance checks:**
- `.unwrap()` or `.expect()` calls outside of `#[cfg(test)]` blocks — these panic in
production. Flag every occurrence with context. Note: `.expect("invariant reason")`
in truly-impossible paths is acceptable if the reason is clear.
- `todo!()` or `unimplemented!()` macros in non-test production code paths.
- `sqlx::query!` / `sqlx::query_as!` macros (banned — project uses SQLX_OFFLINE=true
with runtime queries only).
- `format!()` used to construct SQL strings (injection risk — parameterize instead).
- `unwrap_or_default()` on `Option<String>` producing empty strings that get used as
real values without validation.
**Auth coverage:**
- Read `server/src/api/mod.rs` — identify which route groups use
`.layer(middleware::from_fn(...))` or similar auth middleware vs. which are public.
- Any non-public route that doesn't go through JWT auth or agent-key auth middleware
is a `[CRITICAL]` finding.
- Check that agent-key-authenticated routes cannot be accessed with JWT tokens and
vice versa (separation of agent vs. admin plane).
**Logging hygiene:**
- Grep for `tracing::` / `log::` calls that include agent keys, passwords, tokens,
or PII (email addresses, user names). These should use redacted representations.
**Error handling:**
- HTTP handlers returning 500 with `e.to_string()` — raw error messages can leak
internals to API callers. Should be logged server-side, generic message returned.
**Search paths:** `server/src/` only. Exclude `server/src/db/mod.rs` re-exports.
Return structured findings with file:line references.
---
### Agent C — TypeScript / Frontend Quality
**Goal:** Find frontend code quality issues, standards violations, and missing
UI patterns.
**Instructions for agent:**
**TypeScript quality:**
- `any` type annotations in `dashboard/src/` — each is a type safety gap.
- `@ts-ignore` or `@ts-expect-error` comments — note reason and whether they're
still needed.
- `console.log` / `console.error` left in production code (not in dev-only blocks).
- Hardcoded API base URLs instead of using `import.meta.env.VITE_API_URL`.
**Component patterns:**
- React components without error boundaries on data-fetching sections — if the
query throws, the entire page crashes.
- `useQuery` calls with no `isLoading` or `isError` handling — silent failures.
- Forms with no validation on submit (empty strings submitted as values).
- Missing `key` prop on mapped elements.
**API client completeness:**
- For each resource in `client.ts`, verify the TypeScript interface matches what
the server actually returns. Focus on fields that were added recently:
`Agent` should have `is_dc`, `maintenance_mode_note`, `agent_version`.
`AgentUsers` should have `is_dc: boolean`, `groups: GroupEntry[]`.
Any missing field means the UI silently shows `undefined`.
**Accessibility basics:**
- Buttons with icon-only content (no text) — need `title` or `aria-label`.
- Form inputs without associated `<label>` elements.
**Search paths:** `dashboard/src/` only.
Return structured findings with file:line references.
---
### Agent D — Data Integrity & Security
**Goal:** Verify migration sequencing, wire format consistency between agent and
server, policy system end-to-end completeness, and security boundaries.
**Instructions for agent:**
**Migration integrity:**
- List all files in `server/migrations/` — verify numbering is sequential with no
gaps (001, 002, 003... no 019a or skipped numbers).
- For each `CREATE TABLE` in migrations, verify a corresponding `db/<table>.rs`
module exists in the server.
- For each `db/<table>.rs`, verify the struct fields match the migration columns.
Focus on recently added columns: `agent_users.is_dc`, `agent_users.groups`.
**Agent ↔ Server wire format:**
- Read `agent/src/transport/mod.rs` — list all `AgentMessage` variants and
`ServerMessage` variants.
- Read `server/src/ws/mod.rs` — find the dispatch match arm for each incoming
`AgentMessage`. Any `AgentMessage` variant with no server handler is dead code
(or a missing implementation).
- Read `server/src/policy/config_update.rs` — list all fields in `AgentConfigUpdate`.
Cross-reference with `agent/src/transport/mod.rs` `ConfigUpdatePayload`. Any field
the server sends but the agent doesn't handle (or vice versa) is a silent drop.
**Policy system completeness:**
- Read `server/src/db/policies.rs` `PolicyData` struct — list all sections.
- Read `server/src/policy/merge.rs` — verify every section in `PolicyData` has a
corresponding merge function called in `merge_policy_data()`.
- Read `server/src/policy/config_update.rs` — verify every section in `PolicyData`
is either mapped to `AgentConfigUpdate` or intentionally server-side-only (like
`thresholds`). Document which is which.
- Check `server/src/policy/effective.rs` — are there assertions/tests for every
`PolicyData` section having a system default value?
**Version consistency:**
- `agent/Cargo.toml` version vs. the version string the server expects in heartbeats.
The server should not hard-reject agents on minor version differences.
- `server/Cargo.toml` version — is it being bumped on releases?
**WebSocket message validation:**
- In `server/src/ws/mod.rs`, for each `AgentMessage` variant that carries a payload,
is the payload validated before use? (e.g., empty hostnames, negative numbers,
excessively large strings that could be a DoS vector).
Return structured findings with file:line references.
---
## Phase 2: Aggregating Findings
Collect all four agents' outputs. Classify each finding:
| Severity | Meaning |
|----------|---------|
| `[CRITICAL]` | Security vulnerability, data loss risk, or production crash path |
| `[HIGH]` | Functional gap blocking a core workflow, or standards violation with user impact |
| `[MEDIUM]` | Code quality issue, UI gap, or inconsistency without immediate impact |
| `[LOW]` | Minor polish, dead code, missing comment |
| `[INFO]` | Neutral observation, completed item, or context note |
Deduplicate: if two agents flag the same issue from different angles, merge into one
finding with both references.
---
## Phase 3: Write Report + Update Living Docs
### Report Location
Write to: `projects/msp-tools/guru-rmm/reports/YYYY-MM-DD-rmm-audit.md`
(use actual date). If a report from today already exists, append a `-2` suffix.
### Report Format
```markdown
# GuruRMM Audit Report — YYYY-MM-DD
**Auditor:** Claude (claude-sonnet-4-6)
**Passes:** API Coverage, UI Gaps, Rust Quality, TypeScript Quality, Data Integrity
**Previous audit:** [link to prior report if one exists, else "First audit"]
---
## Executive Summary
| Pass | Total | Critical | High | Medium | Low |
|------|-------|---------|------|--------|-----|
| API Coverage | N | N | N | N | N |
| UI Gaps | N | N | N | N | N |
| Rust Quality | N | N | N | N | N |
| TypeScript | N | N | N | N | N |
| Data Integrity | N | N | N | N | N |
| **TOTAL** | **N** | **N** | **N** | **N** | **N** |
**Requires immediate action:** [list of CRITICAL findings in one line each]
---
## Pass 1: API Coverage
### [SEVERITY] Finding Title
**File:** path/to/file.rs:LINE
**Detail:** What the problem is, why it matters.
**Recommendation:** What to do.
[repeat for each finding]
---
## Pass 2: UI Gaps
[Same format. Cross-reference against UI_GAPS.md — note which items in that doc
are now COMPLETE vs. still open vs. newly discovered.]
---
## Pass 3: Rust Code Quality
[findings]
---
## Pass 4: TypeScript / Frontend Quality
[findings]
---
## Pass 5: Data Integrity & Security
[findings]
---
## UI_GAPS.md Delta
Items completed since last audit:
- [x] Example completed gap
Items still open:
- [ ] Example open gap — still unimplemented
New gaps discovered this audit:
- [ ] Example new gap
---
## Recommended Action Order
1. [CRITICAL items, sorted by impact]
2. [HIGH items]
3. [MEDIUM items — can be batched]
```
### Update UI_GAPS.md
After writing the report, update `docs/UI_GAPS.md`:
- Mark items `[x]` if the audit confirmed they're fully implemented
- Update "Last Updated" date
- Add any newly discovered gaps under the appropriate priority section
- Do NOT remove completed items — move them to the "Completed Features" section
---
## Phase 4: User Summary
Present a concise summary to the user:
```
Audit complete. Report: projects/msp-tools/guru-rmm/reports/YYYY-MM-DD-rmm-audit.md
CRITICAL (N): [one-line each]
HIGH (N): [one-line each]
MEDIUM (N): Batched in report.
UI_GAPS.md: N items marked complete, N new gaps added.
Recommended first action: [the single highest-priority finding]
```
Then ask: "Want me to start on any of these findings?"
---
## Conventions
- **Read, don't run.** This skill never executes code or makes API calls. It reads
files and uses Grep/GrepAI for search.
- **Derive from code, not docs.** Treat all `.md` documentation as potentially stale.
The code is truth.
- **Be specific.** Every finding needs a file:line reference. Vague findings ("the
code could be better") are useless.
- **No false positives.** If something looks like a problem but context makes it
acceptable, note it as `[INFO]` with the reason it's OK.
- **Severity is impact, not effort.** A two-line fix can be `[CRITICAL]` if it's a
security issue.
- **Commit the report.** After writing, delegate to Gitea Agent to commit the report
file (not the code changes — those are separate work items).
---
## Reference: Key Files by Area
### Server
| Area | Key Files |
|------|-----------|
| Routes | `server/src/api/mod.rs` |
| DB layer | `server/src/db/*.rs` |
| WebSocket | `server/src/ws/mod.rs` |
| Policy system | `server/src/policy/` |
| Migrations | `server/migrations/*.sql` |
### Dashboard
| Area | Key Files |
|------|-----------|
| Routes | `dashboard/src/App.tsx` |
| Pages | `dashboard/src/pages/*.tsx` |
| API client | `dashboard/src/api/client.ts` |
| Components | `dashboard/src/components/*.tsx` |
### Agent
| Area | Key Files |
|------|-----------|
| Wire format | `agent/src/transport/mod.rs` |
| WS handler | `agent/src/transport/websocket.rs` |
| Metrics | `agent/src/metrics/` |
| Users | `agent/src/users.rs` |
### Docs / Standards
| Area | Key Files |
|------|-----------|
| Coding standards | `.claude/CODING_GUIDELINES.md` |
| Feature roadmap | `projects/msp-tools/guru-rmm/docs/FEATURE_ROADMAP.md` |
| UI gaps tracker | `projects/msp-tools/guru-rmm/docs/UI_GAPS.md` |
| Architecture decisions | `projects/msp-tools/guru-rmm/docs/ARCHITECTURE_DECISIONS.md` |
| Past audit reports | `projects/msp-tools/guru-rmm/reports/` |