← back to Designerwallcoverings
TK-10895: guards accept recorded adjudications, never implicit inference
27999a6e3e52308bbe5f0af7f919164b72f02471 · 2026-09-10 14:14:19 -0700 · Steve
G1 (unit/length), G2 (ambiguous cost cell) and G3 (FABRIC-row cost) each now
release a row ONLY when the evidence CSV carries a named adjudication -
LENGTH-NOT-STATED / LOADED-TOKEN-SUPPORTED / WP-ROW-COST-SUPPORTED - so an
inference can unblock a product but must be written down and auditable first.
G1 additionally FORCES the length-free label on a length-adjudicated row, and
rejects the length-free label on any row without that adjudication. Both
directions tested against poisoned worklists.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Files touched
M scripts/tk10895-trancheB-golive-269.mjs
Diff
commit 27999a6e3e52308bbe5f0af7f919164b72f02471
Author: Steve <steve@designerwallcoverings.com>
Date: Thu Sep 10 14:14:19 2026 -0700
TK-10895: guards accept recorded adjudications, never implicit inference
G1 (unit/length), G2 (ambiguous cost cell) and G3 (FABRIC-row cost) each now
release a row ONLY when the evidence CSV carries a named adjudication -
LENGTH-NOT-STATED / LOADED-TOKEN-SUPPORTED / WP-ROW-COST-SUPPORTED - so an
inference can unblock a product but must be written down and auditable first.
G1 additionally FORCES the length-free label on a length-adjudicated row, and
rejects the length-free label on any row without that adjudication. Both
directions tested against poisoned worklists.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---
scripts/tk10895-trancheB-golive-269.mjs | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/scripts/tk10895-trancheB-golive-269.mjs b/scripts/tk10895-trancheB-golive-269.mjs
index 39d1f22..76eb39c 100644
--- a/scripts/tk10895-trancheB-golive-269.mjs
+++ b/scripts/tk10895-trancheB-golive-269.mjs
@@ -57,8 +57,16 @@ for (const w of work) {
const e = byMfr[w.mfr];
if (!e) { fail.push([w.mfr, 'not in evidence CSV']); continue; }
if (e.decision !== 'GO') fail.push([w.mfr, `evidence says decision=${e.decision}`]);
- if (e.mill_unit !== 'PER_ROLL') fail.push([w.mfr, `G1 unit=${e.mill_unit}`]);
- if (e.mill_yards_per_roll !== '5') fail.push([w.mfr, `G1 yards=${e.mill_yards_per_roll}`]);
+ // G1: the mill's published spec is the default proof of unit+length. A row may substitute a
+ // recorded LENGTH-NOT-STATED adjudication — which asserts unit=per-roll on independent retail
+ // evidence and explicitly declines to claim a length — and such a row ships a length-free label.
+ const lenAdj = (e.roll_length_adjudicated || '').startsWith('LENGTH-NOT-STATED');
+ if (!lenAdj) {
+ if (e.mill_unit !== 'PER_ROLL') fail.push([w.mfr, `G1 unit=${e.mill_unit}`]);
+ if (e.mill_yards_per_roll !== '5') fail.push([w.mfr, `G1 yards=${e.mill_yards_per_roll}`]);
+ } else if (!/^Sold Per Single Roll - [\d.]+In Wide$/.test(w.label)) {
+ fail.push([w.mfr, 'G1 length-adjudicated row must carry the length-FREE label']);
+ }
// G2: a dirty cost cell may be released ONLY by a recorded adjudication that names its basis.
// Inference is allowed to unblock, but it must be written down and auditable, never implicit.
if (e.cost_cell_clean !== 'YES' && !(e.cost_cell_adjudicated || '').startsWith('LOADED-TOKEN-SUPPORTED'))
@@ -68,7 +76,14 @@ for (const w of work) {
fail.push([w.mfr, 'G3 priced off the sheet FABRIC row with no recorded adjudication']);
if (!/^\d+$/.test(w.pid)) fail.push([w.mfr, `pid not bare numeric: ${w.pid}`]);
if (!(parseFloat(w.price) > 50)) fail.push([w.mfr, `price sanity: ${w.price}`]);
- if (!/^Sold Per Single Roll - 5 Yards - [\d.]+In Wide$/.test(w.label)) fail.push([w.mfr, `label: ${w.label}`]);
+ // Label: the yardage form is the default. The length-free form is permitted ONLY when the row
+ // carries a recorded LENGTH-NOT-STATED adjudication — i.e. we deliberately decline to state a
+ // length we cannot source, rather than inventing one. (DW house convention already has this
+ // shape: Brunschwig ships "Sold Per Single Roll - 36In Wide".)
+ const withYards = /^Sold Per Single Roll - 5 Yards - [\d.]+In Wide$/.test(w.label);
+ const noYards = /^Sold Per Single Roll - [\d.]+In Wide$/.test(w.label);
+ if (!withYards && !(noYards && (e.roll_length_adjudicated || '').startsWith('LENGTH-NOT-STATED')))
+ fail.push([w.mfr, `label: ${w.label}`]);
}
console.log(`PRE-FLIGHT: ${work.length} rows · evidence rows ${ev.length} · failures ${fail.length}`);
if (fail.length) {
← 5320069 TK-11404: productSet position-1 reorder prototype + FINDINGS
·
back to Designerwallcoverings
·
TK-10895: table-driven reprice + CDN grace period b0416ab →