From bc6dde5b8980fdb3ab32c7b83969ba57a26e8ab4 Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Tue, 30 Jun 2026 11:54:48 -0700 Subject: [PATCH] sync: auto-sync from HOWARD-HOME at 2026-06-30 11:54:16 Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-06-30 11:54:16 --- .../cascades-tucson/docs/printer-gpo-map.md | 2 +- ...-06-30-howard-syncro-category-skill-fix.md | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 session-logs/2026-06/2026-06-30-howard-syncro-category-skill-fix.md diff --git a/clients/cascades-tucson/docs/printer-gpo-map.md b/clients/cascades-tucson/docs/printer-gpo-map.md index 958d31b3..3e6eb877 100644 --- a/clients/cascades-tucson/docs/printer-gpo-map.md +++ b/clients/cascades-tucson/docs/printer-gpo-map.md @@ -33,7 +33,7 @@ prints). Any GPO/share for those Canons MUST use `Canon Generic Plus UFR II V250 | `\\CS-SERVER\Kitchen` | Canon MF743CDW | 192.168.3.232 (pre-migration) | (verify) | (kitchen) | chefs | — | Kitchen printer (with the chefs). Not yet migrated to VLAN20 this round. | ## Machine rename TODO -- **RECEPTIONIST-PC** (the Memory Care box, "memory care" user, S/N MJ0KQH4R, agent 57f19e17) shares its hostname with the front-desk RECEPTIONIST-PC box — too hard to tell apart in the agent list. **Rename to a unique `MEMCARE-*` name** (pending Howard's chosen name + reboot). The OTHER RECEPTIONIST-PC (frontdesk user, S/N MJ0KQHNP) is the actual front desk. +- **RECEPTIONIST-PC** (the Memory Care box, "memory care" user, S/N MJ0KQH4R, agent 57f19e17) shares its hostname with the front-desk RECEPTIONIST-PC box — too hard to tell apart in the agent list. **Rename STAGED 2026-06-30 -> `MEMCARE-STATION`; applies on next reboot** (not forced; user was active). The OTHER RECEPTIONIST-PC (frontdesk user, S/N MJ0KQHNP) is the actual front desk. ## Notes - Workgroup machines (DESKTOP-MD6UQI3, CHEF-PC) get **direct-IP local printers** for now diff --git a/session-logs/2026-06/2026-06-30-howard-syncro-category-skill-fix.md b/session-logs/2026-06/2026-06-30-howard-syncro-category-skill-fix.md new file mode 100644 index 00000000..517c7e12 --- /dev/null +++ b/session-logs/2026-06/2026-06-30-howard-syncro-category-skill-fix.md @@ -0,0 +1,57 @@ +## User +- **User:** Howard Enos (howard) +- **Machine:** Howard-Home +- **Role:** tech + +## Session Summary + +Howard flagged a Syncro billing defect on his invoice list (invoice 1650806091 view): "Windows Pro Upgrade" line items on Cascades of Tucson tickets #32466 and #32474 (invoices 67887 and 67890) went out with a blank CATEGORY column, while labor lines correctly showed "Labor". The directive was explicit — do NOT fix the ticket (Winter already corrected the records); fix the skill so I stop making this mistake, since categories are a fixed set in Syncro and must not be invented or left blank. + +Investigated the root cause read-only via the Syncro REST API. Located the product "Windows Pro Upgrade" (id 23571919) and confirmed both `category` and `product_category` are `null` on the product itself — that null propagates to every line item billed from it, producing the blank CATEGORY column. Confirmed `product_category` is the operative field (the field that shows "Labor" on labor products like 1190473). Enumerated the controlled vocabulary by paging all ~960 products: real categories in the tenant are Labor, Default, Subscriptions, Product, Service/Services, Other, Contract, Discount, Exempt Labor, Prepay Hours, Deposit, Hardware (plus Software per Howard's set selections). The `/product_categories` API endpoint returned empty, so the live set must be derived by enumerating distinct `product_category` across `GET /products`. + +Fixed the skill rules only (no ticket/product writes). Added a controlled-vocabulary rule and a pre-flight check to `.claude/commands/syncro.md`, created a `feedback` memory with an index line, and logged the correction to `errorlog.md`. The net behavioral change: before invoicing, the `/syncro` flow must `GET /products/`, verify `product_category` is a real non-null value, halt on a blank one, and never substitute an invented category. + +## Key Decisions + +- Fixed the skill at two layers: the bolded rules block (next to the `taxable` rule) AND the `add_line_item` required-fields procedure, so the check sits in the workflow, not just the header. +- Did not hardcode the category list as authoritative — instructed the skill to enumerate the live set from `GET /products` (it changes), with known-good values listed only as a reference and "ASK if none fits." +- Targeted the line-item/invoicing path (where I act) rather than product creation — the skill does not create products, and the product-level fix is Winter's record correction. +- Wrote a `feedback`-type memory (shapes future behavior fleet-wide) in addition to the errorlog correction (pattern-linting), per the complementary-logging rule. + +## Problems Encountered + +- `/product_categories` API endpoint returned empty — resolved by enumerating distinct `product_category` across all paged `GET /products` to recover the controlled vocabulary. +- Product exposes several category-ish fields (`category`, `product_category`, `category_id`, `category_path`) — confirmed `product_category`/`category_path` are the populated ones (both "Labor" on a labor product) and `product_category` is the canonical field to check. + +## Configuration Changes + +- Modified: `.claude/commands/syncro.md` — added controlled-vocabulary + no-blank-category rule (after the taxable rule); added category pre-flight to the `add_line_item` required-fields list. +- Created: `.claude/memory/feedback_syncro_line_item_category.md` — feedback memory for the rule. +- Modified: `.claude/memory/MEMORY.md` — added index line for the new memory. +- Modified: `errorlog.md` — logged the correction (--correction). + +## Credentials & Secrets + +None created or discovered. Used the per-user Syncro API key already baked into `.claude/commands/syncro.md` (howard token) for read-only GETs. + +## Infrastructure & Servers + +- Syncro PSA: `https://computerguru.syncromsp.com/api/v1` — query-param auth (`?api_key=`). + +## Commands & Outputs + +- `GET /products?query=Windows%20Pro%20Upgrade` → product id 23571919, `product_category: null`, `price_retail: 99.0`, `taxable: true`. +- `GET /products/1190473` (Labor - Remote Business) → `product_category: "Labor"` (confirms the field that renders the CATEGORY column). +- Paged enumeration of all products → distinct `product_category`: Labor, Default, Subscriptions, Product, Service(s), Other, Contract, Discount, Exempt Labor, Prepay Hours, Deposit, Hardware (+ Software per Syncro admin set). +- `bash .claude/scripts/log-skill-error.sh "/syncro" "..." --correction` → `[OK] logged skill error to errorlog.md`. + +## Pending / Incomplete Tasks + +- None for the skill fix. (Ticket/product record correction is Winter's, already done — invoices 67887/67890, product 23571919.) +- Optional future: the product 23571919 `product_category` should be set to "Software" at the product level so future bills inherit it — outside this session's scope (Winter handling records). + +## Reference Information + +- Tickets: Cascades of Tucson #32466, #32474. Invoices: 67887, 67890. Invoice list view: invoice 1650806091. +- Product: "Windows Pro Upgrade" id 23571919. +- Files: `.claude/commands/syncro.md`, `.claude/memory/feedback_syncro_line_item_category.md`, `.claude/memory/MEMORY.md`, `errorlog.md`.