The DSCA33/DSCA45 main spec files lost in the cryptolocker wipe are recoverable: the original software published correct certs to the Hoffman product API before the wipe and our null-skipping renderer never overwrote them. Mine per-model Final-Test templates (names + specs + verbatim accuracy headers) straight from those originals instead of requesting spec files from Dataforth/John. - dsca33-45-templates.json: 56 models (DSCA33 34/35, DSCA45 22/23); only DSCA33-1948 + DSCA45-1746 (24 units) lack an original. - mine-hoffman-dsca.py: the re-runnable miner. - DSCA33-45-HOFFMAN-RECOVERY handoff for the AD2 session (incl. the gate: validate each render vs its Hoffman original before enabling live rendering). - memories: Hoffman recovery (supersedes the spec-gap "need John" note) and the AD2 SSH MTU-blackhole root cause/fix; errorlog entries (syncro jq, ssh correction). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.6 KiB
DSCA33 / DSCA45 — Recover the "lost" specs from Hoffman (Handoff to AD2)
For: the Claude session on AD2 (C:\Shares\testdatadb). Ref: Syncro #32441.
Supersedes the FIX2-5 handoff's TODO 2 (request DSCA33/45 main spec files from John) —
we do not need John. The original specs are recoverable from the Hoffman API.
The finding (why this changes the plan)
The DSCA33/DSCA45 "main spec" records (DSCMAIN/DSCOUT with SENTYPE/MAXIN/input-type) were
lost in the cryptolocker wipe, so render-datasheet.js bails (null render) and the pipeline
skips those models. BUT the original software published correct DSCA33/45 certs to the
Hoffman API before the wipe, and our broken renderer never overwrote them (it skips null
renders). They are still there, pristine.
Verified from GURU-5070 against the public API
(GET https://www.dataforth.com/api/v1/TestReportDataFiles/{serial}, OAuth client-creds,
vaulted clients/dataforth/hoffman-product-api):
| Family | Models | Mineable from Hoffman | Units already correct+live on Hoffman | No original anywhere |
|---|---|---|---|---|
| DSCA33 | 35 | 34 | 2,633 / 3,397 | DSCA33-1948 (16 units) |
| DSCA45 | 23 | 22 | 4,524 / 5,413 | DSCA45-1746 (8 units) |
So of the ~8,763 "blocked" certs: ~7,157 are already correct and live on the public site (no action needed), ~1,580 not-yet-uploaded units just need rendering, and only 24 units across 2 niche models have no original to recover.
The artifact (already built — use it, don't re-derive)
projects/dataforth-dos/dsca33-45-templates.json — 56 models, mined from the Hoffman
originals with the same ===-rule column-span extractor as STAGE 1. Schema is a superset of
dsca-templates.json:
"DSCA45-05E": {
"accOut": "Output (mA)",
"accHeader": [
" Frequency Calculated Measured",
" (Hz) Output (mA) Output (mA)* Error (%) Status"
],
"rows": [ {"name":"Supply Current","spec":"< 105 mA"}, ... ],
"_srcSerial": "176326-2"
}
rows= the Final-TestParameter | Specificationlist (incl. the spec-less rows like240 VAC Withstand,Hi-Pot, and section sub-headsZero-Crossing Input/TTL Input— kept, same skip-rule reconciliation as STAGE 2).accHeader= the verbatim 2-line accuracy header from the original. Use it — DSCA33/45 introduce header tokens the 92-model set never had (see flags) and the frequency-input layout._srcSerial= a known already-uploaded serial for that model → your validation oracle.
Spot-checked DSCA33-07C and DSCA45-05E row-for-row against their live Hoffman originals: exact.
Regenerate if needed: python projects/dataforth-dos/tools/mine-hoffman-dsca.py <map.json> <out.json>.
Flags (DSCA33/45 differ from the 92 you already did)
- New accOut tokens:
Output (VDC)andOutput (mADC)(DSCA33 current/voltage DC outputs), not justOutput (V)/Output (mA). Your accuracy-block must emit the verbatim token. - Model-specific accuracy input label: DSCA33 uses
Vin (mVAC)/Vin (VAC)/Iin (AAC)/Iin (mAAC). Use theaccHeaderlines rather than synthesizing from a (missing) spec field. - DSCA45 is frequency-input: two-line super-header
Frequency/(Hz)and a frequency sweep in the accuracy block — structurally unlike the voltage/current-input models. Confirm the accuracy renderer reproduces it (theaccHeadergives you the exact text). - Your DSCA33/45 slotMaps are already derived and come from the same original layout as these rows, so order should align — verify during validation.
Plan
- Backup first (fresh
pg_dump+ VSS) per FIX2-5 discipline. Save-statedatasheet-exact.js. - Load
dsca33-45-templates.jsonforfamily in (DSCA33, DSCA45), same wiring as STAGE 2 (templaterowsdrive names+specs; map raw_data STATUS groups positionally via the slotMaps; QBMath.froundrounding; data-driven loadNote). For the accuracy block, drive the header fromaccHeader/accOut. - VALIDATE against Hoffman (the gate — stronger than STAGE 3): for each model, render its
_srcSerial(an already-uploaded unit) and content-normalized byte-compare againstGET /api/v1/TestReportDataFiles/{_srcSerial}. Require a clean match per model before that model is allowed to render/publish.CRITICAL — do not enable live DSCA33/45 rendering until each model passes. The moment the renderer returns non-null for DSCA33/45, the pipeline stops skipping them and will re-push and UPDATE the ~7,157 already-correct originals on the next cycle. That is only safe if the render byte-matches the original — which the per-model gate proves. A mismatched model would overwrite good customer certs. Gate hard.
- Publish the gap: for validated models, render +
uploadBySerialNumbersthe not-yet-uploaded units (~1,580;api_uploaded_at IS NULL). Already-uploaded units returnUnchanged(idempotent). - Leave blocked (24 units):
DSCA33-1948(16),DSCA45-1746(8) — no Hoffman original. Low priority; only these would ever need John, and they look like one-off custom part numbers.
Commit to ad2; update #32441 (hidden notes). The remote operator sees it on sync.
Reference
- Templates:
projects/dataforth-dos/dsca33-45-templates.json(56 models) - Miner:
projects/dataforth-dos/tools/mine-hoffman-dsca.py - Hoffman API creds: vault
clients/dataforth/hoffman-product-api(read =GET .../TestReportDataFiles/{serial}) - Memory:
project_dsca33_45_spec_gap(updated — resolved via Hoffman, not John)