main
John Lauer bridge-rs: Rust bridge vertical slice (health via ab, agent file-IPC, Phase 1 verbs) — verified live on AdomLapper; doc… 0be1503 1mo ago

Adom Altium-Bridge Phase-2 Design-Lint Catalog

Field Value
Title Adom altium-bridge Phase-2 DESIGN-LINT CATALOG
Document id ALTIUM-LINT-SPEC-001
Status SPEC ONLY — no implementation, no scripts to ship
Modeled on eda-agent design_lint_report (31 checks) plus 4 Adom-specific checks
Check count 35
Date 2026-08-31

Purpose

This catalog is the Phase-2 read-only design-lint specification for Adom's altium-bridge. It lists every check an agent is expected to run against an open Altium Designer project, including:

  • What each check detects
  • Severity (error / warning / info)
  • Surface (schematic sheet / PCB board / library / project)
  • Altium DelphiScript objects and properties to read (no mutating APIs except read-side rebuilds such as Polygon.Rebuild used only to inspect pour state)
  • Detection logic in plain steps
  • An example good finding message

The catalog maps 1:1 onto eda-agent's 31-check design_lint_report sweep (schematic hygiene, connectivity, PCB geometry, variant DNP, polygon validity) and adds four Adom extras:

  1. mouser_digikey_lcsc_params — all three supplier PNs required
  2. pin1_symbol_footprint — pin-1 / pad-1 disagreement
  3. unused_mechanical_layers — mechanical layers with leftover content
  4. missing_power_testpoints — power rails without a test point

Severity mapping vs eda-agent: eda-agent uses critical / warning / info. This catalog uses error / warning / info (error ≡ eda-agent critical).

Out of scope

  • No implementation. This file is not Pascal, Python, or MCP tool code.
  • Do not launch Altium. Do not open .PcbDoc / .SchDoc / .PrjPcb.
  • Do not touch any altium-bridge repo, Adom Bridge folders, or Altium install.
  • Do not run adom-bridge / altium_eval against a live designer in this phase.
  • Do not write exploits, DRC mutators, or auto-fix scripts. Lint is read-only. pcb.run_drc (if ever invoked later) mutates the .DRC report file and is optional, off by default.
  • Library authoring (creating symbols/footprints) is out of scope; library reads (models, pin-1, 3D bodies) are in scope.

How an AI would run these checks later (via altium_eval)

This is documentation of the intended execution model. It is not permission to run it now.

  1. Ensure Altium Designer has the target .PrjPcb focused and compiled (IProject.DM_Compile / workspace GetWorkspace). Prefer SmartCompile; force recompile only if the netlist is stale.
  2. For each check, emit a read-only DelphiScript snippet (no AddPCBObject, no SchObjectFactory create, no file writes except returning JSON through the bridge stdout/IPC channel).
  3. Send the snippet through the existing altium-bridge altium_eval (or equivalent audit.* IPC command) against SchServer / PCBServer.
  4. Typical entry points:
    • Schematic: SchServer.GetCurrentSchDocument → ISch_Document / ISch_Sheet; SchIterator_Create; AddFilter_ObjectSet(MkSet(eSchPort, eNetLabel, ePowerPort, eSchComponent, …)).
    • PCB: Board := PCBServer.GetCurrentPCBBoard; Board.BoardIterator_Create; Iterator.AddFilter_ObjectSet(MkSet(eViaObject, ePadObject, eTrackObject, …)); Iterator.AddFilter_LayerSet(AllLayers); Iterator.AddFilter_Method(eProcessAll).
    • Project / nets: GetWorkspace → IWorkspace → IProject → IDocument / flattened DM_DocumentFlattened; INet.DM_PinCount, IComponent.
  5. Destroy iterators (SchIterator_Destroy, BoardIterator_Destroy) after each walk.
  6. Aggregate {checked, violations, items[]} per check into a design_lint_report-shaped payload: summary, sections, totals, _failed.
  7. Never highlight/select on canvas as the primary result; return structured findings with designator, net, sheet/board, and coordinates in mils.

Shared API conventions (verified unless marked)

Server Object Notes
SchServer ISch_Sheet / ISch_Document Current schematic
SchServer ISch_Iterator SchIterator_Create / FirstSchObject / NextSchObject
Object ids eSchPort, eNetLabel, ePowerPort / ePowerObject, eSchComponent, ePin, eWire, eBus, eSheetEntry, eImage
Interfaces ISch_Port, ISch_NetLabel, ISch_PowerPort / ISch_PowerObject, ISch_Component, ISch_Pin, ISch_Parameter, ISch_Wire
PCBServer IPCB_Board PCBServer.GetCurrentPCBBoard
Iterators BoardIterator_Create, spatial iterator, group iterator
Objects IPCB_Component, IPCB_Via, IPCB_Pad, IPCB_Track, IPCB_Arc, IPCB_Polygon, IPCB_BoardOutline, IPCB_LayerObject, IPCB_Text, IPCB_ComponentBody, IPCB_Net, IPCB_Region
Stack ILayerStack
Workspace IWorkspace, IProject, IDocument, IComponent, INet Flattened netlist after compile
Units TCoord; MilsToCoord / CoordToMils 1 mil = 10000 internal units

