dataforth(datasheet): Fix 2 — data-driven DSCA load note (fixes DSCA39 footer artifact)

Root cause of the DSCA39 footer mismatch: the "Standard output load for test is
250 ohms." line is a footer note, not a parameter, but the STAGE 1 extractor
captured it as a (column-truncated) row "Standard output load for te". And the
renderer's OUTSIGTYPE==='CURRENT' emission was wrong on both ends — it printed the
note (after the underline, invisible to the validator gate) for many -C current
models whose staged originals never had it, and never placed it correctly for the
models that do.

Fix is data-driven, matching the rest of the template approach:
- derive-dsca-templates.js: detect the "Standard output load..." line, capture it
  as a per-model `loadNote` property, and exclude it from rows. Regenerated
  dsca-templates.json — surgically clean: only the 5 DSCA39 models changed (lost
  the truncated row, gained loadNote); all 121 others byte-identical.
- datasheet-exact.js: emit `dscaTpl.loadNote` (blank line + note) before the footer
  underline, only for models that have it; removed the OUTSIGTYPE-based emission.

STAGE 3 re-validation: FINAL-TEST CLEAN 85 -> 88, mismatches 9 -> 6, matches
2206 -> 2278. DSCA39-01/02/07 now fully clean; DSCA39-01 byte-content-verified.
No regression — the -C current models stayed clean and no longer carry the
spurious after-underline note.

The 6 remaining dirty models (DSCA38-05/-1793/-19C/-19E, DSCA39-05, DSCA39-1950)
are ALL retest data-vintage: the staged .TXT is an older test run than the DB
latest-wins record (Supply Current / Linearity differ by more than rounding).
Not render bugs — cannot be reconciled against an older sheet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-18 07:31:48 -07:00
parent 9bef6fe920
commit 3372455b79
5 changed files with 26 additions and 56 deletions

View File

