Files
claudetools/.claude/memory/MEMORY.md
Mike Swanson a42d657c55 docs(session)+rules: 2026-05-27 — Quantum M365 onboarding, IX autodiscover fix, Syncro emergency/labor/attribution rules
Session logs: root (Michael #32329 hosting offer + IX simplehost.email autodiscover DNS fix + Cascades #32332 emergency correction) + Quantum client log (M365 tenant 2fd0092b onboarding, break-glass GA, CA report-only).

Syncro rule overhaul:
- Emergency billing: prepaid -> 26184 @ hours x1.5 (was 26118); non-prepaid -> 26184 with channel rate (onsite $262.50 / remote+inshop $225)
- Never make up labor items (existing product + real name; QuickBooks sync)
- Corrections preserve original tech's user_id (commission); adding notes/labor never changes ticket owner

/remediation-tool: Conditional Access may be managed programmatically (report-only first + exclude break-glass + confirm before enforce); fabb3421 deprecated for customer tenants; Quantum tenant onboarded (gotchas table).

Memory: 4 new (no-madeup-labor, corrections-preserve-tech, ca-programmatic, quantum-godaddy-tenant) + updates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 14:57:55 -07:00

85 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Memory Index
## 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.
- [Approval Workflow: Tools vs Projects](approval-workflow-tools-vs-projects.md) — Tools (remediation, scripts): Howard/Claude with approval. Projects (GuruRMM): Mike approval; features→roadmap, bugs→bug list.
- [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 SSH Access](reference_ix_server_ssh.md) - SSH access notes for GURU-5070 — re-verify key auth (was CachyOS)
- [IX Access via Tailscale](reference_ix_access_tailscale.md) - IX server accessible with Tailscale on, no VPN needed
- [Matomo Analytics](reference_matomo_analytics.md) - Self-hosted analytics at analytics.azcomputerguru.com, site IDs, tracking for all 3 sites
- [Dataforth Contact - AJ](reference_dataforth_contact.md) - AJ at Dataforth, dataforthgit@ email forwarding to him
- [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/.
- [MSP Audit Scripts](reference_msp_audit_scripts.md) — server_audit.ps1 / workstation_audit.ps1 at projects/msp-tools/msp-audit-scripts/.
- [GuruRMM Server Layout](reference_gururmm_server.md) - SSH as `guru`, repo at /home/guru/gururmm, deploy to /var/www/gururmm/dashboard/
- [GuruRMM API — run script on agent](reference_gururmm_api.md) — POST /api/agents/:id/command (command_type=powershell); poll /api/commands/:id for output. Beats ScreenConnect copy-paste.
- [Pluto Build Server](reference_pluto_build_server.md) — Windows build VM, 172.16.3.36, SSH Administrator, MSVC + WiX. Use for any EXE/MSI build.
- [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.
## Users
- [Howard Enos](user_howard.md) — Mike's brother, technician, full access. Machines: ACG-TECH03L, Howard-Home (authoritative in users.json).
## Feedback
- [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.
- [GuruRMM agent parity rule](feedback_gururmm_agent_parity.md) — "Add feature X to the agent" = Windows + Linux + macOS in the same change, no exceptions. Stub + TODO if real impl not feasible.
- [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
- [No indented code blocks](feedback_no_indented_code_blocks.md) — Never indent code inside fences; Howard copy-pastes directly and leading spaces break PowerShell
- [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
- [Syncro Emergency Billing](feedback_syncro_emergency_billing.md) — Emergency = time-and-a-half (×1.5), applied once, never additive. Branch by `customer.prepay_hours`: no-prepaid → `26184` at actual hrs; prepaid → `26184` at hrs×1.5 (premium in the QUANTITY). One line. Always set `price_retail`. (Updated 2026-05-27: prepaid now uses 26184, not 26118.)
- [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. Caused wrong-comment incident on Syncro #32225.
- [Syncro — leave contact blank by default](feedback_syncro_blank_contact.md) — Default to blank contact ("Not Assigned") on tickets and billing for ALL customers. Blank lets Syncro use company-level email defaults; setting a contact may route to a secondary email and bypass distribution. Generalizes the prior Cascades-only rule per Winter 2026-05-04.
- [Syncro — Cascades contact incident (Meredith Kuhn)](feedback_syncro_cascades_contact.md) — Meredith Kuhn is the recurring wrong Syncro default at Cascades. Incident context only; global rule is in feedback_syncro_blank_contact.md.
- [Syncro — use a billable labor type, never "Prepaid project labor"](feedback_syncro_labor_type.md) — Billable line items must use in-shop / onsite / remote / web labor. "Prepaid project labor" is exempt and won't decrement prepay blocks. Default is Remote labor for typical support tickets. Winter caught this 2026-05-04.
- [Syncro — bill with add_line_item, not timers](feedback_syncro_timer_first.md) — Bill tickets with `POST /tickets/{id}/add_line_item` directly; the timer workflow (`timer_entry → charge_timer_entry`) is NOT used. Set product_id, quantity (decimal hours), price_retail, name, description, taxable:false. Supersedes the old "timers required" rule (Mike confirmed 2026-05-21).
- [Syncro — timer_entry response is FLAT (HISTORICAL)](feedback_syncro_timer_response_shape.md) — Reference only: timers are NO LONGER part of the billing workflow (superseded by add_line_item — see feedback_syncro_timer_first.md). Retained for the rare manual-timer case: response is flat (`{"id": N, ...}`), parse `.id` not `.timer.id`. Originally hit on #32253 2026-05-05.
- [Syncro — warranty has its own product, never patch dollar amounts](feedback_syncro_warranty_product.md) — Warranty/no-charge work uses product `1049360` (Labor- Warranty work, $0). Don't fake a free line by patching `price_retail` or neutralizing a regular product — pick the correct product and re-run. Hit on #32225 2026-05-06.
- [Syncro — never make up labor items](feedback_syncro_no_madeup_labor_items.md) — Labor lines MUST be an existing Syncro product used with its REAL name; never invent/rename a line. Description field is free text. Made-up items break the QuickBooks sync. Incident #32332.
- [Syncro — preserve attribution (labor + ticket owner)](feedback_syncro_corrections_preserve_tech.md) — Corrections keep the original tech's labor user_id (commission); update_line_item preserves it, remove+add defaults to the API-key owner. Adding notes/labor never changes the ticket owner. Only reassign labor or ticket ownership when explicitly asked. (#32332)
- [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. IMC1 2026-05-05/06 near-miss.
- [Syncro — confirm appointment owner explicitly](feedback_syncro_appointment_owner.md) — When creating tickets with appointments, always ask "who is the appointment owner?" in the preview. Don't auto-default to ticket's assigned tech. Don't add additional attendees without explicit confirmation. Howard caught on Kittle ticket #32263 2026-05-08.
- [Syncro — verify appointment date day-of-week](feedback_syncro_appointment_date_check.md) — Always compute and display the day name (e.g. "Saturday 2026-05-23") in the ticket preview — never just the numeric date. Verify with `py -c "import datetime; ..."` before posting. Wrong-day incident on #32312 2026-05-21 (Sunday booked instead of Saturday). Reported by Winter.
- [Syncro estimate hardware product](feedback_syncro_estimate_hardware.md) — All hardware on estimates uses product_id 32252 ("Hardware", $0 base); set name/price_retail per item. Never look up individual hardware product IDs.
- [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. Hit on ASSISTMAN-PC 2026-05-08.
- [Cascades — ask security group on user creation](feedback_cascades_user_security_group.md) — When creating any Cascades user, always ask which security group(s) they go in. Deliberate per-user decision; an OU→group auto-mirror was explicitly declined 2026-05-14. OU = sync scope; group = access/CA decision.
- [Cascades folder redirect — fdeploy failure/recovery](feedback_cascades_folder_redirect.md) — Must pre-create subfolders before first logon. fdeploy caches failures silently. Recovery: fix-shell-redirect.ps1. Both GUID and legacy name keys required.
- [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."
- [GuruRMM dev is Mike's, not Howard's](feedback_rmm_dev_is_mike.md) — Never route RMM dev/bug coord notes to Howard (0 RMM commits by him). Howard only submits RMM feature requests; GuruScan is his project, RMM is not.
- [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.
- [Command Formatting](feedback_command_formatting.md) — Always multi-line scripts, never one-liners; one-liners wrap in chat and break on copy-paste
## 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.
## Pending Setup
- [Mac gururmm setup pending](project_mac_gururmm_setup_pending.md) — ACTION REQUIRED: run `bash scripts/install-hooks.sh` in gururmm repo on Mikes-MacBook-Air before any RMM work
## Project
- [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. Managed = no DNS takeover; need GoDaddy/GA access.
- [Cascades Migration Plan](project-cascades-migration-plan.md) — Active multi-day migration. Plan file: `C:\Users\Howard\.claude\plans\wise-discovering-panda.md`. Syncro ticket: #110680053. Resume: "resume the Cascades migration plan".
- [GuruRMM Development Principles](gururmm-development-principles.md) - MANDATORY: every feature needs full stack (backend, API, UI, docs, scalability). Product must work without AI agents (AI features are enhancements). Documented in guru-rmm/docs/DESIGN.md.
- [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), so untracked-only changes are caught. Added .gitignore for the datto BSOD dumps so the fix doesn't sweep 54MB of binaries.
- [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/.
- [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 Security Incident](project_dataforth_incident_2026-03-27.md) - DF-JOEL2 compromised, MFA deployed, IC3 filed. CA policies enforce April 4.
- [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. Multiple co-hosts have rotated through the show.
- [Cascades admin accounts](project_cascades_admin_accounts.md) — Howard uses sysadmin@cascadestucson.com, Mike uses admin@cascadestucson.com; daily admin, NOT break-glass.
- [Cascades CA phased rollout](project_cascades_ca_phased_rollout.md) — Caregiver CA policies scoped to SG-Caregivers-Pilot, expand by dept; PATCH excludeGroups, never delete the all-users-MFA policy.
- [Cascades caregiver pilot cleanup](project_cascades_pilot_cleanup.md) — Remove pilot accounts (pilot.test@, howard.enos@) at the end of the caregiver bypass pilot.
- [Proposal: centralize config in identity.json](proposal_identity_centralization.md) — Rationale for the identity.json machine-config centralization (claudetools_root, ollama/python); now implemented.