ResetParameters is a parametric-process helper (Client API), not an object walker; lint scripts should not need it unless invoking a process.


Check catalog

Each check uses snake_case id. eda-agent names are noted where they differ.


1. floating_ports

  • name: Floating / unconnected schematic ports
  • what it detects: Ports whose electrical hotspot is not on a wire, pin, or sheet entry, or whose net does not appear on any pin / sheet entry on the same sheet.
  • severity: warning
  • surface: schematic sheet
  • eda-agent analog: find_floating_ports
  • API to read:
    • ISch_Sheet + ISch_Iterator filtered to eSchPort → ISch_Port
    • ISch_Port.Name / Text (net name), Location / Location.X / Location.Y UNVERIFIED exact location property name (ISch_GraphicalObject.Location is typical)
    • Spatial / small-area iterator at the port hotspot for eWire, ePin, eSheetEntry
    • Flattened INet membership as a second signal
  • detection logic:
    1. Compile the project.
    2. For every schematic sheet, iterate eSchPort.
    3. A port is floating if no eWire / pin / sheet entry occupies its hotspot or the flattened net for that port name has zero pins and zero sheet entries on that sheet.
    4. Report net, sheet filename, location in mils.
  • example good finding message: Port "SPI_CLK" on sheet MCU.SchDoc at (1250, 800) mils is floating: hotspot is not on a wire, pin, or sheet entry.

2. unmatched_ports

  • name: Multi-driver and no-driver nets (port direction)
  • what it detects: Flattened nets with more than one Output port (multi-driver), or Input ports with zero Output/Bidirectional ports (no driver).
  • severity: error
  • surface: project
  • eda-agent analog: find_unmatched_ports (multi_output / no_driver)
  • API to read:
    • ISch_Port direction: ISch_Port.IOType UNVERIFIED exact enum (ePortIOInput / ePortIOOutput / ePortIOBidirectional typical in Schematic API)
    • Flattened INet.DM_NetName, group ports by net
  • detection logic:
    1. Compile; walk all ports on all compiled documents.
    2. Bucket by flattened net name; count Input / Output / Bidirectional.
    3. Flag output_count > 1 as multi-driver; flag input_count > 0 and output_count + bidir_count = 0 as no-driver.
  • example good finding message: Net "UART_TX" has 2 Output ports (multi-driver) across MCU.SchDoc and IO.SchDoc.

3. orphan_net_labels

  • name: Unconnected / orphan net labels
  • what it detects: ISch_NetLabel objects whose location is not on a wire or bus (phantom nets).
  • severity: error
  • surface: schematic sheet
  • eda-agent analog: find_orphan_net_labels
  • API to read:
    • ISch_NetLabel, object id eNetLabel
    • ISch_NetLabel.Text (label string)
    • Location X/Y; spatial iterate 1-mil square for eWire / eBus
  • detection logic:
    1. Iterate every eNetLabel on every sheet.
    2. If no wire/bus intersects the label location, flag as orphan.
  • example good finding message: Net label "nRESET" on PWR.SchDoc at (420, 210) mils is not on any wire or bus.

4. orphan_power_objects

  • name: Unconnected / orphan power ports
  • what it detects: Power-port markers sitting off-wire (phantom GND/VCC).
  • severity: error
  • surface: schematic sheet
  • eda-agent analog: find_orphan_power_objects
  • API to read:
    • ISch_PowerPort / ISch_PowerObject; object id ePowerPort / ePowerObject (UNVERIFIED which id the running AD version exposes; both appear in docs)
    • Text / net name; Style (ePowerGndPower, ePowerGndSignal, ePowerGndEarth, ePowerBar, …)
    • Spatial 1-mil test for eWire
  • detection logic:
    1. Iterate power objects.
    2. If no wire at the electrical hotspot, flag orphan.
  • example good finding message: Power port "GND" on MCU.SchDoc at (100, 50) mils is not on a wire.

5. single_pin_nets

  • name: Single-pin named nets
  • what it detects: Flattened nets with exactly one pin and at least one net-label / port / power-object (broken named connection, not a silent NC).
  • severity: warning
  • surface: project
  • eda-agent analog: find_single_pin_nets
  • API to read:
    • INet.DM_PinCount (workspace) — also cited as Net.PinCount in some PCB-side IPCB_Net samples
    • INet.DM_NetName; first pin designator + pin number
    • Presence of net identifiers on that net (UNVERIFIED exact INet child enumeration: DM_NetItemCount / schematic objects sharing the name)
  • detection logic:
    1. Compile; use DM_DocumentFlattened.
    2. For each net with DM_PinCount = 1, check that a net label, port, or power object names that net.
    3. Skip unnamed default nets and intentional NC pins if the lone pin name matches NC/DNC/RSVD.
  • example good finding message: Net "I2C_SDA" has exactly 1 pin (U3-12) plus a net label; the other end is missing.

