Saft (TotalEnergies) operates two plants on this pipeline: Valdosta GA
(9,425 SKUs, 22 customers — Verizon, Satair, Airbus, Boeing, Lockheed, Textron,
Learjet, Safran) and Bordeaux FR (43,332 SKUs, 2,990 customers —
Saft Ferak a.s. is the demoed customer on PO P2502253, 264 lines,
€448,650.50). Each PO references customer-side or manufacturer part IDs that
must be reconciled against the plant's ERP master data. We formalize the matching
step as a plant-aware cascade over a weighted SAT classifier (Snake v5.4.6) and
four deterministic fallbacks, prove that the output is order-independent, auditable,
and invariant to noise in the VLM-extracted description, and report measured
accuracy on the full live PO sweep: 274 / 275 lines tier-1 exact
(99.6%), $0.69 aggregate Bedrock cost, 412s wall.
Let a Purchase Order be a set of n line items
where each ℓi = (mi, ci, di, qi, ui) with
Each PO carries a plant routing p ∈ P = { valdosta, bordeaux }, determined at Stage 0 from the supplier address. Stage 4 returns an assignment σ : L → Mp ∪ {⊥} where Mp is the plant-specific master data:
Snake (v5.4.6, cf. Dana 2024) builds a weighted SAT classifier from (text, label) pairs. Three models are trained per plant — six models total in production:
Each model emits prediction with confidence γ ∈ [0, 1] and a human-readable audit.
Training knobs (per internal playbook):
n_layers=5, bucket=50, noise=0.25, oppose_profile=industrial, workers=5
for the 43k-class Bordeaux article model. The 9.4k-class Valdosta model uses
n_layers=15 for max accuracy.
Given a line ℓ in plant p, define Σp : L → Mp ∪ {⊥} as the first-match cascade:
Σp(ℓ) = { k ∈ Mp : key(k) = m } (tier 1: exact on mfr PN)
{ k : key(k) = c } (tier 1: exact on customer PN)
{ k : key(k) ∈ synonyms(k) ∩ (m, c) } (tier 2: synonym alias)
article_matcherp.predict(m + " " + d) if γ ≥ θauto (tier 3: Snake)
match_with_star(m, Mp) (tier 4: star-notation)
fuzzy(m + " " + d, Mp, ≥ θfuzz) (tier 5: Levenshtein)
⊥ otherwise
with θauto = 0.85 (the Snake confidence floor; lowering it has bitten us in past silent SKU hallucinations) and θfuzz = 0.80. The cascade terminates in exactly one of seven branches per line.
The cascade carries one plant-conditional rule. Bordeaux accepts the
line's customer_part_number as a candidate at tier 1, because Saft Ferak
embeds the Saft SKU verbatim under the customer PN. Concretely, all 264 Saft Ferak
lines have customer_part_number = "60-I" + saft_sku:
60-I105006 → 105006 (rondelle M6 A2) 60-I791111PCBA → 791111PCBA (carte fille, suffixe préservé) 60-I778671-00 → 778671-00 (variant, suffixe préservé)
The "strip the literal 60-I prefix" rule covers all 264/264 lines.
The looser "last six digits" heuristic (suggested by the customer over email) succeeds
on 260 lines but corrupts the four PCBA / dash-suffix variants. We apply the strict rule.
Valdosta does NOT accept customer_part_number at tier 1 —
in that catalogue, customer-side aliases collide with mfr-PNs across distinct families.
For a PO P, the trust score is
The router auto-approves when T ≥ 0.85.
Determinism. Snake is a deterministic SAT classifier: identical input yields identical output, independent of training order. Fallback tiers are dictionary lookups and pure string functions. Output is byte-stable across plant restarts.
Auditability. Each matched line carries
(method, confidence, tier, audit).
For Snake predictions, the audit contains the triggered SAT clauses and the bucket
depth, making every decision reconstructible by hand from
data/models/<plant>/article_matcher.json.
Noise invariance. The Dana Theorem (2024) guarantees Snake's SAT formula is polynomial in |Mp| and linear in the number of layers. Adding a new SKU to the basis and retraining preserves all prior correct matches that don't collide on literal tests — in practice collisions are negligible at |M| = 9,425 (Valdosta) and |M| = 43,332 (Bordeaux).
Hallucination guard. The 0.85 floor on tier 3 is what prevents Snake
from inventing plausible-looking SKUs on garbage input. Verified on Safran customer PNs
(BX00201-03) and Boeing identifiers (VHP430KH3) — the
matcher correctly returns ⊥.
Bordeaux's PO PDFs (Saft Ferak) carry a clean text layer that pdftotext can extract.
Stage 2 first attempts a deterministic text parser; if every line item parses AND
the line totals reconcile to the document total within
TOTAL_RECONCILE_TOLERANCE = 1.00 EUR, we skip the VLM entirely. The
reconciliation gate is the quality guarantee: arithmetic equality across 264 lines
is a structural proof, not a heuristic. On Saft Ferak P2502253: 264 lines &
€448,650.50 reconciled to the cent in 134 ms with zero LLM tokens
for stage 2; the PO completes end-to-end in 12.8 s for $0.10 of
stage-0/1/5 Haiku calls only. Glass-industry POs do NOT use this path
— their layouts are too unpredictable for deterministic parsers and the VLM is
load-bearing there.
Per-line match: O(1) exact (indexed cascade), O(|Mp|) worst case (fuzzy tier), O(L · b) Snake. For Bordeaux's 43k-class model with L = 5, b = 50, a single prediction runs in < 5 ms on the r6i.large after the 6.2-s S3-fresh load. Pipeline overhead is dominated by the VLM stages 2 and 5 when text-mode does not engage.
| PO | Plant | GT lines | Got | Tier-1 exact | Trust | Cost |
|---|---|---|---|---|---|---|
| AM4075307 | Valdosta | 2 | 2 | 1 + 1 fee rejected at floor | 81.7 | $0.07 |
| 3002630800 | Valdosta | 2 | 2 | 2 | 100.0 | $0.10 |
| 4500239828 | Valdosta | 4 | 4 | 4 | 98.3 | $0.14 |
| 5002499207 | Valdosta | 1 | 1 | 1 | 98.3 | $0.14 |
| PO0047091502 | Valdosta | 1 | 1 | 1 | 98.3 | $0.05 |
| Satair 4500595986 | Valdosta | 1 | 1 | 1 | 98.3 | $0.09 |
| Saft Ferak P2502253 | Bordeaux | 264 | 264 | 264 | 100.0 | $0.10 |
| Total | — | 275 | 275 | 274 (99.6%) | — | $0.69 |
The single non-tier-1 line (AM4075307 line 2) is a 3.4% Textron customs surcharge with no Saft SKU counterpart; the 0.85 floor correctly returns ⊥ rather than hallucinate.
local_pop reintroduces a Bayesian contradiction);
cure needs gatherer-side post-routing global injection. noise=0 is
hard-coded at the leaf for now. Local Snake training on this service is unaffected.