@@ -7,11 +7,11 @@ Corpus: 2806 staged DSCA originals across 126 models.
SUMMARY
models with staged originals: 126
models FINAL-TEST CLEAN (>=1 compared, 0 mismatch): 85
models with FINAL-TEST mismatches: 9
models FINAL-TEST CLEAN (>=1 compared, 0 mismatch): 88
models with FINAL-TEST mismatches: 6
certs compared: 2316
Final-Test match: 2206
Final-Test mismatch: 110
Final-Test match: 2278
Final-Test mismatch: 38
(certs with accuracy-section diffs: 1337 — informational)
staged serials not in DB: 40
in DB but not rendered (skipped/null): 450
@@ -39,59 +39,20 @@ MODELS WITH FINAL-TEST CONTENT MISMATCHES (investigate before re-push):
[finaltest L3] SN 179698-16
render: "Supply Current 42.7 mA < 60 mA PASS"
golden: "Supply Current 45.7 mA < 60 mA PASS"
DSCA39-01 compared=4 ftMatch=0 ftMismatch=4
[finaltest L12] SN 177576-1
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
[finaltest L12] SN 177576-2
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
[finaltest L12] SN 177576-3
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
DSCA39-02 compared=4 ftMatch=0 ftMismatch=4
[finaltest L12] SN 179998-1
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
[finaltest L12] SN 179998-2
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
[finaltest L12] SN 179998-3
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
DSCA39-05 compared=17 ftMatch=0 ftMismatch=17
[finaltest L12] SN A276-2
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
DSCA39-05 compared=17 ftMatch=16 ftMismatch=1
[finaltest L3] SN A276-2
render: "Supply Current, Nom 61.7 mA < 75 mA PASS"
golden: "Supply Current, Nom 60.0 mA < 75 mA PASS"
[finaltest L12] SN 178026-10
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
DSCA39-07 compared=33 ftMatch=0 ftMismatch=33
[finaltest L13] SN 178714-1
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
[finaltest L13] SN 178714-2
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
[finaltest L13] SN 178714-3
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
DSCA39-1950 compared=17 ftMatch=0 ftMismatch=17
DSCA39-1950 compared=17 ftMatch=15 ftMismatch=2
[finaltest L4] SN 178236-12
render: "Linearity 0.013 % +/- .05 % PASS"
golden: "Linearity 0.009 % +/- .05 % PASS"
[finaltest L4] SN 178236-13
render: "Linearity 0.017 % +/- .05 % PASS"
golden: "Linearity 0.012 % +/- .05 % PASS"
[finaltest L12] SN 178236-14
render: "Standard output load for te PASS"
golden: "Standard output load for test is 250 ohms."
FINAL-TEST CLEAN MODELS (85):
DSCA30-01, DSCA30-02, DSCA30-03, DSCA30-06, DSCA30-07, DSCA30-08, DSCA30-08C, DSCA30-09, DSCA30-09C, DSCA30-1944, DSCA30-1945, DSCA30-1946, DSCA31-02, DSCA31-03, DSCA31-06, DSCA31-07, DSCA31-11, DSCA31-12, DSCA31-1273, DSCA31-12C, DSCA31-13, DSCA31-13C, DSCA31-15, DSCA31-1918, DSCA32-01, DSCA32-01C, DSCA32-01E, DSCA34-01, DSCA34-02C, DSCA34-04, DSCA34-04C, DSCA34-05, DSCA34-05C, DSCA34-1858, DSCA36-01, DSCA36-02, DSCA36-03, DSCA36-04, DSCA36-04C, DSCA36-1949, DSCA38-02, DSCA38-03, DSCA38-07, DSCA38-08C, DSCA38-09, DSCA38-09E, DSCA38-12C, DSCA38-12E, DSCA38-1468, DSCA38-1544, DSCA38-15C, DSCA38-16, DSCA38-16C, DSCA38-18C, DSCA38-19, DSCA40-03, DSCA40-05, DSCA40-05C, DSCA40-06, DSCA40-1951, DSCA40-1952, DSCA41-01, DSCA41-02, DSCA41-03, DSCA41-05C, DSCA41-06, DSCA41-09, DSCA41-13, DSCA41-14, DSCA41-15, DSCA41-15E, DSCA42-01, DSCA42-01C, DSCA42-02, DSCA43-10, DSCA43-20E, DSCA47E-08C, DSCA47J-01C, DSCA47J-03, DSCA47K-05, DSCA47K-13, DSCA47K-14, DSCA47N-15, DSCA47T-06, DSCA47T-1928
FINAL-TEST CLEAN MODELS (88):
DSCA30-01, DSCA30-02, DSCA30-03, DSCA30-06, DSCA30-07, DSCA30-08, DSCA30-08C, DSCA30-09, DSCA30-09C, DSCA30-1944, DSCA30-1945, DSCA30-1946, DSCA31-02, DSCA31-03, DSCA31-06, DSCA31-07, DSCA31-11, DSCA31-12, DSCA31-1273, DSCA31-12C, DSCA31-13, DSCA31-13C, DSCA31-15, DSCA31-1918, DSCA32-01, DSCA32-01C, DSCA32-01E, DSCA34-01, DSCA34-02C, DSCA34-04, DSCA34-04C, DSCA34-05, DSCA34-05C, DSCA34-1858, DSCA36-01, DSCA36-02, DSCA36-03, DSCA36-04, DSCA36-04C, DSCA36-1949, DSCA38-02, DSCA38-03, DSCA38-07, DSCA38-08C, DSCA38-09, DSCA38-09E, DSCA38-12C, DSCA38-12E, DSCA38-1468, DSCA38-1544, DSCA38-15C, DSCA38-16, DSCA38-16C, DSCA38-18C, DSCA38-19, DSCA39-01, DSCA39-02, DSCA39-07, DSCA40-03, DSCA40-05, DSCA40-05C, DSCA40-06, DSCA40-1951, DSCA40-1952, DSCA41-01, DSCA41-02, DSCA41-03, DSCA41-05C, DSCA41-06, DSCA41-09, DSCA41-13, DSCA41-14, DSCA41-15, DSCA41-15E, DSCA42-01, DSCA42-01C, DSCA42-02, DSCA43-10, DSCA43-20E, DSCA47E-08C, DSCA47J-01C, DSCA47J-03, DSCA47K-05, DSCA47K-13, DSCA47K-14, DSCA47N-15, DSCA47T-06, DSCA47T-1928
MODELS WITH NO COMPARABLE CERT (no staged serial in DB, or all skipped/null):
DSCA31-1947(null), DSCA33-01(null), DSCA33-01A(null), DSCA33-02(null), DSCA33-02C(null), DSCA33-03(null), DSCA33-03A(null), DSCA33-03C(null), DSCA33-04(null), DSCA33-04C(null), DSCA33-05(null), DSCA33-05C(null), DSCA33-07C(null), DSCA33-1917(null), DSCA33-1919(null), DSCA33-1948(null), DSCA45-01(null), DSCA45-01C(null), DSCA45-02(null), DSCA45-03(null), DSCA45-03C(null), DSCA45-04(null), DSCA45-04C(null), DSCA45-05C(null), DSCA45-06(null), DSCA45-07(null), DSCA45-08(null), DSCA47N-15C(null), DSCA49-04(null), DSCA49-05(null), DSCA49-1601(null), DSCA49-1895(null)

