← Commit history

demo: every picker part is now verified ANONYMOUSLY readable - 3 of the 10 were private, so the browser got 404 and the card reported 'blocked'. Also: verify the part name AFTER staging (the symbol's real name is only known then), and only verify surfaces whose window title actually names the part.

John Lauer ·1fa7c6b178 ·2mo ago ·parent a785ba3
1 file changed +36−26
web-control-demo.html+36−26
@@ -935,15 +935,20 @@ for (const w of mine) {     // The window title carries the part name, so this is cheap - and it is the     // check that would have caught a green "Done" printed over screenshots of     // the previous part (John, 2026-08-20) instead of shipping it as success.-    if (c._verifyName) {-      var want = norm(c._verifyName);+    // Resolve the expected name NOW, not when the card was clicked. The symbol's+    // real name is only learned during staging (kicad_install_symbol reports it),+    // which runs AFTER the click - so capturing a value up front pinned the file+    // stem and flagged a correct open as a mismatch.+    var expect = (typeof c._verifyName === "function") ? c._verifyName() : c._verifyName;+    if (expect) {+      var want = norm(expect);       var titles = withImg.map(function (s) { return (s.title || s.label || s.window || "").toString(); });       if (titles.length && !titles.some(function (t) { return norm(t).indexOf(want) >= 0; })) {         withImg.forEach(function (s) { addShot(c.card, s.image || s.base64 || s.png, "MISMATCH: " + (s.title || s.label || "window")); });         setRes(c.res, "err", "WRONG PART on screen",-          "asked for " + esc(c._verifyName) + " but the surface shows " + esc(titles.slice(0, 2).join(" | ")) ++          "asked for " + esc(expect) + " but the surface shows " + esc(titles.slice(0, 2).join(" | ")) +           " - the evidence below is NOT this part");-        clog(c, "  MISMATCH: no rendered window mentions '" + c._verifyName + "' -> " + titles.join(" | "));+        clog(c, "  MISMATCH: no rendered window mentions '" + expect + "' -> " + titles.join(" | "));         c.btn.disabled = false;         return true;       }@@ -1362,16 +1367,16 @@ for (const w of mine) {   // (1N4148, 2N7000, LM1117, TL074) are missing one and would fail halfway   // through staging, so they are deliberately not offered.   var PARTS = [-    { name: "CR0603-FX-5601ELF",   owner: "aravk", slug: "cr0603-fx-5601elf",   step: 40618,   kind: "resistor 0603" },-    { name: "CL21B104KBCNFNC",     owner: "aravk", slug: "cl21b104kbcnfnc",     step: 155456,  kind: "capacitor 0805" },-    { name: "WS2812B-2020",        owner: "aravk", slug: "ws2812b-2020",        step: 120696,  kind: "addressable LED" },-    { name: "IN-S42ATR",           owner: "aravk", slug: "in-s42atr",           step: 214421,  kind: "red 0402 LED" },-    { name: "tja1051t-3-118",      owner: "adom",  slug: "tja1051t-3-118",      step: 434142,  kind: "CAN transceiver" },-    { name: "nRF52840-CKAA",       owner: "john",  slug: "nrf52840-ckaa",       step: 593793,  kind: "BLE SoC (WLCSP)" },-    { name: "type-c-31-m-12",      owner: "adom",  slug: "type-c-31-m-12",      step: 1059856, kind: "USB-C receptacle" },-    { name: "ads1220irvar",        owner: "adom",  slug: "ads1220irvar",        step: 1930666, kind: "24-bit ADC - the ab#90 fixture" },-    { name: "rp2350b",             owner: "adom",  slug: "rp2350b",             step: 3059576, kind: "RP2350B MCU" },-    { name: "s10b-ph-sm4-tb",      owner: "adom",  slug: "s10b-ph-sm4-tb",      step: 3921735, kind: "JST PH 10-pin header - largest" }+    { name: "CR0603-FX-5601ELF",       owner: "aravk", slug: "cr0603-fx-5601elf",       step: 40618,   kind: "resistor 0603" },+    { name: "0402B102J500CT",          owner: "aravk", slug: "0402b102j500ct",          step: 43502,   kind: "capacitor 0402" },+    { name: "WS2812B-2020",            owner: "aravk", slug: "ws2812b-2020",            step: 120696,  kind: "addressable LED" },+    { name: "CL21B104KBCNFNC",         owner: "aravk", slug: "cl21b104kbcnfnc",         step: 155456,  kind: "capacitor 0805" },+    { name: "IN-S42ATR",               owner: "aravk", slug: "in-s42atr",               step: 214421,  kind: "red 0402 LED" },+    { name: "MachinePinLargeStandard", owner: "adom",  slug: "machinepinlargestandard", step: 293811,  kind: "machine pin, mechanical" },+    { name: "tja1051t-3-118",          owner: "adom",  slug: "tja1051t-3-118",          step: 434142,  kind: "CAN transceiver" },+    { name: "nRF52840-CKAA",           owner: "john",  slug: "nrf52840-ckaa",           step: 593793,  kind: "BLE SoC (WLCSP)" },+    { name: "nRF54L15",                owner: "john",  slug: "nrf54l15",                step: 1088914, kind: "BLE SoC - crosses the 1 MB chunk threshold" },+    { name: "s10b-ph-sm4-tb",          owner: "adom",  slug: "s10b-ph-sm4-tb",          step: 3921735, kind: "JST PH 10-pin header - over the /command body cap" }   ];   // A spec's label is a FUNCTION when it names the part (so it can be re-rendered   // when the part changes) and a plain STRING when it does not ("2D board", ...).@@ -1406,8 +1411,8 @@ for (const w of mine) {     var note = document.getElementById("part-note");     if (note) {       note.innerHTML = esc(PART.kind) + " - .step is <strong>" + fmtKB(PART.stepBytes) + "</strong>" +-        (PART.stepBytes > 2000000-          ? ' <span style="color:#3fb950">- staged in ~1 MB chunks via write_file_chunk (ab#90), so the 3D model transfers fine</span>'+        (PART.stepBytes > 1048576+          ? ' <span style="color:#3fb950">- over the ~2.5 MB /command body cap once base64-inflated, so it is staged in ~1 MB chunks via write_file_chunk (ab#90)</span>'           : "");     }   }@@ -1612,15 +1617,20 @@ for (const w of mine) {         stage: s.stage, pickTitle: s.pick, stateCmd: "kicad_state", note: s.note,         // Verify against the name we ACTUALLY asked for, which for a symbol is         // the in-file name, not the file stem.-        // WHAT can be verified by window title differs per surface:-        //   symbol    -> the in-file symbol name (often NOT the file stem)-        //   footprint -> the part name-        //   library   -> NOTHING: the window shows the LIBRARY, and its title-        //                is whichever symbol the editor landed on, so demanding-        //                the part name there is a false alarm, not a catch.-        verifyName: s.cmd === "kicad_show_library" ? null-                  : s.cmd === "kicad_show_symbol"  ? (PART.kicadSymbolName || PART.name)-                  : PART.name,+        // WHAT can be verified by window title differs per surface, because the+        // WINDOW differs. Only verify where the title actually names the part:+        //   symbol    -> "Adom:<NAME> - Symbol Editor"     verifiable+        //   footprint -> "Adom:<NAME> - Footprint Editor"  verifiable+        //   3d chip   -> "3D Viewer"                       NOT verifiable, generic title+        //   library   -> whichever symbol the editor landed on, not the part+        // Checking the last two reports a mismatch on a CORRECT open, and a false+        // alarm is worse than no alarm: it teaches you to ignore the real one. The+        // honest cost is that those two surfaces open but go unverified.+        verifyName: function () {+          return (s.cmd === "kicad_show_symbol")    ? (PART.kicadSymbolName || PART.name)+               : (s.cmd === "kicad_show_footprint") ? PART.name+               : null;+        },         onShown: function () { KICAD_SHOWN = PART.name; }       });     };@@ -1694,7 +1704,7 @@ for (const w of mine) {         // Fusion DESIGN surfaces (schematic / board / project) open a generated         // design whose window is not named after the part, so only the COMPONENT         // surfaces can be verified by title.-        verifyName: s.verifiable === false ? null : PART.name });+        verifyName: function () { return s.verifiable === false ? null : PART.name; } });     };   });   // Single full-screen shot (keep the simple case too).