Skip to content

part-watch — the lifecycle and price watch

Task #101 (Purchasing). The nightly pass that tells us a part we build with has gone not-recommended or sharply more expensive, before a build order needs it. Procedure: SOP-034 (sop.embeddedera.com). Source assistant/scripts/part-watch, installed at ~/.local/bin/part-watch, tests assistant/tests/test_part_watch.py.

Why it is this shape

The plan called for it in ai-across-departments — third of the five things worth doing, "on keys we already hold, raising tasks… the one that quietly saves a build six months from now". Three constraints shaped it:

  • No new service and no AI. It is a deterministic scan. Nexar/Octopart was rejected in the same note for being paid when we already hold Digi-Key and Mouser keys.
  • Reuse, not rebuild. The cache, the daily API budget and the status/price parsing were already in partlookup.py; the "scanner raises a deduplicated Kanboard task" pattern was already in sop-tasks. part-watch is the thin part in the middle: scope, baseline, and the two thresholds.
  • Cache aggressively, never poll. Only BOM parts, only records older than seven days, a per-run fetch cap, inside the shared daily budget. About 33 MPNs × 2 sources ≈ 10 calls a night against a 400-call budget, so an interactive part-lookup never waits on it.

What it watches

Manufacturer part numbers reachable from an active assembly's BOM, including substitutes and sub-assembly BOMs. Today that is 33 MPNs across Robot Cow (EE-A-0002-A), Cow Remote (EE-A-0004-A), Cow Finger (EE-A-0005-A) and Dashcam Drive (EE-A-0001).

Two findings, each deduplicated to one task per part: lifecycle (NRND, not-for-new-design, obsolete, discontinued, EOL, last-time-buy — high, due 14 days, closes itself when the status clears) and price (≥15% and ≥$0.01 on the price at 100 against the last agreed baseline — normal, due 30 days, only a person closes it). Not-found at a distributor is never a finding.

Coverage — read this before trusting a clean run

A quiet night means "nothing bad in what we can see", and what we can see is narrower than the BOM:

  • 18 BOM components carry no manufacturer part, so they are invisible to the watch: EE-C-0001, 0065, 0069, 0098, 0131, 0143, 0173, 0182, 0185, 0186, 0187, 0188, 0189, 0190, 0191, 0192, 0193, 0194. (The four EE-P PCBs have none by design — they are ours.) R16/R29–R44 on the Cow Remote alone is eleven placements of one unwatched resistor.
  • ~11 of the 33 watched MPNs are carried by neither distributor — the DB125 connectors, the E01-ML01 radios, SZYY1206O, HY-DSHP04TS, FRC0603F1002TS, YBK0805X5R476M6R3NT and friends. They are LCSC parts and LCSC has no public lookup, so their obsolescence risk sits with whoever places the JLCPCB order.
  • Two MPNs look like catalogue placeholders, not orderable parts. PTS810 is the C&K switch series root, not a full part number, and BAT54S,215 is a packaging-suffixed Nexperia number; both come back from Digi-Key as not found and only resolve at Mouser. Worth tightening in the ERP so the watch and a purchase order agree on what we buy.

First run, 2026-09-18: 33 MPNs scanned, 10 with no distributor data, no bad lifecycle status anywhere, no price findings, baselines stored for 23 MPNs. The fetch pass cost four API calls out of a 400/day budget. The parts worth watching for cost are STM32G0B1KET6 at ~$3.59/100 and the USB-C receptacle at $0.25; everything else on these boards is passives at under two cents.

Open

  • Add manufacturer parts to the 18 BOM components listed above, so the watch can see them. Engineering owns part records (SOP-002); the fastest route is the intake "Create part number" form, which takes a distributor link. Until this is done, a clean part-watch night covers roughly two thirds of each board.
  • Decide what to do about the LCSC-only parts: either a second source per part, or an explicit statement in SOP-034 that their risk is accepted and reviewed at each order.
  • After Purchasing works the first real finding end to end, lift SOP-034 out of draft.

Log

  • 2026-09-18: built, reviewed, installed and seeded. Scope, thresholds and the Kanboard reconciliation follow sop-tasks; 12 offline fixture tests; part-watch.timer nightly at 04:50. Review caught the one that mattered: the lifecycle auto-close fired whenever no source reported a bad status, which includes a part that has vanished from both catalogues — so a discontinued part would have closed its own task saying "normal again" at the moment it became unbuyable. The close is now gated on having data. Assistant e44fdce.
  • 2026-09-18: task #101 closed. The card's only machine check pointed at decisions/ai-across-departments.md with a phrase that is not in the vault; corrected to projects/ai-across-departments.md and the sentence that is actually there. The register requires the Done: comment to come from the card's owner, so #101 moved from Yara to Angel before closing — Purchasing owns the procedure (SOP-034), Engineering built the tool. task-verify passed every line and moved it to Done.