# Memory Index

## Reference
- [ACG resource map](reference_resource_map.md) — **READ THIS FIRST** when a task references a server/service/tenant/API. What we have access to, how to connect from this machine, per-machine exceptions, gotchas. Points at the detail files below.
- [MSP360 backup monitoring](reference_msp360_backup_monitoring.md) — Authoritative "is client X actually backing up / last run" source for the whole fleet (NOT B2 bucket contents). MSP360 MBS API `/api/Monitoring`, vault `msp-tools/msp360-api.sops.yaml`. CompanyName also IDs B2 buckets (ACG-PST=Peaceful Spirit, ACG-TCA=Tucson Coin).
- [Backup checks only for billed clients](feedback_backup_check_only_billed.md) — Don't scan backup status for clients with no billed Data Backup line (Syncro schedule qty=0); verify billed clients only. Non-billed-but-backing-up = revenue-leak question for Mike/Winter, not a scan target.
- [ALIS (Medtelligent)](reference_alis_medtelligent.md) — Cascades assisted-living EHR. API host api.alisonline.com, community 622; username must be tenant-qualified (howard.enos@cascadestucson). Staff are READ-ONLY via API — create/change staff via web-UI Staff Import .xls. Use the `alis` skill.
- [GuruRMM User Manager](reference_gururmm_user_manager.md) — GuruRMM has a built-in per-agent User Manager tab (reset_password/enable/disable/groups for local+domain+AAD endpoint users; domain users only on a DC via `is_dc`). Use it, NOT raw Set-ADAccountPassword via /rmm. Endpoints: /api/agents/{id}/users + /users/action.
- [RMM map network drive (err67 double-hop)](reference_rmm_map_network_drive.md) — Pushing a persistent mapped drive to a remote share via /rmm user_session fails with err67/1702 (impersonated token = no network cred/double-hop). Plant HKCU:\Network\<drv> keys + cmdkey; mounts at next interactive logon. Immediate visibility needs the live session (ScreenConnect).
- [exchange-op = all-access Exchange tier](feedback_exchange_op_all_access.md) — STOP claiming "no tier can write mail." Exchange Operator app = Exchange Admin role + full_access_as_app + Exchange.ManageAsApp = full all-access (move mail, rules, config, EWS). Default to `exchange-op` for any Exchange write.
- [Tedards tenant facts](reference_tedards_tenant_facts.md) — Bill Tedards law office; tenant `4fcbb1f4…`; bt@/y226@ mailboxes; matter-number filing; UAL ingestion OFF; 9 synced devices; botched-import DUPLICATE folder.
- [Investigator EXO ManageAsApp gap](reference_investigator_exo_manageasapp_gap.md) — Security Investigator app lacks `Exchange.ManageAsApp` (only `full_access_as_app`) so `investigator-exo` 401s on EXO adminapi; use `exchange-op` tier for InvokeCommand.
- [Windows edition upgrade via RMM](reference_windows_edition_upgrade_rmm.md) — Verified Home->Pro/Pro-for-Workstations fleet procedure: `changepk.exe /ProductKey <generic Pro>` (NOT DISM Set-Edition — Error 50) -> reboot with `Restart-Computer -Force` (`shutdown /r /t N` is silently dropped in SYSTEM session) -> `slmgr /ipk <MAK>` + /ato. The vault MAK is a Pro-for-WORKSTATIONS key (auto-upgrades edition past plain Pro).
- [Tailscale subnet-route key expiry](reference_tailscale_subnet_key_expiry.md) — "internet OK but all of 172.16.3.x (Gitea .20, RMM/coord .30) dead" = Tailscale infra-node KEY EXPIRY (pfSense subnet router advertises 172.16.0.0/22), NOT a LAN outage; expiry now disabled on infra nodes (2026-06-25). Fallback: gururmm-server direct at tailnet 100.86.12.15:3001.
- [GravityZone support center](reference_gravityzone_support.md) — Authoritative Bitdefender GravityZone product + Public API docs; use to confirm UNVERIFIED `bitdefender` skill methods/param shapes (push setPushEventSettings, assignPolicy, report/account writes, maintenancewindows/integrations names).
- [GURU-5070 Rust toolchain](reference_guru5070_rust_toolchain.md) — toolchain installed BUT a WDAC/Smart App Control policy (since 2026-07-04) BLOCKS running rustc/cargo/sops/openssl locally (os error 4551) — build the Windows agent on Beast, not here. Toolchain paths + CI gates still valid for reference.
- [ACG Office Network Infrastructure](infra_office_network.md) — IPs/hosts/roles for pfSense/Jupiter/VMs/Docker. Check before assuming; .21 (Uranus) is storage.
- [Power Failure Runbook](../POWER_FAILURE_RUNBOOK.md) — Recovery order after a power event: Tailscale routes, libvirt/VMs, Seafile, NPM/DNS.
- [Syncro API — Invoice Verification Pattern](syncro_invoice_verification_pattern.md) — /invoices?customer_id=X returns no ticket linkage; query /invoices/{number} for ticket_id. Compare by ticket ID, not number.
- [Syncro asset/RMM IS API-drivable](reference_syncro_rmm_api_gui_only.md) — CORRECTED 2026-07-10: asset read/create/update, patches, installed_apps, rmm_alerts all work via API; ONLY policy folders + `policy_folder_id` move need the `Assets - Policy Change` token scope (401 today). Archive stays GUI-only. Full catalog: `.claude/standards/syncro/api-reference.md`.
- [Datto EDR detection behavior](reference_datto_edr_detection_behavior.md) — alert `sourceType`: `av`=Datto AV signature, `rule`=EDR reputation detection (both via `edr.py detections`). EDR is reputation-based not structural (wire known-bad file as autostart exe to trip it; loose files aren't surveyed). AV is tamper-protected (console-only disable); disabling Datto AV uninstalls it + Defender auto-reactivates (AMSI blocks scripts with literal EICAR → build from char codes). Verified live on RMM-TEST-MACHINE.
- [Bug & Project Tracker (Gitea Issues)](project_bug_tracker_gitea.md) — Official tracker for bugs/features/skills across GuruRMM, GuruConnect, ClaudeTools. Dashboard + `bug-tracker` skill. Set up 2026-07-17.
- [Approval Workflow: Tools vs Projects](approval-workflow-tools-vs-projects.md) — Tools (remediation, scripts): Howard/Claude with approval. Projects (GuruRMM): Mike approval for architecture/features; Howard can handle merges/deploys himself (2026-06-21); bugs→bug list.
- [CDP Chrome driver](reference_cdp_chrome_driver.md) — Drive Chrome via DevTools Protocol (.claude/scripts/cdp.py): visible window + screenshots-to-disk so Gemini/Grok can SEE the live site. Use localhost not 127.0.0.1; dedicated profile. Antigravity-style.
- [Firefox driver (ff.py)](reference_ff_firefox_driver.md) — PREFERRED browser driver. Drive Firefox via Playwright (.claude/scripts/ff.py): daemon on :9333, persistent profile, nav/shot/click/type/eval/console/network. Mike dislikes Chrome; claude-in-chrome connector disabled 2026-06-06.
- [Community Forum (Flarum)](reference_community_forum.md) — Flarum forum at community.azcomputerguru.com, API access, database, posting workflow.
- [Radio Show Website](reference_radio_website.md) — Astro static site at radio.azcomputerguru.com on IX server.
- [IX Server Access](reference_ix_server_access.md) — `ix.azcomputerguru.com` / 172.16.3.10. Reachable when Tailscale is on (no VPN). SSH currently uses sshpass with root password; key auth from GURU-5070 not configured yet (was CachyOS, now Win11 — verify).
- [Cloudflare access](reference_cloudflare_access.md) — Cloudflare API creds in SOPS `services/cloudflare.sops.yaml` (full DNS + account tokens; azcomputerguru zone_id 1beb9917...). azcomputerguru.com DNS is on Cloudflare (not IX) — edit via Cloudflare API, not whmapi1.
- [Matomo Analytics](reference_matomo_analytics.md) — Self-hosted analytics at analytics.azcomputerguru.com, site IDs, tracking for all 3 sites.
- [TickTick Integration](reference_ticktick_integration.md) — OAuth API integration, MCP server, SOPS vault creds, project/task CRUD.
- [Client Docs Structure](reference_client_docs_structure.md) — clients/<name>/docs/ layout (overview, network, servers, cloud, security, rmm). Template: clients/_client_template/.
- [Client Wi-Fi Inventory](reference_client_wifi_inventory.md) — Building a fleet Wi-Fi list to connect onsite without asking. Passwords → vault `clients/<slug>/wifi.sops.yaml` (`credentials.<key>_ssid/_password`); readable index → `wiki/reference/client-wifi.md`. `/wifi` importer deferred (structure-only 2026-07-06).
- [Git Bash TZ ignored](feedback_gitbash_tz_ignored.md) — `TZ=America/Phoenix date` in Git Bash silently prints UTC (no tzdata) — confidently-wrong "current time". Use PowerShell `Get-Date` (machine already AZ) or plain `date` with no TZ override for now-time on Windows.
- [Discord read replies](feedback_discord_read_replies.md) — Discord DM replies don't come through coord/repo sync. Use `discord-dm.sh read <user>` to see if mike/winter/rob actually answered before assuming silence.
- [MSP Audit Scripts](reference_msp_audit_scripts.md) — server_audit.ps1 / workstation_audit.ps1 at projects/msp-tools/msp-audit-scripts/.
- [Pluto Build Server](reference_pluto_build_server.md) — Windows build VM: hostname PLUTO = Unraid VM "Claude-Builder" = 172.16.3.36 (all the same box). MSVC + WiX + Azure Trusted Signing. Drive via /rmm (agent enrolls as PLUTO) when SSH key isn't authorized.
- [Coord /messages API shape](reference_coord_messages_api_shape.md) — GET /api/coord/messages returns {total,skip,limit,messages[]} NOT a bare array; parse .messages[], strip control chars, read flag may be null.
- [Gitea API credential](reference_gitea_api_credential.md) — Gitea API (PRs/merges) as howard uses services/gitea-howard.sops.yaml password on internal http://172.16.3.20:3000; NOT the gururmm-server SSH password.
- [Gitea Internal API Access](reference_gitea_internal.md) — git.azcomputerguru.com is NOT behind Cloudflare — it's the office Cox IP NAT'd to NPM (openresty) on Jupiter. Prefer internal 172.16.3.20:3000 for reliability (bypasses NPM SSL-renewal reload blips).
- [Gitea git-op latency](reference_gitea_git_op_latency.md) — SSH (.20:2222) is SLOWEST (~1.5s); internal HTTP+token ~0.55s; SOPS lookup only ~0.33s. Don't switch to SSH for speed. Gitea SSH is .20:2222 (API ssh_url .21 is wrong).
- [GuruRMM technical reference](reference_gururmm.md) — Server (172.16.3.30) layout + downloads dir `/var/www/gururmm/downloads` + `.channel` sidecar rollout control (stable/beta) + privileged server access via the server's OWN root RMM agent (hostname `gururmm`, no SSH needed; plink fallback) + API + `context=user_session` (WTS impersonation) + build-pipeline vendoring at `deploy/build-pipeline/` + Linux agent systemd sandbox trap.
- [GuruRMM command timeout_seconds](reference_gururmm_command_timeout_seconds.md) — agent command dispatch honors `timeout_seconds`, NOT `timeout`; long jobs die ~300s / go zombie (`running`, empty stdout) otherwise. Cost Birth Biologic a full day.
- [SharePoint Graph large-file upload](reference_sharepoint_graph_large_file_upload.md) — <4MB simple PUT, >=4MB MUST use chunked upload session (Content-Range); `\\?\` long paths; idempotent size-check; verify counts via /root/delta; single stream ~40Mbps (SPO throttle).
- [Exchange REST uses exchange-op tier](reference_exchange_online_exchangeop_tier.md) — ALL Exchange adminapi (Get-Mailbox/InboxRule/MailboxPermission, Set-*) goes through `exchange-op`, NEVER `investigator-exo` (401s: Security Investigator app lacks `Exchange.ManageAsApp`). 401=wrong app→exchange-op; 403=missing Exchange Admin role. Recurred 6+ times.
- [RMM-spawn headless Claude](reference_rmm_spawn_headless_claude.md) — run `claude -p` on any RMM-managed Windows box with Claude Code (reaches coord-isolated sites like AD2); use `context:user_session`, UNSET the stale machine `ANTHROPIC_API_KEY` (shadows OAuth → "Invalid API key"), detach + poll a DONE marker. Validated on AD2 2026-07-01.
- [RMM agent update model](rmm-agent-update-model.md) — Agent updates are server-PUSH on heartbeat (no self-poll); available versions = filesystem scan needing a `.sha256`; promote flips `.channel` sidecars beta→stable globally. Two stranders: beta-first freezes stable until an explicit promote; agents older than ~0.6.50 re-enroll with a NEW device_id/agent row when updated.
- [GuruRMM physical server storage](gururmm-physical-server-storage.md) — New box 172.16.1.231 (temp IP→will be .30), Ubuntu 26.04, ssh key `gururmm-physical`/alias `gururmm-new`. SSD (915G root) = HOT (PG default tablespace + WAL + builds); HDD ext4 at `/data` = COLD (`gururmm_cold` PG tablespace for aged `agent_logs` partitions + downloads + backups + archive). The #3 retention answer.
- [Trebesch DESKTOP-QNP3ON5 shell replacement](reference_trebesch_qnp3on5.md) — AT Trebesch box runs an Explorer shell replacement; explorer.exe owner check returns blank — use Win32_ComputerSystem.UserName. GuruRMM SWIFT-LION-2892.
- [reference_backblaze_storage_rate](reference_backblaze_storage_rate.md) -- ACG's Backblaze B2 storage cost rate ($0.00695/GB) for the GuruRMM mspbackups storage-cost calculation
- [Unraid VM no-IP causes](unraid-windows-vm-virtio-no-ip.md) — PRIMARY (general "new VMs stopped getting IPs lately"): Docker sets bridge-nf-call-iptables=1, so br0 VM DHCP OFFERs hit DOCKER-FORWARD (no br0 ACCEPT) and get dropped; new VMs can't complete DORA (existing renew via ESTABLISHED). Fix `=0` runtime (needs persistent post-Docker hook; not yet persisted on Jupiter). SECONDARY (Windows VM): virtio-net has no in-box driver -> use e1000 or virtio-win. Diagnose: tcpdump DHCP on pfSense; /sys vnetN rx_packets.
- [Starr Pass mail routing](reference_starrpass_mail_routing.md) — starrpass.com is DIRECT to MS (EOP/Defender, tenant 222450dd…); only devconllc.com is on Mailprotector (MP acct 16170). Check @starrpass.com quarantine/rejects via remediation-tool, not Mailprotector.
- [INKY outbound breaks DMARC](reference_inky_outbound_breaks_dmarc.md) — Reverse-resolve DMARC rua failing IPs before blaming a sender: ipw-outbound.inkyphishfence.com / us.cloud-sec-av.com = INKY re-injection breaking DKIM+SPF. INKY is in-M365 (connectors+transport rules) per enrolled tenant, but hosting-level (IX/cPanel website) outbound also routes through it independent of M365 enrollment. Fix is INKY-side (outbound DKIM/SPF/ARC), not cPanel DNS.
- [Syncro prepay: full-GET only](feedback_syncro_prepay_full_get_only.md) — read prepay_hours ONLY from GET /customers/{id}; the customer search/list endpoint returns null/stale prepay. Never assert "no block" in a billing preview from search data.
- [Syncro priority/type format](feedback_syncro_priority_type_format.md) — every ticket create needs a number-prefixed priority ("2 Normal", not bare "Normal" which renders blank) AND a valid problem_type. Winter flagged #32193/#32194. Use the syncro skill's create flow.
- [Syncro line-item category](feedback_syncro_line_item_category.md) — product_category is a controlled vocab: never invent one, never invoice a line whose product has product_category:null (blank CATEGORY breaks QB mapping). Pre-flight GET /products/<id>. Winter fixed Cascades 67887/67890 "Windows Pro Upgrade".
- [RMM drive-map Explorer refresh](reference_rmm_drive_map_explorer_refresh.md) — drive mapped via RMM user_session works but the user's running Explorer won't show it until SHChangeNotify(DRIVEADD); also UNC \\ gets eaten in heredoc+jq, build it from [char]92.
- [Verify live before acting](feedback_verify_live_before_acting.md) — pull LIVE data (OMSA/iDRAC/live API) before acting on a hardware/infra flag; wiki/logs go stale. Cascades CS-SERVER "degraded RAID" was 9-day-stale (mirror self-recovered, SSDs bought needlessly). Windows can't see RAID member health.
- [Windows Pro upgrade billing](feedback_windows_pro_upgrade_billing.md) — ACG MAK key (vault infrastructure/windows-pro-mak, Mike's ACG key) for Home->Pro upgrades; RULE: invoice $99 PER machine activated, name the machine on the line item, bill after success. Each use consumes a MAK count.
- [AAD Connect msDS-KeyCredentialLink writeback](reference_aadconnect_keycredlink_writeback.md) — "completed-export-errors" + 8344 INSUFF_ACCESS_RIGHTS on a protected admin account = WHfB key writeback blocked by AdminSDHolder. Diagnose with csexport /f:x; fix with dsacls WP;msDS-KeyCredentialLink on AdminSDHolder + SDProp.
- [UniFi Site Manager cloud API](reference_unifi_site_manager_api.md) — `api.ui.com` + `X-API-KEY` (vault `services/unifi-site-manager`) = remote access to the WHOLE ACG UniFi fleet (~36 consoles) outside UOS. Tier1 `/v1/hosts|sites|devices|isp-metrics` = inventory+health+WAN. Tier2 CONNECTOR `/v1/connector/consoles/{id}/proxy/network/api/s/default/stat/{device,sta}` = **full UOS parity** (per-radio cu_total airtime + per-client RSSI) for ANY console, remote. Backend `unifi-wifi/scripts/gw-sitemanager.sh` (`fleet|devices|sites|isp|net`). Standalone UDM WAN SSH usually firewalled; per-console SSH pw at `clients/<slug>/udm-ssh`.
- [reference_sqlx_migrations_immutable](reference_sqlx_migrations_immutable.md) -- NEVER edit an already-applied sqlx migration file — even a comment. sqlx::migrate! checksums each file at compile time and validates against _sqlx_migrations at startup; a changed checksum crash-loops the server with "migration N was previously applied but has been modified". Code review MUST flag any edit to an applied migration.
- [AD2 SSH MTU blackhole](ad2-ssh-mtu-blackhole.md) — AD2 SSH "lockouts"/mid-session read-errors over the Dataforth OpenVPN were a PMTU blackhole (tunnel PMTU ~1424 vs adapter MTU 1500), NOT a ban/account-lockout/flaky tunnel. Fix: pin the OpenVPN adapter MTU to 1400 (done on GURU-5070 via its SYSTEM RMM agent); permanent = `mssfix 1360` on the OpenVPN server. Diagnose over RMM, not SSH.
- [DSCA33/45 resolved via Hoffman](project_dsca33_45_resolved_via_hoffman.md) — The "lost" DSCA33/45 spec files are recoverable from the Hoffman API (original certs survived the wipe); do NOT ask John. 56/58 models mined into projects/dataforth-dos/dsca33-45-templates.json; only DSCA33-1948 + DSCA45-1746 (24 units) lack an original. AD2 handoff: DSCA33-45-HOFFMAN-RECOVERY-2026-06-18.md.
- [AD2 comms via sync only](ad2-comms-via-sync-only.md) — The AD2 Dataforth-box Claude session is coord-API-isolated (Gitea only); coord msg/lock/todo never reach it. Coordinate with AD2 ONLY via git /sync (committed docs + ## Note blocks).
- [reference_syncro_agent_handle_leak](reference_syncro_agent_handle_leak.md) -- RDS "no available computers in the pool" (0x3/0x408) can really be a SyncroLive.Agent.Runner handle leak starving the box. How to spot + fix.

## Users
- [Howard Enos](user_howard.md) — Mike's brother, technician, full access. Machines: ACG-TECH03L, Howard-Home (authoritative in users.json).
- [Mike — font preference](user_font_preference.md) — Mike prefers Lucida Console for monospace UI.

## Feedback
- [Simplest solution first](feedback_simplest_solution_first.md) — Start with the least-complex thing that could answer the problem (one DNS lookup / one API call / one command), confirm it works, THEN graduate to advanced/complicated as needed. Don't reach for SSH/plink/multi-hop when a one-shot query answers it. Now a CLAUDE.md core rule.
- [Report times in Arizona time](feedback_timezone_arizona_reporting.md) — All user-facing times in America/Phoenix (MST, no DST), labeled AZ; convert from UTC. Set by Winter 2026-07-02.
- [RMM dashboard: beta before main](rmm-dashboard-beta-before-main.md) — GuruRMM website/dashboard changes land on beta (rmm-beta.azcomputerguru.com) and get tested BEFORE pushing/merging to main, unless told otherwise. Pipeline auto-builds beta FROM main, so don't merge to get on beta — build the feature branch's dashboard and rsync to /var/www/gururmm/dashboard-beta via a git worktree. Promote beta→prod with promote-dashboard.sh --confirm.
- [Prefer SSH over RMM](feedback_prefer_ssh_over_rmm.md) — When a target has SSH (key auth) and the task is easier over it, default to `scp script + ssh run` (system OpenSSH); RMM runs as SYSTEM + hits the server-side timeout reaper. Reserve RMM as fallback when SSH/VPN is down.
- [Re-clone submodule creds](reclone-submodule-creds.md) — Re-cloning the restructured claudetools (projects now submodules): set `credential.helper=store` GLOBALLY before `git submodule update --init --recursive` or every Gitea submodule fails "could not read Username". Steps in RECLONE.md.
- [Bot alerts need a ticket link](feedback_bot_alert_ticket_link.md) — Syncro ticket bot-alerts MUST include a clickable link: https://computerguru.syncromsp.com/tickets/<internal_id> (internal id, not ticket number). post-bot-alert.sh posts raw text; put the URL in the message.
- [RMM Set-Acl timeout loses stdout](feedback_rmm_setacl_timeout_password_loss.md) — NTFS ACL propagation (Set-Acl/icacls) on a large folder tree exceeds the RMM command timeout and stdout is dropped, so a password printed in that script is lost. Generate secrets LOCALLY (placeholder-inject) so they survive; isolate the ACL grant into its own long-timeout command.
- [Mac RMM authentication fixed](feedback_mac_rmm_auth_fixed.md) — Use `.claude/scripts/rmm-auth.sh` helper instead of heredoc pattern. Heredoc with `--data-binary @-` fails on macOS. Helper uses `jq -n --arg` to build JSON safely. Usage: `eval "$(bash .claude/scripts/rmm-auth.sh)"` sets $TOKEN, $RMM, $REPO_ROOT. Updated in /rmm Phase 0.
- [Verify committed state before push](feedback_verify_committed_state_before_push.md) — webhook builds from origin/main: verify the COMMITTED build (git stash + build), not the working tree; bad git-add pathspec silently aborts staging. Stage by directory.
- [Scheduling = coord todo, not schedulers](feedback_scheduling_via_coord_todo.md) — Defer future work as a coord todo (POST /api/coord/todos; needs text + created_by_user + created_by_machine) for a later session to pick up. NOT /schedule remote CCR agents (no vault/creds there) or local scheduled tasks.
- [DMARC rua INKY only when onboarded](feedback_dmarc_rua_inky_onboarded_only.md) — Don't point a client's DMARC rua at reports-sg.inkydmarc.com unless that client is onboarded to INKY (most aren't). Use plain `p=none` with no rua otherwise.
- [Use rmm-search to find machines](feedback_rmm_search_skill.md) — Find GuruRMM agents via the `rmm-search` skill (`rmm-search.sh <words> [-c client]`), never hand-grep /api/agents (it bleeds across clients). Then hand hostname/id to `/rmm`.
- [Attribution is read, never inferred](feedback_attribution_from_identity.md) — Who-did-what (user+machine) comes ONLY from identity.json + users.json + git authorship. Never infer from hostname patterns, the userEmail hint, or memory. The "5070" box is Mike's. sync.sh reconciles git config to identity.json; /save renders the User block via whoami-block.sh.
- [D2TESTNAS SSH Access](feedback_d2testnas_ssh.md) — Use root@192.168.0.9 with Paper123!@#, not sysadmin.
- [Bypass Permissions Setting](feedback_bypass_permissions_setting.md) — Set permissions.defaultMode to bypassPermissions in settings.json on all machines.
- [365 Remediation Tool](feedback_365_remediation_tool.md) — "remediation tool" = tiered ComputerGuru app suite via /remediation-tool; NOT CIPP, NOT the deprecated fabb3421.
- [CA managed programmatically (with discipline)](feedback_ca_programmatic_management.md) — Conditional Access CAN be written via Tenant Admin app; ALWAYS report-only first + exclude break-glass + confirm before enforcing. Overrides old "CA manual" rule.
- [Ollama Tier-0 Routing](feedback_ollama_tier0_routing.md) — Route drafts/summaries/classifications through Ollama (qwen3:14b). Mike designed ClaudeTools this way — not optional.
- [/save writes narrative directly](feedback_save_no_ollama.md) — No Ollama for /save; write all sections inline — too slow.
- [Tracker comment discipline](feedback_tracker_discipline.md) — Every issue state change MUST have a Gitea comment with commit refs. No silent closes. The comment trail IS the documentation.
- [Auto-file bugs to tracker](feedback_tracker_autofile.md) — When a bug surfaces during a session, file it via bug-tracker skill immediately. Errorlog alone is not enough — the tracker is what makes bugs visible and trackable.
- [tracker.py Windows encoding](feedback_tracker_encoding.md) — Set UTF-8 stdout on Windows or unicode issue titles crash. Pattern: io.TextIOWrapper with errors='replace'.
- [Identity precedence](feedback_identity_precedence.md) — Trust `.claude/identity.json` over the system-reminder `userEmail` hint when they disagree (shared-login machines).
- [1Password — always use service token](feedback_1password_service_token.md) — Source OP_SERVICE_ACCOUNT_TOKEN from SOPS for every `op` call. Desktop-app integration prompts are unacceptable in agent flows.
- [Point vault-access teammates at SOPS path](feedback_vault_pointer_for_teammates.md) — When relaying infra/credential info to Howard or other vault-access teammates, hand over the SOPS path + key anchors; don't transcribe the entry's fields into the message.
- [/tmp path mismatch on Windows](feedback_tmp_path_windows.md) — Write tool and Git Bash resolve `/tmp` to DIFFERENT real dirs. Use heredoc or workspace path for JSON payloads handed to curl.
- [Windows strips embedded double-quotes](feedback_windows_quote_stripping.md) — Embedded `"` in an arg gets eaten twice over: PowerShell->curl.exe (CommandLineToArgvW) AND RMM->cmd.exe. MECHANICAL FIX: deliver PS scripts via `.claude/scripts/ps-encoded.sh` (-EncodedCommand, byte-exact; author the file with the Write tool). Inline one-offs: single-quoted heredoc `<<'JSON'` + `--data-binary @-`; build `"` from `[char]34`.
- [Interview the AI / read its docs before probing](feedback_interview_ai_read_docs.md) — To learn an external AI/CLI's syntax or capabilities, READ its bundled docs (Grok: `~/.grok/docs/user-guide/`, `README.md`, `grok inspect`/`models`/`--help`) or interview the model; don't guess flags or run slow trial-and-error. One run to confirm a doc-derived hypothesis, not a dozen to discover.
- [Web search over blind probing](feedback_web_search_over_probing.md) — For external API/capability discovery, LEAD with web search (grok/gemini) + vendor docs; live endpoint-probing only CONFIRMS a hypothesis, never the primary discovery method (it mostly 404s, "highly suspect"). Reading a system's OWN config is fine; guessing unknown PATHS is not. Web-search bots being flaky is a must-fix (CT_THOUGHTS Thought 2).
- [Windows bash command mapping](feedback_windows_bash_mapping.md) — `bash` often resolves to WSL stub instead of Git/MSYS bash required by the harness. Fix by prepending `C:\Program Files\Git\bin` (and usr\bin) to PATH, or source `.claude/scripts/ensure-git-bash.ps1`. Profile has the logic; use plain `bash .claude/scripts/...` after remap. See the helper and this memory file for details.
- [Git must authenticate non-interactively](feedback_git_noninteractive_auth.md) — Mike's gripe with Git for Windows is the constant password prompts (GCM) that hang automation, NOT the tool itself. D:\ClaudeTools is set to `credential.helper=store` primed with the azcomputerguru Gitea API token (host 172.16.3.20:3000); always set `GIT_TERMINAL_PROMPT=0`. Any never-prompts solution is acceptable.
- [Vault git auth — GCM shadows store token](feedback_vault_gcm_shadow_auth.md) — vault sync "Failed to authenticate user" on git.azcomputerguru.com: GCM is first in the helper chain and shadows the valid store token. Fix (machine-local): store-only credential.helper reset + pin `azcomputerguru@` in the vault remote URL so store returns the durable PAT (not the volatile OAUTH_USER JWT). Applied GURU-5070 2026-06-07.
- [agy.exe NOW works headless (2026-07-03)](reference_antigravity_agy_not_headless.md) — Antigravity `agy.exe` v1.0.6+ has a working `-p/--print` headless mode (clean stdout, `--add-dir` to read files); use it as the Gemini/Antigravity second-model path, esp. when gemini-cli OAuth is ineligible. Call by full path until PATH refresh. (Supersedes the old "agy is DOA headless" note.)
- [SQL instance role — verify by connections, not name](feedback_sql_instance_role_by_connection.md) — Standard installed under default `SQLEXPRESS` instance name is real. Prove role with `sys.dm_exec_sessions` + `Get-NetTCPConnection -OwningProcess` before recommending stop/uninstall.
- [RMM password setting limitation](feedback_rmm_password_limitation.md) — `net user <user> <password>` via GuruRMM fails silently (exit 0 but password doesn't set). Tested PowerShell AND CMD - both fail. ScreenConnect CMD works (also as SYSTEM). GuruRMM agent bug in process spawning. Use ScreenConnect for password ops. HIGH priority to fix.
- [Clear-RecycleBin fails silently as SYSTEM](feedback_clear_recyclebin_system_context.md) — RMM-dispatched cleanup scripts cannot use `Clear-RecycleBin -Force`; the cmdlet uses Shell COM and silently no-ops without an interactive desktop. Enumerate `C:\$Recycle.Bin\<SID>\*` directly.
- [Graph CA policy reads are eventually consistent](feedback_graph_ca_policy_eventual_consistency.md) — After PATCHing a CA policy (204), wait ~5s before GET-verifying; immediate reads can be stale.
- [Graph password reset needs a privileged role](feedback_graph_password_reset_requires_role.md) — PATCH passwordProfile on an existing user 403s without a directory role; User.ReadWrite.All alone only sets a password at CREATE.
- [Vault writes — do the full sequence yourself](feedback_complete_vault_operations_end_to_end.md) — A vault entry = write plaintext → sops -e -i → git add/commit/push, all of it; don't stop at "encrypted on disk."
- [Exchange role recurring gap — backfill, don't promise](feedback_exchange_role_recurring_gap.md) — EXO email-cleanup 401/403 = Exchange Operator SP missing the Exchange Admin directory role (consent never grants it). Fix: `assign-exchange-role.sh <domain|--all>` (idempotent); audit with `--all --verify`. Fleet backfilled 2026-06-08. Verify membership via roleManagement/directory/roleAssignments (not the laggy directoryRoles/members list); EXO propagation 15-60min.
- [Syncro is the default PSA; Autotask is opt-in](feedback_psa_default_syncro.md) — Ticketing/billing/customers default to Syncro (/syncro). Only use /autotask on an explicit "in Autotask" request. /autotask kept local/undistributed.
- [Paste-safe command formatting (Howard)](feedback_command_formatting.md) — Two clauses, one root cause: (a) multi-line scripts not semicolon one-liners (wrap breaks paste), (b) all code at column 0 inside fences (indentation breaks PowerShell paste).
- [Autonomous infra/build setup](feedback_autonomous_infra_setup.md) — During infra/build/CI/dev setup, just install prerequisites and push through routine steps; reserve check-ins for genuine decisions (forks, destructive/outward, client/prod).
- [Check patterns before asking](feedback_check_patterns_before_asking.md) — Before asking how to do something repeat-style (sync, save, sweep, billing), study existing artifacts and workflow docs first; reach for similar past artifacts as the template.
- [Cascades scan-to-folder uses svc-scan](feedback_cascades_scan_account.md) — Every scanner->network-folder setup at Cascades reuses the one `svc-scan` AD service account (NTLMv2, vaulted); never make a per-printer scan account.
- [Drive-letter mapping convention](feedback_drive_letter_mapping.md) — Pick the MAIN/primary drive letter first (consistent across users for the principal share), then assign smaller/secondary maps. Don't retroactively renumber existing maps unless asked.
- [Calibrate effort to stakes](feedback_calibrate_effort_to_stakes.md) — Don't over-verify or over-engineer low-consequence details; confirm the happy path, note the limitation, and take the simplest path (e.g. put the instruction in the prompt) instead of building robust mechanisms.
- [Pricing verification — no guessing](policy_pricing_verification.md) — ANY cost presented to the team or a client MUST be verified via live web lookup (WebFetch/WebSearch, fallback to headless Chrome). Never estimate from training data. Cite source + date inline. If unreachable, say so — do NOT substitute a guess.
- [Client communication tone](feedback_client_tone.md) — How to write client-facing Syncro comments — expert partner, not intake questionnaire.
- [Impeccable on outbound](feedback_impeccable_on_outbound.md) — Run the `impeccable` skill on anything sent to a client or vendor before delivery; internal drafts exempt.
- [Default to inline links](feedback_inline_links.md) — Use `[text](url)` inline markdown links (clickable, wrap-safe) not bare URLs in code fences; exception = raw URL the user must copy/paste.
- [Add Mike as owner on all Entra apps](feedback_entra_app_owner.md) — Apps created via management SP have no user owner — must add Mike manually or publisher verification fails.
- [No TOML/config file approach for endpoints](feedback_no_toml_config_endpoints.md) — User explicitly prohibits TOML or config-file-based endpoint configuration — this will never be approved.
- [Python on Windows — use py launcher](feedback_python_windows.md) — Windows Store python/python3 aliases disabled; always use py or jq on DESKTOP-0O8A1RL.
- [Memory tooling may delete now — additive-only constraint dropped](feedback_memory_sync_destructive_ok.md) — As of 2026-06-02, memory-dream and sync-memory.sh are sanctioned to perform destructive ops (apply proposed merges/dedups, propagate repo deletions back to harness profile stores). Onboarding-phase safety net now fights deliberate consolidation (e.g. 2026-06-01's 39 deletions resurrected on the next sync). Script updates pending.
- [Unsaved sessions are recoverable from transcripts](feedback_session_recovery.md) — Crashed/closed-before-save sessions live in `~/.claude/projects/<slug>/*.jsonl`; the detector auto-recovers orphans, `/recover <uuid>` does it manually. Ollama prose + Python verbatim. See `.claude/RECOVERY.md`.
- [Scheduled tasks must not flash a console](feedback_scheduled_task_no_console_flash.md) — A task action running bash.exe/py.exe/python.exe with Hidden=False draws a console window every fire (the recurring "command prompt opening/closing"). Wrap bash via a wscript VBS (style 0), use pythonw.exe for python, always add `-Hidden`. Fixed installers: register-edr-watcher.ps1, register-orphan-detector.ps1.
- [agy review is not read-only](feedback_agy_review_not_readonly.md) — agy review/review-files CAN write files + run npm despite docs claiming plan-mode; always git diff after and treat Gemini's output as a proposal to validate, not trusted/finished work.
- [Don't present inferred topology as fact](feedback_no_inferred_topology_as_fact.md) — Private-IP overlap (172.16.x on both sides) is NOT proof of a site-to-site link; I fabricated a VWP<->office VPN. State observations vs inferences; a failed reachability test disproves a link, don't explain it away; test "can reach RMM" against the EXTERNAL endpoint, not internal 172.16.3.30.

### Syncro
- [Skill-first routing + Definition of Done](feedback_skill_first_routing.md) — If a skill covers the task, INVOKE IT (Syncro billing ALWAYS via `/syncro`, never ad-hoc curl), AND gate the result with the matching check-skill before "done" (code→/code-review+/simplify+/security-review; outbound→impeccable/stop-slop; wiki/memory→wiki-lint/memory-dream) — inferred from the request, not user-named. CORE rule; full map in `.claude/SKILL_ROUTING.md`; calibrate to stakes, Ollama Tier-0 for cheap passes.
- [Syncro API plumbing](feedback_syncro_api.md) — Content-Type required on all POST/PUT; NO idempotency anywhere — always GET before retrying; response wrappers (`.ticket.id`, `.comment.id`); add_line_item shape (internal ID, flat response, required fields); HTML uses `<br>` not `<ul>/<li>`; timer_entry response is FLAT but SUPERSEDED (use add_line_item).
- [Syncro billing rules](feedback_syncro_billing.md) — Bill with `add_line_item` directly (not timers); fetch rates LIVE; never invent labor names (real product names only); match labor type to delivery channel (never "Prepaid project labor"); labor `taxable:false` (AZ); warranty `1049360` (never patch price); emergency `26184` ×1.5 once, branch by `prepay_hours`; corrections preserve original tech's user_id; estimate hardware `32252`.
- [Syncro workflow rules](feedback_syncro_workflow.md) — ALWAYS preview comments before posting (no exceptions); verify appointment day-of-week ("Saturday 2026-05-23") before creating; ASK who the appointment owner is; leave `contact_id` BLANK by default for ALL customers (ignore Syncro's contact-picker auto-default).
- [Syncro lessons / incident archive](feedback_syncro_history.md) — Detail behind the three rule files: tickets (#32332, #32312, #32225, #32253, #32203, #32185, #32142, #32304, #32333), verbatim Mike/Howard/Winter quotes, dates, tech user_id table (Mike 1735 / Howard 1750 / Winter 1737 / Rob 1760), labor product table, and superseded-rule history.

### GuruRMM
- [GuruRMM build verification (read before touching the pipeline)](feedback_gururmm_build_verification.md) — Merge-to-main IS the build+deploy; verify locally FIRST. Canonical refs: guru-rmm `docs/BUILD.md` + the `gururmm-build` skill (`verify.sh server|agent|dashboard|migrations`) + `deploy/build-pipeline/README.md`. Compile-gate trap: Windows cargo can't verify Linux-gated agent code (openssl-sys); Linux build on .30 is the real gate. Server needs SQLX_OFFLINE + fresh server/.sqlx; check migration-number collisions.
- [Submodule auto-sync discipline](feedback_submodule_autosync_discipline.md) — In auto-synced submodules (guru-rmm/guru-connect) local branch refs/HEAD don't survive across calls (background sync resets to the lagging gitlink; sessions share the tree). Use a git worktree or commit+push-by-explicit-SHA + `ls-remote` verify; assert HEAD==origin/main (or read `origin/main:<file>`) before audits; never `checkout --` shared files. Recurring fleet friction.
- [GuruRMM operational rules](feedback_gururmm.md) — Six rules: (1) RMM dev = Mike, never Howard (368/0 commits); GuruScan is Howard's. (2) Agent parity Win+Linux+macOS in same change. (3) Builds via Gitea webhook pipeline only, never SSH. (4) #bot-alerts only for client/ticket impact, skip internal infra/dev. (5) Identify agents by IP, not by reconning candidates. (6) UNC paths in user_session need [char]92 — literals get halved.
- [Build channel default = beta](feedback_gururmm_build_channel_default.md) — New agent builds must be tagged BETA by default (stable = explicit promote re-tag); distinct from agents defaulting to the stable CHANNEL (correct). Fixed build-windows/linux.sh 2026-06-01; macOS already correct. Enables beta-first canary.
- [Dashboard beta-first deploy](feedback_dashboard_beta_first.md) — Dashboard auto-builds to rmm-beta.azcomputerguru.com on push; prod (rmm.azcomputerguru.com) is explicit promote-only via promote-dashboard.sh --confirm. Never hand-rsync prod. One artifact, nginx sub_filter BETA banner. Stood up 2026-06-02.

### Cascades
- [Cascades operational rules](feedback_cascades.md) — Active rules: (1) folder redirection (fdeploy) needs subfolders PRE-CREATED before first logon or it caches a failure forever; recovery via fix-shell-redirect.ps1. (2) ALWAYS ask which security group(s) a new user goes into — never auto-derive from OU. (3) Do NOT lock down the legacy Main\Company Web Docs\Accounting (Everyone:Full) folder — still in active use. (4) NEVER change Cascades production infra (pfSense/UniFi/switches/DHCP) without discussing it + explicit per-change go — read-only/dry-run until then.
- [Cascades FR GPO fix](reference_cascades_fr_gpo_fix.md) — Native Folder Redirection was DOA on every machine: redirect targets were in a misnamed `fdeploy1.ini` (Windows reads `fdeploy.ini`) → empty target path → silent no-op → per-user registry workaround every time. Fixed 2026-06-08 (correct fdeploy.ini + version bump). Also: CS-SERVER live RMM agent is `c39f1de7...` (old `6766e973` stale).
- [pfSense 25.07 ops quirks](reference_pfsense_25_07_ops.md) — Cascades pfSense Plus 25.07: logs are PLAIN TEXT (use tail/grep, NOT clog → clog returns empty); clean dhcpd restart = `services_dhcpd_configure()` via slow pfSsh.php (needs 50s+ timeout); dirty boot can leave 2 dhcpd → DISCOVER/OFFER but no ACK; reboot the Cox modem after a config restore; ZFS survives power loss. From the 2026-06-17 power-outage incident.
- [feedback_ascii_only_api_payloads](feedback_ascii_only_api_payloads.md) -- On Windows/Git-bash, non-ASCII chars (em-dash, arrow, smart quotes) in JSON payload TEXT passed to curl get mangled and rejected — Discord bot-alert returns 400, the coord API returns "error parsing the body". Use ASCII-only in API payload text, or a single-quoted heredoc.
- [feedback_bitdefender_unattended_install](feedback_bitdefender_unattended_install.md) -- Bitdefender unattended RMM install must use the FULL KIT as SYSTEM (silent, no UAC) — the downloader stub fails headless and triggers UAC
- [feedback_rmm_longops_fire_and_forget](feedback_rmm_longops_fire_and_forget.md) -- Long-running RMM endpoint ops (software installs, big downloads) must be fire-and-forget, not live-monitored

## Machine
- [GURU-5070 Workstation Setup](reference_workstation_setup.md) — Mike's primary (owner confirmed 2026-05-26). Windows 11 Pro. Renamed from OC-5070 → ACG-5070/acg-guru-5070 → GURU-5070; all the same box, all Mike's.
- [GURU-BEAST-ROG Setup Status](machine_windows_guru_setup_status.md) — Windows workstation fully configured except SSH key deployment to servers.

## Project
- [VWP-ROSE QB updater crash-loop](project_vwp_rose_qb_updater.md) — RESOLVED 2026-07-13 via remote QB repair install; billed 0.5h to VWP prepay block, ticket #32545 Invoiced. Open side findings: NETLOGON 5719 at boot + Syncro agent service crashes on VWP-ROSE.
- [GuruRMM software-removal PR #58](project_gururmm_software_removal_pr58.md) — SPEC-030 hardening (driver exclusion in removal UI, lingering-uninstaller sweep, job list + stale reaper) on PR #58, UNMERGED; merge = beta deploy; live testing planned 2026-07-06 on DESKTOP-MS42HNC.
- [Cascades network + CS-SERVER SMB instability](project_cascades_network_segments.md) — NAS->CS-SERVER migration. NOT a CSC-ENT-vs-CSCNet issue (corrected): fresh SMB to `\\cs-server\*` fails err 67 from BOTH Wi-Fis; only persistent admin-mapped drives work, intermittently → CS-SERVER-side SMB instability (multichannel advertises .248/.254/IPv6 ULAs; Get-SmbServerConfiguration errors). Blockers: CSCNet=WPA3 (old adapters can't join); workstations store domain-admin cred. Repoint tool [[drive-map]].
- [CyndyOffice physical HP lockups](cyndyoffice-physical-hp-lockups.md) — RMM "Howard-VM" site agent CyndyOffice is a PHYSICAL HP Pavilion TP01 (not a VM); ~20 hard freezes/6wk = Kernel-Power 41 bugcheck-0, no dump/WHEA = hardware (RAM/PSU/BIOS), SSD healthy. UUID re-enrolls.
- [Automate memory consolidation/lint (phased)](project_memory_consolidation_automation.md) — Eventually auto-run /memory-dream; lint+additive fixes can automate early, merges/deletes stay human-approved. Engine: .claude/skills/memory-dream/ + .claude/scripts/sync-memory.sh.
- [Trebesch PST consolidation (staged)](project_trebesch_pst_consolidation.md) — Address-book CSV from 24 PSTs on DESKTOP-QNP3ON5; scripts staged at .claude/tmp/treb-*.ps1, WAITING for Howard's 6pm-MST 2026-06-01 go signal (attended run). See [[reference_trebesch_qnp3on5]].
- [GuruRMM security scope — integrate AV, don't replace it](project_gururmm_security_scope.md) — No native virus/malware removal in the RMM; AV products do that. RMM monitors AV reports + sends commands to AV products, and its built-in value is helping techs FIND issues. Program removal is a separate feature.
- [GuruRMM project state](project_gururmm.md) — Dev principles (every feature full-stack: backend+API+UI+docs+scalability; product works without AI; FEATURE_ROADMAP update is part of definition-of-done; mirrors guru-rmm/docs/DESIGN.md). Webhook docs-only build guard (SPEC-020 Phase 0; webhook-handler.py repo copy is STALE — don't redeploy). Mac install-hooks.sh setup STILL PENDING on Mikes-MacBook-Air.
- [GuruConnect](project_guruconnect.md) — v2 direction (native-first full key fidelity Win+R/Ctrl+Alt+Del + bidirectional file cut/paste/drag; WebRTC fallback only; standalone-first + RMM contract; tenancy-ready schema; Mike willing to scrap v1). Manual deploy procedure to 172.16.3.30 (build-on-server in login shell; sqlx runtime queries; NPM `CONNECT_TRUSTED_PROXIES=172.16.3.20` gotcha). v2 live since 2026-05-30.
- [Apple MDM + Developer certs (GuruRMM mobile)](project_apple_mdm_certs.md) — ACG holds Apple Developer+signing and Apple MDM Push certs (acquired 2026-05-29) for SPEC-017. MDM push cert RENEWS ANNUALLY on the same Apple ID or all enrolled iOS devices break.
- [Only RMM & GC are versionable products](project_versionable_products.md) — GuruRMM + GuruConnect are the only products with own repos/submodules; everything else stays in the claudetools monorepo. Split only for independent pipeline OR versioned external consumer.
- [GuruRMM legacy 1.77 build disabled](project_gururmm_legacy_disabled.md) — legacy (2008R2/Win7) Rust 1.77 variant DISABLED 2026-07-04 (`LEGACY_ENABLED=false`) after an edition2024 dep (chacha20/rand_core 0.10.1) broke the unpinned 1.77 re-resolve and fail-closed the whole Windows build; existing legacy artifacts preserved at 0.6.76. Do NOT re-enable blindly — 2008R2 support returns via a C++/.NET or clean-rewrite legacy agent (Mike, required).
- [Quantum GoDaddy M365 tenant](project_quantum_godaddy_m365_tenant.md) — quantumwms.com parked in a GoDaddy-provisioned M365 tenant (id ddf3d2c9-b76c-40d9-a216-9f11a1a26f97, netorg18235235.onmicrosoft.com); blocks Pax8 migration until GoDaddy removed.
- [Howard-Home LAN shadow (RESOLVED)](howard-home-lan-shadow.md) — Howard-Home renumbered 2026-06-16 to **10.137.42.0/24** (gw 10.137.42.1, UniFi — NOT pfSense), off the old 192.168.0.0/24 that shadowed Cascades pfSense .0.x over the VPN. Cascades .0.x should now route via the tunnel; this machine is 10.137.42.x now (not 192.168.0.x).
- [Cascades CARF tech plan](project_cascades_carf_tech_plan.md) — Ashley's "technology plan" is a CARF accreditation deliverable (Aging Services Technology and System Plan standard); must use CARF action-plan structure (owner/cost/target+completion dates per area), persons-served assistive-tech lens, annual-review sign-off; it's Cascades' leadership-adopted plan, ACG supplies content.
- [Cascades](project_cascades.md) — Active state: Syncro ticket #110680053 + plan file (machine-specific path on Howard's box), admin accounts (sysadmin@=Howard, admin@=Mike — daily-driver, NOT break-glass), Phase-B caregiver CA pilot (SG-Caregivers-Pilot, group-scoped never tenant-wide), prepaid block ~37.5h (rate TBD), pilot cleanup checklist.
- [Cascades history](project_cascades_history.md) — fdeploy 502/ACL root cause (Flags=1211→187 fix), 2026-04-29 CA-rescoping decision (Howard pulled the brakes on tenant-wide), 2026-05-14 per-user-security-group decision rationale.
- [Cascades isolated-VLAN pattern](project_cascades_isolated_vlan_pattern.md) — pfSense: the GUEST VLAN (VLAN50/igc1.50) is the isolation template (4 any-proto quick rules: block 192.168.0.0/22 + 10.0.0.0/8 + 172.16.0.0/12, then pass any; public DNS via DHCP). VLAN20 is NOT isolated. Verify with `pfctl -sr`, not config.xml. Protocol MUST be Any (TCP-only leaks UDP). VOICE VLAN30 built to this 2026-06-17.
- [Cascades VLAN20 migration + routing](project_cascades_vlan20_migration_routing.md) — Staff machines/printers moving to VLAN20 (10.0.20.0/24). CS-SERVER couldn't reach VLAN20 printers because the LAN "allow LAN to any" rule policy-routes via WAN_Group → add a top LAN pass rule (src CS-SERVER 192.168.2.248, dst 10.0.20.0/24, gw=default) to bypass. pfSense SSH from VPN is blocked (do firewall in GUI). Printer client-map via GPO or SYSTEM `printui /ga` to dodge the 0x800702e4 PrintNightmare prompt; build UNC with [char]92.
- [Cascades KPI dashboard (parked)](project_cascades_kpi_dashboard.md) — Ashley Jensen wants one dashboard across their reporting SaaS (ALIS/QuickBooks/Bill.com/Relias/You've Got Leads/TELS/Focus HR/Helpany/POS). Power BI Gateway is the WRONG frame (on-prem only). Recommended Tier1→Tier2: scheduled exports → SharePoint → Power BI Pro, automate API-capable systems (Bill.com/QBO) via Power Automate later. Full notes: `clients/cascades-tucson/docs/proposals/kpi-dashboard.md`. Next: draft client one-pager.
- [Sync script bug — untracked files (RESOLVED)](project_sync_script_bug.md) — FIXED 2026-05-21: sync.sh now uses `git status --porcelain` for change detection (repo + vault).
- [MasterBooter Side Project](project_masterbooter.md) — Howard's Rust+Slint Windows deployment toolkit at C:\MasterBooter, separate from client work. Do not log to clients/.
- [AMPIPIT toolkit](project_ampipit.md) — Howard's ACTIVE Rust+Slint Windows deploy/recovery toolkit (not just a reference program), migrated into the fleet as a private Gitea submodule at projects/msp-tools/ampipit (azcomputerguru/ampipit). Active feature: recovery partition with GuruRMM agent + built-in repair scripts for offline-Windows repair (spike GO-WITH-WORK). Preserve all work; PRIVATE Gitea only, no public GitHub.
- [Audio Processor Architecture](project_audio_processor_architecture.md) — Segment-first pipeline: detect breaks before transcription for complete content capture.
- [Neptune SBR Email Routing Setup](project_neptune_sbr_email_routing.md) — Full SBR routing chain, config file locations, MailProtector integration, access methods. Treat routing breakage as systemic (devcon, Sorensen/rieussetcorp), not per-client.
- [Dataforth Test Datasheet Pipeline](project_datasheet_pipeline.md) — Full pipeline rebuilt 2026-03-27. Server-side generation replaces DFWDS/Uploader. Website upload still broken.
- [Dataforth](project_dataforth.md) — M365 email (Graph API; tenant in vault at clients/dataforth/m365.sops.yaml); neptune.acghosting.com is ACG's, NOT Dataforth's. MFA enforced 2026-04-04 (3 CA policies). AJ needs dataforthgit@ forwarding.
- [Dataforth history (2026-03-27 incident)](project_dataforth_history.md) — DF-JOEL2 compromise via ScreenConnect social-engineering, attacker C2 IPs + IC3 case + remediation log + MFA rollout origin story + Joel Lohr retirement. RESOLVED 2026-04-04.
- [Radio show co-host — Tara, not Tom](radio_show_no_cohost_named_tom.md) — Co-host in 2014-s6e19 and 2016-s8e43 is Tara. "Tom" was hallucinated; rename complete.
- [Proposal: centralize config in identity.json](proposal_identity_centralization.md) — Rationale for the identity.json machine-config centralization (claudetools_root, ollama/python); now implemented.
- [Defender: exempt all Claude activity](feedback_defender_claude_exclusions.md) — Mike wants NOTHING Claude/ClaudeTools issues flagged by Defender; ClickFix threat IDs 2147939088/2147945138 (RMM curl dispatch AMSI FPs) set to Allow + broad process/path exclusions. ThreatID-Allow is the lever; exclusions alone don't stop AMSI CmdLine detections.
- [ACG MSP tool stack](reference_acg_msp_stack.md) — ScreenConnect/CW Control, Splashtop, Syncro, Datto RMM, Datto EDR/AV, GuruRMM are ACG's OWN tools; do not flag as foreign/threat on managed machines (Defender-off is expected when Datto AV is active).
- [VoIP vendor stack: PacketDial / OIT / NetSapiens / YMCS](reference_packetdial_oit_netsapiens.md) — PacketDial = ACG's VoIP-dept brand (pbx.packetdial.com, the `packetdial` skill); NetSapiens = the PBX platform (API v2); OIT/OITVOIP = white-label wholesaler running NetSapiens (api.ucaasnetwork.com); reseller `91912.service`. YMCS (Yealink) = phone device-mgmt, pairs with the PBX.
- [ACG Website Hosting](project_azcomputerguru_hosting.md) — azcomputerguru.com is hosted on IX Web Hosting via cPanel.
- [jq on Windows emits CRLF](feedback_jq_crlf_windows.md) — winget jq outputs CRLF; trailing \r silently breaks `for x in $(jq ...)` loops + read-from-@tsv. Override `jq(){ command jq "$@"|tr -d '\r'; }`. Windows-build-specific (passes on Mac/Linux).
- [ScreenConnect RESTful API auth](reference_screenconnect_api.md) — CTRLAuthHeader = raw api_secret (no Basic/b64) + Origin header; now wrapped by the /screenconnect skill. Verified surface: GetSessionsByName/GetSessionDetails + writes SendCommand/SendMessage/UpdateCustomProperties + parameterized self-tagging installer. Still NO full-fleet inventory method (GetSessions missing).
- [No manufactured guardrails on our products](feedback_no_manufactured_guardrails.md) — At Mikes request on GuruRMM/GuruConnect/ClaudeTools, just execute; stop only for genuinely irreversible/destructive ops (with a heads-up). Read the actual code/state before claiming something is disallowed or a security hole.
- [Stream-of-thought design convos](feedback_stream_of_thought_design.md) — Mike brainstorms features free-form, adding requirements iteratively; Claude validates/sharpens as a design partner but does NOT build until an explicit go, then captures parked threads durably (PARKED_*.md + todos) for a later /shape-spec.
- [RMM Thoughts backlog](feedback_rmm_thoughts_backlog.md) — GuruRMM ideas from Mike & Howard go in projects/msp-tools/guru-rmm/docs/RMM_THOUGHTS.md (Status: Raw); pipeline thought -> discuss -> spec (/shape-spec) -> roadmap. Don't build until an explicit go.
- [Syncro preview mandatory](feedback_syncro_preview_mandatory.md) — preview+confirm every Syncro write, including internal notes
- [Refresh session history first](feedback_refresh_session_history_first.md) — read prior incident logs before acting; do not re-remediate already-handled accounts
- [Autonomy scope](feedback_autonomy_scope.md) — confirm only for client-affecting actions; internal docs/wiki/ClaudeTools = act autonomously
- [Check for client-slug fragmentation](feedback_client_slug_fragmentation.md) — Before concluding a client has no records, grep broadly (company/owner/initials/hostname/"Last, First") across clients/, wiki/, session-logs/, vault — one client gets split across slug variants (Wolkin was 4: wolkin/wolkin-law/rswolkin/robert-wolkin). Consolidate to one canonical slug; action prior logs' Pending items.
- [RMM user_session = false SMB failures](feedback_rmm_user_session_smb_false_negative.md) — GuruRMM net use/net view/Add-Printer to a remote \HOST fail with error 67 / RPC 1702 (even with valid creds) because user_session is a WTS-impersonated non-interactive token that can't do authenticated SMB. The share/printer may work fine interactively. Treat RMM SMB results as "can't tell"; verify via ScreenConnect.
- [Prefer SSH over RMM](feedback_prefer_ssh_over_rmm.md) — when a target has SSH (key auth) and it's easier, drive it via system OpenSSH (scp+ssh) instead of the GuruRMM agent; RMM runs as SYSTEM + is bound by the server-side timeout reaper + forces base64/quoting gymnastics. Reserve RMM as the fallback when SSH/VPN is down.
- [Broken [[backlinks]] = write-me-later markers](feedback_broken_backlinks_are_writeme_markers.md) — A [[name]] with no matching file is an intentional "worth writing" marker, not breakage. Flesh the missing memory out from session history/logs and index it; never strip the link to silence the warning. memory-dream reports these as INFO candidates, not errors.
- [gururmm session-logs are in a submodule](gururmm-session-logs-submodule-save.md) — commit in the submodule + `git push origin HEAD:main` (GURU-5070 CAN push over HTTP now); then advance the parent gitlink
- [Use `python` not `python3` on GURU-5070](python3-shim-use-python.md) — `python3` in Git bash hits the flaky MS Store shim; real interpreters are `python` (3.12) / `py` (3.14). coord.py + wiki-compile work via `python`; the coord lock IS claimable here
- [Beast = primary GuruRMM Windows build host](gururmm-beast-windows-build-host.md) — GURU-BEAST-ROG (i9), reached from .30 via Tailscale-on-.30 at 100.101.122.4 as guru; Pluto is the fallback (`attempt_build beast || attempt_build pluto`). WiX must be 4.x (v6+ = OSMF); Beast NuGet needed nuget.org added
- [GuruRMM command_type gotcha](reference_gururmm_command_type.md) — only shell/powershell/python/script/claude_task (+cmd alias); unknown type silently dropped, looks like a black-hole
- [GuruRMM log analysis -> Claude Haiku](gururmm-log-analysis-claude-cutover.md) — cut over from Ollama-on-Beast (timed out on fleet-sized prompts; "unreachable" was a mislabeled 120s timeout) to Anthropic API Haiku 4.5 w/ structured outputs; key at vault `projects/gururmm/anthropic-api`; ZDR pending; deploy needs root on .30 (.env + restart)
- [IX WHM API access = 'ClaudeTools' token, not password](ix-whm-dns-api-access.md) — IX cPanel/WHM (ix.azcomputerguru.com:2087) DNS + all API work uses the FULL-ACCESS-root WHM API token at vault `infrastructure/ix-server` `credentials.whm-api-token` via header `Authorization: whm root:<token>` (force curl -4). Password basic-auth on legacy json-api now 403s. Public NS ns1/ns2.acghosting.com = 52.52.94.202.
- [Vault EVERY credential surfaced in-session](feedback-vault-every-credential.md) — any cred (pasted/created/discovered) -> store via the vault skill + document purpose & exact usage immediately; it's a standing job rule (reinforced in CORE CLAUDE.md). Lost IX creds wasted ~1h on 2026-06-12.
- [GuruRMM install-report v1: reuse endpoint + failed-install agent](gururmm-install-report-failed-agent-v1.md) — legacy NSIS installer reuses /api/install-report (machine info + logs, success+fail); server upserts a visible "failed-install" device on failure reports (Mike: in v1); verify-connect-before-success; trend/near-fail analytics. Server side is a separate sequential SPEC after the legacy-agent branch lands.
- [DM wrapping commands to Mike in Discord](feedback_dm_wrapping_commands_to_mike.md) — long/wrapping output (commands, consent links, URLs) goes via Discord DM (copies clean), not just chat; use the `discord-dm` skill (`discord-dm.sh mike "<x>"`). Gotchas: bot token vault projects/discord-bot/bot-token, Mike uid 264814939619721216, MUST set User-Agent or Cloudflare 403 errcode 1010, build JSON via jq + printf|--data-binary (direct -d → 50109).
- [Physical access codes -> vault + wiki pointer](feedback_physical_access_codes.md) — alarm/lockbox/door codes go in vault clients/<slug>/physical-access-<location>.sops.yaml (kind: physical-access) + a `## Physical Access` pointer section in the client wiki; never plaintext. First entry: Peaceful Spirit NW.
- [CT Thoughts backlog](feedback_ct_thoughts_backlog.md) — ClaudeTools harness ideas go in docs/CT_THOUGHTS.md (trigger "ct thought:"); CT analogue of RMM_THOUGHTS. Don't build until explicit go. First entry = ClaudeTools 3.0 web co-work vision.
- [AI-auth product boundary](project_ai_auth_product_boundary.md) — ClaudeTools/ClaudeTools 3.0 = internal-only, per-person subscription OAuth ok; GuruRMM = sellable, customer brings own API key (never ACG's subscription); backend dev = internal. Anthropic ToS bans subscription auth in third-party products.
- [RMM SYSTEM context can't see user mapped drives](feedback_rmm_system_context_mapped_drives.md) — RMM runs as SYSTEM; `Test-Path F:\` etc. is False even when the user's mapped/redirected drive exists. Diagnose mapped-drive/redirect issues in `context:user_session`. Elevated apps (e.g. QB DB Server Manager "unable to retrieve root folder") need `EnableLinkedConnections=1` + reboot.
- [AD2 = Dataforth-ops fork](project_ad2_dataforth_fork.md) — branch ad2 = main + thin Dataforth layer; keep fork edits ADDITIVE (Dataforth context in clients/dataforth/CLAUDE.dataforth.md, NOT .claude/CLAUDE.md); rebase onto main directly when sync.sh self-lock hits; no vault/jq/sops/age on this box.
- [GuruScan verification IN TEST / paused](project_guruscan_in_test_paused.md) — multi-engine scanner verify on DESKTOP-MS42HNC paused 2026-06-22 (VM rebooted mid-Emsisoft run); HitmanPro done (36 removed), Emsisoft full-scan unverified; resume `guruscan-agent-test.sh DESKTOP-MS42HNC scan-one Emsisoft`; Defender RTP/Tamper still off on VM
- [GuruRMM fleet dispatch-hang fix](project_gururmm_dispatch_hang_fix.md) — blocking send_to on a full bounded channel to one black-holed agent wedged ALL command dispatch; fixed with try_send (9dae20c, deployed); proper black-hole eviction still missing (was reverted in 80df458) — finish it if it recurs
- [Windows won't-boot / offline DISM repair playbook](windows-offline-dism-repair-gotchas.md) — Automatic Repair loop = boot-critical fault (disk/registry/wedged update), NOT shell/appx store corruption (that's a symptom); `FaultyPackageInProgress` + 100s of Install/Uninstall-Pending packages = wedged CU -> RevertPendingActions or clean install. Offline DISM rejects `wim:` source (0x800f082e) -> MOUNT the wim, source `\Windows`. Ventoy breaks WIM mount (0xc1420134) -> use Rufus. 25H2(26200)=24H2(26100)+enablement, so match 26100 media. First hit: Four Paws AvImark #32447.
- [365 app suite — authoritative map + consent-drift fix](reference_365_app_suite.md) — full map in `.claude/skills/remediation-tool/references/app-suite.md`; per-tenant consent is NOT uniform (VWP had the app but no SharePoint role). Run `consent-audit.sh <tenant|--all>` to detect gaps; fix via adminconsent URL or direct appRoleAssignment grant.
- [Remediation-tool has full M365 access (incl. SharePoint)](reference_remediation_tool_365_access.md) — the app suite covers Graph/EXO/Defender/SharePoint; don't declare "no access" on an accessDenied. SharePoint app-only needs a CERT (secret = "Unsupported app only token"); use get-token.sh `sharepoint`/`sharepoint-admin` tiers + CSOM admin API (Graph /admin/sharepoint/settings scope not held). Full map: skill references/app-permissions-and-sharepoint.md.
- [AV migration: Bitdefender -> Datto EDR](project_av_migration_bitdefender_to_edr.md) — retire Bitdefender fleet-wide, ONLY exception Glaztech (Dataforth migrates); end-state per machine = GuruRMM + Datto EDR
- [RMM deploy via ScreenConnect](reference_rmm_deploy_via_screenconnect.md) — push GuruRMM agent to client workstations via SC send-command (SYSTEM), not DC remote-exec (DCOM/schtasks blocked on Win11 clients)
- [ScreenConnect custom-property slots](reference_screenconnect_custom_property_slots.md) — CP1=Company CP2=Site CP3=Department CP4=Device Type CP8=Tag (API hides labels; UpdateSessionCustomProperties replaces the whole array)
- [ScreenConnect cleanup uses wiki as source](feedback_screenconnect_cleanup_wiki_source.md) — per-client SC/RMM metadata cleanup pulls machine->dept/location from the client wiki; enrich the wiki when missing
- [TECH03L systemprofile shortcut corruption](project_tech03l_systemprofile_shortcut_corruption.md) — Auto-Claude "opens then closes" = .lnk pointing at nonexistent systemprofile path; repoint, do not debug the app
- [Claude tui fullscreen crash](feedback_claude_tui_fullscreen_crash.md) — "flicker-free" prompt writes tui=fullscreen; instant-exit crash loop on some Windows terminals; set tui=default (reinstall does NOT fix)
- [Backup targets never guessed](feedback_backup_targets_never_guessed.md) — billed-vs-running mismatches are billing questions for Mike/Winter; never infer/deploy backup targets
- [Fire #dev-alerts for client/RMM work](feedback_fire_dev_alerts_for_client_work.md) — Howard+Mike watch #dev-alerts Discord for live visibility into what techs/sessions touch. Fire post-bot-alert.sh ([DEV]/[RMM]/[DEPLOY]/[GURURMM] prefix -> #dev-alerts) at the START of any RMM/Dev or active-client-machine action. No CLAUDE.md rule yet — this memory is the rule.
- [M365 app: SharePoint needs CERT](reference_m365_app_sharepoint_rest_vs_graph.md) — SP app-only works via the CERT (get-token.sh <tenant> sharepoint); the secret gives "Unsupported app only token". Graph app-only uses the secret.
- [EDR auto-isolates GuruRMM PowerShell](project_edr_rmm_autoisolation_fp.md) — Datto "Exfiltration Over HTTP" rule auto-isolates benign GuruRMM scripts fleet-wide (vwp-qbs 4h outage); watcher + narrow suppression deployed, policy fix pending Mike
- [Background tasks — no shell `&`](feedback_background_task_no_ampersand.md) — with run_in_background:true, run the command in the foreground of the shell; adding `&`/`disown` forks + exits 0 instantly, orphaning a blocking wait so it never delivers (hit twice building ask-forum)
- [ask-forum — human-in-the-loop via #ct-forum](../skills/ask-forum/SKILL.md) — ask a teammate a question in the private ct-forum Discord forum, get their human answer back in-session; forum-only, any human can answer, run the --wait as a proper background task
- [Claude Code Bun crash -> pin 2.1.110](reference_claude_code_bun_crash_pin.md) - v2.1.114+ segfaults on Win11 at new-session start; npm pin 2.1.110 + DISABLE_AUTOUPDATER=1; unpin on #55219 fix
- [GuruRMM build-server SSH key](reference_gururmm_build_server_ssh.md) — guru@172.16.3.30 key is ~/.ssh/gururmm-physical (not id_*); password fallback vault infrastructure/gururmm-server
- [LAB-SVR is current](feedback_labsvr_retired.md) — Len's Auto LAB-SVR is the CURRENT server (replaced old LAB-SERVER); powered back on 2026-07-18
