--- name: comment-dedup description: Never retry POST /comment without first GET /tickets/{id} to confirm it didn't land; always use heredoc payloads applies-to: syncro, all --- # Syncro Comment Deduplication ## The rule Never retry a POST `/comment` call without first doing a `GET /tickets/{id}` to confirm the first attempt did not land. Syncro has no DELETE endpoint for comments. A duplicate comment cannot be removed via the API — only manually through the Syncro GUI by an admin. Duplicate comments are visible to clients (public comments) and to all technicians (hidden comments), and the content cannot be redacted without deleting the entire comment. ## Incident that established this rule 2026-05-01: A comment with completely wrong content ("Karen Rossini" and the ALDOCS Cascades share) was posted to a Sombra Residential ticket. Root cause: a `/tmp` path mismatch on Windows caused curl to read a stale payload from a previous session rather than the newly written one. The wrong comment could not be deleted via API — Howard had to manually delete it through the Syncro GUI. ## Required pattern **Before retrying any failed comment POST:** ```bash # Check if the comment landed before retrying curl -s "https://computerguru.syncromsp.com/api/v1/tickets/${TICKET_ID}?api_key=${API_KEY}" \ | jq '.ticket.comments[-1]' ``` If the comment is there, do not retry. If it is missing, diagnose why before retrying (network failure, wrong API key, wrong ticket ID). ## Payload pattern — use heredocs, not temp files Do not write comment payloads to `/tmp/` files and read them back with curl. On Windows, `/tmp` resolves differently in Git Bash vs. the Claude Code Write tool, causing stale-file reads. **Correct — heredoc piped directly to curl:** ```bash curl -s -X POST "${BASE}/tickets/${TICKET_ID}/comment?api_key=${API_KEY}" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' {"subject": "Resolution", "body": "...", "hidden": false, "do_not_email": false} JSON ``` Use `<<'JSON'` (single-quoted, literal) for static payloads. Use `< /tmp/comment.json << 'EOF' {"subject": "Resolution", ...} EOF curl ... -d @/tmp/comment.json # May read wrong file ``` ## Applies also to All Syncro POST endpoints, not just comments. Timer entries, line items, and invoices all have the same no-retry-without-check rule since duplicates are visible and often cannot be deleted via API.