← Commit history

standard 0.2.1: one keeper (standard-lane) for docs and generated files, bridge threads push only their reference and equivalents (README, Keeping it in sync); decisions on KiCad's proposal batches written down; conventions: read a tool's numeric severity constants from the tool (Fusion's lesson); README: Altium is the reference for the board model, conventions and checks, verbs come from any bridge; generate.py warns on equivalents that name no standard verb and stamps the standard version; regenerated with altium-lane's and fusion-lane's new equivalents (Altium 186, KiCad 113, Fusion 80 of 203)

Colby Knox ·24d78124ad ·14d ago ·parent 9a1d866
9 files changed +113−49
README.md+53−25
@@ -4,12 +4,14 @@ An AI should be able to work on a board the same way whether it lives in Altium Electronics or the next tool someone writes a bridge for: the same verbs, the same board model, the same checks. This page is where that is defined and kept in sync. -The **reference is the Altium bridge** ([adom/altium-bridge](https://wiki.adom.inc/adom/altium-bridge)), the most-complete one: its board model is the model, its conventions are the conventions, and its Rust is the checks-implementation. Its 201 verbs, sorted into tiers, are the base of the verb list, and **any bridge can propose more**:-a job that Altium lacks but KiCad or Fusion does joins the standard once another bridge's thread agrees to it (see-*Proposing a verb* below). Every bridge, Altium included, is measured against the whole list below:+The **Altium bridge** ([adom/altium-bridge](https://wiki.adom.inc/adom/altium-bridge)) is the reference for the+board model, the conventions and the checks: its board model is the model, its replies set the conventions, and its+Rust is where the shared checks engine starts. **Verbs come from any bridge.** Altium's 201 verbs, sorted into tiers,+were the first list; a job that KiCad or Fusion does and Altium lacks joins the standard once another bridge's thread+agrees to it (see *Proposing a verb* below), and then it is on Altium's to-do list like everyone else's. Every bridge,+Altium included, is measured against the whole list: [adom/kicad-bridge](https://wiki.adom.inc/adom/kicad-bridge), [adom/fusion-bridge](https://wiki.adom.inc/adom/fusion-bridge).+A verb one bridge gains should become every bridge's to-do: that is what this page is for.  ## What is in the standard @@ -45,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** | 79 | 60 | 57 | 26 |-| **native** | 36 | 34 | 25 | 16 |+| **core** | 79 | 63 | 57 | 28 |+| **native** | 36 | 35 | 25 | 16 | | **checks** | 32 | 32 | 7 | 3 | | **app** | 56 | 56 | 24 | 33 | | **platform** | 19 | 19 | 0 | 0 |-| standard (all but platform) | 203 | 182 | 113 | 78 |+| standard (all but platform) | 203 | 186 | 113 | 80 | <!-- coverage:end -->  The **checks** tier is where the other bridges are furthest behind, and it is the cheapest to close: those verbs are@@ -69,25 +71,38 @@ KiCad has length tuning, a pair router and teardrops of its own): their bridges  ## Keeping it in sync -`reference/` holds each bridge's verb list at a version (the reference bridge's full `describe`). To refresh:+One thread keeps this page: **standard-lane**. Each bridge's own thread keeps its bridge. To reach standard-lane, open+an issue here whose title starts with your thread's name (`kicad-lane: ...`); the pinned issue+[#3](https://wiki.adom.inc/adom/eda-bridge-standard/issues/3) says how, and names the session to ping.++| File | Who pushes it |+|---|---|+| `reference/<bridge>-<version>.json` | the bridge's own thread, for each new build: its `<prefix>_describe` reply |+| `tools/equivalents.json`, that bridge's section | the bridge's own thread |+| `tools/proposed.json` | the proposing thread once its issue is agreed, or standard-lane |+| generated: `verbs/standard.json`, `verbs/coverage.json`, `docs/coverage.md`, the coverage block above | **standard-lane only** |+| docs, schemas, `tools/generate.py`, `tools/tiers.json`, this README's text, `SKILL.md`, `page.json`, `package.json` | **standard-lane only** |++A bridge thread pushes its reference file and says so on an issue; standard-lane regenerates. Bridge threads do not run+`generate.py` and push its outputs: twice a push from a stale clone overwrote another bridge's newer reference and+numbers.  ```bash-# the reference bridge's catalog, from a machine running it-adom-bridge altium_describe '{}' > reference/altium-<version>.json-# then regenerate the standard, the coverage table and this page's numbers-python3 tools/generate.py+# a bridge thread: its catalog, from a machine running the bridge, then push that one file+adom-wiki repo clone adom/eda-bridge-standard --dir <new dir>        # the head moves: clone right before you push+adom-bridge kicad_describe '{}' > reference/kicad-<version>.json+adom-wiki repo push adom/eda-bridge-standard -m "kicad 1.0.63 reference" --files reference/kicad-<version>.json ``` -`tools/tiers.json` puts each reference verb in a tier; `tools/equivalents.json` records verbs a bridge has under-another name (Altium included, for proposed verbs it already does). An equivalent counts only when every verb it names is in that bridge's newest `reference/` file-(`generate.py` warns and leaves it out otherwise), so add the bridge's catalog before crediting its new verbs. When the reference bridge gains a verb, give it a tier and regenerate.--Clone the page's head right before running `generate.py` and push straight after: a stale clone overwrites another-bridge's newer reference or equivalents.+`generate.py` reads each bridge's newest file in `reference/` by version number. `tools/tiers.json` puts each Altium+verb in a tier; `tools/equivalents.json` records verbs a bridge has under another name (Altium included, for proposed+verbs it already does). An equivalent counts only when every verb it names is in that bridge's newest `reference/` file+(`generate.py` warns and leaves it out otherwise), so push the bridge's catalog before crediting its new verbs.  ## Proposing a verb -A job the standard lacks can come from any bridge. Add it to `tools/proposed.json` with the same fields as a+A job the standard lacks can come from any bridge. Open an issue here with the verbs you propose; standard-lane rules+on the names, tiers and shapes, and another bridge's thread agrees. Then add them to `tools/proposed.json` with the same fields as a `verbs/standard.json` row (`name`, `tier`, `summary`, `input`, `output`, `hint`, and `pitfalls`, `related`, `example` where you can), in the standard's terms (mm, y up, KiCad layer names, `Ref.Pin`, no tool vocabulary), plus: @@ -108,15 +123,28 @@ name the Altium bridge already has (credit the verb in `tools/equivalents.json` - Checks-tier proposals belong in the shared checks engine; a bridge may ship its own first if it answers in the   proposed output shape. +Decisions so far (KiCad bridge, 2026-10-27, agreed by the Altium bridge's thread):++| | Verbs |+|---|---|+| **In the standard (0.2.0)** | batch 1: 21 schematic verbs, `sch_connect_pins` to `sch_create`, and `render_schematic` |+| **Agreed, entries not yet written** | batch 2: `export_odb`, `export_ipc2581`, `export_ipc356`, `export_gencad`, `export_dxf`, `render_board` (`format` svg or png), `estimate_cost` (checks; the reply names its pricing source and date). Batch 3: `remove_parts`, `edit_parts`, `align_parts`, `set_layer_count`, `remove_graphics`, `import_svg`, `check_clearance`, `place_decoupling`, `plan_fanout` (the last three checks), `copy_routing`, `cross_probe`; flipping a part is `side` on `move_parts`. Batch 4: `project_create`, `project_info`, `project_rename`, `project_snapshot`, `read_footprint`, `edit_footprint` |+| **Refused** | `batch` (every edit verb takes a list instead), `export_molecule` (an Adom feature, not an EDA job), `text_bounds` (fold it into `silk_state`) |+| **Waiting for a job sentence** | `export_part`, "make a part project": say what job a user wants done and it gets ruled on |+ ## Status -Version 0.2.0: verbs can come from any bridge. The first batch, 21 schematic verbs from the KiCad bridge+Version 0.2.1: this page has one keeper (standard-lane) and bridge threads push only their own files (*Keeping it in+sync*); the decisions on KiCad's 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 Altium bridge's thread; Altium now shows those as gaps. Earlier: version 0.1.2: the verbs, the board model and the conventions, with Altium bridge 0.2.75 as the reference. 0.1.1 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. It takes the board model and-its companions as plain JSON and calls no bridge, so a bridge can link it or run it. 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 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.
SKILL.md+9−5
@@ -5,7 +5,8 @@ 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: the shared verb names in tiers (core, native, checks, app, platform), the board model JSON every   <prefix>_routing_state returns (mm, KiCad copper layer names, revision guard), the reply and refusal conventions, and-  how far each bridge covers it. Altium bridge is the reference; any bridge can propose verbs (tools/proposed.json). Use when building or extending an EDA bridge, adding a+  how far each bridge covers it. Altium bridge is the reference for the board model and checks; any bridge can propose+  verbs (tools/proposed.json). Use when building or extending an EDA bridge, adding a   verb to kicad/fusion/altium bridges, porting a check between bridges, comparing what each bridge can do, or reading a   board model from any bridge. Trigger words: eda bridge standard, bridge parity, same verbs every eda tool, board model   json, routing_state schema, port altium verb to kicad, what can the kicad bridge not do, standard verb names.@@ -13,8 +14,10 @@ description: >-  # eda-bridge-standard -The standard for Adom EDA bridges. The Altium bridge is the reference: its board model is the model and its verbs are-the base of the verb list. Other bridges add verbs through `tools/proposed.json` once another bridge's thread agrees.+The standard for Adom EDA bridges. The Altium bridge is the reference for the board model, the conventions and the+checks; verbs come from any bridge. Altium's verbs were the first list, and other bridges add verbs through+`tools/proposed.json` once another bridge's thread agrees. The standard-lane thread keeps the page: reach it with an+issue whose title starts with your thread's name (the pinned issue says how).  ## Read first @@ -35,8 +38,9 @@ the base of the verb list. Other bridges add verbs through `tools/proposed.json` 2. If your tool does the job under its own verb already, keep it and add the standard name as an alias. 3. Reply with `success`, `errorCode` and `error` on refusal, and a `_hint` that says the next step. Take    `expectedRevision` on edits; offer `dryRun` where a plan can be wrong.-4. Add the bridge's verb list to `reference/` and run `python3 tools/generate.py` on a fresh clone of the page's-   head, then push at once: `docs/coverage.md` moves.+4. Push the bridge's verb list (`<prefix>_describe`) as `reference/<bridge>-<version>.json` from a fresh clone of the+   page's head, that file only, and say so on an issue. The standard-lane thread regenerates `docs/coverage.md`; a+   bridge thread does not run `generate.py` and push its outputs (README, *Keeping it in sync*).  ## When you port a check (the checks tier) 
docs/conventions.md+6−1
@@ -1,6 +1,6 @@ # Conventions every bridge follows -These are the rules the reference bridge (Altium) already keeps. A bridge that keeps them lets one AI drive every EDA tool+These started as the rules the reference bridge (Altium) keeps, and grow with what every bridge learns. A bridge that keeps them lets one AI drive every EDA tool the same way, and lets the shared checks run on any of them.  ## Names@@ -60,6 +60,11 @@ Checks: - Name each finding with where it is (`at: [x, y]`, a designator, a pad `U1.3`, a net). - Separate errors from warnings, and say when a check could not see something (`noBody`, `poursWithoutRegions`,   `complete: false`) rather than passing it.+- Read a tool's numeric constants from the tool, never assume them. A severity (error or warning), a state (approved,+  waived) or a kind that the tool hands over as a number means what the tool's own API defines, and that differs from+  tool to tool: Fusion's ULP has `ERROR_TYPE_WARNING = 1`, `ERROR_TYPE_ERROR = 2` and `ERROR_STATE_APPROVED = 2`, and+  the Fusion bridge reported DRC errors as warnings and warnings as errors until it read them. Answer the standard's+  words (`severity: "error"`), not the tool's numbers. - Name the source of any outside number (a fab's limit: its page and the date it was read). Fab limits come from   [adom/pcb-design-rules](https://wiki.adom.inc/adom/pcb-design-rules), the canonical record per vendor. 
docs/coverage.md+9−9
@@ -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** | 79 | 60 | 57 | 26 |-| **native** | 36 | 34 | 25 | 16 |+| **core** | 79 | 63 | 57 | 28 |+| **native** | 36 | 35 | 25 | 16 | | **checks** | 32 | 32 | 7 | 3 | | **app** | 56 | 56 | 24 | 33 | | **platform** | 19 | 19 | 0 | 0 |-| standard (all but platform) | 203 | 182 | 113 | 78 |+| standard (all but platform) | 203 | 186 | 113 | 80 |  ## core @@ -19,7 +19,7 @@ Read and edit the design. Every bridge provides these: they are how an AI sees a  | Verb | What it does | Altium | KiCad | Fusion 360 | |---|---|---|---|---|-| `add_body` | Put a 3D body on a footprint of a PcbLib: a STEP model, or an extruded box when no step is given. It REPLACES the footprint's existing 3D bodies (a... | `altium_add_body` |  |  |+| `add_body` | Put a 3D body on a footprint of a PcbLib: a STEP model, or an extruded box when no step is given. It REPLACES the footprint's existing 3D bodies (a... | `altium_add_body` |  | `fusion_attach_3d_package` (partial) | | `add_models` | Attach one or more PCBLIB footprint models, parameters, comment and description to a SchLib component (Altium's several-footprints-per-symbol mechanism). | `altium_add_models` |  |  | | `add_symbol_art` | Draw the chip-outline artwork (the chip-thumbnailer polylines adom-symbol baked into the KiCad symbol) into a SchLib component, fitted to its body... | `altium_add_symbol_art` |  |  | | `apply_silkscreen` | Land a silkscreen plan in one undo step: designators and comments moved, sized and turned (or hidden), free overlay texts and lines added (bottom texts... | `altium_apply_silkscreen` | `kicad_silk_fields_batch / kicad_silk_text_batch / kicad_silk_graphics_batch` | `fusion_apply_silkscreen` |@@ -40,7 +40,7 @@ Read and edit the design. Every bridge provides these: they are how an AI sees a | `layers` | The current board's layer set with ids, names, kind and whether each is displayed. | `altium_layers` |  | `fusion_layers` | | `layers_in_use` | Which layers of the current board actually carry primitives: copper layers with copper (densest first) and every layer with anything on it. | `altium_layers_in_use` | `kicad_layers_in_use` | `fusion_layers_in_use` | | `list_designators` | Every component designator on the current board. | `altium_list_designators` | `kicad_list_designators` | `fusion_list_designators` |-| `list_library` | Names of every component in a .SchLib or every footprint in a .PcbLib (kind taken from the extension). Opens the library; no screenshot. | `altium_list_library` | `kicad_list_footprints / kicad_list_symbols` (partial) |  |+| `list_library` | Names of every component in a .SchLib or every footprint in a .PcbLib (kind taken from the extension). Opens the library; no screenshot. | `altium_list_library` | `kicad_list_footprints / kicad_list_symbols` (partial) | `fusion_library_parts` (partial) | | `list_nets` | Every net on the current board with its pad count. | `altium_list_nets` | `kicad_list_nets` | `fusion_list_nets` | | `move_parts` | Move and rotate placed components; each part is read back to 0.001 mm and the exact rotation. One undo step. | `altium_move_parts` | `kicad_move_footprint` | `fusion_move_parts` | | `net_connections` | Every pad on the board with its net and owner (Designator.Pad), plus a bounding span and the airline length (minimum spanning tree over its pads, airlineMm)... | `altium_net_connections` | `kicad_trace_net / kicad_find_connections` (partial) | `fusion_net_connections` |@@ -68,7 +68,7 @@ Read and edit the design. Every bridge provides these: they are how an AI sees a | `sch_connect` | Connect pins of placed parts: a wire stub from each pin's outer end plus a net label (kind label), a power port (kind power: GND-like nets get a ground... | `altium_sch_connect` | `kicad_sch_connect_to_net / kicad_sch_no_connect / kicad_sch_wire / kicad_sch_label` |  | | `sch_connect_pins` *proposed* | Wire pins to pins on a sheet by Ref.Pin: an L-shaped route (one horizontal and one vertical leg) for each pair, with a junction dot wherever a route meets... |  | `kicad_sch_connect_pins` |  | | `sch_connect_to_bus` *proposed* | Fan pins onto a bus: for each pin a wire running to the bus, a 45-degree bus entry onto it and a member label (D0, D1 ...) on the wire. One undo step. |  | `kicad_sch_connect_to_bus` |  |-| `sch_create` *proposed* | Create an empty schematic sheet with a paper size and title block; optionally add it to a project as a child sheet of the root. It places no parts or nets... |  | `kicad_sch_create` |  |+| `sch_create` *proposed* | Create an empty schematic sheet with a paper size and title block; optionally add it to a project as a child sheet of the root. It places no parts or nets... | `altium_sch_sheet_symbol` (partial) | `kicad_sch_create` |  | | `sch_delete_wire` *proposed* | Delete wires or bus segments by id, by their two ends, or every wire through a point, and remove junction dots that no longer join three or more items. One... |  | `kicad_sch_delete_wire` |  | | `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. |  | `kicad_sch_edit_label` |  |@@ -78,10 +78,10 @@ Read and edit the design. Every bridge provides these: they are how an AI sees a | `sch_junction` *proposed* | Add junction dots at points, or remove dots by id or point. One undo step. |  | `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,... |  | `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_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,... |  | `kicad_sch_pins` |  |+| `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_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... |  | `kicad_sch_sheet_pins` |  |+| `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_symbol` |  | | `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. |  | `kicad_sch_split_wire` |  | | `sch_swap_part` | Replace a placed part with another library part (a different value, package or symbol) at the same place, designator and rotation, keeping its connections:... | `altium_sch_swap_part` | `kicad_sch_replace_symbol` (partial) |  |@@ -128,7 +128,7 @@ Wraps the EDA tool's own feature (its DRC, ERC, Gerbers, pours, Update PCB). Eve | `pcb_report` | Numbers instead of pixels: for a PcbLib, every footprint's pads, pad bounding box, primitive census and 3D bodies; for a board, outline, components with... | `altium_pcb_report` | `kicad_errors` (partial) |  | | `pour_state` | Every polygon pour with the copper it actually poured: filled area per pour and per layer, and the pours that poured nothing. | `altium_pour_state` | `kicad_pour_state` | `fusion_pour_state` | | `remove_pours` | Delete polygon pours by net (and layer), or all of them, and the pour keepouts (cutouts) apply_pours made. Tracks and vias are untouched. | `altium_remove_pours` | `kicad_remove_zone` | `fusion_remove_pours` |-| `render_schematic` *proposed* | Render a sheet to an image without opening a window, through the tool's own plotter, and keep visual baselines: baseline set stores the image, baseline... |  | `kicad_render_schematic` |  |+| `render_schematic` *proposed* | Render a sheet to an image without opening a window, through the tool's own plotter, and keep visual baselines: baseline set stores the image, baseline... | `altium_show_schematic` (partial) | `kicad_render_schematic` |  | | `replicate_layout` | Copy one channel's placement to matching channels: each target keeps its anchor part where it is and every other part takes the source's offset and rotation... | `altium_replicate_layout` |  |  | | `repour` | Repour every polygon on the board (Altium's Repour All) and answer the copper after. Runs outside the script engine so scoped rules apply. | `altium_repour` | `kicad_repour` | `fusion_repour` | | `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` |
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "eda-bridge-standard",-  "version": "0.2.0",+  "version": "0.2.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.2.0",+  "version": "0.2.1",   "hero": {     "type": "billboard",     "headline": "One standard for every EDA bridge",
tools/generate.py+8−1
@@ -103,6 +103,12 @@ def main():             "timeoutSeconds": p.get("timeoutSeconds"), "proposedBy": p["proposedBy"], "since": p["since"], "agreedBy": p["agreedBy"],         })     standard.sort(key=lambda s: (ORDER.index(s["tier"]), s["name"]))+    # an equivalent filed under a name the standard lacks (a typo, a renamed verb) would credit nothing, silently+    names = {s["name"] for s in standard}+    for b, section in eq.items():+        for k in section:+            if k not in names:+                print(f"warning: tools/equivalents.json {b}: {k} is not a standard verb, not counted")      coverage = []     for s in standard:@@ -124,7 +130,8 @@ def main():                 row[b] = None         coverage.append(row) -    meta = {"reference": {"bridge": "altium", "version": ref["version"]}, "proposed": len(proposed),+    meta = {"standard": load("package.json")["version"],+            "reference": {"bridge": "altium", "version": ref["version"]}, "proposed": len(proposed),             "compared": {b: o["version"] for b, o in others.items()}, "tiers": TIERS}     os.makedirs(os.path.join(ROOT, "verbs"), exist_ok=True)     with open(os.path.join(ROOT, "verbs", "standard.json"), "w") as f:
verbs/coverage.json+25−6
@@ -1,4 +1,5 @@ {+ "standard": "0.2.1",  "reference": {   "bridge": "altium",   "version": "0.2.75"@@ -25,7 +26,10 @@     "match": "exact"    },    "kicad": null,-   "fusion360": null+   "fusion360": {+    "verb": "fusion_attach_3d_package",+    "match": "partial"+   }   },   {    "name": "add_models",@@ -334,7 +338,10 @@     "verb": "kicad_list_footprints / kicad_list_symbols",     "match": "partial"    },-   "fusion360": null+   "fusion360": {+    "verb": "fusion_library_parts",+    "match": "partial"+   }   },   {    "name": "list_nets",@@ -718,7 +725,10 @@    "name": "sch_create",    "tier": "core",    "source": "proposed",-   "altium": null,+   "altium": {+    "verb": "altium_sch_sheet_symbol",+    "match": "partial"+   },    "kicad": {     "verb": "kicad_sch_create",     "match": "exact"@@ -831,7 +841,10 @@    "name": "sch_pins",    "tier": "core",    "source": "proposed",-   "altium": null,+   "altium": {+    "verb": "altium_read_sheet_file",+    "match": "partial"+   },    "kicad": {     "verb": "kicad_sch_pins",     "match": "exact"@@ -867,7 +880,10 @@    "name": "sch_sheet_pins",    "tier": "core",    "source": "proposed",-   "altium": null,+   "altium": {+    "verb": "altium_sch_sheet_symbol",+    "match": "partial"+   },    "kicad": {     "verb": "kicad_sch_sheet_pins",     "match": "exact"@@ -1415,7 +1431,10 @@    "name": "render_schematic",    "tier": "native",    "source": "proposed",-   "altium": null,+   "altium": {+    "verb": "altium_show_schematic",+    "match": "partial"+   },    "kicad": {     "verb": "kicad_render_schematic",     "match": "exact"
verbs/standard.json+1
@@ -1,4 +1,5 @@ {+ "standard": "0.2.1",  "reference": {   "bridge": "altium",   "version": "0.2.75"