Files
claudetools/session-logs/2026-06/2026-06-26-howard-june-billing-reconciliation.md
Howard Enos 03ee61f0a6 sync: auto-sync from HOWARD-HOME at 2026-06-26 21:14:15
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-06-26 21:14:15
2026-06-26 21:14:45 -07:00

14 KiB
Raw Blame History

June Billing Reconciliation — Cascades, Rednour + ACG Internal (6-13 to 6-26)

User

  • User: Howard Enos (howard)
  • Machine: Howard-Home
  • Role: tech

Session Summary

Ran a comprehensive Syncro billing reconciliation for Howard's work since June 6, routed entirely through the /syncro skill. Started by indexing every Howard-authored session log since 06-06, filtering out Mike/Winter and internal-only sessions, then worked client-by-client. The headline finding for Cascades was that most of the large June work was already invoiced (voice VLAN + WiFi/RF on #32444 = 7h; Home→Pro round 1 #32466; SSD/UPS hardware tickets; shared mailboxes; Karen ALDOCS; Executive share; Chris Knight). Reconciliation was done against live Syncro (tickets + invoices + line items), not the logs alone, to avoid double-billing — and to catch the inverse: two hardware-only invoices (#32439 Memcare UPS, #32443 Front Desk UPS) that had no install labor.