6. power_port_orientation

  • name: Power-port orientation convention
  • what it detects: Ground symbols not facing down; power bars not facing up.
  • severity: warning
  • surface: schematic sheet
  • eda-agent analog: power_port_orientation
  • API to read:
    • ISch_PowerPort.Style: ePowerGndPower, ePowerGndSignal, ePowerGndEarth, ePowerBar
    • ISch_PowerPort.Orientation / GetState_Orientation — 0 / 90 / 180 / 270 degrees
  • detection logic:
    1. Iterate power ports.
    2. Ground styles must be 270° (down). Bar style must be 90° (up).
    3. Other styles (circle, arrow, wave) are info-only / skip unless project standard says otherwise.
  • example good finding message: Ground power port "GND" on PWR.SchDoc has Orientation=90 (expected 270 / down).

7. duplicate_designators

  • name: Duplicate schematic designators
  • what it detects: Two or more source-sheet components sharing the same designator (pre-flatten).
  • severity: error
  • surface: project
  • eda-agent analog: find_designator_collisions
  • API to read:
    • ISch_Component.Designator / Designator.Text
    • ISch_Component.UniqueId
    • Walk source sheets, not compiled flattened docs (flattening hides collisions with channel suffixes)
  • detection logic:
    1. Collect designator → list of (sheet, unique id).
    2. Flag any designator with count > 1.
  • example good finding message: Designator R12 occurs 2 times (MCU.SchDoc, ANALOG.SchDoc).

8. component_param_visibility

  • name: Per-class visible component parameters
  • what it detects: Caps without visible value+voltage, resistors without visible value, inductors without L+Isat, ICs without visible MPN.
  • severity: info
  • surface: schematic sheet
  • eda-agent analog: component_param_visibility / audit.validate_component_params
  • API to read:
    • ISch_Component.Designator, Comment
    • Child iterator eParameter → ISch_Parameter.Name, Text, IsHidden
  • detection logic:
    1. Classify by designator prefix (C/R/L/U).
    2. Required visible (IsHidden=False) fields: C → value ending F and voltage ending V; R → value ending R|k|M|m; L → H and current A; U → parameter name starting Manufacturer Part Number.
    3. Comment field may satisfy a requirement if visible and matching the pattern.
  • example good finding message: C17 (class capacitor) is missing visible voltage rating (need a parameter or Comment ending in V).

9. missing_datasheets

  • name: ICs missing datasheet URL
  • what it detects: U* components with no http(s):// in HelpURL / Datasheet / DatasheetURL / ComponentLink1URL…ComponentLink4URL.
  • severity: info
  • surface: schematic sheet / library
  • eda-agent analog: find_missing_datasheets
  • API to read: ISch_Parameter.Name and Text on ISch_Component
  • detection logic: Scan U* parameters; if none contain http:// or https:// in those slots, flag.
  • example good finding message: U4 (lib_ref STM32G031K8Tx, comment STM32G031K8T6) has no http(s) datasheet URL in HelpURL/Datasheet/ComponentLink*URL.

10. mpn_inconsistencies

  • name: Conflicting manufacturer part numbers
  • what it detects: Same (lib_ref, comment) group of ICs with different MPNs.
  • severity: warning
  • surface: project
  • eda-agent analog: find_mpn_inconsistencies
  • API to read: ISch_Component.LibReference UNVERIFIED (LibraryPath / SymbolReference also exist); Comment; parameter Manufacturer Part Number
  • detection logic: Group U* by (lib_ref, comment); if unique MPN set size > 1, flag the group.
  • example good finding message: lib_ref=AP2112K-3.3TRG1 comment=3.3V LDO has MPNs AP2112K-3.3TRG1 and AP2112K-3.3TRG1-ND across U10,U11.

11. placeholder_values

  • name: Placeholder parameter strings
  • what it detects: Component parameters equal to TBD/TBA/TODO/FIXME/XXX/?/??/???/PLACEHOLDER/FILLER/ASK/UNKNOWN/N/A/NA (trim, case-insensitive).
  • severity: error
  • surface: schematic sheet
  • eda-agent analog: find_placeholder_values
  • API to read: All ISch_Parameter.Text plus Comment
  • detection logic: Whole-string match after trim; skip empty (other checks cover empty).
  • example good finding message: R9 parameter Comment="TBD" looks like a leftover placeholder.

12. visible_supplier_pn

  • name: Visible supplier part numbers on schematic
  • what it detects: Parameters whose name starts with supplier and IsHidden=False (eda-agent BOM-hygiene: supplier SKUs should not appear on SCH PDF). Note: Adom extra mouser_digikey_lcsc_params requires those parameters to exist; this check only requires they are hidden on the canvas.
  • severity: info
  • surface: schematic sheet
  • eda-agent analog: find_visible_supplier_pn
  • API to read: ISch_Parameter.Name, Text, IsHidden
  • detection logic: Name prefix supplier (case-insensitive) AND not hidden → violation.
  • example good finding message: U2 parameter "Supplier Part Number 1"="296-1234-1-ND" is visible on the schematic; hide it (keep MPN visible).

13. off_grid_components

  • name: Schematic components off snap grid
  • what it detects: Placed symbols whose origin is not on the project grid (default 100 mil).
  • severity: info
  • surface: schematic sheet
  • eda-agent analog: find_off_grid_components
  • API to read: ISch_Component.Location.X / Y (TCoord); compare Abs(CoordToMils(X)) mod grid_mils
  • detection logic: Default grid_mils=100. Flag if remainder ≠ 0. Report dx/dy.
  • example good finding message: U7 on MCU.SchDoc is 4 mil off the 100-mil grid at (1254, 800).

