BOMwiki the bill-of-materials encyclopedia
30,441,948 parts mapped · 192,925 items

BOM Intelligence

BOMwiki runs beside an analysis engine called bomwiki-intelligence. It is a Rust program that reads a snapshot of a product's bill of materials and checks it with deterministic graph algorithms. The wiki sends it every proposed change before a reviewer sees it, sweeps the whole catalog through it on a schedule, and uses its results to award the machine-checked tier of verification. This page explains how it works in enough detail that you can judge the findings it produces. The implementation is closed source; the interface it speaks is open and documented at the bottom.

Products are function graphs

A part number tells a machine nothing. "608ZZ" and "deep-groove ball bearing, 8 mm bore" are the same object, and neither string says what the object is for. So the engine's first move is to leave the part-number world entirely and tag every item against a fixed taxonomy of 20 mechanical functions: store_energy, convert_energy, transmit_motion, guide_motion, fasten_join, support_structure, protect_enclose, seal_contain, regulate_flow, thermal_manage, sense_measure, control_compute, connect_electrical, communicate_signal, display_information, human_interface, process_material, filter_clean, provide_safety, store_material.

Tagging is deterministic. Each function carries a set of seed phrases; item names and summaries are normalized and matched against them; every tag records the exact phrase that produced it as evidence. There is no model in the loop, so the same item always gets the same tag and every tag can be traced back to the words that earned it.

Once items carry functions, a product stops being a list of part numbers and becomes a function profile: the rollup of every function in its subtree, weighted by quantity. That representation is what lets a machine say useful things about hardware it has never seen. A cordless drill and an angle grinder share no part numbers, but both decompose into store energy, convert it to rotation, transmit it to a work surface, and keep fingers out.

×10 ×3 ×14 cordless drill battery pack motor gearbox chuck housing 18650 cell BMS rotor stator planet gear ring gear M3 screw function rollup store_energy11 convert_energy3 transmit_motion6 fasten_join14 control_compute1 protect_enclose1 the same profile computed for every product in the catalog, from a fixed taxonomy of 20 functions
Fig. 1 · The same product seen two ways: a part tree (colored by tagged function) and its function rollup. Items that map to no function are flagged as weakly justified.

The profile does immediate editorial work. An item whose name and summary match no function lands in the unknown bucket and gets flagged as weakly justified: a candidate for renaming, removal, or better evidence. A product whose profile contradicts its nature, say a kettle dominated by transmit_motion, directs reviewer attention before any human has read the page.

The shape of the catalog

The whole catalog is one directed graph: about 192,000 items connected by parent-child BOM lines, rolling up to about 30 million part positions across roughly 4,900 products. Two properties matter for analysis.

Parts are shared. A 608 ball bearing is a single entry with many parents, so evidence attached to it once serves every machine that uses it, and a correction propagates everywhere in one edit. Quantities multiply along paths during explosion: 2 gearboxes × 3 planet gears × 1 bearing is 6 bearings, and the largest page on the site rolls up to about 5.6 million parts this way.

The graph is acyclic. A part cannot contain itself at any depth. The wiki engine enforces this at write time by walking ancestors before accepting any BOM line, and the analyzer independently re-derives it with its own traversal, so a cycle would have to slip past two unrelated implementations. Degree and depth statistics from the same traversal feed the complexity check: an assembly with an unusual number of direct children is flagged as an integration or standardization candidate, with its dominant function attached for context.

espresso machine angle grinder vibration pump spindle assembly 608 ball bearing one entry, many parents gearbox planet carrier ✗ a part containing its own ancestor is rejected at write time; the catalog stays a verified DAG
Fig. 2 · The catalog is a directed acyclic graph. Shared parts have one page and many parents; cycles cannot be written.

What happens to every proposed change

Analysis is wired into the edit loop itself. The pipeline below runs on every proposed changeset, from any account, before a human reviewer looks at it.

proposed changeset structural gates (wiki engine) subtree projection POST /api/analyze → sidecar findings attached to the changeset human decision from any account, via the on-page editor references must exist, quantities must be sane, no duplicate lines, no cycles. Failures are rejected outright, never stored. the affected product trees with the edits overlaid: analysis sees the catalog as it would look if accepted. Up to 3 roots, 20,000 nodes. 4-second budget. If the sidecar is down or slow there are simply no machine findings; analysis is advisory and never blocks an edit. stored with the changeset, shown beside the diff in the review queue on accept, the proposal is three-way merged with the live page, revalidated, and the merged result that ships is analyzed again
Fig. 3 · The change pipeline. Structural checks are binding and run in the wiki engine itself; analyzer findings are advisory context for the human reviewer.

Two details are worth pausing on. First, projection: the analyzer never sees the edit as a diff. The wiki walks the affected product trees with the proposed edits overlaid on the live graph, so the analysis describes the future state of the catalog, including interactions between the edit and parts of the tree the editor never touched. Second, re-analysis at accept time: because concurrent edits are merged field by field, what actually ships can differ from what was proposed, so the merged result is analyzed again and the findings on record always describe what went live.