Billed the genuine Cascades gaps as several small tickets (per Howard's preference for multiple smaller invoices over one large one), all drawn from the prepaid block (which auto-nets $0 and debits hours): UPS install labor on #32439/#32443 (0.5h onsite each); a new Home→Pro round 2 ticket #32474 (2× $99 keys + 1.0h remote = the only real-dollar Cascades invoice, $215.23); a combined EDR-rollout

  • accounting-scan ticket #32475 (1.5h + 1.0h remote); an emergency power-outage recovery ticket #32476 (1.5h emergency onsite → prepaid ×1.5 = 2.25 qty); a Synology→CS-Server migration + SMB diagnosis ticket #32478 (2.0h remote, single combined line dated 06-18); and an Alma Montt offboarding ticket #32479 (0.5h remote). The Cascades block ran 46.75 → 37.50 (9.25h).

Resolved a date/attribution discrepancy on the "power outage" via a raw-transcript dig (sub-agent over ~/.claude/projects/C--claudetools/*.jsonl for 06-16 and 06-19): the 06-16 record was entirely remote (the "I was there" quote was Vertical's VoIP tech, not Howard); 06-19 onsite phone re-keying was already billed in #32444; and the outage was the unplanned 06-16-into-06-17 event (both Howard and Mike onsite for the pfSense recovery). Howard confirmed the outage as one billable item = 1.5h emergency onsite; billed to Howard, comment credits both techs.

For non-Cascades: skipped Lens Auto Brokerage (a transient self-resolving Deskman triage explicitly logged as "not a ticket") and Dataforth (Howard's call). Confirmed Universal Minerals (#32397, $175) and Wolkin (#32465, $225) were already billed. Billed the one open item — Rednour Nick Pafford share setup on #32343 (1.0h onsite, $175 real-dollar; no block), attributed to Howard with ticket owner left as Mike; skipped the 06-26 Mac RMM diagnosis as an internal GuruRMM product bug.

Finally built ACG internal time-tracking ticket #32480 ("Howard - Internal work 6-13-26 to 6-26-26") on the internal account (15353550) — 13 lines of Internal Labor (product 9269124, $0/hr time-tracking), 16.0h total: the three Howard-specified items (radio show 2h, Bitdefender skill 2h, EDR skill 2h) plus a bucket-A split of 10h across the other claudetools/GuruRMM dev work (Security Assessment, GuruRMM fixes, SPEC-030 uninstall, UniFi/pfSense verbs, AMPIPIT, ScreenConnect, GuruScan, Win11 KB, skill-first governance, sync/harness). Period total billed 6-13→6-26: ~31.5h (15.5h client + 16.0h internal).

Key Decisions

  • Reconciled against live Syncro before billing anything — pulled tickets/invoices/line items per customer to establish already-billed vs gaps, rather than billing off session logs (which record work done, not billing state). This caught both double-bill risks and the labor-missing hardware tickets.
  • Hours are the tech's call, not derived from logs — every line's hours came from Howard explicitly; the logs only supplied the work scope and delivery channel.
  • Several small tickets over one big invoice (Howard's stated billing preference) — each Cascades gap got its own ticket/invoice; B (EDR) + C (scan) deliberately combined into one ticket per Howard.
  • Prepaid mechanics: all Cascades labor billed against the block (auto-nets $0, debits by quantity); emergency on a prepaid customer billed on 26184 at qty = actual ×1.5 (2.25 for 1.5h), not a separate regular+emergency line. Keys (product 23571919) are taxable and bill real dollars; block labor on the same invoice nets $0 via "- Applied N Prepay Hours."
  • Attribution: new labor attributed to the API-key owner (Howard, 1750); on Rednour #32343 (owner Mike) the line was set user_id:1750 so Howard gets the commission without changing ticket ownership.
  • Emergency outage billed as one event to Howard (mentions Mike in the comment) per Howard, after the transcript dig showed 06-16 was remote and the real onsite emergency was the 06-16→17 pfSense recovery.
  • Lens skipped — transient updater-lock crash that self-resolved; the log explicitly recorded it as "not a ticket," so nothing to bill.
  • Internal labor is $0 time-tracking (product 9269124 price_retail 0.0) — #32480 records hours for utilization, not revenue; Bitdefender/EDR skill work was billed under the internal ticket, not double- counted in the dev-bucket split.
  • Bucket-A split of the 10 internal items weighted by scope (SPEC-030 + Security Assessment + GuruRMM fixes heaviest), summing to exactly the 10h Howard set.

Problems Encountered

  • #32439/#32443 looked billed but were hardware-only — initial pass checked for any line item; Howard flagged the install labor was missing. Re-validated by line type and billed 0.5h onsite each.
  • "Power outage on the 16th, onsite" did not match the record — session logs had 06-16 as remote planning and the outage recovery as 06-17 (Mike onsite, Howard remote). Resolved with a raw-transcript sub-agent dig that surfaced the true picture; Howard then clarified it was one 06-16→17 event with both techs onsite. Billed per Howard's direct knowledge, flagged the discrepancy before posting.
  • Universal Minerals / Wolkin assumed unbilled — both were already invoiced (#32397 $175, #32465 $225); verified live before proposing anything, so nothing was double-billed.
  • Multiple invoices per ticket on already-Invoiced tickets — confirmed Syncro pulls only uninvoiced lines into a new invoice (matches the existing #32330/#32303 multi-invoice pattern), so adding labor + a new invoice to #32439/#32443/#32343 did not re-bill the prior hardware/remote lines.

Configuration Changes

No repo code/config changes. Syncro records created (all via the /syncro skill, heredoc/jq payloads):

  • #32439 (id 112780453): +0.5h Labor-Onsite (line 43041905), invoice 1650816983 ($0), Resolution comment 420976000.
  • #32443 (id 112827387): +0.5h Labor-Onsite (line 43041908), invoice 1650816984 ($0), comment 420976008.
  • #32474 (NEW, id 113124973) "Windows Home -> Pro edition upgrades (round 2) - NurseAssist + DESKTOP-MD6UQI3": 2× Windows Pro Upgrade ($99 taxable) + 1.0h Labor-Remote (block); invoice 1650816992 ($215.23); status Invoiced.
  • #32475 (NEW, id 113124984) "Datto EDR rollout + Accounting scan-to-folder setup": 1.5h + 1.0h Labor-Remote (block); invoice 1650816999 ($0); Invoiced.
  • #32476 (NEW, id 113124998) "Emergency Onsite - Building power outage / pfSense recovery (06-16 overnight)": 2.25 qty Labor-Emergency (26184, 1.5h ×1.5, block); invoice 1650817007 ($0); priority 4 Urgent; Invoiced.
  • #32478 (NEW, id 113125316) "Synology -> CS-SERVER file migration + SMB diagnosis": 2.0h Labor-Remote (block), single combined line dated 06-18; invoice 1650817187 ($0); Invoiced.
  • #32479 (NEW, id 113125318) "Alma Montt - user offboarding (M365 + AD)": 0.5h Labor-Remote (block); invoice 1650817191 ($0); Invoiced.
  • #32343 (id 111409967, Rednour, owner Mike): +1.0h Labor-Onsite ($175, user_id 1750=Howard), invoice 1650817586 ($175.00), no-block upsell note; comment 420978674.
  • #32480 (NEW, id 113125980, ACG internal 15353550) "Howard - Internal work 6-13-26 to 6-26-26": 13 Internal-Labor lines ($0), 16.0h total; invoice 1650817773 ($0); Invoiced; comment 420981118.

This session log created at session-logs/2026-06/2026-06-26-howard-june-billing-reconciliation.md.

Credentials & Secrets

None discovered, created, or rotated this session. Syncro auth via the per-user Howard API key baked into the /syncro skill (attribution user_id 1750).

Infrastructure & Servers

  • Syncro: base https://computerguru.syncromsp.com/api/v1, query-param auth, Howard key (user_id 1750).
  • Customers: Cascades of Tucson 20149445 (prepaid block 46.75 → 37.50 after this run); Rednour Law 1224246 (prepay 0.0, no block); Arizona Computer Guru internal 15353550 (prepay 0.0); Universal Minerals 34844920; Wolkin/Robert 796910; Len's Auto Brokerage 3289131.
  • Labor products: 26118 Onsite $175; 1190473 Remote $150; 26184 Emergency $262.50 (onsite ×1.5); 23571919 Windows Pro Upgrade $99 taxable; 9269124 Internal Labor $0 (time-tracking).
  • Raw transcripts mined for the 16th/19th: C:\Users\Howard\.claude\projects\C--claudetools\*.jsonl.

Commands & Outputs

  • Per-customer reconciliation: GET /tickets?customer_id=<id>&per_page=100, then GET /tickets/<id> for line-item type/status; GET /invoices?customer_id=<id> to map ticket_id → invoice; control chars stripped with tr -d '\000-\037'.
  • Prepaid rule honored: GET /customers/<id> (full, authoritative) for prepay_hours before every preview — never from the search/list endpoint.
  • Billing sequence per ticket (heredoc/jq, --data-binary): comment → add_line_item(s) → invoices → PUT invoice note → PUT status Invoiced → post-bot-alert; each step guarded (STOP + echo response if any id came back null), no retries on ambiguous results.
  • Emergency prepaid mechanic verified on #32476: Labor - Emergency or After Hours Business qty 2.25, invoice line "- Applied 2.25 Prepay Hours," block 42.25 → 40.00.
  • Internal #32480: 13 lines via a bash array loop (product 9269124, price 0, user_id 1750); invoice hours-sum verified = 16.0.

Pending / Incomplete Tasks

  • Rednour 2-desktop fixes — Howard still needs to fix Nick's two desktops; bill onto #32343 (multi- invoice) or a new ticket when done.
  • GuruRMM macOS enrollment bug — install script writes the site code where /api/enroll wants a UUID (HTTP 422); onsite paste-block delivered to Howard's Discord, fix pending onsite verify; product fix is Mike's (coord todo 6f2d22be). Not client-billable.
  • Deferred per Howard (not billed): Cascades CARF technology plan (06-24), Lupe Sanchez/Trcieja perf diag (06-18), KPI dashboard scoping (06-17); Dataforth 06-23/06-25 sessions; Lens (not-a-ticket).
  • Invoice-date note: #32478 references work date 06-18 in the line/comment; the Syncro invoice itself carries today's creation date (no API backdate).

Reference Information

  • New tickets: #32474, #32475, #32476, #32478, #32479 (Cascades), #32480 (ACG internal).
  • Real-dollar invoices this run: #32474 $215.23, #32343 $175.00 (total $390.23). All other invoices $0 (prepaid block or internal labor).
  • Cascades block: 46.75 → 37.50 (9.25h drawn). Period total billed 6-13→6-26 ≈ 31.5h (15.5 client + 16 internal).
  • Already-billed verified: Cascades #32444 (7h voice/RF, inv 67856), #32466 (inv 67887 $215.23), #32440 (67850), #32439/#32443 hardware (67850/67851/67854), #32417 (67825), #32403 (67811), #32230 (67876), #32193 (67873); Universal Minerals #32397 (inv 67810 $175); Wolkin #32465 (inv 67885 $225).
  • 9 #bot-alerts posted (message_ids in the run output).
  • Syncro skill billing rules applied: .claude/skills/ (syncro); prepaid emergency ×1.5; per-user attribution.

Update: 17:19 PT — session close; 06-01→06-12 hours query abandoned (rate limit)

Attempted to total Howard's billed labor hours across all clients for 2026-06-01 to 2026-06-12. The calc requires fetching each in-range invoice individually (tech attribution user_id lives only on invoice/ticket line items, not the /invoices list endpoint) — 46 ticket-bearing invoices in the window. The bulk per-invoice GET repeatedly failed: Syncro's 180 req/min per-IP limit is shared (Discord bot + other sessions also hit it), so any burst beyond a handful was throttled to empty responses; paced foreground (perl micro-delay) and patient background runs (90s pre-wait + 1.5s pacing + retries) were also starved, returning OK=0/failed=46 even though single and ~5-at-a-time GETs work fine. No billing changes were made — entirely read-only. To finish later: trickle the fetch in bursts of <=6 spaced ~18s apart during a low-contention window (the .trickle.sh logic), summing quantity on line items where item matches /labor/i and user_id==1750, over invoices with date in range. Session closed at user request; no new tickets/invoices created since the prior content above (#32480 internal already captured).

Update: 17:24 PT — .gitignore hardened against root scratch sweep

Root cause of the earlier stray commits (.lab.txt, .invcfg, .fail.txt, .hours_calc.sh): the billing/invoice-calc scratch files were written to the repo root and were not gitignored, so the sync git add -A catch-all committed them. Added a targeted block to .gitignore.*.txt, .*.sh, .invcfg, .inv/, .one.json — which ignores dot-prefixed scratch (legit scripts are scripts/*.sh, not dot-prefixed) without catching tracked root dotfiles (.hosts.json, .devs.json, .mcp.json.example, etc., verified via git check-ignore). Future session scratch in repo root won't be swept into commits.