FA-79506 / Barcode symbology encoding / Open access
Add-ons are allowed on Code 128 · case 01
Layouts reserve space for an EAN-5 next to a Code 128 symbol that scanners will never read together.
ROOT CAUSE
The add-on is not restricted to EAN/UPC symbologies.
VERIFIED REPAIR
Allow add-ons only on EAN-13, UPC-A and EAN-8.
Unsuccessful approach: Excluding only Code 39 still admits Code 128 and ITF-14.
Case contract
Input {sym, modules, x_um, addon?}. Quiet zones in X: ean13 11 left / 7 right, upca 9/9, ean8 7/7, code128, code39 and itf14 10/10. Allowed X-dimensions in micrometres: EAN/UPC 264..660 inclusive, code128/code39 >= 190, itf14 >= 495. An EAN-2 (20 modules) or EAN-5 (47 modules) add-on is only allowed on EAN/UPC; it replaces the right quiet zone by a 7-module gap, the add-on and a 5-module trailing quiet zone. Return [total_um, left_quiet_um] or unknown/x-out-of-range/bad-addon.
Why this case matters
Retail, logistics, pharmacy and document workflows depend on encoders that produce exactly the module pattern, code-set switches, separators and quiet zones scanners expect; one misplaced module or separator makes a label unreadable or, worse, scan as different data.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(spec):
qz = {'ean13': (11, 7), 'upca': (9, 9), 'ean8': (7, 7), 'code128': (10, 10), 'code39': (10, 10), 'itf14': (10, 10)}
xr = {'ean13': (264, 660), 'upca': (264, 660), 'ean8': (264, 660), 'code128': (190, None), 'code39': (190, None), 'itf14': (495, None)}
sym = spec['sym']
if sym not in qz:
return 'unknown'
lo, hi = xr[sym]
x = spec['x_um']
if x < lo or (hi is not None and x > hi):
return 'x-out-of-range'
left, right = qz[sym]
addon = spec.get('addon', 0)
if addon:
if addon not in (2, 5):
return 'bad-addon'
right = 7 + (20 if addon == 2 else 47) + 5
total = left + spec['modules'] + right
return [total * x, left * x]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'sym': 'code128', 'modules': 200, 'x_um': 1000, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 200, 'x_um': 495, 'addon': 2}, 'bad-addon'], [{'sym': 'code39', 'modules': 200, 'x_um': 661}, [145420, 6610]], [{'sym': 'ean13', 'modules': 67, 'x_um': 330}, [28050, 3630]], [{'sym': 'qr', 'modules': 200, 'x_um': 250, 'addon': 2}, 'unknown'], [{'sym': 'ean8', 'modules': 101, 'x_um': 1100, 'addon': 5}, 'x-out-of-range'], [{'sym': 'itf14', 'modules': 95, 'x_um': 250, 'addon': 2}, 'x-out-of-range'], [{'sym': 'code128', 'modules': 67, 'x_um': 400, 'addon': 2}, 'bad-addon']], [[{'sym': 'code39', 'modules': 95, 'x_um': 661, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 263, 'addon': 5}, 'bad-addon'], [{'sym': 'itf14', 'modules': 142, 'x_um': 495, 'addon': 2}, 'bad-addon'], [{'sym': 'itf14', 'modules': 67, 'x_um': 1000}, [87000, 10000]], [{'sym': 'itf14', 'modules': 67, 'x_um': 250}, 'x-out-of-range'], [{'sym': 'code128', 'modules': 200, 'x_um': 660}, [145200, 6600]], [{'sym': 'ean13', 'modules': 95, 'x_um': 661}, 'x-out-of-range'], [{'sym': 'code39', 'modules': 67, 'x_um': 330, 'addon': 5}, 'bad-addon']], [[{'sym': 'code39', 'modules': 200, 'x_um': 190, 'addon': 5}, 'bad-addon'], [{'sym': 'itf14', 'modules': 200, 'x_um': 1100, 'addon': 2}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 661, 'addon': 5}, 'bad-addon'], [{'sym': 'ean13', 'modules': 200, 'x_um': 190}, 'x-out-of-range'], [{'sym': 'code39', 'modules': 101, 'x_um': 400}, [48400, 4000]], [{'sym': 'itf14', 'modules': 95, 'x_um': 263, 'addon': 5}, 'x-out-of-range'], [{'sym': 'code39', 'modules': 101, 'x_um': 190, 'addon': 3}, 'bad-addon'], [{'sym': 'code39', 'modules': 101, 'x_um': 660, 'addon': 2}, 'bad-addon']], [[{'sym': 'code128', 'modules': 101, 'x_um': 400, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 250, 'addon': 2}, 'bad-addon'], [{'sym': 'ean8', 'modules': 142, 'x_um': 400, 'addon': 5}, [83200, 2800]], [{'sym': 'ean13', 'modules': 101, 'x_um': 1100}, 'x-out-of-range'], [{'sym': 'itf14', 'modules': 95, 'x_um': 264, 'addon': 2}, 'x-out-of-range'], [{'sym': 'ean13', 'modules': 67, 'x_um': 661}, 'x-out-of-range'], [{'sym': 'itf14', 'modules': 67, 'x_um': 1100, 'addon': 3}, 'bad-addon'], [{'sym': 'code39', 'modules': 142, 'x_um': 263, 'addon': 5}, 'bad-addon']], [[{'sym': 'code39', 'modules': 142, 'x_um': 190, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 101, 'x_um': 190, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 250, 'addon': 2}, 'bad-addon'], [{'sym': 'ean13', 'modules': 67, 'x_um': 330}, [28050, 3630]], [{'sym': 'ean13', 'modules': 101, 'x_um': 264}, [31416, 2904]], [{'sym': 'ean13', 'modules': 67, 'x_um': 264, 'addon': 2}, [29040, 2904]], [{'sym': 'code128', 'modules': 101, 'x_um': 400}, [48400, 4000]], [{'sym': 'itf14', 'modules': 200, 'x_um': 661, 'addon': 5}, 'bad-addon']]]
labels = ["regression: add-on symbology restriction", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: add-on symbology restriction 0 | [269000, 10000] | bad-addon | Failed |
| repair trap 1 | [119790, 4950] | bad-addon | Failed |
| combined fault 2 | [145420, 6610] | [145420, 6610] | Passed |
| control 3 | [28050, 3630] | [28050, 3630] | Passed |
| control 4 | unknown | unknown | Passed |
| boundary 5 | x-out-of-range | x-out-of-range | Passed |
| boundary 6 | x-out-of-range | x-out-of-range | Passed |
| control 7 | [43600, 4000] | bad-addon | Failed |
SHA-256 / c6a4bf17aeda10fea670ea4a56fa828cbf88b2faf8822df703ba1adb215137b9
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(spec):
qz = {'ean13': (11, 7), 'upca': (9, 9), 'ean8': (7, 7), 'code128': (10, 10), 'code39': (10, 10), 'itf14': (10, 10)}
xr = {'ean13': (264, 660), 'upca': (264, 660), 'ean8': (264, 660), 'code128': (190, None), 'code39': (190, None), 'itf14': (495, None)}
sym = spec['sym']
if sym not in qz:
return 'unknown'
lo, hi = xr[sym]
x = spec['x_um']
if x < lo or (hi is not None and x > hi):
return 'x-out-of-range'
left, right = qz[sym]
addon = spec.get('addon', 0)
if addon:
if sym == 'code39' or addon not in (2, 5):
return 'bad-addon'
right = 7 + (20 if addon == 2 else 47) + 5
total = left + spec['modules'] + right
return [total * x, left * x]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'sym': 'code128', 'modules': 200, 'x_um': 1000, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 200, 'x_um': 495, 'addon': 2}, 'bad-addon'], [{'sym': 'code39', 'modules': 200, 'x_um': 661}, [145420, 6610]], [{'sym': 'ean13', 'modules': 67, 'x_um': 330}, [28050, 3630]], [{'sym': 'qr', 'modules': 200, 'x_um': 250, 'addon': 2}, 'unknown'], [{'sym': 'ean8', 'modules': 101, 'x_um': 1100, 'addon': 5}, 'x-out-of-range'], [{'sym': 'itf14', 'modules': 95, 'x_um': 250, 'addon': 2}, 'x-out-of-range'], [{'sym': 'code128', 'modules': 67, 'x_um': 400, 'addon': 2}, 'bad-addon']], [[{'sym': 'code39', 'modules': 95, 'x_um': 661, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 263, 'addon': 5}, 'bad-addon'], [{'sym': 'itf14', 'modules': 142, 'x_um': 495, 'addon': 2}, 'bad-addon'], [{'sym': 'itf14', 'modules': 67, 'x_um': 1000}, [87000, 10000]], [{'sym': 'itf14', 'modules': 67, 'x_um': 250}, 'x-out-of-range'], [{'sym': 'code128', 'modules': 200, 'x_um': 660}, [145200, 6600]], [{'sym': 'ean13', 'modules': 95, 'x_um': 661}, 'x-out-of-range'], [{'sym': 'code39', 'modules': 67, 'x_um': 330, 'addon': 5}, 'bad-addon']], [[{'sym': 'code39', 'modules': 200, 'x_um': 190, 'addon': 5}, 'bad-addon'], [{'sym': 'itf14', 'modules': 200, 'x_um': 1100, 'addon': 2}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 661, 'addon': 5}, 'bad-addon'], [{'sym': 'ean13', 'modules': 200, 'x_um': 190}, 'x-out-of-range'], [{'sym': 'code39', 'modules': 101, 'x_um': 400}, [48400, 4000]], [{'sym': 'itf14', 'modules': 95, 'x_um': 263, 'addon': 5}, 'x-out-of-range'], [{'sym': 'code39', 'modules': 101, 'x_um': 190, 'addon': 3}, 'bad-addon'], [{'sym': 'code39', 'modules': 101, 'x_um': 660, 'addon': 2}, 'bad-addon']], [[{'sym': 'code128', 'modules': 101, 'x_um': 400, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 250, 'addon': 2}, 'bad-addon'], [{'sym': 'ean8', 'modules': 142, 'x_um': 400, 'addon': 5}, [83200, 2800]], [{'sym': 'ean13', 'modules': 101, 'x_um': 1100}, 'x-out-of-range'], [{'sym': 'itf14', 'modules': 95, 'x_um': 264, 'addon': 2}, 'x-out-of-range'], [{'sym': 'ean13', 'modules': 67, 'x_um': 661}, 'x-out-of-range'], [{'sym': 'itf14', 'modules': 67, 'x_um': 1100, 'addon': 3}, 'bad-addon'], [{'sym': 'code39', 'modules': 142, 'x_um': 263, 'addon': 5}, 'bad-addon']], [[{'sym': 'code39', 'modules': 142, 'x_um': 190, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 101, 'x_um': 190, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 250, 'addon': 2}, 'bad-addon'], [{'sym': 'ean13', 'modules': 67, 'x_um': 330}, [28050, 3630]], [{'sym': 'ean13', 'modules': 101, 'x_um': 264}, [31416, 2904]], [{'sym': 'ean13', 'modules': 67, 'x_um': 264, 'addon': 2}, [29040, 2904]], [{'sym': 'code128', 'modules': 101, 'x_um': 400}, [48400, 4000]], [{'sym': 'itf14', 'modules': 200, 'x_um': 661, 'addon': 5}, 'bad-addon']]]
labels = ["regression: add-on symbology restriction", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: add-on symbology restriction 0 | [269000, 10000] | bad-addon | Failed |
| repair trap 1 | [119790, 4950] | bad-addon | Failed |
| combined fault 2 | [145420, 6610] | [145420, 6610] | Passed |
| control 3 | [28050, 3630] | [28050, 3630] | Passed |
| control 4 | unknown | unknown | Passed |
| boundary 5 | x-out-of-range | x-out-of-range | Passed |
| boundary 6 | x-out-of-range | x-out-of-range | Passed |
| control 7 | [43600, 4000] | bad-addon | Failed |
SHA-256 / 86aee82131a52bb2c65215446f647339f3e6d7b22f47bd53fb833956d4ead964
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(spec):
qz = {'ean13': (11, 7), 'upca': (9, 9), 'ean8': (7, 7), 'code128': (10, 10), 'code39': (10, 10), 'itf14': (10, 10)}
xr = {'ean13': (264, 660), 'upca': (264, 660), 'ean8': (264, 660), 'code128': (190, None), 'code39': (190, None), 'itf14': (495, None)}
sym = spec['sym']
if sym not in qz:
return 'unknown'
lo, hi = xr[sym]
x = spec['x_um']
if x < lo or (hi is not None and x > hi):
return 'x-out-of-range'
left, right = qz[sym]
addon = spec.get('addon', 0)
if addon:
if sym not in ('ean13', 'upca', 'ean8') or addon not in (2, 5):
return 'bad-addon'
right = 7 + (20 if addon == 2 else 47) + 5
total = left + spec['modules'] + right
return [total * x, left * x]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[{'sym': 'code128', 'modules': 200, 'x_um': 1000, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 200, 'x_um': 495, 'addon': 2}, 'bad-addon'], [{'sym': 'code39', 'modules': 200, 'x_um': 661}, [145420, 6610]], [{'sym': 'ean13', 'modules': 67, 'x_um': 330}, [28050, 3630]], [{'sym': 'qr', 'modules': 200, 'x_um': 250, 'addon': 2}, 'unknown'], [{'sym': 'ean8', 'modules': 101, 'x_um': 1100, 'addon': 5}, 'x-out-of-range'], [{'sym': 'itf14', 'modules': 95, 'x_um': 250, 'addon': 2}, 'x-out-of-range'], [{'sym': 'code128', 'modules': 67, 'x_um': 400, 'addon': 2}, 'bad-addon']], [[{'sym': 'code39', 'modules': 95, 'x_um': 661, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 263, 'addon': 5}, 'bad-addon'], [{'sym': 'itf14', 'modules': 142, 'x_um': 495, 'addon': 2}, 'bad-addon'], [{'sym': 'itf14', 'modules': 67, 'x_um': 1000}, [87000, 10000]], [{'sym': 'itf14', 'modules': 67, 'x_um': 250}, 'x-out-of-range'], [{'sym': 'code128', 'modules': 200, 'x_um': 660}, [145200, 6600]], [{'sym': 'ean13', 'modules': 95, 'x_um': 661}, 'x-out-of-range'], [{'sym': 'code39', 'modules': 67, 'x_um': 330, 'addon': 5}, 'bad-addon']], [[{'sym': 'code39', 'modules': 200, 'x_um': 190, 'addon': 5}, 'bad-addon'], [{'sym': 'itf14', 'modules': 200, 'x_um': 1100, 'addon': 2}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 661, 'addon': 5}, 'bad-addon'], [{'sym': 'ean13', 'modules': 200, 'x_um': 190}, 'x-out-of-range'], [{'sym': 'code39', 'modules': 101, 'x_um': 400}, [48400, 4000]], [{'sym': 'itf14', 'modules': 95, 'x_um': 263, 'addon': 5}, 'x-out-of-range'], [{'sym': 'code39', 'modules': 101, 'x_um': 190, 'addon': 3}, 'bad-addon'], [{'sym': 'code39', 'modules': 101, 'x_um': 660, 'addon': 2}, 'bad-addon']], [[{'sym': 'code128', 'modules': 101, 'x_um': 400, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 250, 'addon': 2}, 'bad-addon'], [{'sym': 'ean8', 'modules': 142, 'x_um': 400, 'addon': 5}, [83200, 2800]], [{'sym': 'ean13', 'modules': 101, 'x_um': 1100}, 'x-out-of-range'], [{'sym': 'itf14', 'modules': 95, 'x_um': 264, 'addon': 2}, 'x-out-of-range'], [{'sym': 'ean13', 'modules': 67, 'x_um': 661}, 'x-out-of-range'], [{'sym': 'itf14', 'modules': 67, 'x_um': 1100, 'addon': 3}, 'bad-addon'], [{'sym': 'code39', 'modules': 142, 'x_um': 263, 'addon': 5}, 'bad-addon']], [[{'sym': 'code39', 'modules': 142, 'x_um': 190, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 101, 'x_um': 190, 'addon': 5}, 'bad-addon'], [{'sym': 'code128', 'modules': 67, 'x_um': 250, 'addon': 2}, 'bad-addon'], [{'sym': 'ean13', 'modules': 67, 'x_um': 330}, [28050, 3630]], [{'sym': 'ean13', 'modules': 101, 'x_um': 264}, [31416, 2904]], [{'sym': 'ean13', 'modules': 67, 'x_um': 264, 'addon': 2}, [29040, 2904]], [{'sym': 'code128', 'modules': 101, 'x_um': 400}, [48400, 4000]], [{'sym': 'itf14', 'modules': 200, 'x_um': 661, 'addon': 5}, 'bad-addon']]]
labels = ["regression: add-on symbology restriction", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: add-on symbology restriction 0 | bad-addon | bad-addon | Passed |
| repair trap 1 | bad-addon | bad-addon | Passed |
| combined fault 2 | [145420, 6610] | [145420, 6610] | Passed |
| control 3 | [28050, 3630] | [28050, 3630] | Passed |
| control 4 | unknown | unknown | Passed |
| boundary 5 | x-out-of-range | x-out-of-range | Passed |
| boundary 6 | x-out-of-range | x-out-of-range | Passed |
| control 7 | bad-addon | bad-addon | Passed |
SHA-256 / 8d3f33e973962cb5490cd4cd2aa7aac4f0793f59e263a2a468b3f1f4dd227fba
Verification & scope
A deterministic bounded teaching model with a stipulated contract; it makes no claim of conformance to any published specification. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:45.114230+00:00.
Case digest / ad111081573944a6adf1b38211919eed73f163b8be32a23a09b1c959c4dafcc8