Layered validators

The engine is built as independent validator layers over one graph. Each layer engages when the data it needs exists, returns a verdict of PASS or REVIEW plus a score from 0 to 1, and reports what it could not check, so a passing score on thin data never masquerades as a passing score on rich data.

layerwhat it checksdata that engages itstatus on BOMwiki
structuredangling references, duplicate lines, quantity sanity, cyclesBOM lines alonelive, binding
functiontaxonomy tags, rollups, weakly justified items, complexity outliersitem names and summarieslive, advisory
interface compatibilitymated connections agree on diameter, thread pitch, pin count, voltage, current, pressure, flowinterface ports and numeric specs on partsdormant until pages carry port data
process feasibilityrouting steps form a valid sequence and each operation fits a real machine's force, torque, bed size, and accuracy, with time rollupsroutings, machines, toolingdormant
sourcing feasibilitywhether every part can arrive by a required date given lead times, freight, customs, open orders, and supplier ratingssupplier and logistics recordsdormant

The interface layer shows the flavor of the dormant checks. Parts declare typed ports carrying numeric keys (shaft_diameter_mm, bore_diameter_mm, thread_pitch_mm, pin_count, voltage_v, current_a, pressure_bar, flow_lpm). Declared connections are validated against rules; where no connections are declared, the engine infers plausible ones from the tree and validates those. A failed connection produces both an issue and, when the catalog contains a bridging part, a repair suggestion.

DC motor port: shaft shaft_diameter_mm: 5.0 planetary gearbox port: input bore bore_diameter_mm: 6.0 ✗ issue: shaft 5.0 mm does not match bore 6.0 mm suggestion: 5 mm to 6 mm shaft coupler, found in the catalog
Fig. 4 · An interface check. Both parts exist and the BOM is structurally valid, but the connection is physically impossible. This is the class of error part numbers can never surface.

This is the practical reason BOMwiki asks editors for specs and not just part lists. Every port, tolerance, or spec a contributor adds moves a page from "the machine checked its shape" toward "the machine checked its physics."

The catalog sweep

Beyond per-change review, the engine periodically sweeps the entire graph. The sweep computes suspicion signals for every product: boilerplate summaries repeated across unrelated items, cloned BOM shapes (identical child structures under different names), quantity outliers, items with no parents, and references to pages that do not exist. Products that pass hold the machine-checked tier; the rest sit on a public cleanup worklist. Machine-checked asserts coherence only. The tier above it, human-verified, is granted by people citing evidence and is the strongest trust signal a page can carry. The methodology and its current counts live on the verification page.

Deterministic by design

A checker must not share the failure modes of the content it checks. The largest risk to a BOM catalog is plausible generated content, and a generative checker rates plausibility highly by construction. So every check above is a graph algorithm: reproducible, since the same snapshot always yields the same findings, and explainable, since every finding carries the path, the count, or the seed phrase that produced it. There is no confidence score anywhere in the system that cannot be traced to arithmetic.

The limits are stated just as plainly. The engine can prove a BOM is coherent. It cannot prove a BOM is true. A perfectly consistent tree of parts that were never in the real product passes every structural check. Truth on BOMwiki comes from people citing evidence; the engine's job is to make incoherence impossible to publish and to point reviewers at the pages most worth their attention.

The same layers also gate generation rather than compete with it. The engine emits grounded feature packs (graph statistics, function profiles, rollups) that ranking or drafting models can consume, and any machine-drafted candidate BOM must pass every deterministic gate before a reviewer ever sees it.

The open interface

The public wiki-engine source set documents the analyzer as an optional sidecar behind one HTTP endpoint. It is an AGPL-3.0 reading mirror, not a complete runnable checkout. The analyzer contract itself remains public and is documented below.

POST /api/analyze?product=drill-cordless
{
  "items": [
    { "id": "drill-cordless", "name": "Cordless drill",
      "description": "Handheld 18 V drill driver", "item_type": "product" },
    { "id": "motor-dc", "name": "DC motor",
      "description": "Brushless outrunner", "item_type": "part" }
  ],
  "products": [
    { "id": "drill-cordless", "name": "Cordless drill",
      "root_item_id": "drill-cordless" }
  ],
  "bom_lines": [
    { "parent_id": "drill-cordless", "child_id": "motor-dc", "quantity": 1 }
  ]
}
200 OK (abridged)
{
  "bom_review": {
    "function_profile": { "functions": [
      { "function_id": "convert_energy", "function": "Convert energy", "item_count": 1 },
      { "function_id": "unknown",        "function": "Unknown",        "item_count": 1 }
    ] },
    "complexity_candidates": [
      { "item_id": "drill-cordless", "name": "Cordless drill",
        "child_count": 1, "dominant_function": "convert_energy" }
    ]
  }
}

The snapshot accepts richer optional sections (interface_ports, compatibility_rules, routings, machines, supplier_parts, cost_records), and each one a caller supplies engages the corresponding validator layer in the response.

See also: how verification works · governance · how to edit · policies