14. unconnected_ic_pins

  • name: Unconnected IC pins (excluding NC)
  • what it detects: U* pins with empty / ? net, skipping names matching NC / N.C. / DNC / N/C / NO CONNECT / RSVD / RESERVED.
  • severity: warning
  • surface: project
  • eda-agent analog: find_unconnected_ic_pins (BOM / flattened pins)
  • API to read: Workspace IComponent pins + net name; or ISch_Pin + compiled net. ISch_Pin.Designator, Name, electrical type UNVERIFIED (ISch_Pin.Electrical / eElectricInput …)
  • detection logic: For each U* pin, if net is nil/empty/? and name is not NC-like, flag.
  • example good finding message: U3 pin 12 (PA8) has no net (not named NC/DNC/RSVD).

15. pin_net_name_mismatches

  • name: Power/ground pin name vs net name
  • what it detects: IC pins named VCC/VDD/GND/VSS (etc.) attached to a net that is not a power/ground rail.
  • severity: warning
  • surface: project
  • eda-agent analog: find_pin_net_name_mismatches
  • API to read: Pin Name + connected INet.DM_NetName
  • detection logic: Regex power pin names vs _net_is_power; ground pin names vs _net_is_ground. Flag mismatches.
  • example good finding message: U5 pin 8 name="VCC" is on net "GPIO_PA0" (power_pin_on_non_power_net).

16. missing_decoupling

  • name: IC power pins without a capacitor on the net
  • what it detects: ICs whose recognised power/ground pins do not share a net with any C* component (missing or partial).
  • severity: warning
  • surface: project
  • eda-agent analog: find_missing_decoupling
  • API to read: Flattened pin nets; designators starting with C
  • detection logic: Build net → capacitors. For each U* power pin, require ≥1 C* on that net. Skip ICs with no recognised power pins.
  • example good finding message: U3 status=partial: pin 21 VDDA on net +3V3_A has no capacitor; other power pins are covered.

17. unplaced_components

  • name: Schematic components with no PCB placement
  • what it detects: Fitted schematic components that have no corresponding IPCB_Component on the board (ECO not pushed, or component deleted from PCB).
  • severity: error
  • surface: project
  • eda-agent analog: none (Adom/Phase-2; closest is design-difference snapshot)
  • API to read:
    • Schematic: ISch_Component.Designator.Text
    • PCB: IPCB_Component.Name (refdes); Board.GetPcbComponentByRefDes documented on IPCB_Board as PcbComponentByRefDes / similar — UNVERIFIED exact method spelling (GetPcbComponentByRefDes vs PcbComponentByRefDes)
    • Skip DNP / not-fitted in current variant (see variant_dnp_mismatch)
  • detection logic:
    1. Collect fitted schematic designators.
    2. Collect PCB Component.Name set.
    3. SCH minus PCB → unplaced.
  • example good finding message: C42 is on the schematic (fitted) but has no IPCB_Component on the board.

18. components_outside_board_outline

  • name: Components off the board outline
  • what it detects: Placed footprints whose origin (or body) sits outside IPCB_BoardOutline.
  • severity: error
  • surface: PCB board
  • eda-agent analog: find_components_outside_board_outline
  • API to read:
    • Board.BoardOutline / Board.GetState_BoardOutline → IPCB_BoardOutline
    • IPCB_BoardOutline.PrimitiveInsidePoly (used by eda-agent / SelectCMPInOutSideBOL.pas)
    • IPCB_Component.X, Y, Layer, Name
  • detection logic: For each component, if outline PrimitiveInsidePoly is false for the origin (and optionally bounding box), flag.
  • example good finding message: J1 origin at (3200, -50) mils is outside the board outline (top layer).

19. pads_near_board_edge

  • name: Board-edge clearance violations
  • what it detects: Pads/vias closer than clearance (default 25 mil) to the outline — depaneling damage.
  • severity: warning
  • surface: PCB board
  • eda-agent analog: find_pads_near_board_edge
  • API to read:
    • Board.PrimPrimDistance(Board.BoardOutline, Prim) — documented in eda-agent; UNVERIFIED against current AD if method is PrimPrimDistance vs Board.PrimPrimDistance
    • IPCB_Pad, IPCB_Via
  • detection logic: For each pad/via, if distance < clearance_mils (default 25), flag kind, designator, distance, XY.
  • example good finding message: Pad U3-1 is 12 mil from board outline (min 25 mil) at (40, 800).

