Files
claudetools/.claude/skills/gc-audit/SKILL.md
Mike Swanson c670471c8a fix(gc-audit): correct Pass B sqlx premise (GC uses runtime sqlx)
GC's db layer uses runtime sqlx::query()/query_as() throughout - zero
compile-time macros (verified during v2 Task 1; CLAUDE.md's "compile-time
checked queries" line is stale). Pass B now treats a NEW sqlx::query! macro
as a [LOW] deviation (reintroduces the .sqlx-cache footgun + build-time
DATABASE_URL) instead of blessing macros as the GC norm. Fixed both the
intro divergence note and the Pass B check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 18:39:35 -07:00

35 KiB

name, description
name description
gc-audit Periodic end-to-end verification of the GuruConnect codebase and CI/CD infrastructure. Runs 6 parallel audit passes: (1) API/route & surface inventory, (2) Rust code quality & standards, (3) TypeScript/dashboard quality, (4) protocol & wire-format integrity (proto <-> prost <-> manual TS decode), (5) security & remote-session integrity, (6) docs/roadmap reconciliation. A 7th sequential pass audits CI/CD pipeline health (Gitea Actions workflows, runner registration, clippy/audit gates, deploy host). Produces a timestamped audit report and updates the living docs (FEATURE_ROADMAP.md, TECHNICAL_DEBT.md). Takes 10-20 minutes. Invoke explicitly only — no auto-trigger. Use /gc-audit for a full audit. Optional arg: --pass=<name> to run a single pass (api, rust, ts, protocol, security, docs, pipeline). The docs pass reconciles FEATURE_ROADMAP.md, TECHNICAL_DEBT.md, the docs/specs/SPEC-*.md, and the specs/*/plan.md task markers against the code; quality passes check code against the granular .claude/standards/ files. Cleans up stale entries.

GuruConnect End-to-End Audit

Periodic full-stack sanity check for GuruConnect — the standalone MSP remote-desktop product (Rust/Axum relay server + Windows Rust agent + React/TS viewer component library, Protobuf-over-WebSocket transport). Read-only by default — findings are written to a report file and living docs are updated. No production code is changed.

This is GuruConnect, not GuruRMM. GC diverges from the RMM audit in ways that matter — do NOT copy RMM assumptions. The biggest traps, called out where they apply below:

  • GC uses runtime sqlx::query()/query_as() — NOT compile-time sqlx::query! macros (verified 2026-05-29; CLAUDE.md's "compile-time checked queries" line is stale, and v2 keeps runtime sqlx). This matches RMM. A new query!/query_as! macro is therefore a deviation worth a [LOW] (it reintroduces the .sqlx-cache-regen footgun + a build-time DATABASE_URL requirement), not the norm.
  • Wire format is Protobuf, not RMM's JSON AgentMessage/ServerMessage enums. The integrity pass chases drift across four artifacts: proto/guruconnect.proto → prost-generated agent code → prost-generated server code → hand-written binary decode in dashboard/src/lib/protobuf.ts (hardcoded message IDs). That manual TS decoder is GC's signature failure mode.
  • The dashboard is a React component library + server-served static HTML (server/static/{login,dashboard,viewer}.html), NOT a React Router SPA. There is no App.tsx route tree and no dashboard/src/api/client.ts. The surface pass adapts.
  • CI is Gitea Actions (.gitea/workflows/*.yml) with a Windows runner on Pluto — not RMM's webhook-handler.py + build-shared.sh pipeline.

Execution Overview

Phase 0: Context load (coordinator reads key files)
Phase 1: Spawn 6 parallel audit agents (codebase passes A-F)
Phase 2: Run CI/CD pipeline audit (Agent G — sequential; SSH to deploy host)
Phase 3: Collect findings, aggregate, score
Phase 4: Write report + update living docs
Phase 5: Present summary to user

The audit is orchestrated here (Claude coordinator). All codebase passes run in parallel subagents. The pipeline pass runs sequentially after (it touches live state via SSH / HTTP). Each agent returns structured findings; the coordinator aggregates and writes the final report.

Model (MANDATORY)

Always run every audit pass on Opus. Spawn each agent with model: "opus" (the opus alias resolves to the latest Opus). This overrides default complexity-based routing — do NOT downgrade any pass to Sonnet or Haiku, even the lower-stakes ones (API surface, TypeScript). The coordinator orchestration also runs on Opus.

Repo root

All paths below are relative to projects/msp-tools/guru-connect/ unless prefixed otherwise. GuruConnect is a separate Gitea repo (azcomputerguru/guru-connect), not a submodule of the monorepo in the RMM sense — it lives at projects/msp-tools/guru-connect/ with its own .git. Deploy host: 172.16.3.30:3002, systemd service guruconnect.service.


Phase 0: Context Load (Coordinator Reads These)

Before spawning agents, read these yourself:

  1. CLAUDE.md — GC project instructions, coding standards, ports, auth model
  2. docs/FEATURE_ROADMAP.md — planned features ([ ]/[~]/[x] + P1-P3)
  3. TECHNICAL_DEBT.md — living debt backlog + "Completed Items" section (repo root, NOT docs/)
  4. docs/ARCHITECTURE_DECISIONS.md — ADR-001 (RMM↔GC contract), ADR-002 (release eng)
  5. All docs/specs/SPEC-*.md (Glob them so new specs are auto-picked-up) — the architecture/feature specs. SPEC-001 = release-engineering parity; SPEC-002 = the v2 modernization architecture — read it: it defines the in-flight rebuild and which v1 weaknesses are already planned to be replaced, so passes can distinguish known/planned from net-new.
  6. specs/*/ shape-spec folders (plan.md/shape.md/references.md/standards.md) — pre-implementation plans (e.g. specs/v2-secure-session-core/, specs/native-remote-control/). plan.md is the implementation source-of-truth and tracks progress via [DONE] task markers — a reconciliation target for Agent F.
  7. .claude/CODING_GUIDELINES.md + .claude/standards/ — read index.yml, then the relevant standard files (repo root). .claude/standards/ is the compliance baseline the quality passes check code against (not just the looser CODING_GUIDELINES): security/credential-handling, api/response-format, gururmm/sqlx-migrations, gururmm/platform-parity, conventions/{naming,no-emojis,output-markers}, git/commit-style. Pass the relevant standards and their key rules to Agents B and C.

Capture from server/src/api/mod.rs (+ server/src/main.rs route registration) the complete route list — every .route(...) plus the two WebSocket upgrade endpoints in server/src/relay/mod.rs (agent_ws_handler, viewer_ws_handler). This becomes the authority route list passed to Agents A and E.

Also extract every checkbox line from FEATURE_ROADMAP.md (with section + priority) into a roadmap claims list — passed to Agent F for reconciliation against the code.

During the v2 rebuild (SPEC-002): extract a planned-work list from SPEC-002 and the active specs/*/plan.md files — the known v1 weaknesses already scheduled for replacement (the relay-auth CRITICALs, the broken web protobuf codec, the deploy stub, etc.). Pass this list to every pass. A finding that matches already-planned work is still reported, but tagged [TRACKED — SPEC-002 / <spec>] instead of presented as net-new, so an audit run mid-rebuild does not drown the report in things already decided. Net-new findings (in no spec/plan) are the signal that matters most.


Phase 1: Parallel Audit Agents

Spawn all six parallel agents (A, B, C, D, E, F) simultaneously in a single message. Each agent receives the full context it needs inline — do not assume they share context. (Agent G — Pipeline — runs sequentially afterward; it SSHes the live deploy host and hits HTTP endpoints.)


Agent A — API Surface & Route Inventory

Goal: Find server endpoints with no UI/consumer exposure, handlers that are dead code, and references in the dashboard/static HTML to routes that don't exist.

Instructions for agent:

  1. Read server/src/api/mod.rs and server/src/main.rs — extract every .route(path, method) into a list grouped by resource (auth, users, sessions, downloads, releases, changelog, health, metrics). Include the two WS endpoints from server/src/relay/mod.rs.

  2. The dashboard is NOT a routed SPA. Instead cross-reference route usage against:

    • server/static/login.html, dashboard.html, viewer.html — grep for fetch(, /api/, and ws/wss URLs the static pages call.
    • dashboard/src/hooks/useRemoteSession.ts — the WS connection URLs it opens.
    • dashboard/src/components/*.tsx — any REST calls.
  3. Classify:

    • Server route never referenced by any static page / component / hook → ORPHANED ROUTE (dead code vs. intentionally external/integration — distinguish by context, e.g. routes the RMM integration calls per ADR-001 are not dead).
    • A fetch/WS URL in the frontend that matches no server route → BROKEN CALL.
    • Method mismatch (frontend POSTs to a GET route) → METHOD MISMATCH.
  4. For each API resource group, assess whether the UI (static pages + viewer component) exposes the major operations. Flag resources with full server CRUD but no UI surface.

  5. Return structured findings: [SEVERITY] Description — file:line.


Agent B — Rust Code Quality & Standards

Goal: Find violations of GC's Rust standards and common quality issues across server + agent.

Instructions for agent:

Read CLAUDE.md (GC standards section), .claude/CODING_GUIDELINES.md, and the relevant .claude/standards/ files the coordinator passed you first. GC standards: tracing for logging (not println!/log), anyhow in binaries, thiserror in libraries, async/await preferred, clippy clean. Audit against the concrete .claude/standards/ rules and cite the standard each finding violatessecurity/credential-handling (no hardcoded secrets; hashed/short-lived tokens; log auth attempts), api/response-format (consistent error envelope, no raw e.to_string() to clients, kebab-case segments, idempotent migrations), gururmm/sqlx-migrations (IF NOT EXISTS, server-applied, no manual pre-apply), conventions/naming (Rust/proto/DB casing), conventions/no-emojis, git/commit-style.

Compliance checks:

  • .unwrap() / .expect() outside #[cfg(test)] — panic in production. Flag each with context. .expect("invariant reason") on a truly-impossible path is acceptable if the reason is clear.
  • todo!() / unimplemented!() in non-test production paths.
  • println! / eprintln! used for logging instead of tracing:: macros.
  • format!() used to build SQL strings (injection risk — parameterize instead).
  • sqlx style: GC's db layer uses runtime sqlx::query()/query_as() throughout, NOT compile-time sqlx::query! macros (verified 2026-05-29 — CLAUDE.md's "compile-time checked queries" claim is stale; v2 keeps runtime sqlx, matching RMM). So a new sqlx::query!/query_as! macro is a deviation worth [LOW] (reintroduces the .sqlx-cache-regen footgun + build-time DATABASE_URL), not the norm. Still flag format!()-built SQL (above) as the real injection risk.

Auth coverage (server):

  • Read server/src/api/mod.rs + server/src/auth/mod.rs. Identify which route groups go through the AuthenticatedUser extractor / auth middleware vs. which are public (login, health, downloads, metrics may be intentionally public).
  • Verify the agent plane and viewer/admin plane are separated: the agent WS (agent_ws_handler, auth via support_code OR api_key) and the viewer WS (viewer_ws_handler, auth via JWT) must not accept each other's credentials. Any non-public admin route reachable without JWT → [CRITICAL].
  • Confirm JWT secret + min-length enforcement at startup (server/src/main.rs) and the logout token blacklist (server/src/auth/token_blacklist.rs) is actually consulted on each request.

Logging hygiene:

  • Grep tracing:: calls that include JWT secrets, API keys, support codes, passwords, or PII (emails, usernames). These must be redacted.

Error handling:

  • HTTP handlers returning 500 with raw e.to_string() — leaks internals to callers. Log server-side, return a generic message.

Search paths: server/src/ and agent/src/. Exclude generated proto (OUT_DIR) and server/src/db/mod.rs re-exports.

Return structured findings with file:line references.


Agent C — TypeScript / Dashboard Quality

Goal: Find dashboard quality issues, with special focus on the hand-written protobuf decoder (GC has no schema library on the TS side — correctness is manual).

Instructions for agent:

The dashboard (dashboard/) is a React component library (peer-dep React, no app router, no bundler in-repo). Main artifacts: components/RemoteViewer.tsx, components/SessionControls.tsx, hooks/useRemoteSession.ts, lib/protobuf.ts, types/protocol.ts.

Standards baseline: audit against the relevant .claude/standards/ files the coordinator passed (esp. conventions/no-emojis, conventions/naming, conventions/output-markers for any scripts) and cite the standard each violation breaks.

TypeScript quality:

  • any annotations in dashboard/src/ — each is a type-safety gap (the binary/canvas code is exactly where any hides bugs).
  • @ts-ignore / @ts-expect-error — note reason and whether still needed.
  • console.log / console.error left in non-dev paths.
  • Hardcoded server URLs instead of a passed serverUrl prop / config.

Manual protobuf decoder correctness (lib/protobuf.ts) — HIGH PRIORITY:

  • The decoder parses binary frames with DataView and hardcoded message IDs (e.g. MSG_VIDEO_FRAME, MSG_MOUSE_EVENT, MSG_KEY_EVENT). Verify these IDs and field offsets match proto/guruconnect.proto field numbers / wire layout. A mismatch silently corrupts frames or events. (Agent D cross-checks the same surface from the proto side — coordinate via the report; this side checks the TS implementation correctness.)
  • Bounds checking: does the decoder validate buffer length before reading offsets? A short/hostile frame should not throw an unhandled error or read OOB.

Component patterns:

  • RemoteViewer.tsx canvas rendering: BGRA→RGBA conversion correctness; is the canvas sized to the frame? Are out-of-order frames (the sequence field) handled or dropped?
  • useRemoteSession.ts: WebSocket lifecycle — reconnect handling, cleanup on unmount, error surfacing (a dropped session should not silently hang).
  • Icon-only buttons without aria-label/title; inputs without <label>.

Search paths: dashboard/src/ only.

Return structured findings with file:line references.


Agent D — Protocol & Wire-Format Integrity

Goal: This is GC's signature pass. Detect drift across the four representations of the wire protocol, plus migration/version integrity.

Instructions for agent:

Four-way protocol drift (the core check):

  1. Read proto/guruconnect.proto — list every top-level Message oneof variant and each message's fields with their field numbers. Note session_type, VideoFrame/RawFrame/ EncodedFrame, MouseEvent, KeyEvent, AgentStatus, AdminCommand, UpdateInfo, Heartbeat/HeartbeatAck, StartStream/StopStream.

  2. Agent side: agent/src/transport/mod.rs + agent/src/transport/websocket.rs — confirm it encodes/decodes via prost (encode_to_vec / Message::decode) and handles every inbound variant it should. Any server→agent variant with no handler → dead/missing.

  3. Server side: server/src/relay/mod.rs — confirm the relay decodes agent frames and forwards the right variants to viewers, and decodes viewer input and forwards to the agent. Any proto variant the relay never matches → dead code or missing relay path.

  4. Dashboard side: dashboard/src/lib/protobuf.ts hardcoded message IDs + types/protocol.ts field names. Cross-check the hardcoded IDs against the proto field numbers and the TS field names against the proto field names. Mismatch → [HIGH] (silent frame/event corruption).

    Build the drift matrix: message/field | proto | agent (prost) | server (prost) | dashboard (manual) and flag every row that isn't consistent across all four.

Migration integrity:

  • List server/migrations/*.sql — verify sequential numbering with no gaps (currently 001_initial_schema, 002_user_management, 003_auto_update).
  • For each CREATE TABLE (users, machines, sessions, support_codes, events, releases…), verify a corresponding server/src/db/<name>.rs module exists and its struct fields match the columns.

Version consistency:

  • agent/Cargo.toml, server/Cargo.toml, dashboard/package.json versions — are they in sync? (All were 0.2.0 at last map.) The agent embeds version via agent/build.rs (CARGO_PKG_VERSION
    • git hash). Note divergence; there is no automatic version bump yet (SPEC-001 §3 pending) — so out-of-sync versions are a [MEDIUM] worth surfacing, not necessarily a bug.

WebSocket frame validation:

  • In server/src/relay/mod.rs, are inbound frames size-capped before decode/relay? An unbounded VideoFrame from a hostile agent → server OOM. No cap → [HIGH] (see Agent E for the security framing).

Return structured findings with file:line references and the drift matrix.


Agent E — Security & Remote-Session Integrity

Goal: GC is a remote-control product — the threat surface is session hijack, input injection, and relay abuse. Verify the boundaries the SEC* audits established still hold and check the gaps they flagged.

Instructions for agent:

Read the existing security audit docs first so you don't re-report settled items (note their status and only re-flag if the code regressed): SEC3_SQL_INJECTION_AUDIT.md, SEC4_AGENT_VALIDATION_AUDIT.md / _COMPLETE.md, SEC5_SESSION_TAKEOVER_AUDIT.md / _COMPLETE.md, and TECHNICAL_DEBT.md security items.

Session & auth boundaries:

  • Viewer WS auth: viewer_ws_handler validates a JWT (query param). Confirm the token is verified (signature + expiry + blacklist), not just parsed. A viewer joining a session must be authorized for that session, not any session.
  • Agent WS auth: agent_ws_handler accepts support_code OR api_key. Confirm support codes are single-use and revocation updates the in-memory store immediately (a revoked code must fail even if the agent reconnects before a server restart — server/src/db/support_codes.rs / in-memory map).
  • Session takeover: sessions keyed by UUID, heartbeat timeout ~90s. Confirm a new viewer cannot attach to or hijack an existing session without authorization, and that session IDs aren't guessable/loggable in a way that enables replay.

Relay abuse / DoS:

  • Frame size caps on inbound WS messages (agent video frames AND viewer input) — unbounded → [HIGH] OOM/DoS vector.
  • Input event injection: viewer→agent mouse/key events — is there rate limiting or a bounded queue on the agent input path (agent/src/input/)? Unbounded input spam → agent CPU/queue exhaustion.
  • Rate limiting on auth endpoints (server/src/middleware/rate_limit.rs, tower_governor) — still applied to /api/auth/login? Confirm it's wired, not just present.

Secrets & transport:

  • JWT secret, agent API key sourced from env (not hardcoded) and length-checked at startup.
  • TLS/WSS required for relay; no plaintext fallback that carries frames or credentials.
  • Passwords hashed with Argon2id (server/src/auth/password.rs).

Return structured findings with file:line references. Severity by impact (a session-hijack path is [CRITICAL] even if the fix is small).


Agent F — Docs & Roadmap Reconciliation

Goal: Make GC's living docs tell the truth. Reconcile every roadmap checkbox and debt item against the actual code.

Runs in parallel with A-E (read-only code search, no SSH).

Instructions for agent:

  1. Read docs/FEATURE_ROADMAP.md and extract every checkbox line with state ([ ]/[~]/[x]), section, and priority. Also read TECHNICAL_DEBT.md (repo root; items + the "Completed Items" section), every docs/specs/SPEC-*.md (Glob them — SPEC-001 §1-§6 deliverables, SPEC-002 v2 architecture phases + decisions, and any later specs), and every specs/*/plan.md shape-spec (its task list + [DONE] markers).

  2. For EACH item, find the implementing artifact in code — do NOT trust the checkbox:

    • API/endpoint features → server/src/api/mod.rs routes + handler module
    • Relay/session features → server/src/relay/mod.rs, server/src/session/
    • Protocol features → proto/guruconnect.proto + agent/server prost usage
    • Agent capabilities (capture, input, tray, update) → agent/src/
    • Dashboard/viewer features → dashboard/src/components|hooks/* + static HTML
    • CI/release deliverables (SPEC-001: versioning, signing, changelog API, gc-feature-request skill, coord-API) → .gitea/workflows/*, scripts/*, .claude/commands/gc-feature-request.md
    • Shape-spec plan.md tasks → find the implementing artifact for each task. A task marked [DONE] but not in code → STALE-COMPLETE [HIGH] (the plan is lying); implemented but not marked [DONE] → recommend adding the marker. SPEC-002 phase deliverables → reconcile each against code the same way (a phase claimed done that isn't, or shipped-but-unmarked). Use Grep/GrepAI. Cite the exact artifact (file:line, migration name, route path, workflow job).
  3. Classify each item:

    • STALE-INCOMPLETE[ ]/[~] but code fully implements it end-to-end → recommend [x].
    • PARTIAL[ ]/[~], some layers exist but not end-to-end for the stated scope → keep [ ]/[~], recommend an inline scope annotation. Do NOT flip to [x].
    • STALE-COMPLETE[x] but code does not implement it (never built / reverted) → recommend flip to [ ], flag [HIGH] (the roadmap is lying).
    • ACCURATE — matches. No change.
  4. For TECHNICAL_DEBT.md: identify debt items the code shows are now fixed → recommend moving them to the "Completed Items" section with a date. Identify items still open that the code confirms.

  5. Be conservative: only flip [ ][x] when evidence is unambiguous AND end-to-end. When in doubt → PARTIAL with a note. Bias toward under-flipping.

Return three tables: roadmap item | section | current | verdict | proving-or-missing artifact debt item | current status | verdict (fixed/open/partial) | artifact spec/plan item (SPEC-NNN phase or specs/<slug> plan.md task) | claimed state | verdict (done / partial / not-started / [DONE]-but-missing) | artifact


Agent G — CI/CD Pipeline & Deploy Health

Goal: Verify the build/deploy infrastructure is functioning and the SPEC-001 quality gates are in the state the docs claim. Catches issues invisible to codebase-only audits: broken workflows, unregistered runners, stale deploys, gate drift.

NOTE: Runs sequentially (after A-F) because it SSHes the live deploy host and hits HTTP endpoints. Read-only — checks state, never triggers a build or deploy.

Instructions for agent:

1. Gitea Actions workflow integrity (read the repo files):

  • .gitea/workflows/build-and-test.yml — confirm jobs: build-server (fmt --check, clippy, build, test), build-agent (Windows MSVC on the Pluto runner, PROTOC + crt-static), and security-audit (cargo audit). Note whether clippy/audit are informational (warn-only) or hard-fail (-D warnings / fail-on-vuln).
  • .gitea/workflows/deploy.yml — confirm trigger (tag v*.*.* / manual) and whether the actual SSH deploy step is real or still a stub (echo "[INFO] SSH to 172.16.3.30…").
  • .gitea/workflows/release.yml (if present) — SPEC-001 §2-§4: version bump, changelog gen, jsign + Azure Trusted Signing step. Note which deliverables are wired vs. pending.
  • bash -n is not applicable to YAML; instead sanity-check each workflow for: valid on: triggers, every uses:/run: step present, no job referencing a secret that the audit notes as unset.

SPEC-001 gate cross-check (ties to the active lint-debt work): the SPEC-001 quality gates aim to flip clippy to hard-fail + enforce cargo audit. Report the CURRENT enforced state vs. the SPEC-001 target so it's clear whether the tightening has landed. (~65 pre-spec clippy warnings were noted as informational at last map — confirm count/state.)

2. Gitea runner registration & health:

  • TECHNICAL_DEBT.md item #1 flagged runner registration as CRITICAL/blocking. Verify a runner is registered and online for both ubuntu-latest (server/audit jobs) and the Windows/Pluto runner (agent job). On the Gitea host or via the Gitea API, check the actions runner list. If no Windows runner is online → [CRITICAL] agent builds cannot run. Reference .claude/machines/pluto.md for the Pluto runner setup (PROTOC at C:\protoc\bin\protoc.exe, Administrator .cargo/.rustup).

3. Deploy host health (ssh guru@172.16.3.30):

systemctl status guruconnect.service --no-pager
curl -s -o /dev/null -w '%{http_code}' http://localhost:3002/health
curl -s http://localhost:3002/metrics | head -20
ls -lht /home/guru/guru-connect/server/migrations/
  • guruconnect.service not active (running)[CRITICAL].
  • /health non-200 / refused → [CRITICAL].
  • /metrics empty or refused → [HIGH] (Prometheus scrape broken).
  • Confirm the binary on disk matches a recent commit: cd /home/guru/guru-connect && git log --oneline -5 and compare to the running version (the service version vs. git rev-parse HEAD). Months-old running binary while git shows recent work → [HIGH] deploy stuck (consistent with the stubbed deploy step).
  • Confirm migrations applied: query _sqlx_migrations (003 should be present). Missing → [HIGH].

4. Artifact distribution:

  • Agent download served at https://connect.azcomputerguru.com/downloads/guruconnect.exe (or the path configured in server/src/api/downloads.rs). Verify the file exists and its mtime is recent relative to agent commits. Stale/missing → [HIGH] (clients download an old agent).
  • Confirm the served EXE is signed if SPEC-001 §2 signing has landed; unsigned while signing is marked done → [HIGH].

5. Monitoring stack (per INFRASTRUCTURE_STATUS.md):

  • Prometheus scraping GC /metrics; Grafana dashboard reachable. Backup timer (guruconnect-backup.timer) enabled: systemctl status guruconnect-backup.timer --no-pager. Disabled/failed backup timer → [MEDIUM].

Return structured findings with source (file path + line, or command + output) for every finding.


Phase 3: Aggregating Findings

Collect all agents' outputs. Classify each finding:

Severity Meaning
[CRITICAL] Security vuln (session hijack, auth bypass), data loss, production crash, or broken-build/deploy blocker
[HIGH] Functional gap blocking a core workflow, protocol drift causing silent corruption, or standards violation with user impact
[MEDIUM] Code quality issue, version skew, 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 (e.g. Agent C on the TS decoder and Agent D on the proto side of the same field), merge into one finding with both references.


Phase 4: Write Report + Update Living Docs

Report Location

Write to: projects/msp-tools/guru-connect/reports/YYYY-MM-DD-gc-audit.md (use the actual date). The reports/ directory does not exist yet — create it on first run. If a report from today already exists, append a -2 suffix.

Report Format

# GuruConnect Audit Report — YYYY-MM-DD

**Auditor:** Claude (<model id>)
**Passes:** API Surface, Rust Quality, TypeScript/Dashboard, Protocol Integrity, Security & Session, Docs Reconciliation, CI/CD Pipeline
**Previous audit:** [link to prior report if one exists, else "First audit"]

---

## Executive Summary

| Pass | Total | Critical | High | Medium | Low |
|------|-------|---------|------|--------|-----|
| API Surface | N | N | N | N | N |
| Rust Quality | N | N | N | N | N |
| TypeScript/Dashboard | N | N | N | N | N |
| Protocol Integrity | N | N | N | N | N |
| Security & Session | N | N | N | N | N |
| CI/CD Pipeline | N | N | N | N | N |
| **TOTAL** | **N** | **N** | **N** | **N** | **N** |

**Requires immediate action:** [one line per CRITICAL finding]

---

## Pass 1: API Surface
### [SEVERITY] Finding Title
**File:** path:LINE
**Detail:** What the problem is, why it matters.
**Recommendation:** What to do.
[repeat per finding]

---
## Pass 2: Rust Code Quality
## Pass 3: TypeScript / Dashboard Quality
## Pass 4: Protocol & Wire-Format Integrity
[include the 4-way drift matrix]
## Pass 5: Security & Remote-Session Integrity
## Pass 6: CI/CD Pipeline Health
[Gitea Actions workflow state, runner registration, gate state vs SPEC-001 target, deploy host, artifact freshness]

---

## FEATURE_ROADMAP.md Delta (Agent F)
Checkboxes corrected to match code reality this audit:
- `[ ]`/`[~]``[x]` **<item>** — shipped. Proof: `<artifact>`.
- `[x]``[ ]` **<item>** — marked complete but NOT in code (regression / never built). `[HIGH]`
Annotated as partial (scope clarified): - `[ ]` **<item>** (<scope note>) — `<artifact>`
Verified accurate (no change): N items.

## TECHNICAL_DEBT.md Delta (Agent F)
Items moved to "Completed Items": - **<item>** — fixed. Proof: `<artifact>`.
Still open (confirmed): N items.

---

## Recommended Action Order
1. [CRITICAL items, sorted by impact]
2. [HIGH items]
3. [MEDIUM items — can be batched]

Update Living Docs

After writing the report, apply Agent F's reconciliation (this is the cleanup the audit owns; editing living docs fits the "living docs are updated" exception to read-only):

  • docs/FEATURE_ROADMAP.md — default is reconcile-and-flip:
    • STALE-INCOMPLETE → flip [ ]/[~] to [x] for every item proven shipped end-to-end; optionally append (verified <date>).
    • PARTIAL → leave the box, append the scope annotation. Never flip a partial to [x].
    • STALE-COMPLETE → flip [x] to [ ], add [REGRESSION — flagged YYYY-MM-DD], mirror as a [HIGH] finding in the report.
  • TECHNICAL_DEBT.md — move confirmed-fixed items into the "Completed Items" section with a date; leave open items in place.
  • Every doc change MUST also appear in the report's Delta section with its proving artifact — no silent edits. When evidence is ambiguous, do NOT change the doc; record as PARTIAL/INFO for human review. Bias toward under-flipping.

Phase 5: User Summary

Present a concise summary to the user:

Audit complete. Report: projects/msp-tools/guru-connect/reports/YYYY-MM-DD-gc-audit.md

CRITICAL (N): [one-line each]
HIGH (N):     [one-line each]
MEDIUM (N):   Batched in report.

Protocol drift: [one-line — e.g. "proto/agent/server/dashboard consistent" or the worst mismatch]
Pipeline: [one-line — e.g. "all green" or highest-severity finding; note clippy/audit gate state vs SPEC-001]
Roadmap: N checkboxes corrected (N stale-incomplete flipped, N partial annotated, N regressions flagged).
Tech debt: N items moved to Completed.

Recommended first action: [the single highest-priority finding]

Then ask: "Want me to start on any of these findings?"


Conventions

  • Read, don't run. Never executes production code or triggers builds/deploys. Reads files, uses Grep/GrepAI, and (Agent G only) runs read-only status/HTTP checks.
  • Derive from code, not docs. Treat all .md/.json status docs as potentially stale. Code is truth. (The whole point of Agent F.)
  • Be specific. Every finding needs a file:line reference. Vague findings are useless.
  • No false positives. If something looks wrong but context makes it acceptable, note it [INFO] with the reason. (Especially: sqlx::query! macros are fine here; informational clippy/audit gates are a known SPEC-001 state, not a bug — report the state, don't cry wolf.)
  • Severity is impact, not effort. A two-line fix can be [CRITICAL] if it's a session-hijack path.
  • Commit the report. After writing, delegate to the Gitea Agent to commit the report file and the living-doc updates to the guru-connect repo (not any code fixes — those are separate work items). Respect any active coord lock on guruconnect before editing .gitea/workflows or docs.

Reference: Key Files by Area

Server (server/src/)

Area Key Files
Routes api/mod.rs (+ main.rs registration), submodules api/{auth,users,downloads,releases,changelog}.rs
WebSocket relay relay/mod.rs (agent_ws_handler, viewer_ws_handler)
Sessions session/mod.rs
DB layer db/mod.rs, db/{users,machines,sessions,events,support_codes,releases}.rs
Migrations migrations/00{1,2,3}_*.sql
Auth auth/{jwt,token_blacklist,password,mod}.rs
Rate limiting middleware/rate_limit.rs
Generated proto OUT_DIR via server/build.rs (do not audit generated code)

Agent (agent/src/)

Area Key Files
Transport / wire transport/mod.rs, transport/websocket.rs
Capture screen/DXGI-GDI capture modules
Input injection input/
Version embed agent/build.rs

Dashboard (dashboard/src/)

Area Key Files
Viewer component components/RemoteViewer.tsx, components/SessionControls.tsx
Session hook hooks/useRemoteSession.ts
Manual protobuf lib/protobuf.ts (hardcoded message IDs — drift hazard)
Protocol types types/protocol.ts
Served static UI server/static/{login,dashboard,viewer}.html

Protocol

Area Path
Proto definition proto/guruconnect.proto

CI/CD & Infra

Area Path
CI gate .gitea/workflows/build-and-test.yml
Deploy .gitea/workflows/deploy.yml
Release/signing .gitea/workflows/release.yml, SPEC-001
Runner setup scripts/install-gitea-runner.sh, .claude/machines/pluto.md
Deploy host 172.16.3.30:3002, systemd guruconnect.service
Monitoring infrastructure/{prometheus.yml,grafana-dashboard.json,alerts.yml}, guruconnect-backup.timer

Docs / Standards

Area Path
GC instructions/standards CLAUDE.md
Shared coding standards .claude/CODING_GUIDELINES.md (monorepo root)
Feature roadmap docs/FEATURE_ROADMAP.md
Tech debt backlog TECHNICAL_DEBT.md (repo root)
Architecture decisions docs/ARCHITECTURE_DECISIONS.md (ADR-001 RMM↔GC contract, ADR-002 release eng)
Architecture/feature specs docs/specs/SPEC-*.md (SPEC-001 release-eng, SPEC-002 v2 architecture, …)
Shape-spec plans specs/*/{plan,shape,references,standards}.md (e.g. v2-secure-session-core, native-remote-control) — plan.md [DONE] markers are a reconciliation target
Granular standards (compliance baseline) .claude/standards/index.yml + .claude/standards/**/*.md
Changelogs (SPEC-001 changelog API) changelogs/LATEST_{SERVER,AGENT,DASHBOARD}.md, changelogs/<component>/v*.md, CHANGELOG.md
Security audits SEC{3,4,5}_*_AUDIT.md / _COMPLETE.md
Past audit reports reports/ (create on first run)