Repository navigation
Conversation
The check measured centre-to-centre against `Pad::radius_nm`, which is half the pad's *long* side. That radius exists for connectivity, where over-reaching is the safe direction, and it is wrong for a violation: on a 1.95 x 0.6 mm SOIC pad it reaches 0.975 mm from the centre while the copper reaches 0.3 mm across the narrow axis. Every Class-A board failed on it. a3_protected_power_entry was rejected for a via 0.268 mm clear of U1.2's edge, against the 0.1 mm same-net clearance Synth had asked the router for; the router had over-delivered and was blamed for it. Pads now carry their board-frame orientation and answer `contains_point` exactly, by shape. The old test could not have caught this: it used square pads, where the long and short half-dimensions are the same number, and placed the via dead centre. (cherry picked from commit d25cba0)
The exported `.kicad_pro` stated `min_clearance` and `min_track_width` and nothing else. Three parties read those rules and all three were reading a board that declared almost nothing: - `kicad-cli pcb drc` has no rule to apply where the key is absent, which is why it passed boards Synth called unfabricable; - the external router is asked to preserve "the board's declared minimums" and can only preserve what the project states; - `synth-router`'s independent validation judges the result against the full profile. With no `min_through_hole_diameter` the router had no drill floor, took the 0.15 mm rung its fabrication tier allows, and Synth then rejected the board against the profile's 0.3 mm. The rules are now derived from the board's declared manufacturer, so the three agree by construction. `min_via_diameter` follows from drill plus two annular rings, the relationship KiCad itself enforces, rather than being a fourth number to choose. `min_hole_to_hole` has no profile field and is left out. (cherry picked from commit 77d810b)
A `.kicad_pcb` carries no design rules or net classes; they live in the
sibling `.kicad_pro`, which every KiCad tool finds by swapping the
extension. The preserved baseline is `<stem>.synth.kicad_pcb`, so the
router looked for `<stem>.synth.kicad_pro` while the export had written
`<stem>.kicad_pro`. That file has never existed.
So every board, every engine, every run has been routed against the
engine's own defaults rather than the board's rules. KiCadRoutingTools
reported it plainly once asked: `board_floors: {}`, and it created a
Default net class because "project had none".
With the project copied alongside, a3 goes from two sub-minimum drills
to none, and from three fab-tier escalations to zero. Best-effort: a
board exported without a project still routes, where a missing baseline
is unrecoverable.
(cherry picked from commit 5e6ad65)
A footprint's `(at x y angle)` angle is anticlockwise on screen, and KiCad's y axis points down, so a pad offset transforms by -angle. The reader applied +angle, putting every pad with a non-zero offset on the wrong side of its footprint. The independent validation pass then looked for copper where no copper was, and reported nets open on boards the engine had routed correctly. On the new Class-A board it rejected three: a 1x2 JST rotated 90 had pad 2 read 5 mm from its own copper, and the 1x4 probe connector had two. Pad 1 of each sits at offset (0, 0), where rotation cannot matter, which is why one pin of a connector worked and the rest did not. It survived because the corpus is mostly symmetric two-pad passives. At +-90 those produce the same *set* of pad positions and merely swap which pad is which, so every net still closes. Only an asymmetric multi-pad part shows it. The fixture that should have caught it certified it instead: its B.Cu segment was drawn to the point the reader's own arithmetic reported, so the reader was checked against itself. Its coordinates are corrected here and the note says to check such numbers against a routed board. The front-side transform is measured against copper KiCadRoutingTools produced. The mirror composition for bottom-side footprints is reasoned only: the placer puts every footprint on the front, so no board exercises it. (cherry picked from commit ba3ccd8)
`ice40hx4k_bg121` is the registry's first ball-grid part: a Lattice iCE40 HX4K on an 11 x 11 grid at 0.8 mm pitch, which is what absmach#40 case 1 asks escape routing to be demonstrated against. All 121 balls are declared and checked both ways against the stock symbol and footprint, so neither load-time rule can fail on it. The symbol `extends` its HX8K sibling and carries no pins of its own; both the pin check and the schematic loader follow that chain, so the part names the device it is. Twenty-eight pins are marked required: every supply and ground ball plus CRESET and CDONE. An untied ball on a BGA is not a cosmetic omission. `hdmi_a_receptacle` gives the four TMDS pairs somewhere to go. Polarity lives in the electrical types, because `diff_pair_positive` requires `differential_positive` and the two have to agree for the part to load. The lane shields and GND are `ground_reference`, not `power_input`: as supplies they read as power pins wanting their own decoupling, which is what E-SYNTH-KG-001 reported. No part had used that type before. The FPGA's general-purpose I/O declares both I2C roles because an FPGA's I/O is soft and any pin can serve either. That is weaker than a fixed-function part, where a capability pins down one function and a wrong connection is caught; the registry cannot say "any of these pins, any of these roles, one at a time". Noted on the part.
Writing the Class-C board walked into all three. `osc_smd_25mhz` named `Oscillator:SiT8008B` and `Oscillator_SMD_SiTime_SiT8008-4Pin_5.0x3.2mm`. Neither exists in KiCad 10.0.6. The stock pair for the same 4-pin 5.0 x 3.2 mm SiTime part is `SiT8008xx-1x-xxE` and `Oscillator_SMD_SiT_PQFN-4Pin_5.0x3.2mm`; the pin map already matched OE/GND/OUT/Vdd on pads 1-4 and is unchanged. Its declared dimensions were 5.0 x 5.0, the body is 5.0 x 3.2 and the courtyard 6.0 x 4.32. `tvs_array_5v` declared pad 8 on a 6-pad SOT-363, which fails E-SYNTH-PIN-001, and its description said SOIC-8. `mp2307_buck` named a footprint that does not exist and left the exposed thermal pad out of the pin map. The last two are the same corrections already made under absmach#87 on the qualification branch, brought here because this board cannot ground a thermal pad or clamp an input through a pad that is not there.
`diff_pair` could already bound the two halves of one pair with `max_skew`. Nothing could bound one net against another, which is what a length-sensitive bus needs: absmach#40 case 2 asks for a length-matched interface and there was no way to declare one. `netclass "TMDS" { match_length 0.25mm }` says every net in the class must come back the same routed length, within that tolerance. It is measured, not merely recorded. `check_length_matching` sums copper per net from the same geometry the connectivity pass walks, and reports the class with its spread and the two nets at the extremes. A declared constraint nothing checks is the complaint in absmach#65, so the tolerance reaches the independent validation and blocks there. Vias are not counted: they add board thickness, which is common to every net in a class, and the tolerances here are about planar routing. A net with no copper is skipped rather than measured as zero, because it is already reported as an open net and would otherwise also be named the shortest member of its class. `Length::to_nm` comes with it, so a tolerance compares against integer copper geometry without a round trip through `f64`.
…it stops An iCE40 HX4K on a 121-ball BGA driving HDMI, written from a prompt through the MCP server. It carries absmach#40's four cases: the BGA escape, the four TMDS pairs at 100 ohm with `max_skew` and `couple tight`, the lanes matched net-to-net with the new `match_length`, and two rails from one 5 V input. Validate reports no errors and the knowledge graph no missing support circuit. Four warnings were acted on rather than silenced: the TVS channels were spent on D+/D- that this power-only inlet never connects while CC sat unprotected, three rails carried more load than their decoupling supported, and the HDMI lane shields were typed as supplies so they read as power pins wanting their own capacitors. It does not route, and the board says why. Synth pours ground and nothing else, so the 3.3 V rail's thirty pads and the core rail are traces across a dense four-layer BGA board; the router leaves 29 open nets, almost all supply. That is the limit on absmach#40 case 4, not a router defect, and granting via-in-pad does not move it. The placement sidecar holds one override: the placement review refused to route until J2 was turned parallel to the board edge, and named the rotation. `synth_place_with_hints`, which the same message says to rerun, takes region/edge/near and no rotation, so the recommendation can only be applied through a layout override.
A registry change that completes a part's pin map moves the rendered plot of every design using that part. The assertion fired on the first one, so regenerating the goldens meant running the suite once per design to learn the next name. Collect them all and print the golden and live fingerprints side by side. (cherry picked from commit 5359106)
`every_language_constraint_is_supported_unsupported_or_unverified` reads the attribute list straight off the AST and fails on anything the descriptor does not place, so adding `match_length` to `NetclassAttr` without listing it left it unclassified. It is listed as supported, which is what it is: declared, lowered, and measured against the routed copper. A good guard. It is the reason a new constraint cannot quietly ship without saying whether Synth stands behind it.
…elines `keywords_recognized` lexes a fixed source and compares the whole token stream, so adding `match_length` to that source without adding `KwMatchLength` to the expected list failed it. Another guard worth having: the keyword vocabulary cannot grow silently. The two schematic baselines are CI's own numbers from this branch's run, because both depend on KiCad symbol geometry this machine does not have. All ten golden fingerprints moved — `main` is red on the same drift at 79daf6f and absmach#116 is the fix in flight there — and the feather placement moved by hundredths of a millimetre, which is the corrected oscillator courtyard propagating to its neighbours. Every old value in the placement snapshot was checked against the file before being replaced. An earlier attempt at this skipped that and had crossed two snapshot regions in the log, which would have written numbers no run ever produced into a release baseline.
Two defects, both of which made a declared tolerance read as satisfied. Only the CLI populated `length_groups`. Both MCP routing entry points left it empty, and an empty group list makes `check_length_matching` iterate nothing and report nothing — indistinguishable from a pass. The derivation now lives on `RouteRequest` and all three callers use it, so a fourth caller cannot quietly skip it. And declaring a `netclass` puts no net in it: nets join one through `class "NAME"` on a `connect`, `net` or `power` statement. No board in this repo did that, so every netclass in the corpus is inert — the widths and clearances on a1, a2, a3, b1-b5, c1 and c2 have never applied to anything either. c3's eight TMDS lane connects now carry `class "TMDS"`, and the IR confirms the eight nets and the 0.25 mm tolerance reach the netclass. The claim in the earlier commit that this is "measured, not merely recorded" is true of the mechanism and not yet evidenced by this board. Tightening the tolerance to 0.001 mm still reports nothing, because seven of the eight lanes have no copper: the class has one measurable net, and one net cannot be mismatched against itself. c3 will exercise the check when it routes, which waits on absmach#117. The unit test is the evidence that exists today.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 14, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 14, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
Contributor
Author
|
Closing: every piece of this has been re-landed as a reviewable PR, as the review asked.
Two things did not come across, deliberately:
The CI render job added here was also dropped here; board images are rendered locally and attached to the board PR instead. Splitting it this way turned up five defects the monolith had buried, each now its own issue or PR: #157, #158, #165, the |
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 16, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 16, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 17, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 17, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 17, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 20, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 20, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 20, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 20, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
JeffMboya
added a commit
to JeffMboya/synth
that referenced
this pull request
Oct 21, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
rodneyosodo
pushed a commit
to JeffMboya/synth
that referenced
this pull request
Oct 30, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
rodneyosodo
pushed a commit
to JeffMboya/synth
that referenced
this pull request
Nov 2, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
rodneyosodo
pushed a commit
to JeffMboya/synth
that referenced
this pull request
Nov 2, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
rodneyosodo
pushed a commit
to JeffMboya/synth
that referenced
this pull request
Nov 2, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
rodneyosodo
pushed a commit
to JeffMboya/synth
that referenced
this pull request
Nov 2, 2026
`escape { method underpad layers "In1.Cu", "In2.Cu" }` on a component, or
`escape { off }` to leave a package to the general router. Geometric
selection stays the default: the block overrides it rather than replacing
it, and precedence is `off` first, then what the design declared, then the
geometry.
Needing an escape is a property of the package, but *how* to escape it is a
design decision — which layers it may use, and whether a part the geometry
would pick should be left alone. Before this the engine's choice was the
only one available, and a board had no way to disagree with it.
`method` and `off` are contextual identifiers so a design already using
those words as names keeps parsing. `layers` cannot be: it is the reserved
keyword that declares the board's copper count, so the sub-setting arrives
as `KwLayers` and is matched as such.
E-SYNTH-PARSE-040 names an attribute the block does not take, and
E-SYNTH-PROCESS-004 an escape method this build does not know; both ship
their diagnostic pages.
Taken from the absmach#138 monolith, minus the parts that belonged to work which
has not landed: the `match_length` length groups, which absmach#145 closed in
favour of a netclass `max_skew`, and the netclass via-geometry constants.
The MCP call sites are re-derived against main's `evaluate_candidate_mcp`
refactor rather than the inline body they were written for, and the
candidate evaluator takes the intent too, because a declared `off` would
otherwise change which placement wins.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What type of PR is this?
This is a feature
What does this do?
Adds
requires via_in_pad, the design's half of a decision that lived only at the command line:ManufacturerProfile.via_in_pad— what the tier sellsrequires via_in_pad— what the board needsE-SYNTH-PROCESS-002— refusal when they disagreeWhich issue(s) does this PR fix/relate to?
Have you included tests for your changes?
Yes
Did you document any new/modified features?
Yes
Notes
Via-in-pad was one boolean answering two questions: can this process fill and cap a via in a pad, and may this board use one. Conflating them meant a board exported against an advanced tier inherited a permission it never asked for, and a board that asked on a standard tier had nowhere to be told no.
The filled-via tier carries JLC's standard floors and nothing else. Filling a via buys the capability, not a finer drill, so a board cannot reach geometry it never paid for by asking for the fill — there is a test pinning that.
--krt-allow-via-in-padsurvives as an operator override and still outranks the profile, because a human passing it has taken responsibility for one panel.The Class C board declares the requirement. Its README keeps the pre-declaration routed numbers and says so: the engine is now given the permission, which KRT encodes as a clearance sentinel, so the copper may differ. CI measures that.