20. via_antennas

  • name: Via antennas / dangling vias
  • what it detects: Vias electrically connected on only one layer (open stub).
  • severity: warning
  • surface: PCB board
  • eda-agent analog: find_via_antennas
  • API to read:
    • IPCB_Via.X, Y, LowLayer, HighLayer, Net, HoleSize, Size
    • Via.IsConnected — UNVERIFIED (may not exist as a boolean; eda-agent counts layers via Board.PrimPrimDistance = 0 to track/arc/pad/fill/region, plus Via.IsConnectedToPlane on plane layers)
    • ILayerStack to enumerate signal vs plane layers between Low and High
  • detection logic:
    1. Iterate eViaObject.
    2. Count layers where a same-net primitive touches the via, or plane connection is true.
    3. If connected-layer count = 1, flag antenna. If count = 0, flag dangling via (orphan).
  • example good finding message: Via on net "SPI_CLK" at (1250, 900) mils is connected on only 1 layer (antenna).

21. unrouted_connections

  • name: Unrouted net connections
  • what it detects: Ratsnest / incomplete routing: nets with pads not fully connected by tracks/arcs/vias.
  • severity: warning
  • surface: PCB board
  • eda-agent analog: pcb.get_unrouted_nets (review snapshot, not a numbered audit) — included here so the 31-check lint covers routing completeness
  • API to read:
    • IPCB_Net; Board.ConnectivelyValidateNets documented on IPCB_Board — UNVERIFIED return shape
    • From-to / connection object id UNVERIFIED (eConnectionObject / ratsnest primitives)
    • Pad count vs connected copper graph
  • detection logic:
    1. Optional: Board.ConnectivelyValidateNets.
    2. For each net with PinCount/PadCount ≥ 2, if any from-to remains or pads are in disjoint copper islands, flag net + incomplete node count.
    3. Skip nets that are intentionally unrouted only if a rule/class says so (UNVERIFIED class name).
  • example good finding message: Net "+3V3" has 4 unrouted connections (14 pads, 2 copper islands).

22. polygon_validity

  • name: Polygon validity / islands
  • what it detects: Polygons/regions with zero area, failed pour, or orphan copper islands disconnected from the assigned net.
  • severity: error
  • surface: PCB board
  • eda-agent analog: find_invalid_regions (zero-area regions); Adom extends to pour islands
  • API to read:
    • IPCB_Polygon.Rebuild (read-side rebuild to inspect pour; treat as inspection, not an ECO)
    • IPCB_Polygon.Net, Layer, Name / PolygonOutline
    • Region area; IPCB_Region not owned by component/dimension
    • Island enumeration UNVERIFIED (GetState_Island, pour result island count — mark unverified; fallback: after Rebuild, spatial-split regions whose net copper does not touch a same-net pad)
  • detection logic:
    1. Iterate polygons and free regions.
    2. Flag area = 0 / unset.
    3. After Rebuild, flag islands that do not touch any pad/via of the polygon net.
  • example good finding message: Polygon "GND_Top" on Top Layer has 2 islands; island at (1800, 400) mils touches no GND pad.

23. variant_dnp_mismatch

  • name: DNP / variant not-fitted mismatches
  • what it detects: Components Not Fitted in the current variant that still look fitted on PCB (paste, no DNP marking), or fitted SCH parts marked DNP inconsistently.
  • severity: warning
  • surface: project
  • eda-agent analog: variant_not_fitted
  • API to read:
    • Project current variant description
    • Flattened component fitted flag — UNVERIFIED exact property (IComponent.DM_Fitted / DM_NotFitted / variant GetState_Fitted). eda-agent returns {designator, comment, unique_id} for NotFitted.
    • PCB: IPCB_Component still present (Altium keeps DNP footprints); paste-mask expansion / locked primitives as secondary signals UNVERIFIED
  • detection logic:
    1. If no variant selected, report info and skip mismatch logic.
    2. List NotFitted designators.
    3. Cross-check SCH parameters (DNP, Fitted) vs variant table; flag disagreement.
  • example good finding message: Variant "Build-A": R99 is Not Fitted in the variant table but schematic parameter Fitted=True.

24. missing_footprint_models

  • name: Missing footprint / PCB model on schematic component
  • what it detects: Schematic components with empty Footprint / no ISch_Implementation of type PCB, or PCB components with empty Pattern / SourceFootprintLibrary.
  • severity: error
  • surface: library / schematic sheet / PCB board
  • eda-agent analog: none (library hygiene)
  • API to read:
    • ISch_Component implementations: ISch_Implementation (ModelName, ModelType = PCBLIB / PCB)
    • PCB: IPCB_Component.Pattern, SourceFootprintLibrary, SourceLibReference
  • detection logic: Flag if no PCB implementation, or Pattern is empty, or source library path is empty and footprint cannot be resolved.
  • example good finding message: U12 has no PCB footprint implementation (Pattern empty; SourceFootprintLibrary blank).

25. missing_3d_bodies

  • name: Missing 3D bodies on footprints
  • what it detects: Placed PCB components with no IPCB_ComponentBody child (STEP/extruded body).
  • severity: info
  • surface: library / PCB board
  • eda-agent analog: none
  • API to read:
    • IPCB_Component group iterator, eComponentBodyObject → IPCB_ComponentBody
    • IPCB_Component.DefaultPCB3DModel documented
    • Mechanical layer extruded bodies as fallback
  • detection logic: Skip fiducials, mounting holes, logos (designator prefixes FID/MH/HOLE or ComponentKind mechanical UNVERIFIED enum). Flag electrical parts with zero bodies and empty DefaultPCB3DModel.
  • example good finding message: U3 (Pattern=QFN-48) has no IPCB_ComponentBody and DefaultPCB3DModel is empty.

