toga-ai 1.0.729 → 1.0.730

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@ client: compass-usa
6
6
  type: workflow
7
7
  status: active
8
8
  updated: 2026-09-01
9
- owners: ["jcardinal"]
9
+ owners: ["jcardinal", "bala"]
10
10
  files:
11
11
  - test/team/2.0 deployment/duplicate_items_merge_ALL_CLIENTS.sql
12
12
  - test/team/2.0 deployment/duplicate_items_merge_analysis.sql
@@ -59,6 +59,15 @@ NULL-catalog junk items** and **199 duplicate-Agilant items** (from the NetSuite
59
59
  inventory-adjustment item-create bug). **Only the 199 catalog-1 → catalog-2 folds were the
60
60
  damage.**
61
61
 
62
+ **⚠ Open contradiction — not resolved, do not assume either side.** Folding by
63
+ `UPPER(partNumber)` requires those 199 pairs to have **shared a part number across catalogs**
64
+ pre-merge, and the reversal restored them. But a prod check of `Client_Compass` on **2026-09-01**
65
+ found **zero part numbers duplicated at all, and zero spanning more than one catalog**. Both
66
+ statements cannot be true of prod today. Re-check on prod whether the restored catalog-1 twins
67
+ carry **distinct** part-number variants (the `#B1H` / `-S` forms) or genuinely-shared ones before
68
+ relying on either the 199 figure or table-wide `partNumber` uniqueness. Same flag from the other
69
+ side: [two-catalog item model](../features/item-catalogs-and-duplicate-items.md).
70
+
62
71
  ## The reversal playbook (durable)
63
72
 
64
73
  1. **Restore a pre-merge snapshot as a scratch DB** — e.g. `Client_Compass_20260831_120000`
@@ -127,6 +136,10 @@ catalog-1 items were folded into catalog-2 **AND** storefront/transmit depends o
127
136
  NULL-`assetType` order lines alone are **not** damage (Prudential and Quad show that as normal).
128
137
 
129
138
  ## Change history
139
+ - 2026-09-01 — Flagged (did **not** resolve) the contradiction between this doc's 199
140
+ shared-`UPPER(partNumber)` catalog-1→catalog-2 folds and the same-day prod verification that zero
141
+ Compass part numbers span two catalogs; mirrored from the item-catalogs doc so it is visible from
142
+ both sides. (bala)
130
143
  - 2026-09-01 — **Blast-radius assessment complete.** Resolved the outstanding per-client
131
144
  assessment: only **2 of 17** clients were damaged — Compass (reversed prior session) and Quad
132
145
  (storefront-only, reversed this session). The other 15 needed no reversal: 13 single-catalog
@@ -160,7 +160,8 @@ Cron 3a resolves each line through that SKU when the `VA` text does not match th
160
160
  **onto the ODP SalesOrder (customerId=1), never the Compass SO (customerId=2)**.
161
161
  **Exclusion filters** (an order legitimately waiting is not a bug):
162
162
  - `CompassSalesOrders.number NOT LIKE 'MA%'` — MA orders are excluded.
163
- - the two-part **release gate** below (this is the "30-minute delay").
163
+ - the two-part **release gate** below (usually releases on the **next 10-minute run**; the
164
+ 30-minute timeout is the fallback, not the normal path).
164
165
  - **computer-kit orders** (Bundles 187–196) wait for a **2nd PO** before syncing. This one is
165
166
  **not** in the `WHERE` clause — it is a per-row check run in PHP *after* the query