File diff suppressed because one or more lines are too long

View File

@@ -697,6 +697,13 @@ function generateExactDatasheet(record, specs) {
}
lines.push(line);
}
// Footer load note ("Standard output load for test is ... ohms.") — printed
// before the underline, only by the models whose staged original had it
// (captured per-model in STAGE 1; not all current-output models print it).
if (dscaTpl.loadNote) {
lines.push('');
lines.push(TAB5 + dscaTpl.loadNote);
}
} else {
// QB: TAB(12); "Parameter"; TAB(30); "Measured Value"; TAB(51); "Specification "; TAB(70); "Status"
let hdr1 = setCol('', 11, 'Parameter');
@@ -794,11 +801,6 @@ function generateExactDatasheet(record, specs) {
lines.push(setCol(TAB5 + 'Pins Straight: __X__', 44, 'Module Header: __X__'));
}
// DSCA current output load note
if (family === 'DSCA' && specs && specs.OUTSIGTYPE && specs.OUTSIGTYPE.trim().toUpperCase() === 'CURRENT') {
lines.push(TAB5 + 'Standard output load for test is 250 ohms.');
}
lines.push('');
lines.push(TAB5 + 'It is hereby certified that the above product is in conformance with');
lines.push(TAB5 + 'all requirements to the extent specified. This product is not');

View File

@@ -1 +1 @@
["DSCA30-01","DSCA30-02","DSCA30-03","DSCA30-06","DSCA30-07","DSCA30-08","DSCA30-08C","DSCA30-09","DSCA30-09C","DSCA30-1944","DSCA30-1945","DSCA30-1946","DSCA31-02","DSCA31-03","DSCA31-06","DSCA31-07","DSCA31-11","DSCA31-12","DSCA31-1273","DSCA31-12C","DSCA31-13","DSCA31-13C","DSCA31-15","DSCA31-1918","DSCA32-01","DSCA32-01C","DSCA32-01E","DSCA34-01","DSCA34-02C","DSCA34-04","DSCA34-04C","DSCA34-05","DSCA34-05C","DSCA34-1858","DSCA36-01","DSCA36-02","DSCA36-03","DSCA36-04","DSCA36-04C","DSCA36-1949","DSCA38-02","DSCA38-03","DSCA38-07","DSCA38-08C","DSCA38-09","DSCA38-09E","DSCA38-12C","DSCA38-12E","DSCA38-1468","DSCA38-1544","DSCA38-15C","DSCA38-16","DSCA38-16C","DSCA38-18C","DSCA38-19","DSCA40-03","DSCA40-05","DSCA40-05C","DSCA40-06","DSCA40-1951","DSCA40-1952","DSCA41-01","DSCA41-02","DSCA41-03","DSCA41-05C","DSCA41-06","DSCA41-09","DSCA41-13","DSCA41-14","DSCA41-15","DSCA41-15E","DSCA42-01","DSCA42-01C","DSCA42-02","DSCA43-10","DSCA43-20E","DSCA47E-08C","DSCA47J-01C","DSCA47J-03","DSCA47K-05","DSCA47K-13","DSCA47K-14","DSCA47N-15","DSCA47T-06","DSCA47T-1928"]
["DSCA30-01","DSCA30-02","DSCA30-03","DSCA30-06","DSCA30-07","DSCA30-08","DSCA30-08C","DSCA30-09","DSCA30-09C","DSCA30-1944","DSCA30-1945","DSCA30-1946","DSCA31-02","DSCA31-03","DSCA31-06","DSCA31-07","DSCA31-11","DSCA31-12","DSCA31-1273","DSCA31-12C","DSCA31-13","DSCA31-13C","DSCA31-15","DSCA31-1918","DSCA32-01","DSCA32-01C","DSCA32-01E","DSCA34-01","DSCA34-02C","DSCA34-04","DSCA34-04C","DSCA34-05","DSCA34-05C","DSCA34-1858","DSCA36-01","DSCA36-02","DSCA36-03","DSCA36-04","DSCA36-04C","DSCA36-1949","DSCA38-02","DSCA38-03","DSCA38-07","DSCA38-08C","DSCA38-09","DSCA38-09E","DSCA38-12C","DSCA38-12E","DSCA38-1468","DSCA38-1544","DSCA38-15C","DSCA38-16","DSCA38-16C","DSCA38-18C","DSCA38-19","DSCA39-01","DSCA39-02","DSCA39-07","DSCA40-03","DSCA40-05","DSCA40-05C","DSCA40-06","DSCA40-1951","DSCA40-1952","DSCA41-01","DSCA41-02","DSCA41-03","DSCA41-05C","DSCA41-06","DSCA41-09","DSCA41-13","DSCA41-14","DSCA41-15","DSCA41-15E","DSCA42-01","DSCA42-01C","DSCA42-02","DSCA43-10","DSCA43-20E","DSCA47E-08C","DSCA47J-01C","DSCA47J-03","DSCA47K-05","DSCA47K-13","DSCA47K-14","DSCA47N-15","DSCA47T-06","DSCA47T-1928"]

View File

@@ -15,16 +15,23 @@ function extract(t) {
const cols = colSpans(sep); if (cols.length < 4) return null;
const [pc, mc, sc, stc] = cols;
const rows = [];
let loadNote = null;
for (let i = hi + 2; i < lines.length; i++) {
const l = lines[i];
if (/Check List|^\s*_{5,}/.test(l)) break;
if (!l.trim()) continue;
// The "Standard output load for test is ... ohms." line is a footer note, not
// a parameter row — it spans past the name column so column-slicing truncates
// it ("Standard output load for te"). Capture the full line as loadNote and
// keep it out of rows; the renderer emits it (before the footer underline)
// only for models whose staged original actually printed it.
if (/^Standard output load/i.test(l.trim())) { loadNote = l.trim(); continue; }
const name = (l.slice(pc[0], mc[0]) || '').trim();
const spec = (l.slice(sc[0], stc[0]) || '').trim();
if (!name && !spec) continue;
rows.push({ name, spec });
}
return { accOut, rows };
return { accOut, rows, loadNote };
}
(async () => {
const files = walk(STAGE, []);
@@ -40,7 +47,7 @@ function extract(t) {
}
const models = Object.keys(byModel).sort();
console.log('DSCA models templated: ' + models.length);
const out = {}; for (const m of models) out[m] = { accOut: byModel[m].accOut, rows: byModel[m].rows };
const out = {}; for (const m of models) { out[m] = { accOut: byModel[m].accOut, rows: byModel[m].rows }; if (byModel[m].loadNote) out[m].loadNote = byModel[m].loadNote; }
fs.writeFileSync(OUT, JSON.stringify(out));
console.log('wrote ' + OUT + ' (' + fs.statSync(OUT).size + ' bytes)');
const rc = {}; for (const m of models) { const n = byModel[m].rows.length; rc[n] = (rc[n] || 0) + 1; }