26. silkscreen_over_pad

  • name: Silkscreen overlapping pads
  • what it detects: Overlay text/tracks/arcs overlapping SMD/through-hole copper pads (fab ink on paste).
  • severity: warning
  • surface: PCB board
  • eda-agent analog: none (DRC silk-to-solder-mask sometimes covers this)
  • API to read:
    • IPCB_Text, IPCB_Track, IPCB_Arc on eTopOverlay / eBottomOverlay
    • IPCB_Pad on top/bottom signal layers
    • Overlap helper UNVERIFIED: Board.PrimPrimDistance(silk, pad) = 0 or bounding-rect intersect then exact outline. No dedicated SilkscreenOverPad API documented.
  • detection logic:
    1. For each overlay primitive (including component silk children if primitive lock allows iteration), measure distance to pads on the same side.
    2. Distance ≤ 0 (or < silk-to-pad rule clearance) → violation.
    3. Ignore courtyard-only mechanical layers.
  • example good finding message: Silkscreen text "U3" on Top Overlay overlaps pad U3-1 (PrimPrimDistance=0 at (1010, 540) mils).

27. tented_via_ratio

  • name: Tented vs untented via surfaces
  • what it detects: Fraction of outer via surfaces that are tented; reports ratio (consumer boards typically want ~1.0).
  • severity: warning (if untented ratio exceeds project threshold; default report-only with warning when any outer surface is untented on a production board)
  • surface: PCB board
  • eda-agent analog: tented_via_ratio
  • API to read:
    • IPCB_Via tenting: GetState_IsTenting_Top / GetState_IsTenting_Bottom (NEXUS/AD docs)
    • Query-language equivalents SolderMaskTentingTop / SolderMaskTentingBottom
    • SolderMaskExpansion on pad cache
  • detection logic: Count top/bottom surfaces that actually reach outer layers. Buried/blind inner-only ignored. Emit tented, untented, ratio.
  • example good finding message: Via tenting ratio=0.72 (48 untented outer surfaces / 172); example untented via on net GND at (200, 200).

28. bad_connections

  • name: Near-miss track / arc endpoints
  • what it detects: Track/arc endpoints within tolerance_mils (default 1.0) of another same-net primitive but not actually touching (photoplot open).
  • severity: warning
  • surface: PCB board
  • eda-agent analog: find_bad_connections
  • API to read: IPCB_Track (X1,Y1,X2,Y2, Layer, Net), IPCB_Arc; spatial iterator; skip teardrops, in-component prims, no-net, full-circle arcs
  • detection logic: For each signal-layer endpoint, if no same-net pad/via/track/arc at exact coord but one exists within tolerance, flag dangling/near-miss.
  • example good finding message: Track on net "nCS" layer TopLayer endpoint (812.4, 400.0) mils is 0.6 mil from via copper (tolerance 1.0); photoplot will not bridge.

29. signal_vias_without_return

  • name: Signal vias without nearby return via
  • what it detects: Non-power/ground vias with no GND/power via within radius_mils (default 50).
  • severity: warning
  • surface: PCB board
  • eda-agent analog: find_signal_vias_without_return
  • API to read: IPCB_Via.Net.Name; heuristic prefixes GND / V / + / −
  • detection logic: For each signal via, spatial-search power/ground vias within radius. None → violation. Simplified proximity, not stackup-aware.
  • example good finding message: Signal via on net "USB_DP" at (1500, 700) mils has no GND/power via within 50 mils.

30. removed_pad_shapes

  • name: Removed unused pad / via copper
  • what it detects: Pads/vias with annular ring stripped on layers that still need copper (Tools → Remove Unused Pad Shapes over-applied).
  • severity: warning
  • surface: PCB board
  • eda-agent analog: find_removed_pad_shapes
  • API to read:
    • Via.SizeOnLayer(L) <= Via.HoleSize
    • Pad.IsPadRemoved(L) — used by community PadShapeRemoved.pas
  • detection logic: For each layer in the via/pad stack, flag removed copper. Count per layer-instance.
  • example good finding message: Via on net "+3V3" at (600, 600) has SizeOnLayer(Mid1)=HoleSize (annular ring removed on Mid1).

31. unlocked_component_primitives

  • name: Unlocked footprint primitives
  • what it detects: Placed components with primitive lock off (pads can be dragged off-center).
  • severity: warning
  • surface: PCB board
  • eda-agent analog: find_unlocked_component_primitives
  • API to read: IPCB_Component primitive lock — UNVERIFIED exact name (PrimitiveLock / GetState_PrimitiveLock). Community and eda-agent treat it as a boolean on the component.
  • detection logic: Iterate components; flag unlocked. Skip if intentionally exploded for documentation.
  • example good finding message: Q2 has PrimitiveLock=False; a pad can be dragged off the footprint without warning.