166
167
  (`Bundles.number IN (192, 187, 188, 195, 193, 189, 194, 190, 191, 196)`, then a count of that
@@ -182,6 +183,19 @@ holds (verified against the cron source 2026-08-28, the `WHERE` block around `:9
182
183
  created at least **30 minutes** ago (`IFNULL(MIN(OfficeDepotPO.dtCreated), NOW()) <=
183
184
  DATE_SUB(NOW(), INTERVAL 30 MINUTE)`), in which case it transmits with whatever has come back.
184
185
 
186
+ **⚠ Branch (a) is the normal path — do NOT expect a 30-minute wait.** (a) is satisfied the instant
187
+ every expected Office Depot PO has arrived, so a straightforward order transmits on the **very next
188
+ `*/10` run**, typically **within ~2 minutes** of the ODP PO being created. The 30-minute timeout is
189
+ the **exception**, reserved for orders where something never comes back (see the mixed buy-from-ODP
190
+ case below). Verified on prod (2026-09-01): ODP POs created 14:50-14:55 on 2026-08-31 transmitted at
191
+ 14:57-14:58; ODP PO `41850937-5125` created `2026-09-01 13:18:20` transmitted at `13:20:46`
192
+ (NetSuite SO `7441681`).
193
+
194
+ **Why this matters when triaging:** if you assume half an hour is normal, a genuinely stalled
195
+ transmission looks fine for 30 minutes. It is not. An order that has all its 850s back and is still
196
+ untransmitted **two `*/10` runs later** is already abnormal — go look at the bridge rows
197
+ (`PurchaseOrders_SalesOrders` / `SalesOrders_PurchaseOrders`) rather than waiting.
198
+
185
199
  **Cron 5 never opens an EDI file and never looks in S3.** It infers that the 850 arrived purely from
186
200
  the **link rows cron 3a writes**: Compass PO → `PurchaseOrders_SalesOrders` → Office Depot SO →
187
201
  `SalesOrders_PurchaseOrders` → Office Depot PO. If 3a did not write the bridges, cron 5 cannot tell
@@ -210,10 +224,12 @@ order never reached NetSuite," and it is not.
210
224
  `7437998` / `7437898` / `7438098`. Only after that check is "it never reached NetSuite" a real
211
225
  finding.
212
226
 
213
- **⚠ Do not infer the schedule from transmission times.** Transmissions cluster at **:00 and :30**,
214
- which reads like a 30-minute cron — it is not. The schedule is **`*/10`** (re-verified in
215
- `worker/schedules/cron.worker.sync.json` on 2026-08-28); the clustering is the 30-minute **release
216
- gate** above, not the cadence.
227
+ **⚠ Do not infer the schedule from transmission times.** Some transmissions cluster at **:00 and
228
+ :30**, which reads like a 30-minute cron — it is not. The schedule is **`*/10`** (re-verified in
229
+ `worker/schedules/cron.worker.sync.json` on 2026-08-28); that clustering is the timeout branch of
230
+ the **release gate** above firing on the orders that can only release that way, not the cadence.
231
+ Orders released by branch (a) do **not** cluster — they land on whichever `*/10` run follows their
232
+ last 850 (e.g. `13:20:46`).
217
233
 
218
234
  ### ⚠ Office Depot only sends an 850 back for what they buy FROM us
219
235
 
@@ -356,6 +372,11 @@ wrong record makes every order look "stuck." Use the **join**, never a number ma
356
372
  transmission feature.)
357
373
 
358
374
  ## Change history
375
+ - 2026-09-01 — **Corrected the expected cron 5 timing:** release branch (a) ("every expected ODP
376
+ PO has arrived") is the **normal** path and fires on the next `*/10` run (~2 min), so the
377
+ 30-minute timeout is the exception, not the rule — previously this doc read as if 30 minutes were
378
+ the standard delay. Prod evidence: 2026-08-31 POs created 14:50-14:55 transmitted 14:57-14:58; ODP
379
+ PO `41850937-5125` created 13:18:20 transmitted 13:20:46 (NetSuite SO `7441681`). (bala)
359
380
  - 2026-09-01 — Added the diagnostic that the **Office Depot PO number lands in NetSuite's
360
381
  `otherRefNum`, which global search does not index** — searching it finds nothing even on an order
361
382
  that transmitted fine, so open the SO by `c_netsuiteInternalSalesOrderId` off the ODP SO
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.729",
3
+ "version": "1.0.730",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",