diff --git a/.claude/commands/syncro.md b/.claude/commands/syncro.md
index bc70a9a..722a99a 100644
--- a/.claude/commands/syncro.md
+++ b/.claude/commands/syncro.md
@@ -275,7 +275,7 @@ Whether the draft came from Ollama or Claude wrote it directly:
2. `quantity` = minutes ÷ 60 — verify the arithmetic (e.g. 45 min = 0.75, not 0.77)
3. Computed total = `price_retail × quantity` — matches what was communicated to user
4. If labor_type is `emergency` and `prepay_hours > 0`: product must be `26184` (emergency item), qty must be actual_hours × 1.5 (premium in the quantity)
-5. `comment_body` uses `
`, not `
/- `
+5. `comment_body` uses `
` — scan the string for `\n` (literal backslash-n) or bare newlines and replace with `
`. No ``/`- `.
6. No internal notes or credential data in a customer-visible comment body
If a check fails: correct it and note the fix in the preview so the user can see what changed.
@@ -575,6 +575,13 @@ Every endpoint's response shape, verified against the live API. Parse exactly as
#### Comments
+**Dead-end paths (all return 404 — do not probe):**
+- `POST /ticket_comments` — top-level; GET works for listing but POST does not exist
+- `POST /tickets/{id}/comments` (plural) — does not exist
+- `POST /ticket_comments` with `ticket_id` in body — 404 regardless of payload
+
+**Correct path:** `POST /tickets/{id}/comment` (singular, nested under ticket). Verified 2026-05-28.
+
```bash
# POST comment — response: {"comment": {...}}
COMMENT_RESP=$(curl -s -X POST "${BASE}/tickets/${ID}/comment?api_key=${API_KEY}" \
@@ -594,6 +601,7 @@ COMMENT_ID=$(echo "$COMMENT_RESP" | jq -r '.comment.id')
- `hidden: true` = internal only (customer can't see)
- `do_not_email: true` = suppress email to customer
- Body is HTML; use `
` for line breaks. ``/`- ` do not render in Syncro.
+- **`\n` does NOT render as a line break in Syncro** — it shows as a space or is ignored. Every line break in the body MUST be a literal `
` tag. This applies whether the body was drafted by Ollama, Claude, or built from a shell variable. When using `jq --arg body "$VAR"`, a variable containing `\n` characters passes them as literal backslash-n, not HTML breaks. Write body strings with `
` inline, or use the heredoc form below to write proper HTML. Incident: ticket #32339 Birth Biologic 2026-05-28 — tech notes posted with `\n` separators, rendered as one unreadable block.
- Do NOT wrap the payload in `{"comment": {...}}` — returns 422.
- **If `COMMENT_ID` is null:** GET `/tickets/{id}` and check `.ticket.comments[]` by subject before doing anything else. Comments cannot be deleted via API — duplicates require manual GUI removal.
@@ -608,7 +616,15 @@ curl -s "${BASE}/customers/${CUST_ID}?api_key=${API_KEY}" | jq '{id: .customer.i
#### Line Items
-All billing uses `add_line_item` directly. Do not use `timer_entry → charge_timer_entry`.
+All billing uses `add_line_item` directly. Do not use `timer_entry → charge_timer_entry`. Do not use timers.
+
+**Dead-end paths (all return 404 — do not probe):**
+- `POST /ticket_line_items` — does not exist
+- `POST /tickets/{id}/line_item` (singular) — does not exist
+- `POST /tickets/{id}/line_items` (plural) — does not exist
+- `PUT /tickets/{id}` with `line_items_attributes` in body — silently no-ops (returns ticket with empty line_items)
+
+**Correct path:** `POST /tickets/{id}/add_line_item` using the **internal ticket ID** (e.g. 111387456, from `.ticket.id`), not the ticket number. Verified 2026-05-25 and 2026-05-28.
```bash
# Add line item — response is FLAT: {"id": N, "ticket_id": N, "product_id": N, "price_retail": N, ...}
diff --git a/.claude/worktrees/agent-ad3a8120cb99cdb4a b/.claude/worktrees/agent-ad3a8120cb99cdb4a
deleted file mode 160000
index b0695ab..0000000
--- a/.claude/worktrees/agent-ad3a8120cb99cdb4a
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit b0695ab3a0d4c906b2a9035daae921c5345d9723
diff --git a/session-logs/2026-05-28-session.md b/session-logs/2026-05-28-session.md
index 705eb05..8479896 100644
--- a/session-logs/2026-05-28-session.md
+++ b/session-logs/2026-05-28-session.md
@@ -250,3 +250,80 @@ $pkg.Uninstall()
- GuruRMM agent (KSTEENBB2025): `ee3c6aea`
- Datto CLSID fixed: `{3C639243-95A2-400D-B4B4-4384DA7F61D3}`
- Office build across all three BB machines: M365 C2R `16.0.19929.20172`
+
+## Update: 10:17 PT — Syncro ticket finalization + skill fixes + SPEC decisions
+
+## User
+- **User:** Mike Swanson (mike)
+- **Machine:** GURU-5070
+- **Role:** admin
+
+## Session Summary
+
+This update covers the tail end of the Birth Biologic / Kristin Steen SmartBadge work carried over from the earlier session segment, plus two skill maintenance fixes and GuruRMM spec decisions relayed to Howard.
+
+The primary task was completing Syncro ticket #32339 (Birth Biologic, internal ID 111387456). Three API calls were needed: a private tech notes comment, a public customer-facing comment, and a warranty labor line item. All three required endpoint discovery through trial and error because the wrong paths were attempted first. The correct comment endpoint is `POST /tickets/{number}/comment` (singular, nested) — not the top-level `POST /ticket_comments` which exists for GET only. The correct line item endpoint is `POST /tickets/{internal_id}/add_line_item` — not `/line_item`, `/line_items`, or `PUT` with `line_items_attributes` (all 404). Both endpoints are already documented in the syncro skill; the session logs were searched to recover them after the live probing failed. Warranty labor (product 1049360, $0.00, taxable: false) was logged as 60 minutes per Mike's instruction.
+
+After ticket work was complete, the syncro skill was updated in two places: dead-end comment and line item endpoint paths were documented explicitly to prevent future trial-and-error, and the `\n` vs `
` formatting issue was documented after Mike flagged that the tech notes comment rendered as an unreadable block. The `\n` characters in the shell variable passed through `jq --arg` were not converted to HTML `
` tags. The review checklist in the skill now explicitly calls this out.
+
+A coord message from Howard arrived with two new GuruRMM feature specs (SPEC-013 File Browser P3, SPEC-014 Event Log Viewer P2). Mike's decisions were relayed back via coord: SPEC-013 deferred until file transfer (P2) ships first (shared filesystem logic), SPEC-014 approved as Phase 1 PowerShell relay with Phase 2 native Rust swap deferred until UI and alert schema are proven. A bot alert for ticket #32339 was posted manually after the automated alert failed to fire during the original billing run.
+
+## Key Decisions
+
+- **Syncro comment endpoint:** `POST /tickets/{ticket_number}/comment` (singular) — ticket number (e.g. 32339) works here; internal ID also works for GET but comment POST accepts number.
+- **Syncro line item endpoint:** `POST /tickets/{internal_id}/add_line_item` — must use internal ID (111387456), not ticket number.
+- **SPEC-013 deferred:** File browser shares agent-side filesystem logic with file transfer (P2); building it first means rebuilding parts on transfer landing. One focused effort preferred.
+- **SPEC-014 Phase 1 approved:** Get-WinEvent PowerShell relay covers 100% of query/filter/alert UX. Native Rust bindings are 3-4x more effort for no user-visible benefit at this stage; swap deferred until UI schema proven.
+- **60 min warranty labor:** Mike confirmed duration. Product 1049360 ($0.00, taxable: false, block time unaffected).
+
+## Problems Encountered
+
+- **`POST /ticket_comments` returns 404:** Top-level endpoint exists for GET (returns comment list) but POST route does not exist. Multiple variants tried before finding singular `/comment` nested under ticket. Resolution: grep session logs for prior art — found `POST /tickets/{id}/add_line_item` and `/comment` documented in 2026-05-25 session.
+- **`\n` in comment body rendered as plain text:** Shell variable constructed with literal `\n` separators passed through `jq --arg` — Syncro received backslash-n characters, not line breaks. Rendered as one unformatted block. Resolution: documented in skill with incident reference; future bodies must use `
` inline or heredoc form.
+- **Bot alert did not fire:** Alert for ticket #32339 was not posted during the original billing workflow (carried over from prior session context). Manually posted this session.
+
+## Configuration Changes
+
+- `.claude/commands/syncro.md` — Added dead-end endpoint callouts for comments (top-level `POST /ticket_comments`, plural `/comments` both 404) and line items (`/line_item`, `/line_items`, PUT `line_items_attributes` all 404). Added `\n` vs `
` warning to Comments section and review checklist.
+- `C:\Users\guru\.claude\projects\D--claudetools\memory\feedback_syncro_line_items.md` — New memory: `add_line_item` endpoint, never use timers, test-only rule for ACG internal account.
+- `C:\Users\guru\.claude\projects\D--claudetools\memory\MEMORY.md` — Index entry added for `feedback_syncro_line_items.md`.
+
+## Credentials & Secrets
+
+None new this update. Syncro API key (Mike): `T259810e5c9917386b-52c2aeea7cdb5ff41c6685a73cebbeb3` (in vault, unchanged).
+
+## Infrastructure & Servers
+
+No changes.
+
+## Commands & Outputs
+
+```bash
+# Correct Syncro comment endpoint (singular, nested):
+curl -s -X POST "https://computerguru.syncromsp.com/api/v1/tickets/32339/comment" \
+ -H "Authorization: " -H "Content-Type: application/json" \
+ -d '{"subject":"...","body":"... use
not \n ...","hidden":true,"do_not_email":true}'
+# Response: {"comment": {"id": N, ...}}
+
+# Correct line item endpoint (internal ID, not ticket number):
+curl -s -X POST "https://computerguru.syncromsp.com/api/v1/tickets/111387456/add_line_item" \
+ -H "Authorization: " -H "Content-Type: application/json" \
+ -d '{"product_id":1049360,"name":"Labor- Warranty work","description":"...","quantity":1,"price":0.0,"taxable":false}'
+# Response: FLAT {"id": 42622310, "ticket_id": 111387456, ...}
+```
+
+## Pending / Incomplete Tasks
+
+- **Kristin Steen (KSTEENBB2025):** Needs to close and reopen Excel to confirm SmartBadge tab is present. No follow-up scheduled — Mike to confirm with client.
+- **SPEC-013 / SPEC-014:** Howard received decisions via coord. SPEC-014 needs shape spec before sprint assignment. SPEC-013 status remains P3 deferred.
+- **GuruRMM install script (e239b27):** Deployed in prior session segment — confirm agents on beta channel pulled the update.
+
+## Reference Information
+
+- Syncro ticket #32339 (Birth Biologic / Kristin Steen SmartBadge): https://computerguru.syncromsp.com/tickets/111387456
+- Private tech notes comment ID: 414138634
+- Public customer comment ID: 414139056
+- Warranty labor line item ID: 42622310
+- Coord message (SPEC-013/014 decisions to Howard): e72b2145-b518-4f16-b78e-5ff84f29126c
+- Syncro dead-end paths: `POST /ticket_comments`, `POST /tickets/{id}/comments`, `POST /tickets/{id}/line_item`, `POST /tickets/{id}/line_items`, `PUT /tickets/{id}` with `line_items_attributes`
+- Working paths: `POST /tickets/{number}/comment`, `POST /tickets/{internal_id}/add_line_item`