Files
claudetools/session-logs/2026-07/2026-07-10-howard-syncro-skill-expansion.md
Howard Enos fe91b4ecfc sync: auto-sync from HOWARD-HOME at 2026-07-10 17:21:24
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-07-10 17:21:24
2026-07-10 17:21:55 -07:00

8.6 KiB

User

  • User: Howard Enos (howard)
  • Machine: Howard-Home
  • Role: tech

Session Summary

Expanded and end-to-end tested the /syncro skill from PSA-only to full Syncro API coverage, including asset/RMM management and a working Syncro-agent deployment path. Started by auditing the live OpenAPI 3.0 spec (api-docs.syncromsp.com/swagger.json) against the existing skill and discovered the skill deliberately avoided asset writes based on a memory (reference-syncro-rmm-api-gui-only) that turned out to be a token-scope symptom, not an API limit. Pulled the complete inventory (~180 operations across 38 resource types), built a new verified reference doc, and probed the live tenant with Howard's per-user token to map exactly what works vs. what needs scope.

Corrected the record: the entire asset/RMM surface (create/update, patches, installed_applications, rmm_alerts, contacts, contracts, leads, vendors, POs, products, payments, wiki) is API-drivable; only policy-folder operations were 401-gated by a missing "Assets - Policy Change" token scope. Mike upgraded Howard's token to full scope mid-session; verified the policy-folder move works via flip-and-restore on a test asset. Also checked Mike's and Winter's keys — Winter full, Mike's vaulted token (…ebbeb3) still 401 (needs re-vault).

Ran a full live test campaign on a new sandbox customer ("Howard Test", 36118743). Phase 1 exercised the complete PSA + breadth write surface (tickets, comments, line items, invoices, estimates, appointments, schedules, contracts, contacts, leads, vendors, products, purchase orders, worksheets) and captured every response shape and gotcha. Phase 2 proved the deploy path end-to-end: pushed the per-policy-folder Syncro MSI installer to RMM-TEST-MACHINE via GuruRMM (/rmm), the box auto-enrolled as a Syncro asset in the correct client + policy folder, then tested patches, installed_applications, policy-folder create/move/delete, and rmm_alerts on the real device.

Decoded the installer URL structure and confirmed it is a per-client secret (not constructible), so harvested links are vaulted per client (4 seeded). Confirmed Syncro's public API has NO remote device-control/exec endpoint — execution stays on GuruRMM. Finished by cleaning up the sandbox (API-deleted the deletable records, uninstalled the Syncro agent from RMM-TEST-MACHINE) and recording all findings in a living test-findings.md plus the skill's hard rules.

