← Commit history

2.1.0: CfT 152 fix + egress-IP finding (analog), 5 sites added (avnet, infineon, newark, nxp, rs-online), 2026-09-14 fleet matrix

John Lauer ·33fc603592 ·22d ago ·parent 91e4065
1 file changed +133−13
gen.py+133−13
@@ -8,7 +8,7 @@ sites. ASCII punctuation only (wiki rule: no em/en dashes anywhere). import json, os, re, sys  ROOT = os.path.dirname(os.path.abspath(__file__))-VERIFIED = "2026-09-12"+VERIFIED = "2026-09-14" PACK = "electronics-sites-skillpack" TITLE = "Electronics Industry Sites Skillpack" BRIEF = ("One skill per popular electronics-industry website (ST, TI, Mouser, DigiKey, SnapEDA, "@@ -20,7 +20,7 @@ LANES = ["WebFetch", "curl", "pup", "nb"] LANE_NOTE = {     "WebFetch": "the Anthropic fetcher behind WebFetch / WebSearch",     "curl": "curl or python from the Adom container",-    "pup": "pup, Chrome for Testing 148 in the durable adom-you profile, background window",+    "pup": "pup, Chrome for Testing 152 (matched to the installed Chrome as of pup 2.0.549) in the durable adom-you profile, extension lane (no debug port), background window",     "nb": "nb, the user's real signed-in Chrome 152 via the Adom Native Browser Extension", } @@ -141,18 +141,21 @@ SITES = [   dict(slug="analog", name="Analog Devices (incl. Maxim, Linear)", domains=["www.analog.com"],   what="Manufacturer. Product pages, datasheets, LTspice models, eval boards.",-  defense="Akamai Bot Manager, strict: RSTs curl's HTTP/2 stream and serves an 'Access Denied' page to pup.",+  defense="Akamai Bot Manager, strict. The single hardest case in this pack and the one that drove the 2026-09-14 investigation (see the root skill). TWO stacked causes, both measured: (1) browser VERSION - on CfT 148 the bmak sensor never initialised (typeof bmak undefined) and the edge denied; on CfT 152, matched to the installed Chrome, the sensor runs and the page loads; (2) egress IP - even on 152, loads from a VPN/Azure egress and denies from the bare office LAN NAT.",   lanes={-   "WebFetch": ("untested", ""),+   "WebFetch": ("BLOCKED", "Akamai edge"),    "curl": ("BLOCKED", "curl (92) HTTP/2 INTERNAL_ERROR in ~100 ms"),-   "pup": ("BLOCKED", "'Access Denied' page (217 chars)"),-   "nb": ("OK", "product page renders (AD8232 Datasheet and Product Info)"),+   "pup": ("PARTIAL", "CfT 152 REQUIRED (on 148 always denied). On 152: LOADS from a clean egress (AdomLapper VPN, winvm Azure, bmak:object), DENIED from the bare office LAN (arav-rog, ConfRoomROG, bmak:undefined). 2026-09-14"),+   "nb": ("OK", "the user's real Chrome loads it (AD8232 Datasheet and Product Info); use nb when pup's egress is flagged"),   },-  symptoms=["'Access Denied' + 'Reference #18.xxxxxxxx'", "HTTP/2 stream reset to curl"],-  recipes=[("Anything on analog.com", "nb only. Datasheet PDFs are under /media/en/technical-documentation/data-sheets/<part>.pdf; fetch them with nbrowser_fetch_url once you have the link from the page.")],+  symptoms=["'Access Denied' + 'Reference #18.3351db17...'", "typeof bmak === undefined on the denied page (rejected upstream)", "HTTP/2 stream reset to curl"],+  recipes=[+   ("Load the site in pup", "Requires CfT matched to the installed Chrome (pup 2.0.549+, CfT 152). If it still denies with bmak undefined, the egress IP is flagged: use nb, or a box on a VPN/residential/cloud IP. Clear cookies first if it denied you earlier: pup_clear_cookies {domain:'analog.com'}."),+   ("Datasheet PDF", "/media/en/technical-documentation/data-sheets/<part>.pdf; nbrowser_fetch_url once you have the link, or pup on a clean egress."),+  ],   api="None public. Stock via adom-parts-search.",-  gotchas=["Same edge behavior as st.com and arrow.com: do not retry, switch to nb."],-  evidence="curl + pup + nb sweep 2026-09-12."),+  gotchas=["Never conclude 'analog is down' - it is version+IP. Check CfT version (pup_readiness.chromeBuildId) and the egress before blaming the site.", "The denial poisons _abck to ~-1~; clear it before re-testing."],+  evidence="Full 2026-09-14 investigation: CfT 148->152 flips bmak undefined->object; 4-box egress split measured. Earlier curl+pup+nb sweep 2026-09-12."),   dict(slug="arrow", name="Arrow Electronics", domains=["www.arrow.com"],   what="Distributor. Product search, stock, price, reference designs; free CAD via its own SnapEDA/UL embeds.",@@ -259,6 +262,84 @@ SITES = [   gotchas=["JLCPCB is never the delivery recommendation in adom-parts-search; it is the assembly library."],   evidence="curl sweep 2026-09-12; browser lanes not yet verified: contribute."), + dict(slug="nxp", name="NXP Semiconductors", domains=["www.nxp.com"],+  what="Manufacturer. Product pages, datasheets, dev boards, MCUXpresso software.",+  defense="Header-class at most; loads on every lane with the consumer identity. No blocking wall observed 2026-09-14.",+  lanes={+   "WebFetch": ("OK", "product and datasheet pages return"),+   "curl": ("PARTIAL", "200 but JS-heavy; use pup for rendered content"),+   "pup": ("OK", "loads on every box, all four egresses, 2026-09-14 (extension lane, CfT 152)"),+   "nb": ("OK", "loads"),+  },+  symptoms=["none - loads"],+  recipes=[("Datasheet / product page", "pup_open_window {url:'https://www.nxp.com/...'}; datasheets are linked from the Documentation tab.")],+  api="None public for product data; stock via adom-parts-search.",+  gotchas=["Heavy SPA - allow the page to settle before reading innerText."],+  evidence="20-site fleet matrix 2026-09-14, pup 2.0.549 / CfT 152: loaded on all four boxes."),++ dict(slug="infineon", name="Infineon Technologies", domains=["www.infineon.com"],+  what="Manufacturer (incl. Cypress). Product pages, datasheets, ModusToolbox, eval boards.",+  defense="Header-class at most; loads on every lane. WebFetch passes (noted in the root ladder).",+  lanes={+   "WebFetch": ("OK", "passes - one of the fetch-friendly manufacturers"),+   "curl": ("OK", "200"),+   "pup": ("OK", "loads on every box and egress, 2026-09-14 (extension lane, CfT 152)"),+   "nb": ("OK", "loads"),+  },+  symptoms=["none - loads"],+  recipes=[("Datasheet / product page", "WebFetch is enough for text; pup for the rendered page and CAD links.")],+  api="None public for product data; stock via adom-parts-search.",+  gotchas=["Cypress parts live under infineon.com now; old cypress.com links redirect."],+  evidence="20-site fleet matrix 2026-09-14: loaded on all four boxes."),++ dict(slug="rs-online", name="RS (RS Components / Allied)", domains=["www.rs-online.com", "uk.rs-online.com"],+  what="Distributor. Product pages, stock, price, datasheet links; regional domains.",+  defense="None blocking observed 2026-09-14; loads on every lane.",+  lanes={+   "WebFetch": ("OK", "product pages return"),+   "curl": ("PARTIAL", "200; JS for stock/price"),+   "pup": ("OK", "loads on every box and egress, 2026-09-14 (extension lane, CfT 152)"),+   "nb": ("OK", "loads"),+  },+  symptoms=["none - loads"],+  recipes=[("Product page / datasheet", "pup_open_window; the US site is www.rs-online.com, UK is uk.rs-online.com - use the region the part is stocked in.")],+  api="Stock/price via adom-parts-search where available.",+  gotchas=["Region-split domains: a part may show 'no stock' on the wrong regional site."],+  evidence="20-site fleet matrix 2026-09-14: loaded on all four boxes."),++ dict(slug="newark", name="Newark / element14 (Farnell)", domains=["www.newark.com", "www.farnell.com"],+  what="Distributor (Avnet-owned). Product pages, stock, price, datasheets; element14 community.",+  defense="None blocking observed 2026-09-14; loads on every lane. (Contrast avnet.com, the parent, which runs an interactive Akamai challenge.)",+  lanes={+   "WebFetch": ("OK", "product pages return"),+   "curl": ("PARTIAL", "200; JS for stock/price"),+   "pup": ("OK", "loads on every box and egress, 2026-09-14 (extension lane, CfT 152)"),+   "nb": ("OK", "loads"),+  },+  symptoms=["none - loads"],+  recipes=[("Product page / datasheet", "pup_open_window {url:'https://www.newark.com/...'}; Farnell is the EU face of the same catalog.")],+  api="Stock/price via adom-parts-search where available.",+  gotchas=["Newark (US) and Farnell (EU) share a catalog but split stock by region."],+  evidence="20-site fleet matrix 2026-09-14: loaded on all four boxes."),++ dict(slug="avnet", name="Avnet", domains=["www.avnet.com"],+  what="Distributor. Product search, stock, design services.",+  defense="Akamai INTERACTIVE challenge ('Challenge Validation'). Denied on every box and egress 2026-09-14 - this is a human-click wall, not a silent block.",+  lanes={+   "WebFetch": ("BLOCKED", "challenge"),+   "curl": ("BLOCKED", "challenge"),+   "pup": ("BLOCKED", "'Challenge Validation' on every box and egress, 2026-09-14 - the interactive Akamai challenge, not a fingerprint issue"),+   "nb": ("PARTIAL", "the user can complete the challenge by hand in their real browser; hand it to them"),+  },+  symptoms=["title 'Challenge Validation'", "an interactive Akamai challenge widget"],+  recipes=[+   ("Product data", "Do not fight the challenge in pup. Use Newark/element14 (avnet-owned, same catalog, no challenge) or adom-parts-search for numbers."),+   ("Must be avnet.com specifically", "nb, and hand the challenge to the user to click - this is nb's whole job for a human-gated wall."),+  ],+  api="Stock via adom-parts-search / the Newark catalog.",+  gotchas=["An interactive challenge is NOT the version/IP problem analog has - no browser change clears a human-click wall. Route to Newark or nb."],+  evidence="20-site fleet matrix 2026-09-14: denied on all four boxes with 'Challenge Validation'."),+  dict(slug="manufacturer", name="Other manufacturers (generic playbook)", domains=["www.nxp.com", "www.infineon.com", "www.renesas.com", "www.espressif.com", "www.newark.com (Farnell / Avnet)"],   what="The generic approach for a manufacturer or distributor site that does not have its own skill yet, plus lane-0 readings for a few we have only curl-tested.",   defense="Varies. Lane-0 readings 2026-09-12: infineon.com 200 (open), renesas.com 200 (Cloudflare, passes curl), espressif.com 200 (Apache, open), newark.com 200 (Akamai, passes curl), nxp.com 404 on /products/ (URL shape differs; product pages are /products/<family>/...:<PART>).",@@ -362,9 +443,47 @@ evidence, so the next AI routes around the wall in one move instead of rediscove  Every sub-skill has the same sections (domains, bot defense, lane matrix, failure signatures, recipes, API lane, gotchas, evidence). Verified live on {VERIFIED} from an Adom cloud container against a-Windows desktop running Adom Bridge 2.1.104, pup 2.0.464 (Chrome for Testing 148) and the Native+Windows desktop running Adom Bridge 2.1.104, pup 2.0.549 (Chrome for Testing 152, extension lane) and the Native Browser Extension 0.16.14 (Chrome 152). +## 2026-09-14 update: two causes that are NOT the page, found chasing analog.com++Two independent discoveries this date, each measured, that reframe the hardest Akamai sites:++**1. The Chrome-for-Testing VERSION is itself a bot signal.** pup pinned CfT 148 while the user's+real Chrome was 152. On 148, Akamai's `bmak` sensor never initialised (`typeof bmak === "undefined"`+on every load) and analog.com served Access Denied. On CfT **152** (matched to the installed Chrome)+the sensor initialises (`typeof bmak === "object"`), runs, and the page loads. It was NOT a fingerprint+match (the JA4 still differs from branded Chrome); Akamai gated on the sensor being able to EXECUTE,+which a 4-version-old build broke. Keep CfT within ~1 milestone of the installed Chrome. Several sites+that were pup-BLOCKED on 148 (st.com among them) load on 152. Diagnostic on a denial: `typeof bmak`+`undefined` = rejected upstream (version or IP); `object` = the sensor ran and failed you (IP/behaviour).++**2. Egress IP reputation is a separate, stacked cause.** Same CfT 152, same code, four boxes:+AdomLapper (corporate VPN egress) and winvm (Azure) LOAD analog.com; arav-rog and ConfRoomROG (bare+office LAN) are DENIED. Identical browser, opposite result: the bare office NAT IP is Akamai-flagged.+pup cannot fix this from inside the browser; the lever is a cleaner egress (VPN/residential/cloud) or+nb on the user's own connection.++**Cookie hygiene:** a rejected Akamai visit writes `_abck` to a `~-1~` reject state that persists.+`pup_clear_cookies {{domain}}` / `pup_clear_site_data {{origins}}` before re-testing, or the stale verdict+masks a fix.++## Fleet matrix (extension lane, CfT 152, 2026-09-14)++16 of 20 load on every box; the spread is the Akamai-hardened four (analog, avnet, arrow, digikey):++| Site | AdomLapper (VPN) | arav-rog (office) | ConfRoomROG (office) | winvm (Azure) |+|---|:--:|:--:|:--:|:--:|+| ST, Mouser*, TI, Microchip, Nordic, SnapEDA, UltraLib, CSE, Octopart, LCSC, JLCPCB, Newark, RS, Infineon, NXP | load | load | load | load |+| DigiKey | load | load | block | block |+| Arrow | load | block | block | block |+| Analog | load | block | block | load |+| Datasheets | load | load | load | block |+| Avnet | interactive Akamai challenge (human click, nb's job) | | | |++*Mouser loads its home page but scores behaviour on crawls (DataDome) - use the API for data.+ ## The rule: a fetch failure on a vendor domain is a ROUTING signal  1. **One plain attempt only.** WebFetch or curl once. It is the cheapest lane and it works on TI,@@ -503,6 +622,7 @@ def main():             'install_skill(){ mkdir -p "$DEST/$1"; cp "$2" "$DEST/$1/SKILL.md"; echo "  installed $1"; }',             'echo "Installing electronics-sites-skillpack -> $DEST"',             'install_skill electronics-sites SKILL.md']+    names.append(('electronics-sites-template', 'skills/_template/SKILL.md'))     inst += [f'install_skill {n} {p}' for n, p in names]     inst += ['# v1 of this pack was named chip-sourcing-*; retire those copies so the two sets do not drift',              'for old in chip-sourcing chip-sourcing-digikey chip-sourcing-mouser chip-sourcing-snapeda chip-sourcing-manufacturer; do rm -rf "$DEST/$old"; done',@@ -520,7 +640,7 @@ def main():                {"label": "Which browser for DigiKey", "prompt": "which browser lane do I need to read a DigiKey product page"},                {"label": "Mouser 200 but denied", "prompt": "why does Mouser return HTTP 200 with access denied and what do I do"},                {"label": "Add a site", "prompt": "add an electronics-sites skill for nxp.com and verify its lanes"}]-    pkg = {"name": PACK, "slug": PACK, "version": "2.0.1", "type": "skill", "title": TITLE, "description": BRIEF,+    pkg = {"name": PACK, "slug": PACK, "version": "2.1.0", "type": "skill", "title": TITLE, "description": BRIEF,            "license": "MIT", "files": files, "scripts": {"install": "./install.sh", "uninstall": "./uninstall.sh"},            "dependencies": {}, "tags": TAGS, "keywords": TAGS, "discovery_triggers": TRIGGERS, "discovery_pitch": PITCH,            "sample_prompts": PROMPTS, "hero": {"path": "docs/hero.png"}}@@ -568,7 +688,7 @@ No captcha solving, no fingerprint spoofing: this pack routes around walls, it d """     write("README.md", readme)     page = json.load(open(os.path.join(ROOT, "page.json")))-    page.update({"slug": PACK, "version": "2.0.1", "title": TITLE, "brief": BRIEF, "readme": readme, "license": "MIT",+    page.update({"slug": PACK, "version": "2.1.0", "title": TITLE, "brief": BRIEF, "readme": readme, "license": "MIT",                  "tags": TAGS,                  "hero": {"type": "image", "path": "docs/hero.png"},                  "sample_prompts": PROMPTS, "discovery_triggers": TRIGGERS, "discovery_pitch": PITCH,