Compressed memory store 104 -> 71 files via four passes: - Syncro: 19 scattered feedback_syncro_* files merged into 3 rule files (api/billing/workflow) + an on-demand feedback_syncro_history.md for incident detail, quotes, and tech/product ID tables. - Four near-duplicate merges: Howard paste-safety, Pluto build server, Howard backend deferral, IX server access (ssh+tailscale). - Per-cluster rule/state/history split applied to GuruConnect (2->1), Dataforth (3->2), Cascades (7->3), GuruRMM (13->3). - New reference_resource_map.md: single auto-loaded cheatsheet for "do I have access to X and how do I connect from this machine?" - MEMORY.md rewritten to match the new layout. Health: broken backlinks 8->7, overlap clusters 12->5, orphans 17->0.
12 KiB
name, description, metadata
| name | description | metadata | ||
|---|---|---|---|---|
| Syncro lessons — incidents, quotes, and the events behind the rules | Detail and incident archive backing the Syncro feedback rules. Read this when you need to judge an edge case, verify a rule is still right, or understand WHY a rule exists. Tickets, dates, verbatim quotes, and tech user_id table live here so the main rule files can stay terse. Companion to feedback_syncro_api / billing / workflow. |
|
This file is the incident archive behind feedback_syncro_api, feedback_syncro_billing, and feedback_syncro_workflow. Those three files state the rules; this one preserves the events, quotes, and specifics so you can judge edge cases and verify a rule still applies. Read on-demand, not at session start.
Tech user_id table
Used by feedback_syncro_billing Section "Corrections preserve attribution".
| Tech | user_id |
|---|---|
| Mike | 1735 |
| Howard | 1750 |
| Winter | 1737 |
| Rob | 1760 |
Labor / hardware product IDs (verify rates live)
Used by feedback_syncro_billing. Rates change — always GET /products/<id> for .product.price_retail. The product IDs are stable; the table in .claude/commands/syncro.md is authoritative for the live list.
| product_id | name | role | typical rate |
|---|---|---|---|
1190473 |
Labor - Remote Business | remote (most common) | $150 |
26118 |
Labor - Onsite Business | onsite | $175 |
573881 |
Labor - In-Shop Business | in-shop | (check live) |
26184 |
Labor - Emergency or After Hours Business | emergency/after-hours | $262.50 |
1049360 |
Labor- Warranty work | warranty / no-charge | $0 |
32252 |
Hardware | generic estimate hardware | $0 base |
Incidents — by ticket / date
#32333 (2026-05-28) — Content-Type missing
- Posted a comment without
-H "Content-Type: application/json". Syncro returned a 400 HTML error page twice before the fix. The HTML response looks like a hard failure but it's just a missing header. - Lesson → feedback_syncro_api Section "Content-Type required".
#32332 (Cascades — Chris Knight new-user setup, 2026-05-27) — multi-lesson
This one ticket informed several rules at once:
-
Fabricated labor names. Product
26118("Labor - Onsite Business") was billed on two lines as"Emergency Call Setup"and"Onsite Computer Setup"— both invented. Breaks the Syncro → QuickBooks sync because QB maps each labor line to an existing item.- Mike's exact words: "You CANNOT make up labor items. You MUST use existing items only for all labor items… the labor item must use the ones that already exist in syncro (otherwise it messes things up in Quickbooks)."
- Lesson → feedback_syncro_billing "Never invent labor names".
-
Prepaid emergency billed as a split made-up onsite/emergency. 1.5 hours of emergency on a prepaid customer (Cascades has 27h block). Howard had split it into fabricated onsite + emergency lines. Correct shape: ONE line on
26184at quantity2.25(hrs×1.5).- This also confirmed the 2026-05-27 update: prepaid emergency now uses
26184at ×1.5 quantity, REPLACING the older "prepaid → onsite26118at ×1.5" rule. 26184 labels the line correctly as emergency and maps right in QuickBooks. - Lesson → feedback_syncro_billing "Emergency labor".
- This also confirmed the 2026-05-27 update: prepaid emergency now uses
-
Correction via Mike's API key would have stolen Howard's commission. The original line was Howard's (
user_id=1750). Correcting viaupdate_line_itempreserveduser_id=1750. A remove + re-add would have defaulted the new line to Mike's1735(the API-key owner).- Lesson → feedback_syncro_billing "Corrections preserve attribution".
-
Ticket ownership is sticky. Mike confirmed (also 2026-05-27): adding notes or labor to a ticket does NOT change the ticket owner. Multiple techs routinely work the same ticket. Only change ticket ownership when explicitly asked.
- Lesson → feedback_syncro_billing same section.
#32312 (Winter, 2026-05-21) — wrong day of week
- "Saturday" was computed as May 24, which is actually a Sunday. The appointment landed on the wrong day and didn't appear where Winter expected it on the calendar.
- Lesson → feedback_syncro_workflow "Verify appointment day-of-week". Always display
Day YYYY-MM-DD(e.g., "Saturday 2026-05-23") in the preview, never the numeric date alone.
2026-05-21 (Mike) — timer workflow superseded
- Mike confirmed the timer workflow (
timer_entry → charge_timer_entry) is not used. The previous rule requiring timers was wrong and caused repeated billing failures (wrong product on the timer,product_idsilently ignored bycharge_timer_entry). - Lesson → feedback_syncro_billing "Bill with add_line_item directly". The timer-response-shape rule in feedback_syncro_api is now historical / reference-only.
#32304 (Cascades, 2026-05-20) — hardcoded rates wrong
- Hardcoded rate table in the skill had Labor - Remote Business at $150/hr. The correct rate was $175/hr. Rates vary by contract and change over time.
- Lesson → feedback_syncro_billing "Fetch rates live".
Kittle Design #32263 (Howard, 2026-05-08) — appointment owner
- Howard created an 11:30 AM onsite to set up Joshua. I auto-added Howard's
user_idto the appointment'suser_idsarray without confirming whether Howard was the owner or just an attendee. - Howard's direction: "when setting up an appointment confirm the appointment owner — don't just add additional attendees."
- Lesson → feedback_syncro_workflow "Ask the appointment owner explicitly".
#32225 (Sombra Residential, 2026-05-06) — warranty hack
- Picked product
1190473(Labor - Remote Business, $150/hr) for a warranty cleanup, setbillable: falseon the (then-used) timer, and assumed the timer flag would zero the line. Syncro silently overrodebillable: falseand the line came in at $75. I patchedprice_retailto$0to "fix" it. - Howard caught it: warranty has its own product in the dropdown, and patching dollar amounts is never how this is solved. Use
1049360. - The earlier guidance in
.claude/commands/syncro.md("Warranty → use closest labor product withbillable=false") was wrong; warranty has its own product like Onsite, Remote, Emergency. - Lesson → feedback_syncro_billing "Warranty → product 1049360, never patch the price".
#32253 (Cascades, 2026-05-05) — duplicate timers from wrong jq path (HISTORICAL)
- The skill doc used
TIMER_ID=$(jq -r '.timer.id // .timer_entry.id')on a flat response → resolved tonull. AnullTIMER_ID brokecharge_timer_entry("Not found"). The script retried and created a duplicate timer. - Created two 0.5hr duplicate timers; deleted one via
delete_timer_entry. - Lesson → feedback_syncro_api timer section. Timers are no longer the workflow (see 2026-05-21), so this is reference-only.
2026-05-04 (Winter) — wrong labor type default, blank-contact rule generalized
Two adjacent lessons:
- Tickets I created used "Prepaid project labor" as the auto-selected labor type. That product is exempt and does NOT consume hours from a customer's prepaid block. Block-hour accounting silently drifted. Winter is fixing them retroactively.
- Lesson → feedback_syncro_billing "Labor type matches delivery channel".
- Winter generalized the prior Cascades-only blank-contact rule to "most customers" — blank
contact_idlets Syncro apply company-level email defaults, which route to the right people. Setting a specific contact overrides that.- Lesson → feedback_syncro_workflow "Leave contact blank by default".
#32203 (Desert Auto Tech, 2026-04-23) — emergency was additive
- Billed "1h onsite + 1h emergency" as two additive lines = $437.50. The correct shape is ONE emergency line at time-and-a-half — 1 actual hour of emergency should bill at $262.50 (or $225 remote).
- Lesson → feedback_syncro_billing "Emergency = ×1.5 applied once".
#32142 (2026-04-23) — comment dup from wrapper-key error
- POST to
/commentreturned{"comment": {...}}. The script parsed.id(returningnull), saw an error, and retried — creating a duplicate. - Lesson → feedback_syncro_api "Response wrappers". POST
/commentresponse is{"comment": {...}}— use.comment.id. Also: when GETting to verify, check ALL comments not just[-3:]— the new comment may not be the most recent if other activity occurred.
2026-04-22 — ticket dup from retry
- A
POST /ticketsresponse looked wrong (null fields, jq error). The response wrapper is{"ticket": {...}}—.ticket.idnot.id. Retried the POST, creating a duplicate ticket. - Lesson → feedback_syncro_api "No idempotency — GET before retry" applies to ticket creation, not just comments.
#32185 — comment dup from shell-quoting error
- Subject contained an em-dash (
—) → shell interpolation issue → the POST appeared to fail but actually succeeded. Retry created a duplicate comment. Comments cannot be deleted via API. - Lesson → feedback_syncro_api "No idempotency". Hardening: write comment payloads to a temp file (e.g.
tmp/syncro_comment.json) before posting — avoids shell quoting/encoding failures that produce misleading errors on requests that actually succeeded.
HTML formatting incident — <ul>/<li> rendered as one line
- Posted a comment with
<ul><li>items; Syncro's renderer collapsed them into a single line with no spacing. Had to post a corrected duplicate. - Lesson → feedback_syncro_api "HTML formatting". Use
<br>inside a<p>wrapper for bulleted lists.
Cascades — Meredith Kuhn keeps being the wrong default
- At Cascades of Tucson (
customer_id 20149445), Syncro's contact picker repeatedly pre-selects Meredith Kuhn (Assistant Manager, ASSISTMAN-PC). She's the wrong contact — assigning her overrides distribution emails and routes notifications only to her. - Howard surfaced the pattern; Mike confirmed the global blank-contact rule on 2026-05-24.
- Lesson → feedback_syncro_workflow "Cascades-specific guard".
Superseded rules — kept for context
| Rule (old) | Replaced by | Date |
|---|---|---|
All time billing through timer_entry → charge_timer_entry |
Bill with add_line_item directly |
2026-05-21 |
Prepaid emergency → onsite 26118 at ×1.5 |
Prepaid emergency → emergency 26184 at qty ×1.5 |
2026-05-27 |
| Blank contact only at Cascades | Blank contact for ALL customers by default | 2026-05-04 |
Warranty → closest labor product with billable=false |
Warranty → product 1049360 (its own product) |
2026-05-06 |
Related ACG-internal references
- Skill doc:
.claude/commands/syncro.md— current labor product table, billing workflow, examples. - API docs:
api-docs.syncromsp.com(Swagger spec). - Tenant attribution rule (cross-product): per-user-key attribution; see
/syncroAttribution rule and[[feedback_psa_default_syncro]].