Key Decisions

  • Kept the high-frequency PSA workflows in syncro.md and put the full breadth in a new api-reference.md rather than bloating the incident-scarred core.
  • Installer-push (deploy-agent) lives in /syncro (Howard's call) but uses GuruRMM as the execution arm — Syncro has no installer-download or exec API.
  • Chose lazy harvest of installer URLs (grab+vault+wiki-pointer at first deploy) over proactive harvesting of all ~69 clients.
  • Vaulted installer URLs (they embed an unguessable per-client secret token) rather than storing plaintext in the wiki; wiki gets a pointer.
  • Built move-asset with a capability preflight + mandatory post-write verify because an under-scoped token returns HTTP 200 and silently no-ops the folder change.
  • Did not probe undocumented endpoints (e.g. guessed exec routes) per the skill's hard rule.

Problems Encountered

  • Emails not delivered despite 200 "Email sent". Invoice/estimate email endpoints take no recipient param and send to nobody when customer.email is null. customer.email is unique tenant-wide (Howard's real email was "already taken"). Fixed with a plus-addressed unique email (howard+synctest@), which delivered — resolved.
  • Null write responses looked like failures. POST /contacts (flat .id), POST /contracts (no echo) returned null on the wrapped parse though the writes succeeded. GET-verify caught it; a blind retry would have duplicated. Documented the three response-shape families.
  • Policy-folder 401 then 404. Old token 401'd on /policy_folders; upgraded token 404s on the bare route but 200s with ?customer_id=N. POST /policy_folders requires parent_id.
  • PO line item rejected until the product had maintain_stock:true.
  • Customer would not hard-deleteDELETE /customers disables instead when associated data (asset/lead) exists. Expected; noted GUI-only leftovers.
  • jq --arg path lookup quirk on the swagger file — switched to single non-parameterized walks / hardcoded paths.
  • /tmp write blocked by the block-tmp-path hook (working as intended) — used repo-relative .claude/tmp/.

Configuration Changes

Created:

  • .claude/standards/syncro/api-reference.md — full verified Syncro endpoint catalog + worked templates.
  • .claude/standards/syncro/test-findings.md — living log of verified behaviors/gotchas.
  • session-logs/2026-07/2026-07-10-howard-syncro-skill-expansion.md — this log.

Modified:

  • .claude/commands/syncro.md — asset read/write/move, RMM alerts, deploy-agent, capability preflight helper, email-delivery hard rule, expanded Verified Response Shapes table, reference pointer.
  • .claude/memory/reference_syncro_rmm_api_gui_only.md + .claude/memory/MEMORY.md — corrected the "RMM is GUI-only" belief to the verified token-scope reality.
  • errorlog.md — two --correction entries (asset-API assumption; email 200 != delivered).

Vault (separate repo, pushed):

  • clients/{cascades-tucson,grabb-durando,reliant,howard-test}/syncro-agent-installer.sops.yaml — Syncro RMM MSI installer URLs (encrypted).

Credentials & Secrets

  • Syncro per-user API keys (unchanged): msp-tools/syncro (Mike, uid 1735, …ebbeb3 — still lacks Policy-Change scope), msp-tools/syncro-winter (Winter, uid 1737, …5edb3a — full), msp-tools/syncro-howard (Howard, uid 1750, …680e18 — full, upgraded this session).
  • Syncro installer URLs vaulted at clients/<slug>/syncro-agent-installer (credentials.installer_url). Structure: base64(v1-{customer_id}-{A:secret}-48753-{policy_folder_id}); 48753 = ACG Syncro account id; A is an unguessable per-client secret (not API-derivable).
  • GuruRMM API creds unchanged: infrastructure/gururmm-server.sops.yaml.

Infrastructure & Servers

  • Syncro PSA API: https://computerguru.syncromsp.com/api/v1 (query-param auth, 180 req/min).
  • Syncro RMM installer host: https://rmm.syncromsp.com/dl/msi/<token> (Kabuto, separate from PSA API).
  • GuruRMM: http://172.16.3.30:3001 (JWT auth).
  • RMM-TEST-MACHINE (GuruRMM agent id 99d6d692-99e0-4359-9f9c-f43be89f49e5, online, v0.6.66, client "AZ Computer Guru", site "Howard-VM"). A second stale enrollment exists (7d3456f5-…, offline). Syncro agent MSI product code {B7F56D3D-2AD3-4021-9D36-3B9E9C9FBE33}.
  • Sandbox: Syncro customer "Howard Test" 36118743 (now DISABLED), policy folder 5092561, enrolled asset 12676769.

Commands & Outputs

  • Decode installer token: echo <b64> | base64 -dv1-{customer_id}-{A}-48753-{policy_folder_id}.
  • Capability preflight (policy scope): GET /policy_folders?customer_id=N → 200 has scope, 401 lacks.
  • Deploy (GuruRMM): download MSI, Start-Process msiexec.exe -ArgumentList @('/i',$msi,'/qn','/norestart') -Wait → service Syncro Running, asset enrolls in ~1 min.
  • Uninstall (GuruRMM): find Uninstall reg entry DisplayName -match 'Syncro', msiexec /x {ProductCode} /qn /norestart → service/process/dir/reg all removed.
  • DELETE /customers/{id} on customer with associated data → {"message":"Customer was disabled instead of deleted because they have associated data."}.

Pending / Incomplete Tasks

  • Mike's Syncro token (…ebbeb3) still lacks Assets-Policy-Change — re-vault after he confirms/upgrades the correct token, so move-asset works in Mike-attributed sessions.
  • GUI-only sandbox leftovers (no API DELETE): Howard Test asset 12676769 (archive), lead 43492446, vendor 809317, product 23639304, PO 2101221; customer 36118743 stays DISABLED until asset+lead cleared.
  • Optional: add a deploy-agent --uninstall action (msiexec /x method verified).
  • Optional: grant Policy-Change scope to all per-user tokens for consistent move-asset.
  • Lazy-harvest installer URLs for other clients at first deploy.

Reference Information

  • Spec: https://api-docs.syncromsp.com/swagger.json (OpenAPI 3.0, 116 paths / ~180 ops / 38 tags).
  • Skill: .claude/commands/syncro.md; reference .claude/standards/syncro/api-reference.md; findings .claude/standards/syncro/test-findings.md.
  • Commits this session: 1f56098, 12bb9f1, 555e1ff, 1fa1a42, ae2ee34, 269449d, 8afd7ec (+ this save).
  • Vault installer entries: clients/{cascades-tucson,grabb-durando,reliant,howard-test}/syncro-agent-installer.