diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index dcdccd9..e03b189 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -34,6 +34,7 @@ - [Syncro — never set contact on Cascades tickets](feedback_syncro_cascades_contact.md) — Cascades-specific instance of the blank-contact rule above. Kept for the Meredith-defaulting incident detail. - [Syncro — use a billable labor type, never "Prepaid project labor"](feedback_syncro_labor_type.md) — Time entries 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 — log time entries first, never bare add_line_item](feedback_syncro_timer_first.md) — All Syncro work-time billing MUST go through `timer_entry → charge_timer_entry`. Bare `add_line_item` leaves Syncro time tracking at 00:00:00 and breaks reporting. Mike caught this on 2026-04-30 across 31 tickets; I repeated the bug on 2026-05-01 across 3 more. +- [Syncro — timer_entry response is FLAT](feedback_syncro_timer_response_shape.md) — POST /tickets/{id}/timer_entry returns `{"id": N, ...}` directly, NOT `{"timer": {...}}`. Parse as `.id`. The skill doc's `.timer.id // .timer_entry.id` fallback always resolves to null and causes duplicate-timer retries. Hit on #32253 2026-05-05. ## Machine - [ACG-5070 Workstation Setup](reference_workstation_setup.md) - Windows 11 Pro clean install 2026-03-30, replaced CachyOS. All tools installed. diff --git a/.claude/memory/feedback_syncro_timer_response_shape.md b/.claude/memory/feedback_syncro_timer_response_shape.md new file mode 100644 index 0000000..6803436 --- /dev/null +++ b/.claude/memory/feedback_syncro_timer_response_shape.md @@ -0,0 +1,48 @@ +--- +name: Syncro — timer_entry response is FLAT, not wrapped +description: POST /tickets/{id}/timer_entry returns a flat object {"id": N, "ticket_id": ..., "product_id": ..., ...}, NOT wrapped in {"timer": {...}} or {"timer_entry": {...}}. Parse as `.id`, never `.timer.id` — using the wrapped pattern silently returns null and creates duplicate timers when the script "retries". +type: feedback +--- + +**Rule:** When parsing the response from `POST /tickets/{id}/timer_entry`, use `.id` directly — the response is a FLAT object. Do NOT use `.timer.id // .timer_entry.id`. + +**Verified response shape (2026-05-05, ticket #32253):** +```json +{ + "id": 39031258, + "ticket_id": 109895882, + "user_id": 1750, + "start_time": "2026-05-05T09:00:00.000-07:00", + "end_time": "2026-05-05T09:30:00.000-07:00", + "recorded": false, + "billable": true, + "notes": "...", + "product_id": 26118, + "comment_id": null, + "ticket_line_item_id": null, + "active_duration": 1800, + "billable_time": 1800 + ... +} +``` + +**Why:** The skill doc at `.claude/commands/syncro.md` shows +```bash +TIMER_ID=$(echo "$TIMER_RESP" | jq -r '.timer.id // .timer_entry.id') +``` +That fallback resolves to `null` because neither key exists on the flat response. A `null` TIMER_ID then breaks `charge_timer_entry` ("Not found"). If the script retries the timer_entry POST after the perceived failure, it creates a duplicate — Syncro has no idempotency. Hit this on ticket #32253 (Cascades) on 2026-05-05; created two duplicate 0.5hr timers and had to delete one via `delete_timer_entry` before charging. + +**How to apply:** + +- **Parsing:** Always `jq -r '.id'` on the timer_entry response. +- **After ANY ambiguous timer_entry response** (null `.id`, jq error, network blip): GET the ticket and inspect `.ticket.ticket_timers[]` BEFORE retrying. Filter for `recorded: false` entries with the start/end times you just sent. +- **Cleanup if duplicates exist:** `POST /tickets/{id}/delete_timer_entry` with `{"timer_entry_id": N}` for the older duplicate(s). Returns `{"success": true}`. +- **Verifying the timer is on the ticket:** `GET /tickets/{id}` → `.ticket.ticket_timers` is the authoritative list. The standalone `/ticket_timers?ticket_id=N` query parameter does NOT filter by ticket — returns the entire global timer history. + +**Charge timer response is also flat:** +```json +{"id": 39031258, "recorded": true, "ticket_line_item_id": 42313052, ...} +``` +Parse as `.ticket_line_item_id` to get the auto-generated line. Do not look for a wrapper. + +**Where this lands in skill code:** `.claude/commands/syncro.md` example block needs `.id` not `.timer.id // .timer_entry.id`. Until the skill is patched, override the example pattern when running. diff --git a/clients/cascades-tucson/session-logs/2026-05-05-howard-chef-pc-slow-and-mdirector-ram.md b/clients/cascades-tucson/session-logs/2026-05-05-howard-chef-pc-slow-and-mdirector-ram.md index c19643e..e18829d 100644 --- a/clients/cascades-tucson/session-logs/2026-05-05-howard-chef-pc-slow-and-mdirector-ram.md +++ b/clients/cascades-tucson/session-logs/2026-05-05-howard-chef-pc-slow-and-mdirector-ram.md @@ -168,3 +168,57 @@ Datto AEMAgent 290 s Datto RMM ### Note for Mike **Fleet-wide MSP cleanup decision needed.** Every Cascades workstation we onboarded into GuruRMM since 2026-04-18 still has the previous MSP's Datto RMM, Datto AV, Datto EDR (Infocyte), Syncro RMM, and Splashtop running concurrently with our agent. CHEF-PC is the visible symptom — five RMM/EDR stacks plus three remote-access tools running simultaneously, with `SyncroLive.Agent.Runner` alone consuming 35+ minutes of CPU time and `WmiPrvSE` saturated. Before I scrip a fleet uninstall, need confirmation: (1) is GuruRMM the canonical RMM going forward? (2) Datto AV out, Defender in? (3) Are we still under contract on any of the Datto/Syncro tooling we'd be ripping out? Will scope this onsite workstation by workstation, but the fix is fleet-wide, not just CHEF-PC. + +--- + +## Update: 16:42 PT — Syncro tickets created (#32253 invoiced, #32254 opened) + +### What landed +Two Syncro tickets created via API on 2026-05-05 for Cascades of Tucson (customer 20149445). Ticket #32253 covers earlier today's onsite RAM install on MDIRECTOR-PC and is fully billed + invoiced. Ticket #32254 documents the Chef-PC slow-performance issue and stages the upcoming Windows reinstall — no billing applied yet. Both created with `contact_id: null` per the Cascades blank-contact rule. Initial-issue comments posted with `do_not_email: true`. + +### Ticket #32253 — Shelby Trozzi 4GB RAM upgrade (Invoiced) +- **Subject:** Shelby Trozzi - 4GB RAM upgrade for slowness +- **Issue type:** Hardware. Priority: 2 Normal. Status: Invoiced. +- **Initial issue comment summary:** Per audit, Shelby's machine ran slow due to programs/photos left open for extended periods. Installed one 4GB DDR4 RAM stick to alleviate slowness. Advised user to reboot regularly and close unused programs. Recommended replacing the machine — current hardware is at end of useful life. +- **Billing:** + - Onsite labor (product 26118): 0.5 hr @ $175/hr — applied to Cascades prepay block (auto-generated line via `charge_timer_entry`) + - Hardware (product 32252): 1 × 4GB DDR4 RAM stick @ $25.00, taxable +- **Invoice:** #67564 — total **$27.18** ($25.00 hardware + $2.18 tax). Labor line shows "Applied 0.5 Prepay Hours" — block decremented as expected. + +> Note vs. the earlier plan in this log: the original recommendation was a matched 2× 4GB DDR4-2400 SODIMM pair for dual-channel. Mike's instruction at billing time was a single 4GB stick (asymmetric with whatever was already there). The dual-channel rebalance remains a follow-up if performance is still poor after RAM + reboot discipline. + +### Ticket #32254 — Chef JD / Chef-PC Windows reinstall (open) +- **Subject:** Chef JD - Chef-PC running slow / Windows reinstall +- **Issue type:** Software. Priority: 2 Normal. Status: New. +- **Asset linked:** CHEF-PC (Syncro asset 9794584). +- **Initial issue comment summary:** Chef-PC running slow. Built-in Windows repairs are getting stuck on the backend. Plan: full Windows reinstall. +- **No billing applied** — ticket scopes the upcoming reinstall. +- **Scope note:** This ticket frames the reinstall as the resolution, but the parent log's "Note for Mike" still stands — the underlying cause on this fleet is the previous-MSP agent stack (Datto RMM/AV/EDR + Syncro + Splashtop running concurrently with GuruRMM). A clean Windows install on CHEF-PC will fix the symptom on this one machine without addressing the fleet-wide stack-removal decision Mike still owes. + +### Skill bug encountered (Syncro `timer_entry` response shape) +The Syncro skill (`.claude/commands/syncro.md`) example for `POST /tickets/{id}/timer_entry` parses the response as `.timer.id // .timer_entry.id`. The actual API response is a **flat** object — `{"id": N, "ticket_id": ..., ...}` — and that fallback always resolves to `null`. + +What happened on Ticket #32253: +1. First `timer_entry` POST succeeded and created timer 39031253. My jq returned null because of the `.timer.id` pattern. +2. Subsequent `charge_timer_entry` with `null` ID returned `{"message":"Not found"}`. +3. Reading the response shape, I retried the POST. Syncro has no idempotency, so it created a SECOND timer (39031258). +4. Verified two unrecorded timers on the ticket via `GET /tickets/{id}` → `.ticket.ticket_timers`. +5. Deleted the older duplicate via `POST /tickets/{id}/delete_timer_entry` (returned `{"success": true}`). +6. Charged the survivor — generated one labor line item at the correct $175 rate. + +**No double-billing landed.** Only one labor line item exists on the ticket and the invoice. Net Cascades prepay debit is the intended 0.5 hr. + +**Documentation:** +- Saved feedback memory: `.claude/memory/feedback_syncro_timer_response_shape.md` +- Indexed under Feedback in `.claude/memory/MEMORY.md` +- The skill file `.claude/commands/syncro.md` example block still has the bad pattern — flagged for fix in the Pending section below. + +### Cascades prepay block (post-billing) +- Before this session: 50.0 hours +- After Tickets #32253 (0.5 hr) + #32255 (1.0 hr): **48.5 hours** +- Verified via `GET /customers/20149445` → `.customer.prepay_hours == "48.5"` + +### Pending (added) +- [ ] Patch `.claude/commands/syncro.md` `timer_entry` example: change `jq -r '.timer.id // .timer_entry.id'` to `jq -r '.id'`. Same fix applies to the `charge_timer_entry` response (also flat — `.ticket_line_item_id` directly on the root). +- [ ] Decide on the dual-channel rebalance for MDIRECTOR-PC if a 0.5-hr session of "reboot + close apps + reseat single 4GB stick" doesn't resolve user complaints within ~2 weeks. +- [ ] Schedule Chef-PC Windows reinstall (ticket #32254). Reinstall on its own will not remove the previous-MSP agents on the rest of the fleet — track that as the parent fleet-cleanup decision (still on Mike). diff --git a/clients/cascades-tucson/session-logs/2026-05-05-howard-zachary-nelson-onboarding.md b/clients/cascades-tucson/session-logs/2026-05-05-howard-zachary-nelson-onboarding.md index af8b615..677c484 100644 --- a/clients/cascades-tucson/session-logs/2026-05-05-howard-zachary-nelson-onboarding.md +++ b/clients/cascades-tucson/session-logs/2026-05-05-howard-zachary-nelson-onboarding.md @@ -100,3 +100,26 @@ Two separate one-time passwords delivered to Mike in chat: - AD domain account password Neither committed to repo. Both forced to change at first sign-in. + +--- + +## Update: 16:42 PT — Syncro ticket #32255 invoiced + +### Ticket #32255 — Zachary Nelson onboarding (Invoiced) +- **Customer:** Cascades of Tucson (Syncro 20149445) +- **Subject:** Zachary Nelson - New user / email / desktop setup +- **Issue type:** New User / Workstation Deployment. Priority: 2 Normal. Status: Invoiced. +- **Contact:** null (Cascades blank-contact rule). +- **Initial issue comment summary:** Set up new M365 email and user account for Zachary Nelson; configured account on his desktop; added Zachary to share folders on cascadesDS — ALdocs, Business Office, Business AL. +- **Billing:** Onsite labor (product 26118): 1.0 hr @ $175/hr — applied to Cascades prepay block. +- **Invoice:** #67565 — total **$0.00** (1.0 hr applied to prepay; no taxable items). Labor line shows "Applied 1.0 Prepay Hours". + +### Coverage note +This ticket bills only the desktop / share-folder portion of today's Zachary work. The M365 cloud account creation, on-prem AD account creation on CS-SERVER, license assignment (SPB), and password handoff to Mike are documented earlier in this log and folded into the same 1.0-hr onsite block. If this scope ends up needing a second pass (manager assignment, group memberships, or the broader O365_BUSINESS_PREMIUM → SPB migration sweep tracked in "Not done"), open a follow-up ticket rather than appending to #32255. + +### Cascades prepay block (post-billing) +- Block at 50.0 hours before today's billing session. +- Decremented 1.5 hours total today (0.5 on #32253 + 1.0 on #32255) → **48.5 hours remaining**. + +### Cross-reference +Skill bug hit on Ticket #32253 (Syncro `timer_entry` response shape) is documented in the parallel chef-pc-slow log (`2026-05-05-howard-chef-pc-slow-and-mdirector-ram.md`, "Update: 16:42 PT" section). Ticket #32255 was created cleanly after the workaround was understood.