32. mouser_digikey_lcsc_params (Adom extra)

  • name: Mouser, Digi-Key, and LCSC part-number parameters required
  • what it detects: Every procurable (fitted, non-mechanical) schematic component missing any of the three required supplier parameters. Adom rule: all three are required, even if an MPN already exists.
  • severity: error
  • surface: schematic sheet / project
  • eda-agent analog: none (opposite emphasis of find_visible_supplier_pn, which only hides them)
  • API to read:
    • ISch_Component parameter iterator → ISch_Parameter.Name, Text
    • Accepted names (normalize case/spaces/underscores):
      • Mouser: Mouser, Mouser Part Number, Mouser PN, Supplier Part Number n where supplier name is Mouser
      • Digi-Key: DigiKey, Digi-Key, DigiKey Part Number, DK PN
      • LCSC: LCSC, LCSC Part Number, LCSC PN, JLCPCB
    • Altium Supplier link slots Supplier n + Supplier Part Number n — UNVERIFIED whether Adom libraries use native supplier links vs free parameters
  • detection logic:
    1. Skip logos, fiducials, mechanical-only, and current-variant DNP parts.
    2. For each remaining component, require non-empty Text for all three families.
    3. Missing one, two, or three all fail; list which keys are empty.
    4. Do not require the parameters to be visible (IsHidden may be True). Existence is the Adom rule; visibility is check 12.
  • example good finding message: R4 is missing required supplier parameters: Mouser=ok, DigiKey=empty, LCSC=empty (Adom rule: all three required).

33. pin1_symbol_footprint (Adom extra)

  • name: Pin-1 disagreement between symbol and footprint
  • what it detects: Symbol pin whose designator is 1 does not correspond to footprint pad Name = '1' in electrical mapping (wrong pin-swap, rotated QFN, pin-1 dot vs pad 1).
  • severity: error
  • surface: library / schematic sheet / PCB board
  • eda-agent analog: none
  • API to read:
    • SCH: ISch_Pin.Designator (pin number), ISch_Pin.Name, orientation / location relative to symbol
    • PCB: IPCB_Pad.Name = '1' (user requirement); IPCB_Pad.Layer; component Rotation
    • Pin-to-pad map: ISch_Implementation / pin mapping model — UNVERIFIED (ISch_ModelDatafileLink, MappedPin / PinMapping)
    • PCB IPCB_Component.Getstate_PadByName('1') documented as Getstate_PadByName
  • detection logic:
    1. For each component with a PCB implementation, fetch symbol pin Designator='1' and footprint pad Name='1'.
    2. If either side is missing, flag.
    3. If a pin-map exists and pin 1 is mapped to a pad whose name is not '1', flag disagreement.
    4. Optional geometric heuristic (UNVERIFIED): symbol pin-1 in the "upper-left" of unrotated symbol vs footprint pad-1 in the courtyard pin-1 marker; report as info only, not error.
  • example good finding message: U6 symbol pin Designator=1 (name=VSS) maps to footprint pad Name=12; footprint pad Name=1 is mapped to symbol pin 12 (QFN rotation/pin-1 mismatch).

34. unused_mechanical_layers (Adom extra)

  • name: Unused mechanical layers that still have content
  • what it detects: Mechanical layers that are not part of the active layer stack / fabrication output set, yet still contain tracks, arcs, text, fills, or component bodies (leftover courtyard, fab notes on Mechanical 13–16, etc.).
  • severity: info
  • surface: PCB board
  • eda-agent analog: none
  • API to read:
    • ILayerStack / Board.LayerStack — UNVERIFIED exact property (IPCB_MasterLayerStack)
    • IPCB_LayerObject; mechanical layer ids eMechanical1 … eMechanical16 (AD extends beyond 16 in later versions — UNVERIFIED max)
    • Board.LayerIsUsed / Board.MechanicalLayerEnabled — UNVERIFIED names; fallback: iterate all primitives and bucket by Prim.Layer
    • Pairing: courtyard often Mechanical 15, 3D on Mechanical 13 — project convention, not API
  • detection logic:
    1. Build the set of mechanical layers that appear in the stack or are enabled for Gerber/ODB output (UNVERIFIED output-job API).
    2. Iterate primitives (eTrackObject, eArcObject, eTextObject, eFillObject, eRegionObject, eComponentBodyObject) on mechanical layers.
    3. If a mechanical layer has content but is disabled / not in stack / not in the fab output set, flag layer id + primitive count + sample coordinates.
    4. Do not flag empty disabled layers.
  • example good finding message: Mechanical 14 is not in the active layer stack but contains 11 primitives (example text "OLD COURTYARD" at (0, 0) mils).

35. missing_power_testpoints (Adom extra)

  • name: Missing test points on power rails
  • what it detects: Power/ground nets (VCC/VDD/+3V3/+5V/GND/…) with no dedicated test-point pad or test-point component (TP* / pad with testpoint property).
  • severity: warning
  • surface: PCB board / project
  • eda-agent analog: none (DRC has IPCB_TestPointUsage / IPCB_TestPointStyleRule but that is rule-engine, not this lint)
  • API to read:
    • IPCB_Pad testpoint flags — UNVERIFIED (IsTestPoint / GetState_IsTestpointTop / TestpointTop / TestpointBottom; query language has test-point fields)
    • IPCB_Component.Name matching TP* or comment/type Test Point
    • IPCB_Net.Name power heuristic (same as decoupling check)
    • Design rules IPCB_TestPointUsage only as optional cross-check, not required
  • detection logic:
    1. Identify power nets from names: GND*, VCC*, VDD*, VSS*, leading +, VBAT, VBUS, VREF, …
    2. A net has a test point if any pad has the testpoint property or any TP* component pad is on that net.
    3. Flag power nets with ≥1 connected pad and zero test points.
    4. Optionally require both top-accessible TP for rails brought to connectors (UNVERIFIED policy).
  • example good finding message: Power net "+3V3" has 22 pads and 0 test points (no TP* component and no pad TestpointTop/Bottom).

