From c3aeef60fbf10491f392bc5de2f23ccf407564e8 Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Wed, 1 Jul 2026 15:07:34 -0700 Subject: [PATCH] sync: auto-sync from GURU-5070 at 2026-07-01 15:06:42 Author: Mike Swanson Machine: GURU-5070 Timestamp: 2026-07-01 15:06:42 --- .claude/skills/agy/SKILL.md | 8 +- .claude/skills/alis/SKILL.md | 12 +- .claude/skills/b2/SKILL.md | 8 +- .claude/skills/bitdefender/SKILL.md | 11 +- .claude/skills/coord/SKILL.md | 8 +- .claude/skills/datto-edr/SKILL.md | 11 +- .claude/skills/discord-dm/SKILL.md | 7 +- .claude/skills/drive-map/SKILL.md | 2 +- .claude/skills/frontend-design/SKILL.md | 2 +- .claude/skills/gitea/SKILL.md | 7 +- .claude/skills/grok/SKILL.md | 9 +- .claude/skills/gururmm-build/SKILL.md | 10 +- .claude/skills/mailprotector/SKILL.md | 3 +- .claude/skills/onboard365/SKILL.md | 2 +- .claude/skills/packetdial/SKILL.md | 3 +- .claude/skills/remediation-tool/SKILL.md | 127 +++++++++--------- .claude/skills/rmm-audit/SKILL.md | 7 +- .claude/skills/rmm-search/SKILL.md | 8 +- .claude/skills/screenconnect/SKILL.md | 10 +- .claude/skills/synology/SKILL.md | 8 +- .claude/skills/unifi-wifi/SKILL.md | 2 +- .claude/skills/vault/SKILL.md | 2 +- .claude/skills/yealink-ymcs/SKILL.md | 9 +- ...6-07-01-mike-self-check-skill-desc-trim.md | 115 ++++++++++++++++ 24 files changed, 200 insertions(+), 191 deletions(-) create mode 100644 session-logs/2026-07/2026-07-01-mike-self-check-skill-desc-trim.md diff --git a/.claude/skills/agy/SKILL.md b/.claude/skills/agy/SKILL.md index 11bb88b8..38932043 100644 --- a/.claude/skills/agy/SKILL.md +++ b/.claude/skills/agy/SKILL.md @@ -1,12 +1,6 @@ --- name: agy -description: > - Route a task to the official Google Gemini CLI for an independent second model — a - sibling of the `grok` second-opinion router. Use for a different-vendor SECOND OPINION - or adversarial VERIFICATION of a Claude finding/design, a Gemini code REVIEW of files / - a git diff, and one-shot Gemini TEXT answers. Triggers: ask gemini, gemini verify, - second opinion from gemini, gemini review, agy ... A second model, NOT a replacement - for Claude's own codebase work. +description: "Route a task to the Google Gemini CLI for an independent second model (sibling of grok): different-vendor second opinion, adversarial verification, Gemini code review of files/diffs, one-shot text answers. Triggers: ask gemini, gemini verify, gemini review, agy." --- # AGY — Gemini capability router diff --git a/.claude/skills/alis/SKILL.md b/.claude/skills/alis/SKILL.md index cae9be3d..e7d95bee 100644 --- a/.claude/skills/alis/SKILL.md +++ b/.claude/skills/alis/SKILL.md @@ -1,16 +1,6 @@ --- name: alis -description: >- - Build the ALIS (Medtelligent assisted-living EHR) staff bulk-import spreadsheet so new - staff/logins can be created in the ALIS web UI, and read the live ALIS staff roster via - the API as the setup reference. Maps a CSV/JSON of new hires onto Medtelligent's exact - 13-column import template, validates Status/Login/Gender against the dropdowns, and infers - each new hire's Security Roles from how existing staff of the same Job Role are configured - (a job-role -> security-role map learned from live data). The ALIS API is READ-ONLY for - staff (no write endpoint exists) - changes happen by uploading the generated .xls. Tenant: - Cascades of Tucson (communityId 622). Triggers: alis, alisonline, medtelligent, import - staff/users into alis, alis staff import, add staff to alis, build the alis import file, - alis staff roster, alis security roles. +description: "Build the ALIS (Medtelligent) staff bulk-import .xls (13-column template) for Cascades of Tucson (communityId 622) and read the live staff roster via the read-only API. Triggers: alis, alisonline, medtelligent, alis staff import, add staff to alis, alis security roles." --- # ALIS Skill (Medtelligent) — staff import builder + roster reference diff --git a/.claude/skills/b2/SKILL.md b/.claude/skills/b2/SKILL.md index 2552e9e4..0017dacd 100644 --- a/.claude/skills/b2/SKILL.md +++ b/.claude/skills/b2/SKILL.md @@ -1,12 +1,6 @@ --- name: b2 -description: >- - Manage ACG's Backblaze B2 storage account (Native API v3) — the LIVE production - account (accountId 46f69bc61163, us-west-001) holding per-client MSP360/CloudBerry - backup destinations. List buckets/keys/files, compute per-bucket size, run the - headline storage-cost report (mspbackups calc); provision/delete buckets and scoped - keys (destructive ops gated behind --confirm). Read-only by default. Triggers: - backblaze, b2, b2 storage, bucket, storage cost, backup storage, mspbackups storage. +description: "Manage ACG's live Backblaze B2 account (per-client MSP360 backup destinations): buckets/keys/files, per-bucket size, storage-cost report; provisioning/deletes gated --confirm. Triggers: backblaze, b2, bucket, storage cost, backup storage, mspbackups storage." --- # Backblaze B2 Skill diff --git a/.claude/skills/bitdefender/SKILL.md b/.claude/skills/bitdefender/SKILL.md index 4697aead..5d2da801 100644 --- a/.claude/skills/bitdefender/SKILL.md +++ b/.claude/skills/bitdefender/SKILL.md @@ -1,15 +1,6 @@ --- name: bitdefender -description: >- - Manage the ACG Bitdefender GravityZone Cloud MSP tenant (Public JSON-RPC API): - inventory/audit endpoints, live security sweeps (infected / outdated-signature / - outdated-product), client companies, install packages, custom groups, scans, - move/delete endpoints (gated), policies (full read + assign), reports, accounts, - scan tasks, notifications, push event service, quarantine, EDR (isolate / - blocklist). Live production partner tenant — treat destructive actions - conservatively. Triggers: bitdefender, gravityzone, install bitdefender on, list - endpoints, infected machines, av coverage, security sweep, endpoint protection, - assign policy, quarantine, reports, accounts. +description: "Manage the ACG Bitdefender GravityZone Cloud MSP tenant (JSON-RPC API): endpoint inventory/audit, security sweeps, packages, policies, quarantine, EDR isolate/blocklist; destructive ops gated. Triggers: bitdefender, gravityzone, infected machines, av coverage, assign policy." --- # Bitdefender GravityZone Skill diff --git a/.claude/skills/coord/SKILL.md b/.claude/skills/coord/SKILL.md index 9a5dd26e..4b574fab 100644 --- a/.claude/skills/coord/SKILL.md +++ b/.claude/skills/coord/SKILL.md @@ -1,12 +1,6 @@ --- name: coord -description: > - Talk to the ClaudeTools coordination API (inter-session messaging, fleet todos, - resource locks, component/status) without re-deriving the schema. Send/read messages - to another machine's session or BROADCAST to the fleet; create/list/complete coord - todos; claim/release work locks; read coord status. Triggers: send a coord message, - message /, broadcast to the fleet, coord todo, claim a lock, - coord status, any unread coord messages. +description: "Talk to the ClaudeTools coordination API without re-deriving the schema: send/read inter-session messages or fleet broadcasts, coord todos, claim/release locks, coord status. Triggers: send a coord message, broadcast to the fleet, coord todo, claim a lock, coord status." --- # coord — coordination API helper diff --git a/.claude/skills/datto-edr/SKILL.md b/.claude/skills/datto-edr/SKILL.md index 252c6800..e1d58870 100644 --- a/.claude/skills/datto-edr/SKILL.md +++ b/.claude/skills/datto-edr/SKILL.md @@ -1,15 +1,6 @@ --- name: datto-edr -description: >- - Control the ACG Datto EDR / Datto AV tenant (azcomp4587 — Datto EDR is rebranded - Infocyte HUNT; per-tenant LoopBack REST API). Read the whole MSP fleet from ONE - token: per-client organizations, sites, agents (online/AV/isolation/version), - detections (MITRE-tagged alerts), and a per-client security-posture sweep. Gated - actions: trigger scans, invoke response extensions (host isolation), and emit the - agent install one-liner for RMM-pushed deployment. Read-only by default; mutating - ops require --confirm. Triggers: datto edr, datto av, infocyte, EDR detections, - isolate endpoint, run a scan, deploy edr agent, edr security sweep, endpoint - detection response, azcomp4587. +description: "Control the ACG Datto EDR / Datto AV tenant (azcomp4587): fleet orgs/sites/agents, MITRE-tagged detections, per-client security sweeps; gated scans, host isolation, agent deploy. Read-only default. Triggers: datto edr, datto av, infocyte, EDR detections, isolate endpoint." --- # Datto EDR (Infocyte HUNT) Skill diff --git a/.claude/skills/discord-dm/SKILL.md b/.claude/skills/discord-dm/SKILL.md index ce94a8bd..ddae4fec 100644 --- a/.claude/skills/discord-dm/SKILL.md +++ b/.claude/skills/discord-dm/SKILL.md @@ -1,11 +1,6 @@ --- name: discord-dm -description: > - Send a Discord message to an org member's DMs or a team channel via the ClaudeTools - bot — for handing a person copy-paste-friendly content the terminal would mangle - (consent links, long commands, URLs, tokens-to-rotate) or to ping someone. Addresses - people by name (mike/howard/rob/winter), not raw snowflakes. Triggers: DM/message - in discord, discord DM, send that link to my discord, ping . +description: "Send a Discord message to an org member DM or team channel via the ClaudeTools bot - copy-paste-friendly delivery of links/commands the terminal would mangle; address people by name (mike/howard/rob/winter). Triggers: DM in discord, send that link to my discord, ping ." --- # discord-dm — direct Discord messaging to the org diff --git a/.claude/skills/drive-map/SKILL.md b/.claude/skills/drive-map/SKILL.md index 5b18e4cc..a98f0e85 100644 --- a/.claude/skills/drive-map/SKILL.md +++ b/.claude/skills/drive-map/SKILL.md @@ -1,6 +1,6 @@ --- name: drive-map -description: Reliably create/repoint Windows network drive maps and share shortcuts on a remote endpoint via GuruRMM. Bakes in the things that make this fight every time — runs in the user session (not SYSTEM, so maps actually appear), stores the per-host credential with cmdkey (the workgroup-PC-to-domain-share case), makes maps persistent, repoints/removes stale NAS shortcuts, and verifies access. Built for the Cascades NAS -> CS-SERVER migration but generic. +description: "Reliably create/repoint Windows network drive maps on a remote endpoint via GuruRMM: runs in the user session (not SYSTEM), stores per-host creds with cmdkey, persistent maps, repoints stale NAS shortcuts, verifies access. Triggers: map a drive, drive mapping, repoint share." --- # drive-map — remote drive maps & share shortcuts that actually stick diff --git a/.claude/skills/frontend-design/SKILL.md b/.claude/skills/frontend-design/SKILL.md index 552c2a6e..74e9ea6e 100644 --- a/.claude/skills/frontend-design/SKILL.md +++ b/.claude/skills/frontend-design/SKILL.md @@ -1,6 +1,6 @@ --- name: frontend-design -description: Create distinctive, production-grade frontend interfaces with high design quality. MANDATORY AUTOMATIC INVOCATION: use whenever ANY action affects a UI element, or when the user asks to build web components, pages, artifacts, posters, or applications (websites, landing pages, dashboards, React components, HTML/CSS layouts, styling any web UI). Generates creative, polished UI that avoids generic AI aesthetics. +description: "Create distinctive, production-grade frontend interfaces. MANDATORY AUTOMATIC INVOCATION whenever ANY action affects a UI element or the user asks for web components, pages, dashboards, artifacts, or styling. Avoids generic AI aesthetics." license: Complete terms in LICENSE.txt --- diff --git a/.claude/skills/gitea/SKILL.md b/.claude/skills/gitea/SKILL.md index e1f5d72a..47363c4b 100644 --- a/.claude/skills/gitea/SKILL.md +++ b/.claude/skills/gitea/SKILL.md @@ -1,11 +1,6 @@ --- name: gitea -description: > - Comprehensive git/Gitea operations for ClaudeTools fleet: submodule management - (init/update/sync/fix), status checks, commit/push/pull with proper error handling, - credential injection, identity reconciliation. Makes sync/save bulletproof across all - machines. Triggers: git submodule, gitea, fix submodule, git sync, submodule issues, - clone repo, git status, repo health. +description: "Comprehensive git/Gitea operations for the ClaudeTools fleet: submodule init/update/sync/fix, commit/push/pull, credential injection, identity reconciliation. Triggers: git submodule, gitea, fix submodule, git sync, clone repo, git status, repo health." --- # gitea — Bulletproof git/Gitea operations diff --git a/.claude/skills/grok/SKILL.md b/.claude/skills/grok/SKILL.md index f4ba86a5..b5777693 100644 --- a/.claude/skills/grok/SKILL.md +++ b/.claude/skills/grok/SKILL.md @@ -1,13 +1,6 @@ --- name: grok -description: > - Route a task to the Grok CLI (xAI Grok 4.3) for capabilities Claude lacks or an - independent second model: IMAGE generation/editing, VIDEO (image->video), live - WEB + X/TWITTER search (real-time data past Claude's cutoff), adversarial - second-opinion VERIFICATION. Triggers: ask grok, grok image, generate/make an image, - make a video / animate this, grok verify / second opinion, search X / twitter, - what's the latest . A capability EXTENSION, not a replacement for - Claude's own coding/editing. +description: "Route a task to the Grok CLI (xAI) for capabilities Claude lacks: image generation/editing, video, live web + X/Twitter search, adversarial second-opinion verification. Triggers: ask grok, grok image, make a video, grok verify / second opinion, search X / twitter." --- # Grok capability router diff --git a/.claude/skills/gururmm-build/SKILL.md b/.claude/skills/gururmm-build/SKILL.md index 6ff4e744..3103ff2f 100644 --- a/.claude/skills/gururmm-build/SKILL.md +++ b/.claude/skills/gururmm-build/SKILL.md @@ -1,14 +1,6 @@ --- name: gururmm-build -description: > - Build and pre-merge verification for the GuruRMM codebase (agent/server/dashboard). Encodes the - fleet's build model so every dev/machine builds the SAME way Mike does: merging to main is the - build+deploy trigger (no separate build step), so verify locally first. Wraps the cargo/npm - commands the server-side pipeline runs, with the compile-gate gotcha baked in (Linux-gated agent - code can't be verified by Windows cargo check; server needs SQLX_OFFLINE + a fresh .sqlx cache; - dashboard uses npm install not ci). Triggers: build the rmm agent/server/dashboard, verify the - linux build, gururmm build, pre-merge check, will this compile, sqlx prepare, migration collision, - promote dashboard, what does merging to main do. +description: "Build + pre-merge verification for GuruRMM (agent/server/dashboard). Merge-to-main IS the build+deploy trigger, so verify locally first. Triggers: build the rmm agent/server/dashboard, gururmm build, pre-merge check, will this compile, sqlx prepare, promote dashboard." --- # gururmm-build — Build & pre-merge verification for GuruRMM diff --git a/.claude/skills/mailprotector/SKILL.md b/.claude/skills/mailprotector/SKILL.md index 6798f63d..04951be5 100644 --- a/.claude/skills/mailprotector/SKILL.md +++ b/.claude/skills/mailprotector/SKILL.md @@ -1,7 +1,6 @@ --- name: mailprotector -description: "Manage the ACG Mailprotector CloudFilter email-security gateway (emailservice.io). Search/release held/quarantined mail (in+outbound), pull mail-flow logs (why a message did/didn't deliver), inspect + manage allow/block rules. Read-only default; releases/rule-changes gated --confirm. Triggers: mailprotector, cloudfilter, held/quarantined mail, release email, allow/block rule, INKY." - +description: "Manage the ACG Mailprotector CloudFilter email-security gateway: search/release held mail, mail-flow logs, allow/block rules; releases/rule-changes gated --confirm. Triggers: mailprotector, cloudfilter, held/quarantined mail, release email, allow/block rule, INKY." --- # Mailprotector / CloudFilter Skill diff --git a/.claude/skills/onboard365/SKILL.md b/.claude/skills/onboard365/SKILL.md index 52dc5afc..0c96be46 100644 --- a/.claude/skills/onboard365/SKILL.md +++ b/.claude/skills/onboard365/SKILL.md @@ -1,6 +1,6 @@ --- name: onboard365 -description: "Single-consent onboarding of a customer Microsoft 365 tenant to the ComputerGuru remediation app suite. The customer Global Admin clicks ONE admin-consent link (Tenant Admin); service principals, Graph/EXO/Defender permissions, and Entra roles are then provisioned automatically. Triggers: onboard 365, onboard a tenant, add tenant to remediation tools, single consent, consent link for new client, provision tenant apps, get a tenant ready for breach checks." +description: "Single-consent onboarding of a customer M365 tenant to the ComputerGuru remediation app suite: one admin-consent link provisions service principals, Graph/EXO/Defender permissions, Entra roles. Triggers: onboard 365, onboard a tenant, single consent, consent link." --- # Onboard365 — Single-Consent M365 Tenant Onboarding diff --git a/.claude/skills/packetdial/SKILL.md b/.claude/skills/packetdial/SKILL.md index ffa11d1d..5a22cca7 100644 --- a/.claude/skills/packetdial/SKILL.md +++ b/.claude/skills/packetdial/SKILL.md @@ -1,7 +1,6 @@ --- name: packetdial -description: "Manage the ACG PacketDial/OITVOIP hosted VoIP via the NetSapiens API v2 (pbx.packetdial.com). List/inspect domains, users, devices, DIDs, call queues, time frames, sites, auto-attendants, contacts, and domain billing/limits; pull CDRs; provision domains/users/SIP/numbers (writes gated --confirm; read-only default). Reseller-scoped key live + vaulted. Triggers: packetdial, oitvoip, netsapiens, voip domain/user/extension, call queue, auto attendant, provision phone, add did, CDR. Live production PBX." - +description: "Manage ACG PacketDial/OITVOIP hosted VoIP via the NetSapiens API v2 (live production PBX): domains, users, devices, DIDs, queues, CDRs; provisioning writes gated --confirm. Triggers: packetdial, oitvoip, netsapiens, voip user/extension, call queue, add did, CDR." --- # PacketDial / NetSapiens (OITVOIP) Skill diff --git a/.claude/skills/remediation-tool/SKILL.md b/.claude/skills/remediation-tool/SKILL.md index c9d99979..408c188c 100644 --- a/.claude/skills/remediation-tool/SKILL.md +++ b/.claude/skills/remediation-tool/SKILL.md @@ -1,64 +1,63 @@ ---- -name: remediation-tool -description: "M365 tenant investigation + remediation via the ComputerGuru MSP app suite (Security Investigator/Exchange Operator/User Manager/Tenant Admin/Defender). Direct Graph+Exchange REST (not CIPP). Triggers: 365 remediation, breach/credential-stuffing check, check a mailbox, inbox rules, mailbox forwarding, delegate/SendAs audit, OAuth consent, sign-in/risky-user lookup, tenant sweep." - ---- - -# 365 Remediation Tool - -Read-only by default. All remediation actions require explicit `YES` confirmation in chat (not a permission prompt). - -## App Architecture (Tiered) - -Five multi-tenant apps cover distinct privilege tiers. Use only what the task requires. - -| Tier | App display name | App ID | Vault file | Scope | -|---|---|---|---|---| -| `investigator` | ComputerGuru Security Investigator | `bfbc12a4-f0dd-4e12-b06d-997e7271e10c` | `computerguru-security-investigator.sops.yaml` | Graph read-only | -| `investigator-exo` | ComputerGuru Security Investigator | `bfbc12a4-f0dd-4e12-b06d-997e7271e10c` | `computerguru-security-investigator.sops.yaml` | Exchange Online read | -| `exchange-op` | ComputerGuru Exchange Operator | `b43e7342-5b4b-492f-890f-bb5a4f7f40e9` | `computerguru-exchange-operator.sops.yaml` | Exchange Online write | -| `user-manager` | ComputerGuru User Manager | `64fac46b-8b44-41ad-93ee-7da03927576c` | `computerguru-user-manager.sops.yaml` | Graph user/group write | -| `tenant-admin` | ComputerGuru Tenant Admin | `709e6eed-0711-4875-9c44-2d3518c47063` | `computerguru-tenant-admin.sops.yaml` | Graph high-privilege | -| `defender` | ComputerGuru Defender Add-on | `dbf8ad1a-54f4-4bb8-8a9e-ea5b9634635b` | `computerguru-defender-addon.sops.yaml` | Defender ATP (MDE only) | -| `sharepoint` / `sharepoint-admin` | ComputerGuru Tenant Admin | `709e6eed-0711-4875-9c44-2d3518c47063` | `computerguru-tenant-admin.sops.yaml` | **SharePoint Online** (Sites.FullControl.All) — cert-only | - -**The suite has broad, working access across ALL of M365 — Graph, Exchange Online, Defender, AND SharePoint Online.** Before concluding "the tool can't do X / access denied," verify against the live permission map in `references/app-permissions-and-sharepoint.md` (decode the token `roles` claim). An `accessDenied` usually means wrong tier or wrong endpoint for a scope we DO hold — not a real gap. Two recurring traps: (1) **SharePoint app-only requires a certificate** — a `client_secret` token is rejected everywhere in SharePoint with `"Unsupported app only token"` (get-token.sh forces cert for the `sharepoint*` tiers); (2) Graph `GET /admin/sharepoint/settings` needs a scope no app holds — read/write SharePoint tenant settings via the **CSOM/REST admin API** (`sharepoint-admin` tier) instead. Full map, gotchas, and CSOM examples: `references/app-permissions-and-sharepoint.md`. - -**Default for breach checks:** use `investigator` (Graph) + `investigator-exo` (Exchange read). Escalate to write tiers only when remediating. - -## Auto-Invocation Behavior - -When triggered automatically (vs. via `/remediation-tool`), follow the same workflow in `.claude/commands/remediation-tool.md`: - -1. Parse the user's intent into a subcommand (check/sweep/signins/consent-url/remediate). -2. Resolve tenant ID from domain. -3. Acquire tokens via `get-token.sh ` — use lowest-privilege tier needed. -4. Run checks via scripts in `scripts/`. -5. Interpret findings using `references/checklist.md`. -6. Write report to `clients/{slug}/reports/YYYY-MM-DD-{action}.md` using `templates/breach-report.md`. -7. Chat summary + delegate commit to Gitea agent. - -## Before calling any script, verify - -- The SOPS vault is accessible via `.claude/identity.json` `vault_path` field. The scripts auto-resolve the vault location from identity.json — no hardcoded paths. -- `jq`, `curl`, `bash` are available. -- For Exchange REST checks: confirm the target tenant has **Exchange Administrator** role assigned to the **Security Investigator** SP (for reads) or **Exchange Operator** SP (for writes). If any Exchange REST call returns 403, emit the tenant-scoped Entra Roles link from `references/gotchas.md`. -- For Identity Protection checks: `IdentityRiskyUser.Read.All` is in the Security Investigator manifest AND the tenant has consented to that app. If 403, emit the per-app consent URL from `references/gotchas.md`. -- For Defender checks: confirm tenant has Microsoft Defender for Endpoint (MDE) license before using `defender` tier — it returns AADSTS650052 otherwise. - -## Conventions - -- **Target identifiers**: accept UPN, domain, or tenant GUID. Normalize to tenant GUID internally. -- **Token tiers**: minimum necessary privilege. Never use `tenant-admin` for a read-only check. -- **Token cache**: `/tmp/remediation-tool/{tenant-id}/{tier}.jwt`. TTL 55 minutes. Check `-mmin -55` before reuse. -- **Raw JSON artifacts**: `/tmp/remediation-tool/{tenant-id}/{check}/` — keep so the user can re-analyze. -- **Reports**: `clients/{slug}/reports/YYYY-MM-DD-{action}.md`. Derive slug from domain (strip TLD, hyphenate). -- **UTC dates everywhere**. - -## Scope boundaries - -- **Not a replacement for CIPP.** Use CIPP for bulk baseline configuration, templates, standards alerting. Use this tool for focused investigation and point-in-time remediation. -- **Entra app registrations stay manual in the portal** — don't create/modify the multi-tenant apps themselves via the tool. -- **Conditional Access policies CAN be managed programmatically** (Tenant Admin tier holds `Policy.ReadWrite.ConditionalAccess` + the Conditional Access Administrator role). MANDATORY discipline: (1) always create/modify in **report-only** (`state: enabledForReportingButNotEnforced`) first; (2) always **exclude the tenant's break-glass account** (`conditions.users.excludeUsers`); (3) verify impact in Entra sign-in logs before enforcing; (4) get explicit user confirmation before flipping any policy to `enabled` on a tenant with real users. (CA-manual boundary relaxed 2026-05-27 at Mike's direction — break-glass + report-only keep blast radius near zero.) -- **Not for Graph permissions the apps don't have.** If a call 403s and the scope isn't in the relevant app's manifest, stop and tell the user — don't try to work around it. -- **Defender tier requires MDE license.** If the tenant doesn't have MDE, the token request succeeds but API calls return AADSTS650052. Check before using. +--- +name: remediation-tool +description: "M365 tenant investigation + remediation via the ComputerGuru MSP app suite (direct Graph+Exchange REST, not CIPP). Triggers: 365 remediation, breach check, check a mailbox, inbox rules, forwarding, delegate/SendAs audit, OAuth consent, risky-user lookup, tenant sweep." +--- + +# 365 Remediation Tool + +Read-only by default. All remediation actions require explicit `YES` confirmation in chat (not a permission prompt). + +## App Architecture (Tiered) + +Five multi-tenant apps cover distinct privilege tiers. Use only what the task requires. + +| Tier | App display name | App ID | Vault file | Scope | +|---|---|---|---|---| +| `investigator` | ComputerGuru Security Investigator | `bfbc12a4-f0dd-4e12-b06d-997e7271e10c` | `computerguru-security-investigator.sops.yaml` | Graph read-only | +| `investigator-exo` | ComputerGuru Security Investigator | `bfbc12a4-f0dd-4e12-b06d-997e7271e10c` | `computerguru-security-investigator.sops.yaml` | Exchange Online read | +| `exchange-op` | ComputerGuru Exchange Operator | `b43e7342-5b4b-492f-890f-bb5a4f7f40e9` | `computerguru-exchange-operator.sops.yaml` | Exchange Online write | +| `user-manager` | ComputerGuru User Manager | `64fac46b-8b44-41ad-93ee-7da03927576c` | `computerguru-user-manager.sops.yaml` | Graph user/group write | +| `tenant-admin` | ComputerGuru Tenant Admin | `709e6eed-0711-4875-9c44-2d3518c47063` | `computerguru-tenant-admin.sops.yaml` | Graph high-privilege | +| `defender` | ComputerGuru Defender Add-on | `dbf8ad1a-54f4-4bb8-8a9e-ea5b9634635b` | `computerguru-defender-addon.sops.yaml` | Defender ATP (MDE only) | +| `sharepoint` / `sharepoint-admin` | ComputerGuru Tenant Admin | `709e6eed-0711-4875-9c44-2d3518c47063` | `computerguru-tenant-admin.sops.yaml` | **SharePoint Online** (Sites.FullControl.All) — cert-only | + +**The suite has broad, working access across ALL of M365 — Graph, Exchange Online, Defender, AND SharePoint Online.** Before concluding "the tool can't do X / access denied," verify against the live permission map in `references/app-permissions-and-sharepoint.md` (decode the token `roles` claim). An `accessDenied` usually means wrong tier or wrong endpoint for a scope we DO hold — not a real gap. Two recurring traps: (1) **SharePoint app-only requires a certificate** — a `client_secret` token is rejected everywhere in SharePoint with `"Unsupported app only token"` (get-token.sh forces cert for the `sharepoint*` tiers); (2) Graph `GET /admin/sharepoint/settings` needs a scope no app holds — read/write SharePoint tenant settings via the **CSOM/REST admin API** (`sharepoint-admin` tier) instead. Full map, gotchas, and CSOM examples: `references/app-permissions-and-sharepoint.md`. + +**Default for breach checks:** use `investigator` (Graph) + `investigator-exo` (Exchange read). Escalate to write tiers only when remediating. + +## Auto-Invocation Behavior + +When triggered automatically (vs. via `/remediation-tool`), follow the same workflow in `.claude/commands/remediation-tool.md`: + +1. Parse the user's intent into a subcommand (check/sweep/signins/consent-url/remediate). +2. Resolve tenant ID from domain. +3. Acquire tokens via `get-token.sh ` — use lowest-privilege tier needed. +4. Run checks via scripts in `scripts/`. +5. Interpret findings using `references/checklist.md`. +6. Write report to `clients/{slug}/reports/YYYY-MM-DD-{action}.md` using `templates/breach-report.md`. +7. Chat summary + delegate commit to Gitea agent. + +## Before calling any script, verify + +- The SOPS vault is accessible via `.claude/identity.json` `vault_path` field. The scripts auto-resolve the vault location from identity.json — no hardcoded paths. +- `jq`, `curl`, `bash` are available. +- For Exchange REST checks: confirm the target tenant has **Exchange Administrator** role assigned to the **Security Investigator** SP (for reads) or **Exchange Operator** SP (for writes). If any Exchange REST call returns 403, emit the tenant-scoped Entra Roles link from `references/gotchas.md`. +- For Identity Protection checks: `IdentityRiskyUser.Read.All` is in the Security Investigator manifest AND the tenant has consented to that app. If 403, emit the per-app consent URL from `references/gotchas.md`. +- For Defender checks: confirm tenant has Microsoft Defender for Endpoint (MDE) license before using `defender` tier — it returns AADSTS650052 otherwise. + +## Conventions + +- **Target identifiers**: accept UPN, domain, or tenant GUID. Normalize to tenant GUID internally. +- **Token tiers**: minimum necessary privilege. Never use `tenant-admin` for a read-only check. +- **Token cache**: `/tmp/remediation-tool/{tenant-id}/{tier}.jwt`. TTL 55 minutes. Check `-mmin -55` before reuse. +- **Raw JSON artifacts**: `/tmp/remediation-tool/{tenant-id}/{check}/` — keep so the user can re-analyze. +- **Reports**: `clients/{slug}/reports/YYYY-MM-DD-{action}.md`. Derive slug from domain (strip TLD, hyphenate). +- **UTC dates everywhere**. + +## Scope boundaries + +- **Not a replacement for CIPP.** Use CIPP for bulk baseline configuration, templates, standards alerting. Use this tool for focused investigation and point-in-time remediation. +- **Entra app registrations stay manual in the portal** — don't create/modify the multi-tenant apps themselves via the tool. +- **Conditional Access policies CAN be managed programmatically** (Tenant Admin tier holds `Policy.ReadWrite.ConditionalAccess` + the Conditional Access Administrator role). MANDATORY discipline: (1) always create/modify in **report-only** (`state: enabledForReportingButNotEnforced`) first; (2) always **exclude the tenant's break-glass account** (`conditions.users.excludeUsers`); (3) verify impact in Entra sign-in logs before enforcing; (4) get explicit user confirmation before flipping any policy to `enabled` on a tenant with real users. (CA-manual boundary relaxed 2026-05-27 at Mike's direction — break-glass + report-only keep blast radius near zero.) +- **Not for Graph permissions the apps don't have.** If a call 403s and the scope isn't in the relevant app's manifest, stop and tell the user — don't try to work around it. +- **Defender tier requires MDE license.** If the tenant doesn't have MDE, the token request succeeds but API calls return AADSTS650052. Check before using. diff --git a/.claude/skills/rmm-audit/SKILL.md b/.claude/skills/rmm-audit/SKILL.md index 82cef950..e5a27a53 100644 --- a/.claude/skills/rmm-audit/SKILL.md +++ b/.claude/skills/rmm-audit/SKILL.md @@ -1,11 +1,6 @@ --- name: rmm-audit -description: | - Periodic end-to-end verification of the GuruRMM codebase + build infra: 5 parallel - audit passes (API/route, UI coverage, Rust, TypeScript, security) plus a sequential - pipeline-health pass; writes a timestamped report and updates UI_GAPS.md and - FEATURE_ROADMAP.md. Explicit only — /rmm-audit, optional - --pass=. Detail in the SKILL body. +description: "Periodic end-to-end verification of the GuruRMM codebase + build infra: 5 parallel audit passes + pipeline health; writes a report, updates UI_GAPS/FEATURE_ROADMAP. Explicit only - /rmm-audit, optional --pass=." --- # GuruRMM End-to-End Audit diff --git a/.claude/skills/rmm-search/SKILL.md b/.claude/skills/rmm-search/SKILL.md index 49411058..ceb2f79f 100644 --- a/.claude/skills/rmm-search/SKILL.md +++ b/.claude/skills/rmm-search/SKILL.md @@ -1,12 +1,6 @@ --- name: rmm-search -description: > - Find machines/agents in the GuruRMM fleet cleanly and on the first try — locate an - RMM agent by name, role, client, site, or OS before acting on it, instead of pulling - /api/agents and grepping (which bleeds across clients). Forgiving multi-field search - with a client filter so "hyperv valleywide" returns ONLY Valley Wide's host. Triggers: - find the X machine, which agent is, look up in RMM, 's server/DC/hyperv, - search RMM for, what's the agent id for. Hand the result to the `rmm` skill to run commands. +description: "Find GuruRMM fleet machines on the first try - search agents by name/role/client/site/OS with a client filter instead of grepping /api/agents. Hand the result to /rmm. Triggers: find the X machine, which agent is, look up in RMM, search RMM for." --- # rmm-search — clean machine lookup in GuruRMM diff --git a/.claude/skills/screenconnect/SKILL.md b/.claude/skills/screenconnect/SKILL.md index fe868fe2..ba79b69e 100644 --- a/.claude/skills/screenconnect/SKILL.md +++ b/.claude/skills/screenconnect/SKILL.md @@ -1,14 +1,6 @@ --- name: screenconnect -description: >- - Manage the ACG ConnectWise ScreenConnect (Control) instance via the RESTful API - Manager extension: list/inspect sessions, build PARAMETERIZED access installers - (self-tag a device into the right Company/Site/Tag), run backstage commands, - message guests, and update custom properties. Read-only by default; state- - changing ops are gated behind --confirm. Pairs with /rmm to push the installer. - Triggers: screenconnect, connectwise control, sc session, remote access agent, - build screenconnect installer, run command on a screenconnect session, tag a - device in screenconnect, deploy screenconnect via rmm. +description: "Manage ACG ConnectWise ScreenConnect via the RESTful API Manager extension: sessions, parameterized self-tagging installers, backstage commands, custom properties; writes gated --confirm. Triggers: screenconnect, connectwise control, sc session, screenconnect installer." --- # ScreenConnect (ConnectWise Control) Skill diff --git a/.claude/skills/synology/SKILL.md b/.claude/skills/synology/SKILL.md index 9daf8540..b5185bf0 100644 --- a/.claude/skills/synology/SKILL.md +++ b/.claude/skills/synology/SKILL.md @@ -1,12 +1,6 @@ --- name: synology -description: > - Control a Synology NAS via the DSM Web API (auth + API discovery + any method: system, - storage, shares, users/groups, packages, services, FileStation) plus an SSH backend for - the syno* CLI (ACLs, low-level internals). Reads run free; mutating calls gated behind - --confirm. Default device Cascades cascadesDS; --vault for another client's NAS. Triggers: - synology, diskstation, DSM, cascadesDS, NAS, synology drive, hyper/active backup, synology - package/service/share/user, reboot the nas, synology acl. +description: "Control a Synology NAS via the DSM Web API + SSH backend (system, storage, shares, users, packages, FileStation, ACLs); writes gated --confirm; default device Cascades cascadesDS. Triggers: synology, diskstation, DSM, NAS, hyper/active backup, synology acl." --- # synology — Synology DSM control (Web API + SSH) diff --git a/.claude/skills/unifi-wifi/SKILL.md b/.claude/skills/unifi-wifi/SKILL.md index 7eca6a3e..30382610 100644 --- a/.claude/skills/unifi-wifi/SKILL.md +++ b/.claude/skills/unifi-wifi/SKILL.md @@ -1,6 +1,6 @@ --- name: unifi-wifi -description: "Analyze and tune UniFi WiFi for performance + stability in dense/congested environments. Audits AP/radio config and the neighbor-interference map from the UOS controller, flags issues (2.4GHz over-provisioning, channel width, min-RSSI/sticky clients, channel plan), recommends prioritized changes. Any UniFi site on the UOS (172.16.3.29); Cascades is the hard case. Triggers: unifi wifi tuning, RF/airtime/channel analysis, 2.4GHz congestion, AP channel plan, sticky clients, wireless performance." +description: "Analyze and tune UniFi WiFi in dense/congested environments: audit AP/radio config + neighbor interference from the UOS controller, flag issues, recommend prioritized changes. Triggers: unifi wifi tuning, RF/airtime/channel analysis, 2.4GHz congestion, sticky clients." --- # UniFi WiFi tuning (UOS sites) diff --git a/.claude/skills/vault/SKILL.md b/.claude/skills/vault/SKILL.md index e9c21114..70620d6a 100644 --- a/.claude/skills/vault/SKILL.md +++ b/.claude/skills/vault/SKILL.md @@ -1,6 +1,6 @@ --- name: vault -description: "The ONE canonical way to use the ClaudeTools SOPS+age secret vault — read, store, update, and verify credentials. Use whenever a task involves a password, API key, token, secret, connection string, SSH key, or any credential: retrieving, storing a new/discovered one, or checking what's vaulted. Stops per-session improvising (raw sops, guessed paths, plaintext-field mistakes). Triggers: vault, store/save a secret, add to vault, get the password/api key for X, where is the credential for X, sops, encrypt, decrypt, rotate a credential, 1password fallback." +description: "The ONE canonical way to use the ClaudeTools SOPS+age secret vault - read, store, update, verify credentials; use for ANY password/API key/token/secret task. Triggers: vault, store a secret, get the password/api key for X, sops, rotate a credential, 1password fallback." --- # Vault — one consistent way to handle secrets diff --git a/.claude/skills/yealink-ymcs/SKILL.md b/.claude/skills/yealink-ymcs/SKILL.md index f653334b..75ce5a18 100644 --- a/.claude/skills/yealink-ymcs/SKILL.md +++ b/.claude/skills/yealink-ymcs/SKILL.md @@ -1,13 +1,6 @@ --- name: yealink-ymcs -description: > - Manage ACG's Yealink phone fleets via the Yealink Management Cloud Service (YMCS) v2 open API - (us-api.ymcs.yealink.com). List sites/devices/accounts/firmwares/models/alarms, RPS servers + - devices; gated writes (add devices by MAC, reboot/factory-reset, RPS add/remove, push a SIP - account onto a device). Read-only by default; writes gated --confirm. Pairs with the `packetdial` - skill (NetSapiens PBX) for phone provisioning. One ACG AccessKey sees ALL client sites. - Triggers: yealink, ymcs, provision phone, register MAC, RPS, device firmware, reboot phone, - push sip account to phone, yealink device manager. +description: "Manage ACG's Yealink phone fleets via the YMCS v2 API: sites/devices/accounts/firmware/alarms/RPS; gated writes (add MAC, reboot, push SIP account). Pairs with packetdial. Triggers: yealink, ymcs, provision phone, register MAC, RPS, reboot phone." --- # yealink-ymcs — Yealink Management Cloud Service (YMCS) v2 API diff --git a/session-logs/2026-07/2026-07-01-mike-self-check-skill-desc-trim.md b/session-logs/2026-07/2026-07-01-mike-self-check-skill-desc-trim.md new file mode 100644 index 00000000..9f7a8833 --- /dev/null +++ b/session-logs/2026-07/2026-07-01-mike-self-check-skill-desc-trim.md @@ -0,0 +1,115 @@ +# 2026-07-01 — /self-check run + skill-registry description trim (GREEN) + +## User +- **User:** Mike Swanson (mike) +- **Machine:** GURU-5070 +- **Role:** admin + +## Session Summary + +Ran `/self-check` (the fleet-conformance probe) on GURU-5070. The deterministic probe graded +AMBER: 83 PASS, 1 WARN, 0 FAIL, 35 INFO against provisional manifest 1.0.0. The single warning +was `harness.registry_budget` — the sum of all repo SKILL.md frontmatter `description:` fields +was 15,658 chars against the 10,500 budget (35 skills), i.e. registry bloat taxing every +session's context load. + +Ran both semantic passes the skill mandates on a full check. Pass 1 (rogue-memory +contradiction vs identity.json/settings): clean. The one suspect — `feedback_ollama_tier0_routing.md` +headlining qwen3:14b while this box's identity.json sets `prose_model: qwen3:8b` — self-resolves: +the memory body instructs reading `prose_model` from identity.json and documents that 12 GB boxes +like GURU-5070 get 8b (its Python example hardcoding 'qwen3:14b' is cosmetic only). +Pass 2 (command-vs-standard): `time-entry-protocol.md` still defers to `/syncro` as SSOT and both +agree add_line_item is normal billing with timers outlier-only — no drift. + +Mike asked to trim the descriptions and re-publish. Measured with the probe's own awk logic +(frontmatter-only, description block until next top-level key). Trimmed 23 skills' descriptions +from multi-paragraph essays to single ~250-290 char lines, keeping distinctive trigger keywords +and gating notes. Before cutting, verified every load-bearing fact (tenant IDs, endpoints, +communityId 622, azcomp4587, B2 accountId, cmdkey/SYSTEM gotchas, SQLX_OFFLINE, etc.) already +exists in each SKILL.md body — nothing lost, only deduplicated. Registry total: 15,658 -> 9,786 +chars (~700 headroom). + +Copied the 23 trimmed SKILL.md files to `~/.claude/skills/` so the repo-vs-global duplicate +check stays "identical" rather than flipping to divergent-WARN. Re-ran with `--publish`: +**Grade GREEN** (84 PASS / 0 WARN / 0 FAIL / 35 INFO), census published to coord as component +`selfcheck_GURU-5070 = GREEN`. + +## Key Decisions + +- Trimmed descriptions in-place with a Python script implementing the probe's exact awk + counting logic (frontmatter description block only), rather than eyeballing — the first + naive measurement (whole-file grab) wildly overcounted and would have led to wrong targets. +- Kept distinctive trigger keywords in every trimmed description (skill routing depends on + them); moved nothing that wasn't already duplicated in the SKILL.md body. +- Verified body coverage of load-bearing facts (grep per key fact) BEFORE deleting them from + frontmatter, instead of blindly relocating text. +- Trimmed 4 extra skills (mailprotector, rmm-audit, remediation-tool, gitea) beyond the + minimum needed, to build ~700 chars of headroom so the next added skill doesn't re-trip + the WARN. +- Synced trimmed files to `~/.claude/skills/` immediately to avoid creating repo/global + divergence (the "same skill, different behavior" failure the duplicates check exists for). +- Semantic memory pass: judged from MEMORY.md index one-liners + targeted file reads instead + of opening all ~200 memory files; only opened the one genuine suspect. + +## Problems Encountered + +- Initial description measurement (awk over whole file with `head -50`) gave ~80k total vs the + probe's 15,658 — the probe counts ONLY the frontmatter description block between the `---` + markers. Resolved by reading `check_harness_smoke()` in + `.claude/skills/self-check/scripts/self-check.sh` and reusing its exact awk. +- First trim pass landed at 10,272/10,500 — technically passing but with only ~230 chars + headroom. Trimmed 4 more skills to reach 9,786. + +## Configuration Changes + +Modified (frontmatter description trimmed to one line; body untouched), in BOTH +`.claude/skills//SKILL.md` and `~/.claude/skills//SKILL.md`: + +- agy, alis, b2, bitdefender, coord, datto-edr, discord-dm, drive-map, frontend-design, + gitea, grok, gururmm-build, mailprotector, onboard365, packetdial, remediation-tool, + rmm-audit, rmm-search, screenconnect, synology, unifi-wifi, vault, yealink-ymcs + (23 skills) + +Created: +- `session-logs/2026-07/2026-07-01-mike-self-check-skill-desc-trim.md` (this log) + +Scratch (session temp dir, not in repo): `trim_descs.py` (the trim script). + +## Credentials & Secrets + +None surfaced, created, or rotated. + +## Infrastructure & Servers + +- Coord API `http://172.16.3.30:8001` — reachable; census published as component + `selfcheck_GURU-5070`, state GREEN. +- Capability tier: ollama_local (Ollama 0.30.11 at localhost:11434, fallback Beast + 100.101.122.4:11434, prose_model qwen3:8b). cargo/node/gh/op present; docker absent + (capability off, expected). + +## Commands & Outputs + +- Probe: `SELFCHECK_TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)" bash .claude/skills/self-check/scripts/self-check.sh report` -> AMBER, sole WARN `harness.registry_budget` (15658 > 10500). +- Per-skill budget measurement: probe's awk (frontmatter `description:` block, stop at next + `^[A-Za-z0-9_-]+:` or closing `---`), summed over `.claude/skills/*/SKILL.md`. +- Re-run + publish: `... self-check.sh --publish` -> GREEN, `[OK] Published census to coord: component selfcheck_GURU-5070 = GREEN`. + +## Pending / Incomplete Tasks + +- The 23 trimmed SKILL.md files sync fleet-wide with this /save's commit; other machines + re-run `/self-check` after pulling to clear their own registry_budget WARN and republish. +- Baseline manifest still provisional (1.0.0): 25 skills + 4 commands report as census + candidates — ratification of `baseline/manifest.json` (via fanout + aggregate) still ahead. +- Standing INFO: 27 commands + 35 skills duplicated repo vs `~/.claude` (identical today; + probe flags divergence if it happens). Docker absent — deliberate. + +## Reference Information + +- Probe engine: `.claude/skills/self-check/scripts/self-check.sh` (budget logic in + `check_harness_smoke()`, ~line 588). +- Baseline: `.claude/skills/self-check/baseline/manifest.json` — `harness.registry_desc_budget_chars: 10500`; + `command_standard_links` has one pair (syncro-billing: `.claude/standards/syncro/time-entry-protocol.md` + must defer to `/syncro`) — verified intact and non-contradictory. +- Registry description totals: before 15,658 / after 9,786 (budget 10,500). +- Semantic pass artifacts checked: `.claude/memory/feedback_ollama_tier0_routing.md`, + `.claude/standards/syncro/time-entry-protocol.md`, `.claude/commands/syncro.md`.