← Commit history

standard 0.4.2, engine 0.1.1: stack_layers names copper layers by the stack entry's layer, or by place (In<n>.Cu), planes included, per 0.3.1 (altium-lane's patch from its vendored copy, #8)

Colby Knox ·604f13092c ·14d ago ·parent bfb5047
8 files changed +18−11
README.md+2
@@ -155,6 +155,8 @@ Decisions so far (proposals from the KiCad and Fusion bridges, 2026-10-27; issue  ## Status +Version 0.4.2: the engine (0.1.1) names a stack's copper layers by the stack entry's `layer`, or by place (`In<n>.Cu`),+planes included, as 0.3.1 settled; from altium-lane, which runs the engine inside the Altium bridge now. Version 0.4.1: coverage counts only what works: a bridge marks a verb `partial` (with a note) or `unsupported` in its equivalents file ([conventions](docs/conventions.md)); `sheet` on a tool without sheet files is the sheet number. Version 0.4.0: the checks engine, `adom-eda-checks`, is on this page in `engine/` with its first five checks; fab limits
engine/Cargo.lock+1−1
@@ -4,7 +4,7 @@ version = 4  [[package]] name = "adom-eda-checks"-version = "0.1.0"+version = "0.1.1" dependencies = [  "serde_json", ]
engine/Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "adom-eda-checks"-version = "0.1.0"+version = "0.1.1" edition = "2021" description = "The EDA Bridge Standard's checks, computed from the board model JSON: no bridge calls, no tool." license = "MIT"
engine/src/coppermap.rs+10−5
@@ -84,14 +84,16 @@ impl Raster {     pub fn count(&self) -> usize { self.cells.iter().filter(|c| **c).count() } } -/// The stack's copper layers in order as (routing_state name, plane?, plane net).+/// The stack's copper layers in order as (board model name, plane?, plane net). The name is the stack entry's `layer`+/// when the bridge gives it, else its place in the copper stack (F.Cu, In<n>.Cu, B.Cu): a plane is named like any other+/// inner layer (standard 0.3.1), never by a tool's id. pub fn stack_layers(stack: &Value) -> Vec<(String, bool, String)> {     let ls: Vec<Value> = stack["layers"].as_array().cloned().unwrap_or_default();     let n = ls.len();     ls.iter().enumerate().map(|(i, l)| {-        if l["kind"] == "plane" { return (format!("L{}", 38 + l["plane"].as_i64().unwrap_or(1)), true, l["net"].as_str().unwrap_or("").to_string()); }-        let name = if i == 0 { "F.Cu".to_string() } else if i + 1 == n { "B.Cu".to_string() } else { format!("In{}.Cu", l["mid"].as_i64().unwrap_or(i as i64)) };-        (name, false, String::new())+        let plane = l["kind"] == "plane";+        let name = l["layer"].as_str().map(str::to_string).unwrap_or_else(|| if i == 0 { "F.Cu".to_string() } else if i + 1 == n { "B.Cu".to_string() } else { format!("In{i}.Cu") });+        (name, plane, if plane { l["net"].as_str().unwrap_or("").to_string() } else { String::new() })     }).collect() } @@ -418,8 +420,11 @@ mod tests {     fn stack_names_match_routing_state() {         let s = json!({"layers": [{"name": "Top"}, {"kind": "plane", "plane": 1, "net": "GND"}, {"kind": "signal", "mid": 1}, {"name": "Bottom"}]});         let l = stack_layers(&s);-        assert_eq!(l.iter().map(|x| x.0.as_str()).collect::<Vec<_>>(), vec!["F.Cu", "L39", "In1.Cu", "B.Cu"]);+        assert_eq!(l.iter().map(|x| x.0.as_str()).collect::<Vec<_>>(), vec!["F.Cu", "In1.Cu", "In2.Cu", "B.Cu"]);         assert!(l[1].1 && l[1].2 == "GND");+        // the bridge's own name wins when it gives one+        let named = json!({"layers": [{"layer": "F.Cu"}, {"layer": "In1.Cu", "kind": "plane", "net": "GND", "layerId": 39}, {"layer": "B.Cu"}]});+        assert_eq!(stack_layers(&named)[1], ("In1.Cu".to_string(), true, "GND".to_string()));     }     #[test]     fn gap_runs_group_and_the_fix_patches_the_neighbour() {
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "eda-bridge-standard",-  "version": "0.4.1",+  "version": "0.4.2",   "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.4.1",+  "version": "0.4.2",   "hero": {     "type": "billboard",     "headline": "One standard for every EDA bridge",
verbs/coverage.json+1−1
@@ -1,5 +1,5 @@ {- "standard": "0.4.1",+ "standard": "0.4.2",  "reference": {   "bridge": "altium",   "version": "0.2.76"
verbs/standard.json+1−1
@@ -1,5 +1,5 @@ {- "standard": "0.4.1",+ "standard": "0.4.2",  "reference": {   "bridge": "altium",   "version": "0.2.76"