Host guard in /opt/gururmm/webhook-handler.py skips docs-only pushes; note the
stale repo copy must not be redeployed over it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match a known external IP to the RMM agent rather than reconning every
candidate machine (Mike's correction during the Pavon GuruConnect-client
removal). Notes the GuruRMM agent-IP tracking gap (todo 7459428e).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Several bugs found and fixed during live testing against the ACG GravityZone
tenant:
- security_sweep_all_clients: iterate each company (the companies container is
not a valid endpoint parent; passing it 400'd the whole sweep)
- list_quarantine: use service-scoped path quarantine/computers with companyId
(bare quarantine module 404'd; param is companyId not parentId)
- rename GZEndpointSummary.detection_active -> threat_detected with corrected
semantics (True = active threat, tracks with infected; not an engine-on flag)
- status: readable sectioned table renderer for the nested apiKey/license dict
- portable CLAUDETOOLS_ROOT resolution (derive from file path, not a Windows
literal) so it works on the Mac/Linux fleet
Adds scripts/selftest.py: a 29-check read-only harness (all passing) covering
every read command, --json, error exit codes, and destructive-action gating.
EDR/incident commands (blocklist, isolate/unisolate, blocklist-add/remove) and
raw destructive-method gating are included from this session's work.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- raw now refuses destructive methods (delete/uninstall/remove/reconfigure)
without --confirm (it previously bypassed all gating)
- --json is now accepted after the subcommand (shared via a common parent
parser), matching the documented usage
- drop a placeholder-less f-string
- SKILL.md: document raw gating + that raw echoes upstream responses verbatim
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a /bitdefender skill that drives the ACG GravityZone partner tenant
via the JSON-RPC Public API. Read + management ops (companies, endpoints,
live security sweep, policies [read-only/shallow], packages, quarantine,
scans, groups, move/delete). Identity-tier JSON cache (24h TTL,
--refresh); volatile status is always pulled live, never cached.
Security hardening: API key loaded from SOPS vault at runtime (never on
disk/logs/argv/cache); destructive deletes gated behind --confirm; `raw`
also gates destructive methods; upstream error bodies truncated. UNVERIFIED
API methods reachable only via `raw`. Reuses the auth/JSON-RPC pattern from
api/services/gravityzone_service.py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>
- Load .claude/standards/ (index.yml + files) as the compliance baseline;
Rust/TS passes now cite the specific standard each finding violates
- Glob all docs/specs/SPEC-*.md (incl. SPEC-002) + specs/*/plan.md; Pass F
reconciles SPEC phases and plan.md [DONE] markers against code (3rd table)
- Extract a planned-work list from SPEC-002 + active plans; tag findings that
match already-planned work as [TRACKED] so mid-rebuild audits surface net-new
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Update guru-rmm submodule pointer (SPEC-017 mobile device support)
- Record Apple Developer + MDM Push certs (acquired 2026-05-29); MDM push
cert renews annually on the same Apple ID or all enrolled iOS devices break
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Created .claude/TEMP_GRADUATION.md with review protocol before cleanup
- Graduation decision tree and checklist
- Examples from May 2026 cleanup (what should have been kept)
- Added to CLAUDE.md reference section
/rmm diagnose: dispatches a Windows security/health probe to a newly onboarded
agent, grades RED/AMBER/GREEN, writes an immutable per-client baseline
(clients/<slug>/onboarding-baselines/), diffs vs prior, and alerts CRITICALs to
#dev-alerts. Probe is PS5.1/ASCII/SYSTEM-safe, never-abort, base64 chunked upload
around the agent command-size cap. Code-reviewed (no blockers); folded in
immutability guard, severity-independent finding ids, Defender-unknown sentinel,
expanded competitor/backup detection.
First baselines captured: Rednour FRONTDESKRECEPT + LEGALASST (both RED - prior
MSP ScreenConnect/Splashtop/Syncro still live; LEGALASST OS EOL).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Pluto memory/wiki/machine notes: Unraid VM "Claude-Builder" == hostname PLUTO ==
172.16.3.36 (same box); RMM-agent access path when SSH key unauthorized; now also
builds the GuruConnect Windows agent + hosts a Gitea Actions runner.
- New feedback memories: post #bot-alerts only for client/ticket-affecting RMM commands;
proceed autonomously through routine infra/build prerequisites.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Documents the full GuruRMM onboarding process (POST /api/clients, POST /api/sites
with one-time api_key capture), the vault storage step, and the sops-encryption
gotchas hit while onboarding Rednour Law Offices (--config required, quote dates,
secrets under credentials:).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Corrected the 2026-05-28 SmartBadge fix on KSTEENBB2025: the older Datto
Workplace Desktop v8 had been left in place (diverged from the fleet, which
runs Datto Workplace v10.53.4 / Workplace2). Removed v8, installed v10,
aligned the SmartBadge _CC add-in + CLSID to the EVO-X1 reference, and cleared
Kristin's stuck per-user LoadBehavior=2.
- ksteen-smartbadge-verify.ps1: PASS/FAIL verdict vs fleet reference
- ksteen-smartbadge-fix.ps1: machine + per-user remediation
- check-ksteen-smartbadge.sh: daily runner (RMM -> verdict -> #bot-alerts,
coord message to Mike on drift); driven by a 7-day scheduled task on GURU-5070
- wiki: agents table, dual-Workplace SmartBadge known issue + fleet standard,
2026-05-28/29 history
Syncro #32339. Coord todo 4a5b09b3 (watch expires 2026-06-05).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
guru-connect is now tracked as a submodule (azcomputerguru/guru-connect @ e3e95f8);
its working state was published to the GC repo first, so no content is lost. guru-rmm
advanced to include ADR-008 (GC integration boundary) replayed on top of the team's
Integrations Center / discovery advances. Includes the native-remote-control spec
(now inside the GC submodule), the versionable-products memory, and the session log.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Any ticket, estimate, appointment, or schedule created for testing or API
research must have its subject/name prefixed with [TEST]. Added as a Hard
Rule and cross-referenced in the recurring schedules section.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sanitize_json() called `python3` unconditionally, but on ACG Windows boxes
the Microsoft Store python3 alias is disabled and `py` is the launcher
(feedback_python_windows). When `python3` was missing the function silently
returned empty, and the surrounding `result_safe='{"messages":[]}'` default
dropped every unread coord message — no error, no warning, no toast.
Now prefers identity.json's `.python.command` (set during machine onboarding,
matching the pattern other scripts already use), falls back to
`command -v python3 || command -v py || command -v python`, and if no Python
is available falls back to `tr -d '\000-\037'` so jq can still parse — lossy
on real \n/\t in string fields but keeps messages visible instead of dropping
them.
"Emergency" is a billing modifier, not a delivery channel. Added explicit
hard rule that Remote/Onsite/In-Shop must be confirmed separately when billing
emergency — the delivery channel determines price_retail and cannot be guessed.
Updated both the Hard Rules section and the Billing workflow Step 1 gather prompt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pin down the coord messages endpoint shape after repeated mark-read failures:
{total,skip,limit,messages[]}; parse .messages[], strip control chars, read may be null.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Read and send mail for an ACG mailbox via the shared Claude-MSP-Access Graph app
(fabb3421), defaulting to the running user's mailbox from identity.json (mike/howard).
Send and reply are hard-gated: full To/Cc/Subject/Body preview + explicit confirm,
external recipients flagged, no retries/bulk, saved to Sent. Read path verified live;
token cached to .claude/tmp (gitignored), secret from SOPS vault.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Audit of .claude/memory found and fixed:
- Broken link: Power Failure Runbook (../.claude/... -> ../...)
- 8 orphaned memories not in MEMORY.md index (Graph CA/password-reset,
vault-write-sequence, GURU-BEAST-ROG, 3x Cascades, identity proposal)
-> now indexed under their sections, so they're discoverable
- 5 files missing frontmatter -> added name/description/type
- Duplicate index entry for reference_workstation_setup.md -> deduped
- Trimmed the worst oversized index hooks (Syncro invoice line was 427 chars)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mike's decision (2026-05-27): the roadmap is a maintained status-and-plan
tracker ([ ]=planned, [x]=shipped, dated), consulted going in and updated
coming out.
- gururmm-development-principles memory: new "Living Roadmap (MANDATORY)"
principle — consult before building, update the entry in the SAME change
when shipping/modifying; roadmap update is part of definition-of-done.
Dev is the primary maintainer; the audit is the backstop.
- rmm-audit skill: state the convention explicitly — the roadmap pass
default is reconcile-and-flip (not annotate-only).
(Companion gururmm-repo changes — DESIGN.md principle + baseline checkbox
reconcile — pushed separately to the gururmm repo.)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The skill's frontmatter claimed it updated FEATURE_ROADMAP.md, but the body
had no roadmap-reconciliation logic — so stale checkboxes slipped through
(Network Discovery Node backend + BUG-001 temperature both shipped while
marked [ ]). Added:
- Agent F (parallel, read-only): cross-references every roadmap checkbox
against code artifacts; classifies STALE-INCOMPLETE / PARTIAL /
STALE-COMPLETE / ACCURATE with proving artifact. Conservative — only
flips when end-to-end evidence is unambiguous; backend/scaffolding-only
is PARTIAL, never flipped.
- Living-docs step: actually flip stale checkboxes, annotate partials,
flag [x]-but-missing as [HIGH] regressions; every change logged in the
report's new "FEATURE_ROADMAP.md Delta" section (no silent edits).
- Phase 0 extracts the roadmap claims list; --pass=roadmap added.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removed/simplified sections now handled by identity.json:
- Removed Ollama endpoint table (now in identity.json)
- Condensed verbose Ollama description
- Updated GrepAI CLI path to use $CLAUDETOOLS_ROOT
- Added migrate-identity.sh step to onboarding
All machine-specific config (Ollama, Python, paths) now centralized
in identity.json — CLAUDE.md references it, doesn't duplicate it.
Phase 2 migration complete:
sync.sh:
- Read Python command from identity.json first (.python.command)
- Fall back to auto-detection for legacy machines
- Eliminates per-session detection overhead
syncro.md:
- Read Ollama endpoint from identity.json (.ollama.endpoint // .ollama.fallback)
- Read Python command from identity.json (.python.command)
- Both sections have legacy fallbacks with detection
- Eliminates 2-second curl probe on every write operation
- Updated day-of-week verification code example
- Updated Ollama draft call section
Impact: All scripts now read machine-specific config from identity.json
(populated by migrate-identity.sh). Faster, explicit, offline-safe.
The script auto-detected PYTHON_CMD but then hardcoded `python3` for the
JSON write (exit 127 on Windows where only `py` exists), and passed a Git
Bash POSIX path (/d/...) to native Python (FileNotFoundError). Fixes:
- use "$PYTHON_CMD" instead of hardcoded python3
- convert IDENTITY_PATH via `cygpath -m` for the interpreter (no-op elsewhere)
Verified on GURU-5070: identity.json migrated correctly (py, windows/amd64,
localhost Ollama, qwen3:8b).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Auto-detects Python command, platform, architecture
- Probes Ollama (local vs remote)
- Sets prose_model based on machine (qwen3:8b for GURU-5070, else qwen3:14b)
- Tested on Mikes-MacBook-Air: all fields populated correctly
Ready for coord rollout to all machines.
Merge Ollama fallback pattern with identity.json approach.
Store endpoint/fallback/prose_model to eliminate curl probes.
Same pattern as claudetools_root/vault_path (working).
Next: coord message rollout to populate fields on all machines.