← Commit history

standard 0.3.1: an internal plane is In<n>.Cu by its place in the copper stack, kind plane (agreed with altium-lane on #8); the stack-up companion gains layer (the board model name); README: fixtures live on each bridge's page (Altium's on adom/altium-bridge fixtures/), the checks implementation's home is being decided; regenerated with altium 0.2.76 (223 verbs, all of batch 1): Altium 204, KiCad 143, Fusion 86 of 236

Colby Knox ·9f41b84f77 ·14d ago ·parent 98fa232
8 files changed +40−28
README.md+9−10
@@ -47,12 +47,12 @@ verb by verb: [docs/coverage.md](docs/coverage.md). <!-- coverage:start (tools/generate.py writes this) --> | Tier | Verbs | Altium | KiCad | Fusion 360 | |---|---|---|---|---|-| **core** | 93 | 77 | 72 | 29 |-| **native** | 46 | 35 | 35 | 18 |+| **core** | 93 | 80 | 72 | 29 |+| **native** | 46 | 36 | 35 | 18 | | **checks** | 37 | 32 | 11 | 4 | | **app** | 60 | 56 | 25 | 35 | | **platform** | 19 | 19 | 0 | 0 |-| standard (all but platform) | 236 | 200 | 143 | 86 |+| standard (all but platform) | 236 | 204 | 143 | 86 | <!-- coverage:end -->  The **checks** tier is where the other bridges are furthest behind, and it is the cheapest to close: those verbs are@@ -142,7 +142,7 @@ Decisions so far (proposals from the KiCad and Fusion bridges, 2026-10-27; issue  ## Status -Version 0.3.0: 33 more verbs from other bridges, all agreed by the Altium bridge's thread: 26 from the KiCad bridge (the board exports ODB++, IPC-2581, IPC-356, GenCAD and DXF, `render_board_3d`, `remove_parts`, `edit_parts`, `align_parts`, `copy_routing`, projects, library footprints, `estimate_cost`, `check_clearance`, `place_decoupling`, `plan_fanout`) and 7 from the Fusion bridge (`bodies`, `render_board_layers`, `plan_route`, `generate_body`, `library_views`, `close_all_documents`, `document_info`). A bridge's own equivalents now win over a name match, so a verb that shares a standard name but does another job is not credited for it. Version 0.2.1: this page has one keeper (standard-lane) and bridge threads push only their own files (*Keeping it in+Version 0.3.1: an internal plane is named `In<n>.Cu` by its place in the copper stack, with `kind: "plane"` ([board model](docs/board-model.md#settled-questions)); the stack-up companion gives each copper layer's board model name in `layer`. Version 0.3.0: 33 more verbs from other bridges, all agreed by the Altium bridge's thread: 26 from the KiCad bridge (the board exports ODB++, IPC-2581, IPC-356, GenCAD and DXF, `render_board_3d`, `remove_parts`, `edit_parts`, `align_parts`, `copy_routing`, projects, library footprints, `estimate_cost`, `check_clearance`, `place_decoupling`, `plan_fanout`) and 7 from the Fusion bridge (`bodies`, `render_board_layers`, `plan_route`, `generate_body`, `library_views`, `close_all_documents`, `document_info`). A bridge's own equivalents now win over a name match, so a verb that shares a standard name but does another job is not credited for it. Version 0.2.1: this page has one keeper (standard-lane) and bridge threads push only their own files (*Keeping it in sync*), one file per owner (`tools/equivalents/<bridge>.json`, `tools/proposed/<thread>.json`); the decisions on the KiCad and Fusion proposals are written down above; a lesson from the Fusion bridge on DRC severity is in [docs/conventions.md](docs/conventions.md). Version 0.2.0: verbs can come from any bridge. The first batch, 21 schematic verbs from the KiCad bridge (`sch_connect_pins`, `sch_bus`, `sch_items`, `sch_pins`, `sch_trace_point`, `render_schematic` ...), was agreed by the@@ -150,9 +150,8 @@ Altium bridge's thread; Altium now shows those as gaps. Earlier: version 0.1.2: settles the questions the KiCad and Fusion bridges raised as they adopted the board model (the y-down frame, pour islands, fractured fills, custom pads, reply units): the answers are in [docs/board-model.md](docs/board-model.md#settled-questions). -Next: the checks tier as a shared Rust crate and command-line tool every bridge can call, `adom-eda-checks`. It takes-the board model and its companions as plain JSON and calls no bridge, so a bridge can link it or run it. Its source-will live on this page under `engine/`, and a bridge vendors a copy at a tagged standard version (the wiki has no git-protocol, so Cargo cannot fetch it from here). It moves over from the Altium bridge's Rust a module at a time, Altium-swapping its own copies first. Then fixture boards (the same small board as `.PcbDoc`, `.kicad_pcb` and Fusion) with-the expected board model and check results, so a bridge can prove it conforms.+Next: the checks tier's implementation, so every bridge that serves the board model gets the same checks. Where it+lives is being decided (a shared crate, or Adom's analysis tools reading the board model); the verbs' names and reply+shapes stay here either way. Fixtures, a bridge's saved replies on a small board with the expected check results, live+on each bridge's own page, not here: Altium's are on [adom/altium-bridge](https://wiki.adom.inc/adom/altium-bridge)+under `fixtures/`.
docs/board-model.md+2−1
@@ -61,7 +61,7 @@ layer names.  | Model | Verb | What reads it | |---|---|---|-| Stack-up | `layer_stack` | impedance, current capacity, fab check (copper weight, thickness), copper balance, return paths (planes) |+| Stack-up | `layer_stack` | impedance, current capacity, fab check (copper weight, thickness), copper balance, return paths (planes). Each copper layer carries its board model name in `layer` (`F.Cu`, `In<n>.Cu`, `B.Cu`); an internal plane is `In<n>.Cu` by its place in the copper stack, with `kind: "plane"`, and counts as copper everywhere but its splits and antipads | | Poured copper | `pour_state` | copper balance, return paths and their fix plans. Island by island, outline and holes, filled by the even-odd rule: a fractured fill (KiCad: holes joined to the outline by zero-width cuts, `holes: []`, `fractured: true`) is the same copper and needs no separating | | 3D bodies | `bodies` (Altium: an agent call behind `height_check`) | height check, placement check. One box per body (Altium) or per part (Fusion); z from the surface the part sits on | | Sheet parts with pin types | `read_sheet_file` (Altium reads the .SchDoc file itself) | schematic review, pin-to-pad check. Pin types by name (`input`, `io`, `output`, `power`, `supply`, `not_connected`...); Altium's codes are accepted too |@@ -77,3 +77,4 @@ layer names. | Must fractured fills be split into outline and holes? | No: even-odd filling gives the same copper | [#1](https://wiki.adom.inc/adom/eda-bridge-standard/issues/1) | | Custom pads? | Bounding rectangle, plus `copperPoints` when known | [#2](https://wiki.adom.inc/adom/eda-bridge-standard/issues/2) | | Units in replies? | mm, and a unit-named field says mm (`xMm`); see conventions | [#2](https://wiki.adom.inc/adom/eda-bridge-standard/issues/2) |+| What is an internal plane called? | `In<n>.Cu` by its place in the copper stack, `kind: "plane"` in the stack-up; a tool's own id may ride along (`layerId`), never in its place | [#8](https://wiki.adom.inc/adom/eda-bridge-standard/issues/8) |
docs/coverage.md+7−7
@@ -6,12 +6,12 @@ Generated by `tools/generate.py` from `verbs/coverage.json`; do not edit by hand  | Tier | Verbs | Altium | KiCad | Fusion 360 | |---|---|---|---|---|-| **core** | 93 | 77 | 72 | 29 |-| **native** | 46 | 35 | 35 | 18 |+| **core** | 93 | 80 | 72 | 29 |+| **native** | 46 | 36 | 35 | 18 | | **checks** | 37 | 32 | 11 | 4 | | **app** | 60 | 56 | 25 | 35 | | **platform** | 19 | 19 | 0 | 0 |-| standard (all but platform) | 236 | 200 | 143 | 86 |+| standard (all but platform) | 236 | 204 | 143 | 86 |  ## core @@ -86,14 +86,14 @@ Read and edit the design. Every bridge provides these: they are how an AI sees a | `sch_edit` | Change placed parts on a sheet: move (to x,y mil), moveBy (dx,dy), rotate (degrees), rename (designator), re-comment (comment), delete. One undo step. | `altium_sch_edit` | `kicad_sch_set_property / kicad_sch_move / kicad_sch_delete / kicad_sch_rotate` (partial) |  | | `sch_edit_label` *proposed* | Edit net labels: rotate, move to a point or by a delta, rename, or move every label of a net at once. One undo step. | `altium_sch_edit_label` | `kicad_sch_edit_label` |  | | `sch_fix_connectivity` *proposed* | Snap near-miss wire ends onto the pin, label, sheet pin or wire end they almost touch, within a tolerance. dryRun (the default) lists the moves;... | `altium_sch_fix_connectivity` | `kicad_sch_fix_connectivity` |  |-| `sch_hierarchy` *proposed* | The sheet tree of a design, recursively: each sheet's name, file, id, instance path, page number, position, size and pins. renumber:true renumbers pages... |  | `kicad_sch_hierarchy` |  |+| `sch_hierarchy` *proposed* | The sheet tree of a design, recursively: each sheet's name, file, id, instance path, page number, position, size and pins. renumber:true renumbers pages... | `altium_sch_hierarchy` | `kicad_sch_hierarchy` |  | | `sch_items` *proposed* | List a sheet's wiring items with ids and coordinates: wires, buses, bus entries, net labels (local, global, hierarchical), power ports, junctions,... | `altium_sch_items` | `kicad_sch_items` |  | | `sch_junction` *proposed* | Add junction dots at points, or remove dots by id or point. One undo step. | `altium_sch_junction` | `kicad_sch_junction` |  | | `sch_move_region` *proposed* | Move everything inside a box by (dx, dy): parts, wire ends inside the box (wires crossing its edge stretch), labels, junctions, no-connect markers, texts,... | `altium_sch_move_region` | `kicad_sch_move_region` |  |-| `sch_page` *proposed* | Read or set a sheet's page: paper size, orientation and title block (title, date, revision, company, comment lines). |  | `kicad_sch_page` |  |+| `sch_page` *proposed* | Read or set a sheet's page: paper size, orientation and title block (title, date, revision, company, comment lines). | `altium_sch_page` | `kicad_sch_page` |  | | `sch_pins` *proposed* | Every pin of the named parts on a sheet: its absolute position (rotation and mirror applied), number, name, electrical type, the side it leaves the body,... | `altium_read_sheet_file` (partial) | `kicad_sch_pins` |  | | `sch_place_part` | Place a component from a .SchLib onto an EXISTING sheet at a position, with its library parameters (MPN, Manufacturer, distributor numbers) and its... | `altium_sch_place_part` | `kicad_sch_place_symbol` |  |-| `sch_reset_fields` *proposed* | Put parts' designator and value text (or the named fields) back where the library symbol places them, through each part's rotation and mirror. One undo step. |  | `kicad_sch_reset_fields` |  |+| `sch_reset_fields` *proposed* | Put parts' designator and value text (or the named fields) back where the library symbol places them, through each part's rotation and mirror. One undo step. | `altium_sch_reset_fields` | `kicad_sch_reset_fields` |  | | `sch_sheet_pins` *proposed* | A sheet symbol's pins: list, add, edit (rename, kind, move along an edge) or delete. import:true adds a pin for every hierarchical port inside the child... | `altium_sch_sheet_symbol` (partial) | `kicad_sch_sheet_pins` |  | | `sch_sheet_symbol` | Make a design hierarchical: a sheet symbol on the parent sheet for a child sheet, its entries joined to the parent's nets, and matching ports on the child.... | `altium_sch_sheet_symbol` | `kicad_sch_sheet` (partial) |  | | `sch_split_wire` *proposed* | Split the wire through a point into two wires there, with a junction dot at the cut, so a new branch can end on a wire end. One undo step. | `altium_sch_split_wire` | `kicad_sch_split_wire` |  |@@ -158,7 +158,7 @@ Wraps the EDA tool's own feature (its DRC, ERC, Gerbers, pours, Update PCB). Eve | `routing_drc` | Design-rule violations on the current board WITH locations, plus the unrouted (ratsnest) count, as one clean/not-clean answer. | `altium_routing_drc` | `kicad_routing_validate` (partial) | `fusion_routing_drc` | | `run_drc` | Run the design rule check on a board and read the violation markers back. PCB:DesignRuleCheck opens a MODAL; the bridge clicks 'Run Design Rule Check'... | `altium_run_drc` | `kicad_run_drc` | `fusion_run_drc` | | `run_erc` | Electrical rules check. Same handler as altium_compile: in Altium, compiling the project IS the ERC. | `altium_run_erc` | `kicad_run_erc` | `fusion_run_erc` |-| `sch_update_from_library` *proposed* | Update the placed symbols on a sheet from their libraries (all, or the listed ones) and report which changed, which already matched and which no library has. |  | `kicad_sch_update_from_library` |  |+| `sch_update_from_library` *proposed* | Update the placed symbols on a sheet from their libraries (all, or the listed ones) and report which changed, which already matched and which no library has. | `altium_sch_update_from_library` | `kicad_sch_update_from_library` |  | | `set_design_rules` | Write a fab's design rules into the current board: clearance, track width, routing via style, hole size, annular ring, hole-to-hole and board-edge clearance... | `altium_set_design_rules` | `kicad_set_design_rules` | `fusion_set_design_rules` | | `silkscreen_prep` | Clean the silkscreen off the copper with Altium's own Tools > Silkscreen Preparation: silk clipped clear of every mask opening (pad) by the board's silk... | `altium_silkscreen_prep` |  |  | | `symbol_mode` | Show one display mode (0 = Normal, 1.. = alternates) of the CURRENT SchLib component in the editor and capture a frame. Drives the editor's own mode toggle,... | `altium_symbol_mode` |  |  |
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "eda-bridge-standard",-  "version": "0.3.0",+  "version": "0.3.1",   "type": "skill",   "title": "EDA Bridge Standard: one way for an AI to drive every PCB tool",   "description": "The standard every Adom EDA bridge follows so one AI can drive Altium, KiCad, Fusion 360 and any future PCB tool the same way: shared verb names in tiers, the board model JSON, reply and refusal conventions, and a coverage table of each bridge against the Altium reference.",
page.json+1−1
@@ -4,7 +4,7 @@   "type": "skill",   "title": "EDA Bridge Standard: one way for an AI to drive every PCB tool",   "brief": "The standard every Adom EDA bridge follows so one AI can drive Altium, KiCad, Fusion 360 and any future PCB tool the same way: shared verb names in tiers, the board model JSON, reply and refusal conventions, and a coverage table of each bridge against the Altium reference.",-  "version": "0.3.0",+  "version": "0.3.1",   "hero": {     "type": "billboard",     "headline": "One standard for every EDA bridge",
schema/companions.schema.json+2−2
@@ -12,9 +12,9 @@         "copperLayers": {"type": "integer"},         "totalUm": {"type": "number", "description": "board thickness, micrometres"},         "layers": {"type": "array", "description": "the copper layers top to bottom, each with the dielectric BELOW it", "items": {"type": "object", "required": ["name", "kind", "copperUm"],-          "properties": {"name": {"type": "string"}, "kind": {"enum": ["signal", "plane"]}, "copperUm": {"type": "number"},+          "properties": {"name": {"type": "string", "description": "the tool's own name for the layer (Top Layer)"}, "layer": {"type": "string", "description": "the board model's name for this copper layer: F.Cu, In<n>.Cu by its place in the copper stack, B.Cu. An internal plane is named the same way (kind plane), never by a tool id"}, "kind": {"enum": ["signal", "plane"]}, "copperUm": {"type": "number"},             "dielectricUm": {"type": "number", "description": "to the next copper layer; absent on the last"}, "dk1000": {"type": "number", "description": "the dielectric constant x 1000"}, "material": {"type": "string"},-            "mid": {"type": "integer", "description": "a signal layer's inner index (In<mid>.Cu)"}, "plane": {"type": "integer", "description": "an internal plane's index"}, "net": {"type": "string", "description": "a plane's net"}}}}+            "mid": {"type": "integer", "description": "a signal layer's inner index (In<mid>.Cu)"}, "plane": {"type": "integer", "description": "an internal plane's index in the tool; the board model names it by layer"}, "net": {"type": "string", "description": "a plane's net"}}}}       }     },     "pours": {
verbs/coverage.json+17−5
@@ -1,5 +1,5 @@ {- "standard": "0.3.0",+ "standard": "0.3.1",  "reference": {   "bridge": "altium",   "version": "0.2.76"@@ -956,7 +956,10 @@    "name": "sch_hierarchy",    "tier": "core",    "source": "proposed",-   "altium": null,+   "altium": {+    "verb": "altium_sch_hierarchy",+    "match": "exact"+   },    "kicad": {     "verb": "kicad_sch_hierarchy",     "match": "exact"@@ -1009,7 +1012,10 @@    "name": "sch_page",    "tier": "core",    "source": "proposed",-   "altium": null,+   "altium": {+    "verb": "altium_sch_page",+    "match": "exact"+   },    "kicad": {     "verb": "kicad_sch_page",     "match": "exact"@@ -1048,7 +1054,10 @@    "name": "sch_reset_fields",    "tier": "core",    "source": "proposed",-   "altium": null,+   "altium": {+    "verb": "altium_sch_reset_fields",+    "match": "exact"+   },    "kicad": {     "verb": "kicad_sch_reset_fields",     "match": "exact"@@ -1842,7 +1851,10 @@    "name": "sch_update_from_library",    "tier": "native",    "source": "proposed",-   "altium": null,+   "altium": {+    "verb": "altium_sch_update_from_library",+    "match": "exact"+   },    "kicad": {     "verb": "kicad_sch_update_from_library",     "match": "exact"
verbs/standard.json+1−1
@@ -1,5 +1,5 @@ {- "standard": "0.3.0",+ "standard": "0.3.1",  "reference": {   "bridge": "altium",   "version": "0.2.76"