From 1280f50ff8df4f3a6136df31d6bccb00e3b9f792 Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Fri, 1 May 2026 20:08:27 -0700 Subject: [PATCH] Session log addendum: time-tracking finding + syncro skill rewrite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mike's 4/30 audit (surfaced via /sync) flagged that 31 closed tickets had 00:00:00 in Syncro time tracking — bare add_line_item bypasses time entries and breaks reporting. I had just done the same on today's 3 tickets; Winter retroactively added time entries. Rewrote the syncro skill (commit ec98c6c) to make timer_entry -> charge_timer_entry the default and demote bare add_line_item to a fallback for non-time items only. Disabled the now-redundant scheduled agent (trig_01CAfvwoQ4nLcKEqbU4UQmSa). --- ...cro-billing-batch-and-tmp-path-incident.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/session-logs/2026-05-01-howard-syncro-billing-batch-and-tmp-path-incident.md b/session-logs/2026-05-01-howard-syncro-billing-batch-and-tmp-path-incident.md index 6e33e5b..545c9fd 100644 --- a/session-logs/2026-05-01-howard-syncro-billing-batch-and-tmp-path-incident.md +++ b/session-logs/2026-05-01-howard-syncro-billing-batch-and-tmp-path-incident.md @@ -147,3 +147,53 @@ $ ls -la "/c/Users/Howard/AppData/Local/Temp/comment_payload.json" - Cascades client folder: `clients/cascades-tucson/` - Cascades project state: `clients/cascades-tucson/PROJECT_STATE.md` - New memory: `.claude/memory/feedback_tmp_path_windows.md` + +--- + +## Update: 20:07 PDT — Time-tracking workflow finding + skill rewrite + +After the billing work above, ran `/sync` and pulled in 5 commits from Mike. Mike's 4/30 session log contained a `## Note for Howard` flagging that **all 31 closed tickets he audited had 00:00:00 in Syncro's time-tracking system** — invoices were created with bare `add_line_item` calls and hours were typed into description text. This bypasses Syncro's time-entries table entirely and breaks reporting (hours per client, technician productivity, average resolution time, prepay burn rate). + +The required workflow per Mike: `timer_entry → charge_timer_entry → invoice`. Bare `add_line_item` is only acceptable for non-time items (hardware, flat-fee services with zero labor). Even warranty/free work needs a time entry (`billable: false`); only cancelled tickets are exempt. + +I had just done exactly the wrong thing on three tickets earlier in this session. Winter retroactively added time entries to fix #32225, #32229, and #32214. + +### Actions taken on this finding + +1. **Saved feedback memory** at `.claude/memory/feedback_syncro_timer_first.md` documenting the rule, the rationale, and the two-day repeat-incident timeline (Mike caught 31 tickets 4/30; I repeated on 3 more 5/01). +2. **Saved a separate feedback memory** at `.claude/memory/feedback_syncro_cascades_contact.md` for an unrelated rule Howard surfaced mid-session: never set `contact_id` on Cascades tickets — leaving it blank lets Syncro route to the correct email distribution; setting it (Meredith Kuhn has been the recurring incorrect default) overrides and breaks the distribution. +3. **Delegated a syncro skill rewrite** to the Coding Agent. Result committed as `ec98c6c` and pushed: + - Promoted `timer_entry → charge_timer_entry` to the documented default `/syncro bill` flow (was 13 steps using `add_line_item`; now 16 steps using the timer path). + - Demoted bare `add_line_item` to a clearly-labeled fallback section for non-time items only. Example payload there is now a hardware item, not labor. + - Added two new Hard Rules at the top of the skill: timer-entry-first rule (with warranty exception) and heredoc-payload rule (no `/tmp/*.json` files). + - Replaced every `/tmp/*.json` write+curl pattern with `--data-binary @- <<'JSON' ... JSON` heredocs. Quoting strategy: `<<'JSON'` (literal) for static payloads, `<` arg list to include `warranty` as a labor type. + - Preserved emergency-billing prepaid branching (product 26184 vs 26118 × 1.5), per-user attribution rules, comment-shape warnings, rate tables, endpoint reference tables, and Cascades contact rule references — all untouched. +4. **Disabled scheduled remote agent** `trig_01CAfvwoQ4nLcKEqbU4UQmSa` (was set to fire 2026-05-02 08:00 PDT to do the heredoc-only fix). Its scope was a strict subset of the larger rewrite that just shipped, so leaving it enabled would have been a no-op at best. Updated to `enabled: false` via RemoteTrigger. + +### Files changed in the second half of session + +- `.claude/commands/syncro.md` — major rewrite (timer-first + heredoc throughout) +- `.claude/memory/MEMORY.md` — index entries for the two new memories +- `.claude/memory/feedback_syncro_timer_first.md` (new) +- `.claude/memory/feedback_syncro_cascades_contact.md` (new) + +### Repo state at end of session + +- HEAD: `ec98c6c syncro skill: timer-entry-first workflow + heredoc payloads` +- Local + origin/main in sync +- Three Howard-authored commits today: session log + sync auto-commit + skill rewrite +- Three new feedback memories landed today (tmp-path, Cascades-contact, syncro-timer-first) +- One disabled remote routine (no longer needed) + +### Pattern to apply going forward + +Every Syncro billing operation in future sessions must be: +1. POST `/tickets/{id}/timer_entry` (with `start_at`, `end_at`, `billable`, `product_id`, `notes`) → record time +2. POST `/tickets/{id}/charge_timer_entry` (with `{"timer_entry_id": N}`) → auto-generate line item +3. Verify line item came in with correct `price_retail`; PUT-patch via `update_line_item` if it landed at $0 +4. POST `/invoices` → roll line item onto invoice +5. PUT ticket status to `Invoiced` + +The skill now reflects this. The memory now reinforces it. If a future session reverts to bare `add_line_item` for time-bearing work, it's a regression — call it out and use the timer path.