Known defects
Every defect recorded against every entry, in one list, generated from the entries on each build. Nothing here is written by hand, so it cannot say something an entry does not.
What counts as a defect here
A defect is a mistake: the automation does something other than what the business decided it should. A limitation is a decision: known scope that was chosen, and it deliberately stays on the entry rather than appearing here. Keeping them apart is what stops agreed scope being re-reported as a bug every few months.
A defect is recorded whether or not anyone intends to fix it. "Not worth fixing" is a decision about a defect, not a reason to leave it unwritten.
How to read this
Open first. Open and blocked defects are work; resolved ones are history, and the page would bury the former under the latter if it sorted them together. Closed defects are kept because the resolution is the record of why an entry now says what it says.
Refs are permanent. A defect id is as immutable as a rule id — it lands in Asana tickets and in
conversation, and renaming one breaks every reference to it. Each entry owns a prefix
(LT2-, SA-, CT- …), and its defects are numbered inside that. See
CONVENTIONS.md §13.
The Rule column is mostly blank, and that is the honest answer. Almost no defect in the registry records which rule it breaks. Nobody wrote it down, and it is not inferred here — a guessed link between a defect and a rule is worse than a blank one, because nobody re-checks the ones that look finished. Filling that column in is the single most useful thing that could be done to this page: it is what turns "what is broken?" into "what is broken about the promise we make to customers?".
58 defects open across 8 entries · 19 closed. 52 of the open ones name no rule they break — that link is not recorded anywhere yet, and is not inferred here.
Open
Courier Tracking Status Update 6
Open the entry · draft
| Ref | Status | Defect | Rule |
|---|---|---|---|
CT-1 |
BlockedOpen — blocked on Couriers Please | Couriers Please tracking is blocked. Their API has returned 403 "API access is only permitted from the frontend application" for every request since 2026-08-25. The response is identical with any User-Agent, Referer or Origin, so it is an access-control decision rather than bot detection, and their public page is a client-rendered app carrying no tracking data. The driver fails fast — one request per run, not one per consignment — and every Couriers Please row keeps its existing NetSuite status. The supported fix is an API credential via the CP account manager; an aggregator is the fallback. Their frontend's authentication must not be imitated. |
needs confirming |
CT-2 |
OpenOpen — reporting only, no data impact | The "recognised status" list covers eleven of the twenty. The check for "NetSuite already holds something sensible" tests against eleven labels. Nine real statuses are absent — among them Delivery attempt failed, Returned to seller, In Depot delay and the three Life Interiors depot statuses — so a row sitting on one of those, whose carrier cannot be read, is reported as [NO-DATA]/[NO-MAP] rather than [PRESERVE] and is not counted in the preserved total. Two of the eleven — In transit and Picked up — are not values on the NetSuite list at all (the list has In transit to courier depot and Received by courier), so they can never match. No data is lost either way: nothing is written in both paths. The damage is diagnostic — preserve counts understate, and genuinely stuck rows hide among the no-data traffic |
needs confirming |
CT-3 |
OpenOpen | AusPost has no per-run health check. Its check consignment is unset, so the run reports [CANARY-SKIP] for AusPost every time. AusPost is the highest-volume carrier and the only one behind a paid API, and a change in its response shape would not be caught by the mechanism built to catch exactly that. Needs a known long-delivered AusPost consignment recorded against the driver |
needs confirming |
CT-4 |
OpenOpen — unconfirmed, needs the deployed TZ |
Time zones are unproven. Carrier times arrive in two families: absolute (AusPost, Air Road) and bare wall-clock (the rest). Bare times are read as the runtime's local time and every timestamp is formatted in it. If the Lambda runs on UTC, absolute events land ten hours behind their AEST wall-clock reading, which would make AusPost and Air Road rows look older than NetSuite's note and preserve them spuriously (LI-BL-FUL-023), and could write an actual delivery date a day early for an evening delivery. This has not been reproduced — the Lambda's TZ setting is not in version control, so whether it is UTC or Australia/Sydney cannot be established from the repository. Confirm the setting before treating this as live |
needs confirming |
CT-5 |
BlockedOpen — blocked behind CT-1 |
The Couriers Please health check expects a failure state. Its consignment is recorded as expecting Exception, described in the code as "current state — update when you have a delivered CN". A check pinned to a state that can still change cannot distinguish our fault from the freight's — which is the one thing these checks exist to do |
needs confirming |
CT-6 |
OpenOpen — documentation only | The repository README is behind the code. It documents six carriers; seven are registered, Aramex/Fastway having been added without a README change. Anyone sizing the work from the README alone will under-count the carriers | needs confirming |
Delay Comms — Stage 2: the delay call request 6
Open the entry · draft
| Ref | Status | Defect | Rule |
|---|---|---|---|
DN-D1 |
Open | A failed line-item write is counted as a success. The NetSuite RESTlet catches its own errors and returns the error object as a normal HTTP 200 response, and the Lambda treats any 200 with a body as "updated". So when the write fails, Delay Comms is never set to 2, nothing says so, the success email reports the line items as updated, and the order stays in whatever state the feed search selects on. Verified by reading NetSuite Scripts/delayCommsLineItemUpdates.js:169-176 against controllers/netsuite.mjs:177-186. Not yet reproduced against production, so the frequency is unknown. |
LI-BL-CMS-008 |
DN-D2 |
Open | The note's first line renders a literal backslash before each bracket — it reads "for the following delayed item(s):" to the agent. The escaping is written into the note body at controllers/kustomer.mjs:84 and Kustomer stores and displays it as typed. Verified in production: the stored body of note 6ab3480762417a735f6cce06 on conversation 6ab348065093dee73eed3090 (order S317808, 2026-09-23) carries the backslashes. Cosmetic, but it is the first line of every delay call request an agent reads. |
LI-BL-CMS-006 |
DN-D3 |
Open | The line items are stamped even when the audit note failed. Every earlier step aborts the order on failure, but the audit-log step does not — controllers/kustomer.mjs:256-270 records the failure and falls straight through to the line-item write. The result is an order marked as called, with the customer-facing message switched to "Delayed", and no user note on the sales order saying who raised it or when. The sales order itself then looks as though the call was never requested. |
LI-BL-CMS-009 |
DN-D4 |
Open | One unreadable row drops the entire day's batch. The row formatter throws when a row is missing a field it indexes into, and the caller catches that and returns an empty list (controllers/formatter.mjs:33-37 and 140-144), so every other order in the run is discarded too. An error email is sent, so this is visible rather than silent — but nobody is called that day, and the email does not say how many orders were dropped. |
LI-BL-CMS-005 |
DN-D5 |
Open | A failed customer read silently routes a trade customer to the wrong team. Team routing reads the customer back from Kustomer, and when that read fails the code carries on with no customer rather than stopping — controllers/kustomer.mjs:201-202 with 39-55. Every fallback path, including a missing customer, returns Account Management, so a trade order lands with the retail team and looks correctly assigned. |
LI-BL-CMS-007 |
DN-D6 |
Open | Nothing in the automation checks whether a request already exists, so re-running it repeats the request. Verified in production: on 2026-06-11 orders S309007 and S310078 each received four Stage 2 conversations between 06:35 and 07:02 UTC, and S300636 received three, all outside the normal daily window. The only guard is the Delay Comms write in NetSuite, which does not help a run that starts before the previous one's write is visible to the feed. Whether that day was deliberate testing or a production incident is DN-Q7. | LI-BL-CMS-008 |
Lead Time flow 2 — Inventory item lead time, and the Shopify push 14
Open the entry · active
| Ref | Status | Defect | Rule |
|---|---|---|---|
LT2-D10Customer sees a date that never arrives; daily churn. **Resolved by the `LT2-D17` fix** — removing the uplift removes the only place a date is recalculated from today |
Open | A promise that recedes by a day, every day. Spare bonded stock on hand has no transfer order yet, so its arrival is estimated as today plus the transit allowance. Recomputed on every run, that date moves forward a day each day and the arrival never gets closer. Because the date is embedded in the customer-facing message, the message changes daily, which marks the item as changed and re-pushes it to Shopify every day | needs confirming |
LT2-D11A known-bad state is computed and never surfaced |
Open | Nothing reports an item oversold beyond bonded. The netting calculates exactly how much demand is still uncovered after all bonded stock is applied, labels it a diagnostic, and then discards it. That figure is the clearest signal available that something is oversold, and it is thrown away every run | needs confirming |
LT2-D7Whole-run outage **if a column is dropped**. No live exposure today |
Open | An item with no supply type stops the flow — but only if the column is absent, not if it is blank. Supply type is read and upper-cased without a null check, unlike brand, which is guarded. Corrected 2026-09-23 by the logic replay. A blank list field comes back from the saved search as an empty string, not null, and "".toUpperCase() is perfectly safe. Across all 19,225 rows replayed, 193 carry a blank supply type — 180 in Item Simple, 13 in Local — and every one processed without error — they still get a real lead time, not the contact-showroom fallback — supply type only gates the Made To Order and End Of Line rungs, so the in-stock, on-order and out-of-stock rungs are unaffected by it. Across the 193: 106 compute "14 - 16 weeks", 37 "10 - 12 weeks", 30 "2 - 3 business days", 15 "1 - 2 weeks" and 5 "12 - 14 weeks". A missing supply type is a data-hygiene problem, not a lead-time one. So this is latent, not live: it fires only if supplyType arrives as null or undefined, which means the column being dropped from a saved search, the same event the flow-1 column guard exists to catch. It should still be guarded — a one-line change removing a whole-run outage — but it is not currently at risk, and it is not the reason to treat blank supply types as urgent. An earlier review of this chain stated that 301 Shopify-active items with no supply type each put the run at risk. That was wrong, and this is the correction. |
needs confirming |
LT2-D12Wrong voice and wrong owner on tied dates |
Open | On identical dates the supplier wins, and it should be us. The comparison tests "within a week of each other" with a strictly-positive difference, so two dates falling on exactly the same day fall through to the final branch, which picks the supplier's. The confirmed rule is that ours wins on a tie. The wording the customer reads can therefore name the supplier's warehouse on a date we could have served ourselves | needs confirming |
LT2-D13Two customer-facing numbers that contradict each other |
Open | The dispatch band and the arrival sentence can be measured from different days. The band is always counted from our date; the sentence quotes whichever date the comparison picked. On a product where the supplier's date won, the two disagree, and nothing reconciles them | needs confirming |
LT2-D14Off-by-one dates near the day boundary, on customer-facing wording |
Open | Date arithmetic runs on the server's clock, not Sydney's. Four decisions read new Date() directly: clearing a date more than a fortnight past, counting the weeks to an arrival, the McMullin seventy-day test, and the bonded-on-hand estimate of today plus thirty-five. Celigo's server runs on UTC, so from 10am UTC each day it is already tomorrow in Sydney and each of those can land a day out. The flow's schedule is set to Australia/Sydney, which makes this easy to miss. Flow 1 does it correctly — it converts to the Sydney date explicitly |
needs confirming |
LT2-D15**Largest defect in the chain. 1,374 items wrong, 13 stale** **Two things are needed, not one.** Fixing the change detection only populates an item on its *next* change, so an item that is stable never gets a first write at all — `ST-COO-SCOT-OAK` holds a 24/11/2026 arrival in NetSuite, carries the matching sentence in Shopify written on 3 August, and has never had the four arrival metafields written because it has not changed since they were added on 21 September. A **one-time backfill** is therefore required alongside the fix; the project owner confirmed on 2026-09-23 that this will be run manually. |
Open | Four of the nine Shopify values have no change detection, and it is the largest defect in this chain. The two arrival dates and two arrival quantities are not in the eight-condition comparison and have no read-back column, so a product whose only change is one of those is never marked as changed and Shopify is never called. Measured against a NetSuite-to-Shopify audit on 2026-09-22: of 1,489 items carrying arrival data in NetSuite, 115 carry it in Shopify — 7.7%. 1,374 items hold values that have never reached the storefront. A further 13 items hold a stale quantity, and in all 13 Shopify is higher than NetSuite, never lower — stock was sold, NetSuite decremented, Shopify did not follow. Those 13 also prove the mutation itself works: the value reached Shopify once, so LT2-D16 is not silently failing the whole payload. LT-015, which says sales read the two arrivals in Shopify, is therefore true for 7.7% of the items it applies to. Confirmed 2026-09-23: the fix stays inside this flow and the Kits flow — no new Shopify import is being added — so the change detection has to gain a way to tell that a pass-through value has moved. |
needs confirming |
LT2-D16Storefront advertises arrivals that no longer exist; two fields rejected on every run for two of the four categories |
Open | Neither arrival value can express “blank”, in opposite directions. The two arrival quantities are sent unconditionally, so an item with no arrival pushes an empty string into a number_integer metafield. The two arrival dates are wrapped in a presence test, so a blank is omitted rather than cleared — and Shopify keeps whatever it last held. Live example on 2026-09-22: BE-BEB-MARL-OAK-V3 shows a 2nd PO of 70 units arriving 3 November on the storefront, which NetSuite cleared. Against the confirmed rule that the two systems must match, the fix is a blank quantity written as 0 and a blank date deleted (metafieldsDelete), since a date metafield cannot hold an empty value and the type is staying as date. Narrowed twice: originally raised as “three searches are missing columns” — two omit them by design and the third was given them on 2026-09-21. The worst case, Shopify rejecting the whole mutation, is ruled out by the 13 stale values under LT2-D15, and independently confirmed on 2026-09-23 — a Rugs variant that is sent an empty arrival quantity on every run still had its warehouse quantity written on 14 September, so Shopify rejects the one bad field and saves the rest. Confirmed by the project owner, 2026-09-23: the Local and Rugs searches omit the arrival columns on purpose, because those categories are not normally bought on a purchase order. The Item Simple search does carry all three — an earlier reading of this entry said it did not, which came from Celigo's cached sample rather than the live search. So the asymmetry below is not a missing-column problem, it is a guard problem: the two arrival dates are wrapped in a presence test and the two arrival quantities are not, in the same payload. For Local and Rugs items the two quantities are therefore posted as an empty value into an integer field on every run, six times a day, and rejected every time — invisibly, because of LT2-D18. Only one direction fixes it: wrap the two quantities in the same presence test the dates already have. Removing the test from the dates instead would post an empty value into a date metafield, which Shopify refuses outright. Wrapping the quantities is also consistent with the confirmed rule that blank and zero both publish as nothing.* |
needs confirming |
LT2-D17Storefront and NetSuite disagree; the message churns daily |
Open | The thirty-five day uplift in this flow is legacy, and now only ever overrides a better answer. The confirmed rule is that the customer-facing sentences and the dispatch band read the first arrival written by flow 1. This flow instead takes the earlier of that date and its own bonded-on-hand estimate of today plus thirty-five days. That uplift predates the first-arrival field — it was how bonded transit got accounted for before flow 1 existed to do it, and flow 1's date now already includes the uplift. Applying it again here is the old workaround outliving its purpose. Measured on 2026-09-23: one item holds bonded stock available in Vietnam, and it already carries a first arrival date; no item has bonded stock on hand without one. So the path can only ever override a date flow 1 calculated correctly — it can never fill a gap. Correction, 2026-09-23: an earlier version of this entry cited 332634 Palermo Fabric Dining Chair as holding 27/10 in NetSuite while the message quoted 26/10. That came from replaying the flow's stored sample data through the script, not from production. Checked live the same day, the item holds 27/10 in NetSuite and the storefront message reads “New stock arrives in our warehouse from 27/10/2026 - 03/11/2026” — they agree, because the item has no spare bonded stock on hand right now. The defect is the code path, which is reachable and wrong whenever spare bonded stock exists; it is currently dormant, consistent with only one item holding bonded availability. No verified live example exists today. Fix: remove the uplift from this flow and pass the first arrival through untouched. That also resolves LT2-D10, since nothing here recalculates a date from today any more. |
needs confirming |
LT2-D18**Every Shopify defect in this chain is invisible by construction.** Fix this first or you cannot measure the rest |
Open | A rejected Shopify write is recorded as a success, so no failure in this chain can ever surface. Both Shopify imports post a GraphQL mutation. Shopify answers a rejected metafield with HTTP 200 and the reason inside the body, under userErrors. Neither import is configured to read the response, so Celigo sees 200 and counts a success. Proven 2026-09-23: the run at 02:50 recorded Update Shopify Variant Metafields — 365 successes, 0 errors — while RG-TRC-ADOR-GRAP-200-290, one of those records, demonstrably has no po1_qty_on_order_available metafield in Shopify. The write was rejected and reported as fine. This is why LT2-D15 went unnoticed for months, and it is why "zero errors" on the Celigo dashboard means nothing for this chain. It also blocks verification of every other fix here: until the response is read, nobody can tell whether a change worked |
needs confirming |
LT2-D1920 live products permanently diverged. Two fixes, and they are different: a **default branch that logs** stops it being silent; **fixing the 20 items' Shopify ids** stops it happening |
Open | An item with no Shopify id is discarded silently, and 20 live products lose every update. The Products or Variants router sends a record down the variant branch or the product branch and has no default branch, so anything matching neither is dropped with no error and no log. This is the same shape as LT2-D2, which was closed in August by adding the missing column; the mechanism was never fixed, only that one trigger for it. Measured 2026-09-23 by replaying the router's own filters over a live run of the Item Simple and Rugs searches: 366 of 833 Item Simple records and 9 of 2,159 Rugs records match neither branch. Of the 366: 237 are not on Shopify at all and are correctly skipped, 6 are archived, 3 are draft, and 20 are live and active on Shopify with no Shopify id recorded in NetSuite. Those 20 have their NetSuite fields updated on every run and their storefront never. Across all four searches in that run, NetSuite updated 913 items and Shopify received 693 — a gap of 220 |
needs confirming |
LT2-D20Whole-run outage in principle. **Unreachable by construction since 2026-09-23** |
Open | A missing sentence crashes the whole run, for one brand only. After the ladder, Ellison Studios items have their three sentences rewritten to say "our warehouse" instead of "our partners warehouse". The rewrite calls a text replacement on all three without checking any of them is set — unlike the brand test immediately above it, which is guarded. If a sentence is unset the replacement throws, and a throw stops the entire page, so one product blocks the promise for every product behind it. Same failure shape as LT2-D7. Dormant today, because LT2-D21 keeps the final rung firing and so a sentence is always set. Corrected 2026-09-23 by the full replay — it stays dormant even after LT2-D21 is fixed. An earlier review of this chain put 174 Ellison products at risk, reasoning from NetSuite's item and vendor tables that items with no preferred vendor would have blank supplier lead times. The saved searches do not join the vendor that way. Of 523 Ellison rows across the four searches, the 183 with no stock anywhere all arrive carrying the Ellison vendor's lead times — inStock=".5", oos="12", mto1="19" — so a rung always fires and a sentence always exists. Replaying with the guards corrected produced 0 Ellison fall-throughs and 0 exceptions. The defect is real and the guard is still missing, but its live population is zero, before and after. Methodological note, and this is the second time it has bitten: never infer what a Celigo script receives from NetSuite's own tables — read what the saved search actually returns. Superseded 2026-09-23 by the LT2-D6 fix. The final fallback runs immediately before this rewrite and guarantees all three sentences are set, so the rewrite can no longer meet an unset value by construction — not merely because no item happens to reach it. The missing guard is now a tidy-up rather than a risk. |
needs confirming |
LT2-D21The documented ladder and the running ladder are not the same ladder. **Safe to fix since the catch-all shipped** |
Open | Three of the four ladder guards do nothing, because NetSuite sends text and the guard compares a number. The guards on Made To Order 1, Made To Order 2 and Out Of Stock each test !== 0 against the number zero. Every value arrives from the saved searches as text — confirmed 2026-09-23 from live runs of two of the four searches, where lead times come through as "0", ".5", ".7" and blanks as "". "0" is not equal to 0, so all three guards always pass. The In-Stock guard is written correctly and converts before comparing; the other three were not. Consequences, and they cut both ways. The final rung has become an unintended catch-all, which is the only reason LT2-D6 and LT2-D20 are dormant. But a rung fires with a zero lead time, and assignShipsIn("0") matches no band and falls through to "Please contact showroom for lead time" — so the item gets the fallback wording by accident rather than by rule. Fixing this in isolation breaks the run (LT2-D20) Fixed and deployed 2026-09-23, 06:24 UTC — not yet exercised by a run. Each of the three guards now converts before comparing, matching the In-Stock guard on P4 which was always written correctly. Replayed against the currently deployed script over all 19,225 rows: 0 rows differ, 0 exceptions, the flagged-for-update count unchanged at 61, and no item left without a promise. A third diagnostic run — tight guards with the LT2-D6 fallback disabled — leaves 563 rows with no promise at all, which is the measure of what the fallback is now carrying and why the order of the two changes mattered. The ladder that runs is now the ladder this entry documents, and P9 is no longer an accidental catch-all. Deployed one minute after the pass that ended 06:23:05 completed, so the first run to exercise it is the next scheduled pass — the check to make then is simply that errors stay at zero and the written count stays in its normal range, because a correct deploy changes nothing visible. |
needs confirming |
LT2-D22A confirmed business rule silently stopped applying. **Fixed 2026-09-23**; zero flag changes today, 115 rows now actually evaluated |
Open | The McMullin backorder rule has never fired, because the brand was renamed and the script was not. The rule: a McMullin product whose supplier arrival is more than 70 days out must not be orderable out of stock. The script tests brand === 'mcmullin & co.'. The value in NetSuite's brand list is McMullin (id 146, customlist 83) — confirmed 2026-09-23 by reading the list and by finding McMullin in live export rows. Lower-cased, that is mcmullin, which never equals mcmullin & co., so the branch is unreachable and the 70-day test is dead code. Almost certainly a brand rename that nothing followed up. Dormant today: 105 McMullin products are live on Shopify and none currently has a supplier arrival beyond 70 days, so no product is wrongly orderable right now. It becomes live the moment McMullin quotes a long lead time. Confirmed still wanted by the project owner on 2026-09-23, and fixed. The comparison now matches on the leading word — brand.indexOf('mcmullin') === 0 — rather than an exact string, so it survives the next rename as well. McMullin is the only entry in customlist 83 containing the word, so a prefix match cannot catch anything else, and brand is already null-guarded and lower-cased at that point. Verified against the deployed script over all 19,225 rows: 0 rows differ, 0 exceptions, and the backorder flag flips on none of the 115 McMullin rows — the rule now genuinely runs on all of them and denies none, because no McMullin product currently has a supplier arrival beyond 70 days. It will deny the first one that does, which is the whole point. |
needs confirming |
Lead Time flow 3 — Kit item lead time, rolled up from members 7
Open the entry · active
| Ref | Status | Defect | Rule |
|---|---|---|---|
LT3-D8Most multi-component kits are still rewritten and re-pushed on every run — six times a day since the chain was added, not twice — so the import filter still filters very little |
Open | Change detection still fires on most kits, for a second reason. Raised 2026-08-28, on reading the deployed script. Six of the fifteen comparisons — warehouse on-hand, warehouse on-order, and the four showroom quantities — test each component's own figure against the kit's rolled-up figure, rather than against the value stored on the kit. Any kit whose components hold uneven stock therefore never matches, and qualifies as changed on every run. In the mixed quantity case (LI-BL-INV-010 case 2) the kit figure is forced to zero while components hold stock, so it always fires. This is pre-existing logic, untouched by V3.2; it was invisible while LT3-D1 pinned every kit to changed, and it is what remains now that LT3-D1 is fixed |
needs confirming |
LT3-D12The customer sees nothing while NetSuite says stock is coming. Recurs on every run |
Open | A kit's arrival values reach NetSuite but never Shopify, on 42 kits. Raised 2026-09-24, from the live flow configuration. The NetSuite import Lead Time V2: Import Kit Data had its filter emptied on 2026-09-24 (rules: []), so it writes every kit. The two Shopify branches on Lead times: Kits still require requiresUpdate == "true". requiresUpdate cannot see the three arrival fields, because search 6188 carries no read-back column for them — so a kit whose only change is an arrival value updates NetSuite and is skipped for Shopify. Measured 2026-09-24: of 375 kits with an arrival value, 333 reach Shopify and 42 do not. Worked example: kit 141511 Austen Double Bed (Oak, Cream) holds 5 arriving 12/10/2026 and 2 more on 19/10/2026 in NetSuite, and neither figure is on the storefront. Also 301580 Bowie Textured Velvet 2 Seat Sofa, 273950 Avery Arch Rattan Single Bed, 264661 Bok Extendable Dining Table. Adding the three read-back columns closes this and LT3-D13 together |
needs confirming |
LT3-D13NetSuite governance spent on writes that change nothing |
Open | Every kit is rewritten six times a day. Raised 2026-09-24. With the import filter emptied, all 1,749 kits are written on every run while only 802 are flagged as changed — 947 no-op updates per run, 5,682 a day. This was the safe direction for the arrival backfill and it makes LT3-D8 harmless in practice, but it is a temporary state, not a fix. Restoring the filter before the read-back columns exist would make LT3-D12 worse rather than better |
needs confirming |
LT3-D14Wrong stored data on records nobody is watching |
Open | 91 kit records hold an arrival quantity that nothing will ever correct. Raised 2026-09-24. Search 6188 returns 1,749 kits; NetSuite holds 4,485 kit records. The 2,736 outside the export are never touched by this flow, and 91 of them carry a value in custitem_next_qty_on_order_available left by something since retired. Blanks do clear correctly for kits inside the export — verified on 250 of 250 — so this is purely a scope gap, not a clearing failure. Whether any of the 91 are Shopify-linked is not established |
needs confirming |
LT3-D15Stage and arrival date can disagree on the same record |
Open | A kit's purchase-order stage can be a day behind its own arrival date. Raised 2026-09-24. custitem_po_stage on a kit is written only by Item Purchase Order Stage - Kit part 2/2, once a day at 05:05. Inventory items get theirs from flow 1 six times a day. So a kit can show an arrival date calculated at 16:05 today against a stage from 05:05 yesterday. This is the same class of problem LT3-D2 closed for lead times — the kit lagging its own components — still open for stage |
needs confirming |
LT3-D6Slow diagnosis, and it falls entirely on the person who notices |
Open | Nothing records which component set a kit's promise. The member id and name are returned and discarded, so when a kit shows "please contact showroom" there is no way to tell from the data which of its parts caused it. Diagnosing a wrong kit promise means re-deriving the roll-up by hand | needs confirming |
LT3-D17A kit we hold the parts for cannot be bought at all, because a component sitting on stock is flagged no-backorder for having nothing on order |
Open | A component holding stock still vetoes the kit. Raised 2026-09-30 by the project owner from kit 396981, immediately after LT3-D16 was fixed: the arrival date publishes now, and the kit is still refused on the storefront. Gate 1 of LI-BL-INV-013 requires every component's own backorder setting to allow it, and that setting is decided by LI-BL-INV-008 on what is on order — never on what is on the shelf. So an End Of Line component (rule 3) or a Drop Ship Seasonal Item component (rule 4) sitting on real stock is refused, and refuses the kit with it. On 396981 the Top holds 3 in the warehouse with its checkbox off while the Base allows backorder and brings 3 on 07/12/2026 — three tables we could build and sell, and the storefront takes no order: inventoryPolicy DENY, availableForSale false, verified 2026-09-30 on variant DT-SQH-NOIR-OVA-BLAC-220. Measured the same day against live NetSuite: 49 kits are blocked by a component whose own checkbox is off; 31 of those would be allowed if a component covering at least one kit's worth of stock stopped vetoing — 27 blocked by a Drop Ship Seasonal Item component, 4 by an End Of Line one. The other 18 are refused by gate 2 on the kit's own supply type regardless. 12 of the 31 are unbuyable today (kit availability 0); the remaining 19 already sell up to their stock and would lose that ceiling. That ceiling is not the protection it first appears: 1,305 kits already publish backorder-allowed with no stock, nothing on order, no supplier stock and no arrival date — 1,033 of them Back Order Only, which is that supply type's whole purpose — so the 19 would be joining the majority, not leaving a safe state. Nothing has shipped. The 31 is modelled from NetSuite data against the gates as documented, not replayed against the deployed script, and must be replayed before anything is built. The same pattern exists one level down and is recorded as LT2-Q9: 140 standalone End Of Line items holding warehouse stock with nothing on order are refused against 12 allowed, so LI-BL-INV-008 rule 1 does not fire on custitem_qty_available_wh as that rule is written. Fixing the item rule rather than the kit gate would close both, at a much wider blast radius. The 31 must be re-measured before anything is built. It was counted from custitem_qty_available_wh, and on 2026-10-01 140 components were found to publish more availability than exists anywhere in NetSuite — see the limitation row. Two of the five worked examples used to argue this defect rested on those phantom figures: on 398954 N701 4 Seater Modular Corner Sofa (Dark Grey) the blocking components publish 10 and 9 against a real availability of 0 and 0. The examples verified against raw inventory — 396981, 399037, 88208 — still hold. |
needs confirming |
Lead Time flow 1 — First and second arrival into Sydney 5
Open the entry · active
| Ref | Status | Defect | Rule |
|---|---|---|---|
LT1-D3 |
Open | Transfer orders are not restricted to bonded-into-SydneyEffect: An overflow or showroom transfer can be counted as new supply, overstating what can be soldRule it breaks: Only bonded-to-Sydney transfer orders count | needs confirming |
LT1-D4 |
Open | The two arrivals are not pushed to Shopify from this flowEffect: Sales cannot read them where the rule says they shouldRule it breaks: Sales read the arrivals in Shopify | needs confirming |
LT1-D6 |
Open | The page-split guard is inert, and there is a page boundary on every run — but exactly one product can be caught by it. The guard needs itemLineCount, which saved search 7973 does not supply, so has(h, 'itemLineCount') is always false and the guard never fires. Measured 2026-09-23: the export generates 2 pages at 1,000 rows each, on every run, so a boundary exists every time. Bounded 2026-09-23 by the project owner: the search sorts by item internal id, then receive-by date, then document. Because it sorts by item, a product's rows are contiguous, so with one boundary at most one product straddles it per run — not the whole multi-line population. Because the secondary sort is receive-by date ascending, that product's earliest lines land on page 1 and its later ones on page 2; the two fragments each produce a record, both write, and the second page wins. The affected product therefore ends up quoting a later arrival than it should — it under-promises rather than over-promises, which is the safer of the two ways to be wrong. See Fixing LT1-D6Effect: At most one product per run, quoted later than reality. Silent — no errorRule it breaks: Sellable quantity per line; first and second arrival |
needs confirming |
LT1-D7 |
Open | The purchase-order stage is published as a number, not a name. Saved search 7973 returns poStage as an internal id ("17", "22"), and supplies no poStageName column. The script assigns the same value to both po1_stageID and po1_stageName, so the "name" is an id. The NetSuite import is unaffected — it maps po1_stageID with internal id ticked — but any consumer reading po1_stageName gets "22" where it expects wording a person would recogniseEffect: Latent. Nothing reads the name today; it breaks the first thing that doesRule it breaks: PO stage is recorded against the first arrival |
needs confirming |
LT1-D8 |
Open | An ISO date would be silently misread as a date in the 1920s, not rejected. The date parser splits on / or -, then reads the parts as day, month, year. Search 7973 returns D/M/YYYY, so this is not live. But if any column is ever changed to ISO, 2026-09-23 parses as day 2026, month 9, year 23 — which resolves to the 1920s, is then judged more than a fortnight overdue, and the supply source is dropped without an error. A wrong format should refuse, not quietly delete supplyEffect: Latent, and silent if it ever firesRule it breaks: All date maths uses the Sydney date |
needs confirming |
Shipping Automation — Module 5: Courier Approval & Set Ship Date 9
Open the entry · active
| Ref | Status | Defect | Rule |
|---|---|---|---|
SA-D1 |
OpenOpen — needs confirming | Disapprove reason code disagrees. The board shows (10); config sets N_RFSC_DIS_PCODENOTCOV = 5. Confirm against NetSuite |
needs confirming |
SA-D2 |
OpenOpen | TT (Two Man) has no postcode CSV, so it always fails its postcode check in practice | needs confirming |
SA-D3 |
OpenBy design, worth watching | All-AusPost 2-Man orders are routed to manual review rather than auto-processed | needs confirming |
SA-D4 |
OpenOpen — commercial | Standard → 2-Man upgrade is a margin loss — the customer paid Standard. The front-end rate card is the noted pain point | needs confirming |
SA-D5 |
OpenCosmetic, but it misleads | The board is titled "Module 2" while the repos' package.json call it "Module 5". Same stage, different naming |
needs confirming |
SA-D6 |
OpenOpen | nswo config keys resolve to undefined. queryHelper/rds reference config.AWS_RDS_DBNAME, and several libs read config.AWS_REGION, but neither is defined in nswo config. swo defines AWS_REGION and sources the DB name from Secrets Manager |
needs confirming |
SA-D7 |
OpenOpen — intent versus deployed | PR #12 "remove fallback to dt" (nswo, 2026-07-21, 0ed5ee9) signals a DT fallback was removed, but at that commit DT 2 Man (DT_PRM) and DT Standard (DT_STD) are still present in nswo's courier hierarchy. Which DT fallback was meant to go? Until confirmed, this entry reflects the deployed behaviour |
needs confirming |
SA-D8 |
OpenOpen — this entry is wrong here, correct on the next pass | TLC is a Two Man courier in swo, not Full Service. The rules table and the courier diagram place TLC under Full Service as "auto-approved (no postcode check)". In swo at 69029d7, TLC is tried in the Two Man branch and is only auto-approved when it is the pre-selected front-end courier; otherwise the order falls through to Life 2 Man → DT 2 Man → Pedemont → TT |
needs confirming |
SA-D9 |
OpenResolved in code, entry updated | swo has retired the rate-card lookup. db.checkRateCard is commented out; swo now calls utils.autoApproveFECourier for the "no courier covers the postcode" fallback. The outcome — approve the front-end pick, reason 14 — is unchanged; only the mechanism moved |
needs confirming |
Supply Chain — Item Stage: the message on every open order line 2
Open the entry · draft
| Ref | Status | Defect | Rule |
|---|---|---|---|
IS-D1 |
OpenOpen. No ticket raised yet | When the brand on an item is empty, the brand is still substituted into the message and the customer sees the literal text - None -. Observed in production on 2026-08-31: one open line reading Item is on order with - None -/ our partner |
needs confirming |
IS-D2 |
OpenTo be confirmed with supply chain. Raised 2026-08-31 | Three overseas purchase order stages that have not physically shipped are split across the production and transit buckets, so (Overseas) Ready to Ship reads as still being made while (Overseas) Production Complete reads as on its way. May be deliberate | needs confirming |
Transfer Order Automation — Daily Overflow → Sydney Replenishment 9
Open the entry · draft
| Ref | Status | Defect | Rule |
|---|---|---|---|
TO-D1High |
Open | Saved-search column name mismatch — silently produces zero TOs. The engine reads the backorder item id as item_id; the committed reference capture returns it as item_ID. Running the branch engine over the committed captures unchanged, every one of the six items resolves to an undefined item, finds no bins, and is reported as a total shortfall — zero Transfer Orders created, and a shortfall email listing every backordered item. Correcting the key alone produces the correct result in the worked example above. |
needs confirming |
TO-D2High |
Open | Anti-double-order protection rests on one un-captured field. With demand netting removed, the only thing preventing the same stock being transferred every night is the supply guard's itemallocated field. That field is absent from the committed capture of the bin search, and the code defaults a missing value to zero — meaning "nothing is allocated", so the full bin becomes available again on the next run. |
needs confirming |
TO-D3High |
Open | Amend eligibility never checks the destination. The spec defines an eligible TO as "open TO, Overflow → Sydney, Pending Approval, with room". The code checks the source and the approval marker — never the destination. Any Pending-Approval TO sourced from Overflow qualifies, wherever it is going. | needs confirming |
TO-D4Medium |
Open | Oversized single unit escapes the CBM cap. In the over-cap split, units-per-TO is floored and then raised to a minimum of one. If one unit of an item exceeds 15 CBM, a Transfer Order is created over the cap, silently. Rare, but sofas and modular pieces are the plausible candidates. Flag it as an exception rather than emitting an over-cap TO. | needs confirming |
TO-D5Medium |
Open | Two competing definitions of "amendable". Amendability is decided in two places that read different fields: the engine picks amend targets by matching the text "Pending Approval" in the open-TO search's approval-status column, while the write script's guard checks the custbody_to_approval field equals 1. |
needs confirming |
TO-D6Medium |
Open | Auto-approve conflicts with the amendability model. Created TOs are immediately auto-approved to Pending Fulfilment, because that state commits the source stock and makes the searches self-correct. But BR-11 says a TO is amendable only while Pending Approval. The approval marker is still set to Pending Approval on those same TOs, so the guard would permit an amend to a TO that NetSuite has already locked. The repo carries a test harness written specifically to probe whether a Pending-Fulfilment TO can be amended — i.e. this was known to be unresolved. Confirm the intended end state: auto-approve for commitment, or stay amendable. It cannot be both. | needs confirming |
TO-D7Low |
Open | The spec and the code have drifted apart. The spec is the artefact a reviewer would reach for first, which makes the drift costlier than it looks. | needs confirming |
TO-D8Low |
Open | Merged docs contradict a verified finding. main's README and netsuite/README.md still state that bins/inventory-detail are required and that the save will fail without them, and the write-step comment gives bin management as the reason for choosing a RESTlet. The branch (and PR #2) record the opposite, verified against a real record: inventory detail is not set, and the warehouse assigns bins at fulfilment. Documentation-only, but it is the currently-merged version that a new reader sees. |
needs confirming |
TO-D9High |
Open | The unmerged branch appears to have been merged — this entry's deployment state is stale. Reading main for the script_updated date on 2026-08-21 returned HEAD 0ca95c7, dated 2026-08-17, whose message is "BE-3412: Transfer Order automation — allocation engine (create/amend, auto-approve, commit, shortfalls) (#3)". The Deployment state section above records BE-3412-APPLY-BUSINESS-LOGIC @ 47c0845 as unmerged and not deployed, and main @ 807826a as read-only step 1. |
needs confirming |
Closed
Kept because the answer is the record of why an entry says what it says.
Lead Time flow 2 — Inventory item lead time, and the Shopify push 7
Open the entry · active
| Ref | Status | Defect | Rule |
|---|---|---|---|
LT2-D2Resolved |
Resolved2026-08-21 | Resolved 2026-08-21. Items from saved search 6221 (Item Simple) never reached Shopify, because the search did not return shopifyItemType and the router drops anything matching neither route. The column was added to the search; verified live on 2026-08-21, including on item 181283 Pierre Floor Mirror, which now returns product. Original description: ** The router sends an item down the variant route or the product route by matching shopifyItemType, and drops anything matching neither — there is no default branch. Search 6221 does not return shopifyItemType at all, confirmed both in the Celigo sample and by running the live search. Items in that list with real Shopify ids exist: 181283 Pierre Floor Mirror and 181284 Pierre Side Table. Their NetSuite fields update; their storefront does not** |
needs confirming |
LT2-D3Resolved |
Resolved2026-08-18 | Resolved 2026-08-18 by the bonded change. The bonded warehouse fed nothing: its quantities were returned and never read, and no bonded arrival date was consumed. LI-BL-INV-011 now nets it against the Sydney backorder and lets the spare set both the quantity and the arrival date |
needs confirming |
LT2-D4Resolved |
Resolved2026-09-21 | Resolved, confirmed 2026-09-21. The comparison set is now eight conditions, not eleven, and each value is compared once. The two duplicated pairs — available quantity against both the Life-plus-supplier and the Life-only total, and the same for on-order — are gone, and blank is normalised to zero before comparing. A full run on 2026-09-21 left 5,182 of 5,286 products untouched, which is inconsistent with every-run rewriting. Original description: ** Two of the eleven change-detection comparisons can never both hold, so those items are marked as changed on every run and rewritten needlessly ** | needs confirming |
LT2-D5Resolved |
Resolved2026-08-18 | Resolved 2026-08-18 by the bonded change. Gold Coast stock was named in the in-store message but left out of the showroom total used for change detection, so a Gold-Coast-only change never triggered an update. It is now included in that total | needs confirming |
LT2-D8Resolved |
Resolved | Not reproducible on the current configuration, verified 2026-09-21. Flow 2's NetSuite import maps twelve fields and custitemcust_receive_date is not among them, so the two flows do not write the same field and cannot fight over it. Flow 1 is its sole writer. What remains true, and is recorded in LI-BL-INV-011 rather than as a defect, is that flow 2 can show the customer an earlier date than the field holds when spare bonded stock on hand lands sooner — by design, since the two answer different questions. Whether the mapping was present earlier and removed is not recorded anywhere. Original description: ** Flow 1 and flow 2 write different meanings into the same field, and each overwrites the other four times a day ** |
needs confirming |
LT2-D9Resolved |
Resolved2026-08-21 | Resolved 2026-08-21. The bonded rule only worked for Imported items, because only search 6186 supplied the bonded columns. All four searches now supply them; verified live. Original description: ** The script reads new_receiveDate_bonded and real bonded quantities, but only saved search 6186 (Imported) supplies them. Verified live on 2026-08-18: searches 6212, 6220 and 6221 do not return the bonded date column at all and return the bonded quantities blank. For those three categories the rule is inert. Worse, if their bonded quantities are ever populated without the date column being added, bonded stock would count towards the published on-order quantity while being unable to produce any arrival date — a quantity with no promise attached** |
needs confirming |
LT2-D6**Resolved.** Seven products, one of them live on the storefront |
Resolved2026-09-23 | Resolved 2026-09-23. Deployed and verified end to end. A final fallback was added to Lead Time: Inventory V3.1 Sep 2026 - bonded wh — after the In-Store Only branch and the ladder, before the brand rewrite — setting the dispatch band and the in-stock and on-order sentences to "Please contact showroom for lead time" whenever nothing above set them. Proved by a controlled experiment nobody designed. The deploy landed at 06:13 UTC during a run that had started at 06:08, so one run processed the same search under both versions. Three of the five affected Local products had already passed (rows 1,208 / 1,974 / 2,146) and stayed blank; the two that had not (173797 Palina Candle Holder, row 7,625, and 375674 Pomponette Vase (Amber), row 7,959) came out fully populated. Same run, same data, same item type — only the script differed. Shopify confirms the whole chain: VA-MAB-POMP-AMB and CA-CH-FLI-PALI-MINT-SM both carry the wording, written 06:15:22 and 06:15:00 UTC. The Local export then completed with 11,054 records and 0 errors. Four of the seven confirmed populated by 06:23 UTC: 173797 and 375674 from the split run, plus 173803 and 235919 once the Item Simple export re-ran at 06:21 under the new script. The remaining three — 173783, 182372, 190782 — sit at rows 1,208, 1,974 and 2,146 of the Local export and passed before the 06:13 deploy, so they wait for the next Local pass. A schedule, not a defect. Original: An item that matches no rung has its promise left unset — all three sentences stay unset and may be written to NetSuite as empty, leaving a product page with no lead time at all. |
needs confirming |
Lead Time flow 3 — Kit item lead time, rolled up from members 10
Open the entry · active
| Ref | Status | Defect | Rule |
|---|---|---|---|
LT3-D1Resolved |
Resolved2026-08-28 | Resolved 2026-08-28. Two of the change-detection comparisons tested the kit's current available and on-order quantities, which arrive from search 6188 as text (confirmed live: current_qtyAvailable: "0"), against newly computed numbers under a strict comparison. They could never hold, so every kit qualified for update on every run. V3.2 converts both to numbers first, matching what flow 2 already did. The symptom is reduced, not gone — LT3-D8 and LT3-D7 each independently mark most kits as changed |
needs confirming |
LT3-D2Resolved |
Resolved2026-09-21 | Resolved, verified 2026-09-21. Flow 2 now starts flow 3 on completion, and flow 3 carries no schedule of its own — confirmed on the live flow configuration. A kit no longer lags the items inside it. When this was last checked the chain did not exist; when it was added is not recorded anywhere. The open question about flow 3's timezone falls away with it, since it no longer runs to a clock. Original description: ** Flow 3 is not chained to flow 2, so a kit's promise can lag its own components by up to twelve hours ** | needs confirming |
LT3-D3Resolved |
Resolved2026-08-18 | Resolved 2026-08-18. The kit's warehouse availability was copied from whichever member happened to be first in the group rather than the scarcest, so a kit with three headboards and no footboards reported three. It now takes the minimum like every other quantity | needs confirming |
LT3-D4Not a defect. Kept as a record of the correction |
Resolved | Withdrawn — this was wrong. The entry previously said kits never get a backorder decision. They do: a separate flow, [PROD] Update Back Order Checkbox - Kit Items (5faa31bea44bdf66ac8ae144, twice daily at 10:10 and 23:10 Sydney), maintained the checkbox on the kit record. This flow did not write it, which is what was observed, but the conclusion drawn from that was incorrect. Superseded 2026-08-28 — that separate flow is now disabled, and this flow owns the decision under LI-BL-INV-013 |
needs confirming |
LT3-D5Resolved |
Resolved2026-08-28 | Resolved 2026-08-28. The script was renamed on 2026-08-18 to compute qtyAvailable_gc, but the import kept mapping the retired new_qtyAvailable_mia onto custitem_qty_available_mia, a field that does not exist in NetSuite — so the figure was computed correctly and written nowhere. The import row now reads new_qtyAvailable_gc → custitem_qty_available_gc, confirmed present on the kit record. Both halves of the rename are in |
needs confirming |
LT3-D7Resolved |
Resolved2026-09-24 | Resolved 2026-09-24. The kit import gained the mapping row new_receiveDate_bonded → custitem_receive_date_bonded_wh, confirmed on the live import at 02:10. The calculated Vietnam date now reaches the kit record, and the comparison that could never match now can. Original description: The kit's Vietnam arrival date is calculated, drives updates, and is never saved. LI-BL-INV-012 produces new_receiveDate_bonded and the change-detection compares it against current_receiveDate_bonded. The import has no mapping for it, so it is never written to the kit record. The stored value therefore stays empty while the calculated one holds a date, the comparison can never match, and every kit with bonded stock is marked as changed on every run. Re-checked 2026-08-28: still open, and now one of the two reasons kits are rewritten regardless of change (LT3-D8 is the other). The destination field already exists — custitem_receive_date_bonded_wh, confirmed on the kit record — so this needs a mapping row and no script change |
needs confirming |
LT3-D9Resolved |
Resolved2026-09-24 | Raised and resolved the same day, 2026-09-24. For roughly two hours the imports asked for values that did not exist. Both Shopify imports ask for three values the script does not produce. Raised 2026-09-24, on reading the live imports. Lead Time V2: Update Shopify Variant Metafields and ... Product Metafields were widened to nine metafields on 2026-09-24. Three of them read new_qtyOrder_po1, new_receiveDate_po2 and new_qtyOrder_po2, none of which the deployed script emits. po2_receive_date is wrapped in a conditional and is therefore skipped safely. po1_qty_on_order_available and po2_qty_on_order_available are not, so both render an empty string into a number_integer metafield on every kit. Shopify rejects an empty integer and reports it in userErrors while still returning HTTP 200, so Celigo records the run as successful — the same trap as LT2-D14 on inventory items. Whether the other seven metafields still land on a partial failure has not been verified. The imports cannot simply be guarded: the two objects sit last in the array with no trailing comma, so wrapping them leaves invalid JSON — the two objects must be removed until the script supplies the values. Closed by V3.4 at 02:08, which emits all three — the imports were correct, the script was behind them. Whether any kit push actually failed in the window between 00:53 and 02:08 was never established, and the flow's last run before V3.4 was 2026-09-23 22:50, so most likely none did |
needs confirming |
LT3-D10Resolved |
Resolved2026-09-24 | The ships-in value carries a full stop the list does not. Raised 2026-09-24 by replaying the live script and diffing against NetSuite. custitem_ships_in is a list field. All 23 CUSTOMLIST_SHIPS_IN entries are written without a trailing full stop — the fallback is id 22, "Please contact showroom for lead time". getMsgWithLongestTime returns the sentence form, which ends in one, so the value matches no list entry and the NetSuite import drops the write without raising a Celigo error. 50 kits hold a blank ships-in while the script computes a value, and because the stored value can never match, each is flagged as changed on every run — the same permanent-rewrite loop LT3-D7 had. The inventory script has always emitted the un-stopped form (// id = 22); kits never did. Only new_shipsIn is affected — the three message fields are free text, correctly keep their full stop, and 0 of 1,749 kits differ on them. Resolved — fixed in script content V3.5, deployed 2026-09-24 04:41 and verified against production 2026-09-29: kits holding a blank custitem_ships_in fell from 421 to 371, exactly the 50 this defect affected. The inventory script has always emitted the un-stopped form (// id = 22); kits never did. Only new_shipsIn is affected: the three message fields are free text, correctly keep their full stop, and 0 of 1,749 kits differ on them. Fixed in script content V3.5, deployed 2026-09-24 04:41 — not yet run, so not yet verified in data |
needs confirming |
LT3-D11Resolved |
Resolved2026-09-24 | The Ellison Studios branch counts the supplier pool twice. Raised 2026-09-24, same replay. When our own warehouse figures are empty the branch assigns qtyAvailable_allWarehouses / qtyOnOrder_allWarehouses from supplier_qtyAvailable / supplier_qtyOnOrder; the final two lines then add the supplier minimum again. The published figure is exactly twice the truth. Replayed over the live export: 117 of 256 Ellison kits affected, 1,199 units over-stated, every one a reduction once fixed and none increased. Worked example — kit 297076 Bell Floor Lamp (Chrome / Natural Rattan), two components at supplier 29/34 and 28/34: the branch takes min(29,28)=28 and min(34,34)=34, then adds 28 and 34 again, publishing 56/68 against a true 28/34. Also 397406 Float 4 Seat Sofa 136 → 68 on order and 372090 Alva Armchair 74 → 37. An earlier estimate of 58 kits / 569 units was wrong — it came from a hand-built model of the branch, not a replay. Fixed in V3.5, deployed 2026-09-24 04:41 — not yet run |
needs confirming |
LT3-D16A kit advertises stock on order and a shipping band while refusing to say when, and tells the customer to phone instead |
Resolved2026-09-30 | A split kit is refused an arrival date it could honour. Raised 2026-09-29 by the project owner, from the kit record; confirmed against production the same day. The arrival-date gate asks "could a customer act on a date?" as qtyAvailable_allWarehouses > 0 || kitAllowBackOrder. But LI-BL-INV-010 case 2 forces that availability to 0 by design when a kit is split — some components hold stock with nothing on order, others hold nothing with stock coming. So for every case-2 kit the first test is false by construction and the gate collapses onto the backorder flag alone; one component with its checkbox off then suppresses the date, both arrival quantities and the on-order sentence. The gate's own stated rationale is that the inbound units are "already committed to existing orders" — checked against production and false here: on kit 396981 both components report quantitycommitted 0 and quantitybackordered 0. Measured 2026-09-29 over the live export: 4 kits are refused a date they could honour — 396981 Noir Oval Dining Table (220cm, Black Oak), 88604 Austen Double Bed (Oak, Light Grey), 269851 Noir Oval Dining Table (Black Oak, Marble, 220cm) and 422199 Camille Marble Console Table (Burgundy, Rosso Marble). Pre-existing since V3.0, and V3.4 widened it: the gate now blanks the two arrival quantities as well as the date. Fixed in V3.6, deployed 2026-09-29 02:04 and byte-verified against the live record — not yet run. Pre-run state confirmed the same day: all four kits still hold a blank arrival date, a blank arrival quantity and "Please contact showroom for lead time." Closed 2026-09-30, verified in production data. The flow has since run and kit 396981 now holds custitemcust_receive_date 2026-12-07, custitem_next_qty_on_order_available 3 and the sentence "New stock arrives in our warehouse from 07/12/2026 - 14/12/2026." The rules were brought level with the deployed gate the same day — LI-BL-INV-012 now states all three tests and LI-BL-INV-015 rule 7 carries the second condition. The kit remains unsellable on Shopify for a separate reason, raised as LT3-D17. |
LI-BL-INV-012 LI-BL-INV-015 |
Lead Time flow 1 — First and second arrival into Sydney 2
Open the entry · active
| Ref | Status | Defect | Rule |
|---|---|---|---|
LT1-D2 |
Not a defect2026-09-23 | Not a defect. Reclassified 2026-09-23 on the project owner's confirmation. Bonded stock on hand is captured by flow 2's exports (Lead Time V2: Export Inventory - …), and Lead Time: export po data captures only what sits on a purchase or transfer order — that is, quantity on order. So the split is deliberate and correct: this flow owns arrivals with a document behind them; flow 2 owns bonded stock already sitting in Vietnam. What remains is dead code, not a gap — Lead Time: Update Next Available Receive Date v2 Sep 2026 still reads bondedQtyAvailable off the head row, always resolves it to zero, and builds a bonded-on-hand candidate that can never fire. See Known limitations for the tidy-upEffect: None. The rule is live in flow 2 via LI-BL-INV-011Rule it breaks: Bonded on hand → today + 35 |
needs confirming |
LT1-D5 |
Resolved2026-09-22 | Resolved 2026-09-22. lineID was added to saved search 7973 by the project owner, so the de-duplication key is now exact. Original: lines were keyed on a composite of their own values, so two distinct lines with identical quantities collapsed into oneEffect: ResolvedRule it breaks: Sellable quantity per line |
needs confirming |