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>
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-timesqlx::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 newquery!/query_as!macro is therefore a deviation worth a[LOW](it reintroduces the.sqlx-cache-regen footgun + a build-timeDATABASE_URLrequirement), not the norm.- Wire format is Protobuf, not RMM's JSON
AgentMessage/ServerMessageenums. The integrity pass chases drift across four artifacts:proto/guruconnect.proto→ prost-generated agent code → prost-generated server code → hand-written binary decode indashboard/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 noApp.tsxroute tree and nodashboard/src/api/client.ts. The surface pass adapts.- CI is Gitea Actions (
.gitea/workflows/*.yml) with a Windows runner on Pluto — not RMM'swebhook-handler.py+build-shared.shpipeline.
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:
CLAUDE.md— GC project instructions, coding standards, ports, auth modeldocs/FEATURE_ROADMAP.md— planned features ([ ]/[~]/[x]+ P1-P3)TECHNICAL_DEBT.md— living debt backlog + "Completed Items" section (repo root, NOT docs/)docs/ARCHITECTURE_DECISIONS.md— ADR-001 (RMM↔GC contract), ADR-002 (release eng)- 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. 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.mdis the implementation source-of-truth and tracks progress via[DONE]task markers — a reconciliation target for Agent F..claude/CODING_GUIDELINES.md+.claude/standards/— readindex.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:
-
Read
server/src/api/mod.rsandserver/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 fromserver/src/relay/mod.rs. -
The dashboard is NOT a routed SPA. Instead cross-reference route usage against:
server/static/login.html,dashboard.html,viewer.html— grep forfetch(,/api/, andws/wssURLs the static pages call.dashboard/src/hooks/useRemoteSession.ts— the WS connection URLs it opens.dashboard/src/components/*.tsx— any REST calls.
-
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.
-
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.
-
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 violates — security/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 oftracing::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-timesqlx::query!macros (verified 2026-05-29 — CLAUDE.md's "compile-time checked queries" claim is stale; v2 keeps runtime sqlx, matching RMM). So a newsqlx::query!/query_as!macro is a deviation worth[LOW](reintroduces the.sqlx-cache-regen footgun + build-timeDATABASE_URL), not the norm. Still flagformat!()-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 theAuthenticatedUserextractor / 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 viasupport_codeORapi_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:
anyannotations indashboard/src/— each is a type-safety gap (the binary/canvas code is exactly whereanyhides bugs).@ts-ignore/@ts-expect-error— note reason and whether still needed.console.log/console.errorleft in non-dev paths.- Hardcoded server URLs instead of a passed
serverUrlprop / config.
Manual protobuf decoder correctness (lib/protobuf.ts) — HIGH PRIORITY:
- The decoder parses binary frames with
DataViewand hardcoded message IDs (e.g.MSG_VIDEO_FRAME,MSG_MOUSE_EVENT,MSG_KEY_EVENT). Verify these IDs and field offsets matchproto/guruconnect.protofield 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.tsxcanvas rendering: BGRA→RGBA conversion correctness; is the canvas sized to the frame? Are out-of-order frames (thesequencefield) 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):
-
Read
proto/guruconnect.proto— list every top-levelMessageoneofvariant and each message's fields with their field numbers. Notesession_type,VideoFrame/RawFrame/EncodedFrame,MouseEvent,KeyEvent,AgentStatus,AdminCommand,UpdateInfo,Heartbeat/HeartbeatAck,StartStream/StopStream. -
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. -
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. -
Dashboard side:
dashboard/src/lib/protobuf.tshardcoded message IDs +types/protocol.tsfield 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 (currently001_initial_schema,002_user_management,003_auto_update). - For each
CREATE TABLE(users, machines, sessions, support_codes, events, releases…), verify a correspondingserver/src/db/<name>.rsmodule exists and its struct fields match the columns.
Version consistency:
agent/Cargo.toml,server/Cargo.toml,dashboard/package.jsonversions — are they in sync? (All were0.2.0at last map.) The agent embeds version viaagent/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.
- git hash). Note divergence; there is no automatic version bump yet (SPEC-001 §3 pending) —
so out-of-sync versions are a
WebSocket frame validation:
- In
server/src/relay/mod.rs, are inbound frames size-capped before decode/relay? An unboundedVideoFramefrom 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_handlervalidates 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_handleracceptssupport_codeORapi_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:
-
Read
docs/FEATURE_ROADMAP.mdand extract every checkbox line with state ([ ]/[~]/[x]), section, and priority. Also readTECHNICAL_DEBT.md(repo root; items + the "Completed Items" section), everydocs/specs/SPEC-*.md(Glob them — SPEC-001 §1-§6 deliverables, SPEC-002 v2 architecture phases + decisions, and any later specs), and everyspecs/*/plan.mdshape-spec (its task list +[DONE]markers). -
For EACH item, find the implementing artifact in code — do NOT trust the checkbox:
- API/endpoint features →
server/src/api/mod.rsroutes + 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.mdtasks → 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).
- API/endpoint features →
-
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.
- STALE-INCOMPLETE —
-
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. -
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), andsecurity-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 (tagv*.*.*/ 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 -nis not applicable to YAML; instead sanity-check each workflow for: validon:triggers, everyuses:/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.mdfor the Pluto runner setup (PROTOC atC:\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.servicenotactive (running)→[CRITICAL]./healthnon-200 / refused →[CRITICAL]./metricsempty or refused →[HIGH](Prometheus scrape broken).- Confirm the binary on disk matches a recent commit:
cd /home/guru/guru-connect && git log --oneline -5and 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 inserver/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.
- STALE-INCOMPLETE → flip
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/.jsonstatus 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-connectrepo (not any code fixes — those are separate work items). Respect any active coord lock onguruconnectbefore editing.gitea/workflowsor 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) |