Mapping: eda-agent 31 → this catalog

eda-agent LINT_AUDIT_LIST + BOM-side audits are covered as follows. Some eda-agent checks are folded or omitted to keep the catalog at 35 while absorbing Adom MUST items (unplaced, footprints, 3D, silk-over-pad, unrouted).

eda-agent section This catalog id Notes
component_param_visibility component_param_visibility
power_port_orientation power_port_orientation
find_floating_ports floating_ports
find_unmatched_ports unmatched_ports multi-driver / no-driver
find_designator_collisions duplicate_designators
find_missing_datasheets missing_datasheets
find_mpn_inconsistencies mpn_inconsistencies
find_single_pin_nets single_pin_nets
find_non_embedded_images (omitted from 35; style) Re-add as 36 if needed
find_visible_supplier_pn visible_supplier_pn Complementary to Adom extra 32
find_orphan_net_labels orphan_net_labels
find_orphan_power_objects orphan_power_objects
find_placeholder_values placeholder_values
find_off_grid_components off_grid_components
find_components_outside_board_outline components_outside_board_outline
find_pads_near_board_edge pads_near_board_edge
variant_not_fitted variant_dnp_mismatch
tented_via_ratio tented_via_ratio
find_bad_connections bad_connections
find_signal_vias_without_return signal_vias_without_return
find_via_antennas via_antennas
find_removed_pad_shapes removed_pad_shapes
find_pads_center_not_connected (folded into unrouted_connections / via antennas) UNVERIFIED pad-center API
find_invalid_regions polygon_validity Extended with islands
find_mixed_designator_rotation (omitted from 35; silk style)
find_unlocked_component_primitives unlocked_component_primitives
find_mirrored_pcb_text (omitted from 35; silk style)
find_acute_angles (omitted from 35; DFM)
find_inconsistent_track_widths (omitted from 35; DFM)
find_unconnected_ic_pins unconnected_ic_pins BOM-side
find_pin_net_name_mismatches pin_net_name_mismatches BOM-side
find_missing_decoupling missing_decoupling BOM-side
— unplaced_components MUST
— missing_footprint_models MUST
— missing_3d_bodies MUST
— silkscreen_over_pad MUST
— unrouted_connections MUST
— mouser_digikey_lcsc_params Adom extra
— pin1_symbol_footprint Adom extra
— unused_mechanical_layers Adom extra
— missing_power_testpoints Adom extra

Omitted eda-agent style/DFM checks may be reintroduced later as ids 36+ without changing 1–35.


Finding message quality

A good finding (aligned with eda-agent review discipline, adapted for lint):

  • Names the exact designator, pin, net, sheet or board coordinates in mils
  • States the observed API fact (not a guess about device function)
  • Is actionable (what is missing or wrong)
  • Does not say “verify X” or relay a raw ERC category

Lint is allowed to list many similar items; the later review agent triages them.


Summary table

id severity surface
floating_ports warning schematic sheet
unmatched_ports error project
orphan_net_labels error schematic sheet
orphan_power_objects error schematic sheet
single_pin_nets warning project
power_port_orientation warning schematic sheet
duplicate_designators error project
component_param_visibility info schematic sheet
missing_datasheets info schematic sheet / library
mpn_inconsistencies warning project
placeholder_values error schematic sheet
visible_supplier_pn info schematic sheet
off_grid_components info schematic sheet
unconnected_ic_pins warning project
pin_net_name_mismatches warning project
missing_decoupling warning project
unplaced_components error project
components_outside_board_outline error PCB board
pads_near_board_edge warning PCB board
via_antennas warning PCB board
unrouted_connections warning PCB board
polygon_validity error PCB board
variant_dnp_mismatch warning project
missing_footprint_models error library / schematic sheet / PCB board
missing_3d_bodies info library / PCB board
silkscreen_over_pad warning PCB board
tented_via_ratio warning PCB board
bad_connections warning PCB board
signal_vias_without_return warning PCB board
removed_pad_shapes warning PCB board
unlocked_component_primitives warning PCB board
mouser_digikey_lcsc_params error schematic sheet / project
pin1_symbol_footprint error library / schematic sheet / PCB board
unused_mechanical_layers info PCB board
missing_power_testpoints warning PCB board / project

Document control

  • Nonce: ALTIUM-LINT-SPEC-001
  • Artifact path (box): /workspace/altium-lint-spec.md
  • Intended later copy: C:\Users\john\adom\altium-lint-spec.md
  • This phase: spec only; no Altium launch; no altium-bridge tree edits