PCB Design Rules
Public Made by Adomby adom
Canonical PCB fab design rules (DRC) for every popular vendor: one JSON record per vendor, process and layer count, with generated Fusion/EAGLE .dru and .edru, KiCad .kicad_dru plus board-setup JSON, Altium .RUL exports, and a human comparison table. Every number cites the vendor's own capabilities page and the date it was read.
PCBWay 4L 1oz complete minimal KiCad/Fusion/Altium/index/README: strict opt-in, 8 files change, all 4L (DRAFT; replaces #8; merge blocked) #9
DRAFT, NOT FOR MERGE. This complete set replaces draft #8 (global 382), which omitted four stale PCBWay 4-layer outputs. Please close #8 when this is reviewed. Merge is blocked until a maintainer decision.
Complete, self-consistent 4-layer change (11 files)
Source: tools/generate.py, tools/test_pcbway_4l.py (12 tests), tools/test_legacy_unchanged.py (2 tests), rules/records/pcbway.json. Generated, PCBWay standard 4-layer only: kicad/pcbway-4L.kicad_dru, kicad/pcbway-4L.board-setup.json, fusion/pcbway-4L.dru, fusion/pcbway-4L.edru, altium/pcbway-4L.RUL, rules/index.json (4L sources entry), README.md (4L table row). Measured blast radius against main's generator, over 298 generated and committed files: exactly these 8 change, all PCBWay 4-layer. Every other file is byte-identical. Consistency: a test asserts every committed 4-layer output equals the generator's output for its record. Fusion .edru is well-formed XML. Main's committed outputs match main's generator (0 differences), so there is no pre-existing drift. An earlier draft of this note claimed drift; that was wrong and is withdrawn.
What changed, and why it is smaller than #7
- #7 changed the KiCad export of ALL 55 vendor packs. This draft changes ONE record: PCBWay standard 4-layer 1 oz. Every other record uses the legacy export path, byte for byte.
- Measured blast radius (generator output, main vs this draft): 110 generated KiCad files, 108 byte-identical, 2 changed (PCBWay 4L .kicad_dru and .board-setup.json). Hashes in SHA256-pr-min.txt.
- Opt-in flag
kicadStrict: trueon the PCBWay 4L record only (tested: exactly one record carries it). - The 4L pack has NO unconditional clearance rule. A global custom clearance overrides the Default netclass (0.2 mm): a 0.18 mm gap passes with the rule and fails without it (desktop KiCad 10 DRC). The 0.1524 mm floor is carried as the board minimum clearance (board setup
minClearanceMm), which holds over looser netclasses (0.1 mm netclass, 0.14 mm gap fails against the 0.1524 mm board minimum).
Correction to earlier claims (please read)
- Earlier PCBDS text and issue #6 said KiCad 10 REJECTS the
holeconstraint keyword. That was wrong. The rejection came from the bridge pre-checkkicad_custom_rules validate, not from KiCad's DRC loader. Desktop KiCad 10.0.7 DRC accepts the published pack's(constraint hole ...)and enforces it asmin-hole(drill violations reported under rule 'min-hole'). Evidence: drc-cpn_hole-published.json (SHA-256 in SHA256-pr-min.txt). - Consequence:
hole_sizein the 4L output is the canonical KiCad constraint name, not a compatibility fix. The legacy export for other vendors keepsholeto avoid any output change. - The real defects in the published 4L pack, measured in DRC: (1) an unconditional custom clearance 0.127 mm that overrides netclass clearance, (2) outer 1 oz track minimum too weak (0.1016), (3) no annular-ring rules, (4) no hole-to-hole or hole-to-inner-copper rules, (5) via diameter 0.454 mm.
Sources (archived 2026-11-02 and earlier; SHA-256 of archived bytes)
- https://www.pcbway.com/capabilities.html: 694ce30266e8c0bde8173d590c3ac71e6d928eb730fad3555e6a1dd298e0a980. The 1 oz OUTER conventional row: 35um, Normal process ≥5/6 mil (width/spacing), under "The min width/spacing of outer layer".
- https://www.pcbway.com/helpcenter/Engineering_Questions/limited_holes_spacing.html: 9cebdeed859c3c61d4e104185aa5e6a54fb1a5c6ac5864591fbd5993479145e1 (states 0.45 mm PTH and 0.30 mm via spacing; last updated 2025-06-25).
- https://www.pcbway.com/pcb_prototype/PCB_Manufacturing_tolerances.html: 51142afe99832cc0ee41af19bf7d4c552a2658da466f04850523fab09bb66948. PTH ring 0.20 mm (weaker than the 10 mil table value, not used).
- Stricter value chosen where sources disagree. Vendor values are not weakened.
Verified
- 4L outputs: kicad/pcbway-4L.kicad_dru sha256 ed114795f294b9e6355627166f0d557132d848f2325389c8f54b0b7cf7ee0ef4 (11 rules, every rule an explicit error); kicad/pcbway-4L.board-setup.json sha256 01edbd0b23d3bbe4807e6428dc24ca4dfe320bb4986a963db44c914e4d33a9a5 (identical to the audited file).
- Tests: test_pcbway_4l.py 11/11; test_legacy_unchanged.py 2/2 (non-strict records use the legacy export; exactly one strict record).
- Native KiCad 10 DRC (desktop kicad-cli 10.0.7 via bridge, zone refill on): violating coupon fires the rule-named categories; compliant coupon has zero rule-named errors; netclass coupons (strict 0.2, loose 0.1, compliant) behave as stated above. Evidence files are in the reviewer folder and listed in SHA256-pr-min.txt.
Not in this draft (explicit)
- PR #2 (global 98) InstaPCB record and test_constraints.py are not included.
Merge blockers
- Maintainer decision on the
kicadStrictopt-in name and placement in the record schema. - Board-stage checks are not verified by this PR: pad-to-zone clearance, netclass-zone interaction, mask bridge and expansion, board thickness. They are held for the first board stage.
- The board setup is an adapter contract. Native import of Board Setup constraints into a .kicad_pro is a board-stage capability (kicad_board_rules), not a pre-board ADOM import.
- Publication: merge must be followed by a regenerated published pack and a readback of the default-branch bytes before any project binds it.
🤖 Generated with Claude Code
Diff Skip to comments (1)
@@ -1,573 +1,633 @@⋯ 364 unchanged lines ⋯ # ---------------------------------------------------------------- KiCad -def gen_kicad_dru(vendor, rec):+def gen_kicad_dru_legacy(vendor, rec): tw = rec["minTraceWidth"]["mm"] sp = rec["minSpacing"]["mm"] dr = rec["minDrill"]["mm"]⋯ 47 unchanged lines ⋯ return "\n".join(out) -def gen_kicad_board_setup(vendor, rec):+def gen_kicad_board_setup_legacy(vendor, rec): via_d, via_p = effective_via(rec) setup = { "vendor": vendor,⋯ 22 unchanged lines ⋯ # ---------------------------------------------------------------- Altium .RUL ++def _strict_rule_block(out, name, kind, minimum, condition=None, layer=None):+ if minimum is None:+ return+ rows = [f'(rule "{name}"', ' (severity error)', f' (constraint {kind} (min {fmm(minimum)}mm))']+ if layer:+ rows.append(f' (layer "{layer}")')+ if condition:+ rows.append(f' (condition "{condition}")')+ rows[-1] += ")"+ out.extend(rows + [""])++def gen_kicad_dru_strict(vendor, rec):+ """Opt-in (record flag kicadStrict). NO unconditional clearance rule: a global custom clearance overrides netclass clearance."""+ via = rec["minVia"]+ out = ["(version 1)", "", "# " + description_text(vendor, rec).replace("\n", "\n# "), ""]+ R = lambda *a, **k: _strict_rule_block(out, *a, **k)+ R("min-track-width", "track_width", rec["minTraceWidth"]["mm"])+ R("min-hole", "hole_size", rec["minDrill"]["mm"])+ R("min-via-hole", "hole_size", via["drillMm"], "A.Type == 'Via'")+ R("min-via-diameter", "via_diameter", via["padMm"], "A.Type == 'Via'")+ R("min-via-annular-width", "annular_width", rec["annularRing"]["viaMm"], "A.Type == 'Via'")+ R("min-pad-annular-width", "annular_width", rec["annularRing"]["padMm"], "A.Type == 'Pad' && A.Pad_Type == 'Through-hole'")+ R("min-edge-clearance", "edge_clearance", g(rec, "copperToBoardEdge", "mm"))+ R("min-hole-to-hole", "hole_to_hole", g(rec, "holeToHole", "mm"))+ R("min-hole-to-inner-copper", "hole_clearance", g(rec, "minHoleToInnerCopper", "mm"))+ R("min-silk-height", "text_height", g(rec, "silkMinHeightMm", "mm"), "A.Type == 'Text' || A.Type == 'Text Box'", "*.SilkS")+ R("min-silk-thickness", "text_thickness", g(rec, "silkLineWidth", "mm"), "A.Type == 'Text' || A.Type == 'Text Box'", "*.SilkS")+ return "\n".join(out)++def gen_kicad_dru(vendor, rec):+ if rec.get("kicadStrict") is True:+ return gen_kicad_dru_strict(vendor, rec)+ return gen_kicad_dru_legacy(vendor, rec)++def gen_kicad_board_setup(vendor, rec):+ if rec.get("kicadStrict") is True:+ via_d, via_p = effective_via(rec)+ setup = {+ "vendor": vendor, "process": rec["process"], "layerCount": rec["layerCount"],+ "boardSetupConstraints": {+ "minTrackWidthMm": rec["minTraceWidth"]["mm"],+ "minClearanceMm": rec["minSpacing"]["mm"],+ "minPadClearanceMm": g(rec, "minPadSpacing"),+ "minViaDrillMm": via_d, "minViaDiameterMm": via_p,+ "minHoleMm": rec["minDrill"]["mm"],+ "copperEdgeClearanceMm": g(rec, "copperToBoardEdge"),+ "holeToHoleMm": g(rec, "holeToHole"),+ "annularRingViaMm": g(rec, "annularRing", "viaMm"),+ "annularRingPadMm": g(rec, "annularRing", "padMm"),+ "silkMinLineWidthMm": g(rec, "silkLineWidth"),+ "maskExpansionMm": g(rec, "maskExpansion"),+ },+ "notes": "Apply as Board Setup, Constraints. Apply the matching .kicad_dru alongside the board and project with the same stem. This JSON is an adapter contract, not a native .kicad_pro file. Separate pad/via rules and pad-pair clearance need custom rules. Confirm loaded source hashes and native negative-control findings before claiming enforcement.",+ "sources": rec.get("sources", []),+ }+ return json.dumps(setup, indent=2) + "\n"+ return gen_kicad_board_setup_legacy(vendor, rec)+ def gen_rul(vendor, rec): tw = rec["minTraceWidth"] sp = rec["minSpacing"]⋯ 117 unchanged lines ⋯ if __name__ == "__main__": main()+@@ -0,0 +1,65 @@+"""PCBWay standard 4-layer 1 oz: sourced limits must appear in the generated KiCad rules, each as an explicit error.+Source archive SHA-256 values are the ones recorded in the PCBDS r7 proof. Syntax-only passes are NOT accepted as proof: see DRC coupon evidence."""+import unittest, importlib.util, json, re+from pathlib import Path+BASE = Path(__file__).resolve().parents[1]+spec = importlib.util.spec_from_file_location('rules', BASE / 'tools' / 'generate.py')+g = importlib.util.module_from_spec(spec); spec.loader.exec_module(g)+REC = [r for r in json.loads((BASE / 'rules/records/pcbway.json').read_text())['records'] if r['process'] == 'standard' and r['layerCount'] == 4][0]+TXT = g.gen_kicad_dru('PCBWay', REC)+STD_SHA = '694ce30266e8c0bde8173d590c3ac71e6d928eb730fad3555e6a1dd298e0a980'+LIM_SHA = '9cebdeed859c3c61d4e104185aa5e6a54fb1a5c6ac5864591fbd5993479145e1'+TOL_SHA = '51142afe99832cc0ee41af19bf7d4c552a2658da466f04850523fab09bb66948'+def rule(name):+ m = re.search(r'\(rule "%s"\n(.*?)(?:\n\n|\Z)' % re.escape(name), TXT, flags=re.S)+ return m.group(1) if m else None+class PCBWay4L(unittest.TestCase):+ def test_no_invalid_keyword_or_layer_qualifier(self):+ self.assertNotIn('(constraint hole ', TXT)+ self.assertNotIn('(layer "inner")', TXT)+ def test_every_rule_is_explicit_error(self):+ blocks = re.findall(r'\(rule "[^"]+"\n(.*?)(?:\n\n|\Z)', TXT, flags=re.S)+ self.assertTrue(blocks)+ for b in blocks: self.assertIn('(severity error)', b)+ def test_track_width_outer_1oz_applied_globally(self):+ self.assertIn('(constraint track_width (min 0.127mm))', rule('min-track-width'))+ def test_no_unconditional_clearance_rule_and_board_floor_carries_0_1524(self):+ self.assertIsNone(rule('min-clearance')) # would override netclass clearance (measured)+ bs = json.loads(g.gen_kicad_board_setup('PCBWay', REC))+ self.assertEqual(bs['boardSetupConstraints']['minClearanceMm'], 0.1524)+ def test_via_and_pth_annular_rings_are_separate(self):+ self.assertIn("A.Type == 'Via'", rule('min-via-annular-width'))+ self.assertIn('(constraint annular_width (min 0.15mm))', rule('min-via-annular-width'))+ self.assertIn("A.Pad_Type == 'Through-hole'", rule('min-pad-annular-width'))+ self.assertIn('(constraint annular_width (min 0.254mm))', rule('min-pad-annular-width'))+ def test_hole_spacing_at_least_0_45mm_for_all_pairs(self):+ self.assertIn('(constraint hole_to_hole (min 0.45mm))', rule('min-hole-to-hole'))+ self.assertIsNone(re.search(r'hole_to_hole[^\n]*condition', TXT))+ def test_inner_hole_to_copper_7mil_is_emitted(self):+ self.assertIn('(constraint hole_clearance (min 0.1778mm))', rule('min-hole-to-inner-copper'))+ def test_silk_height_and_width(self):+ self.assertIn('(constraint text_height (min 0.8mm))', rule('min-silk-height'))+ self.assertIn('(constraint text_thickness (min 0.15mm))', rule('min-silk-thickness'))+ def test_copper_edge_and_drill_and_via_diameter(self):+ self.assertIn('(constraint edge_clearance (min 0.25mm))', rule('min-edge-clearance'))+ self.assertIn('(constraint hole_size (min 0.2mm))', rule('min-hole'))+ self.assertIn('(constraint via_diameter (min 0.5mm))', rule('min-via-diameter'))+ def test_record_carries_source_archive_hashes(self):+ shas = [s.get('archiveSha256') for s in REC.get('sources', [])]+ for need in (STD_SHA, LIM_SHA, TOL_SHA): self.assertIn(need, shas)+ def test_pth_ring_is_strictest_of_sources(self):+ self.assertGreaterEqual(REC['annularRing']['padMm'], 0.254) # tolerances page 0.20 is weaker and is not used+class CommittedOutputsMatchGenerator(unittest.TestCase):+ """Every committed PCBWay 4L output must be exactly what the generator produces for its record (no stale 4-layer files)."""+ def test_all_pcbway_4l_outputs_match_generator(self):+ pairs = [+ (BASE/'kicad'/'pcbway-4L.kicad_dru', g.gen_kicad_dru('PCBWay', REC)),+ (BASE/'kicad'/'pcbway-4L.board-setup.json', g.gen_kicad_board_setup('PCBWay', REC)),+ (BASE/'fusion'/'pcbway-4L.dru', g.gen_dru('PCBWay', REC)),+ (BASE/'fusion'/'pcbway-4L.edru', g.gen_edru('PCBWay', REC)),+ (BASE/'altium'/'pcbway-4L.RUL', g.gen_rul('PCBWay', REC)),+ ]+ for path, expected in pairs:+ self.assertEqual(path.read_text(encoding='utf-8'), expected, path.name)+if __name__ == '__main__': unittest.main(verbosity=2)+@@ -0,0 +1,26 @@+"""Blast-radius guard: every record WITHOUT kicadStrict must produce byte-identical KiCad export to main's legacy functions."""+import unittest, importlib.util, json+from pathlib import Path+BASE = Path(__file__).resolve().parents[1]+spec = importlib.util.spec_from_file_location('rules', BASE / 'tools' / 'generate.py')+g = importlib.util.module_from_spec(spec); spec.loader.exec_module(g)+RECS = []+for f in sorted((BASE / 'rules' / 'records').glob('*.json')):+ d = json.loads(f.read_text(encoding='utf-8'))+ for r in d['records']:+ RECS.append((d['vendor'], r))+class LegacyUnchanged(unittest.TestCase):+ def test_non_strict_records_use_legacy_kicad_export(self):+ checked = 0+ for vendor, rec in RECS:+ if rec.get('kicadStrict') is True: continue+ if not all(rec.get(k) for k in ('minTraceWidth', 'minSpacing', 'minDrill')): continue+ self.assertEqual(g.gen_kicad_dru(vendor, rec), g.gen_kicad_dru_legacy(vendor, rec), vendor)+ self.assertEqual(g.gen_kicad_board_setup(vendor, rec), g.gen_kicad_board_setup_legacy(vendor, rec), vendor)+ checked += 1+ self.assertGreater(checked, 50)+ def test_only_pcbway_standard_4l_is_strict(self):+ strict = [(v, r['process'], r['layerCount']) for v, r in RECS if r.get('kicadStrict') is True]+ self.assertEqual(strict, [('PCBWay', 'standard', 4)])+if __name__ == '__main__': unittest.main(verbosity=2)+@@ -1,616 +1,654 @@⋯ 105 unchanged lines ⋯ "process": "standard", "layerCount": 4, "minTraceWidth": {- "mm": 0.1016,- "mil": 4.0,- "condition": "inner layer, 1oz (35um) copper, before compensation; inner 0.5oz: 4mil, 2oz: 6mil, 3oz: 8mil. Outer layer 1oz: 5mil"- },- "minSpacing": { "mm": 0.127, "mil": 5.0,- "condition": "inner layer, 1oz (35um) copper, before compensation; inner 0.5oz: 5mil (4/4mil class), 2oz: 8mil, 3oz: 11mil. Outer layer 1oz: 6mil"+ "condition": "4L 1oz: outer conventional 5mil (0.127) applied to every layer; inner 4mil (0.1016) is looser, not used. Sources: capabilities table (std sha 694ce30266e8); mobile page suggests 6mil. " },+ "minSpacing": {+ "mm": 0.1524,+ "mil": 6.0,+ "condition": "4L 1oz: outer conventional 6mil (0.1524) applied to every layer; inner 5mil (0.127) looser, not used. Sources: capabilities table (std sha 694ce30266e8); mobile page suggests 6mil."+ }, "minDrill": { "mm": 0.2, "mil": 7.87⋯ 1 unchanged line ⋯ "minVia": { "drillMm": 0.2, "drillMil": 7.87,- "padMm": 0.454,- "padMil": 17.87+ "padMm": 0.5,+ "padMil": 19.69,+ "note": "derived: drill 0.2 + 2 x 0.15 via ring (vendor page does not publish a via pad)" }, "annularRing": {- "viaMm": 0.127,- "viaMil": 5.0,- "note": "via, 1oz outer copper; component hole 1oz: 10mil"+ "viaMm": 0.15,+ "viaMil": 6.0,+ "padMm": 0.254,+ "padMil": 10.0,+ "note": "viaMm: pads with vias, 0.15mm (6mil): capabilities page AND manufacturing-tolerances page (0.15 via ring) agree. padMm: 1oz outer component-hole ring 10mil (0.254) from the capabilities table; the manufacturing-tolerances page gives 0.20 for the PTH ring, which is WEAKER and not used. Source disagreement recorded in notes." }, "copperToBoardEdge": { "mm": 0.25,⋯ 1 unchanged line ⋯ "condition": "line to board edge, CNC routing" }, "holeToHole": {- "mm": 0.2794,- "mil": 11.0,- "condition": "via hole to via hole, via diameter 0.45mm or less; component holes: 16mil (0.4064mm)"+ "mm": 0.45,+ "mil": 17.72,+ "condition": "different-net plated holes: 0.45mm (limited_holes_spacing page, last updated 2025-06-25) - stricter than the capabilities table (16mil = 0.4064 PTH; 11mil = 0.2794 via). Via-to-via 0.30mm on that page is looser than 0.45 and is not used separately: 0.45 applies to all pairs (conservative)." }, "maskExpansion": { "mm": 0.0508,⋯ 49 unchanged lines ⋯ { "url": "https://www.pcbway.com/capabilities.html", "dateRead": "2026-09-03"+ },+ {+ "url": "https://www.pcbway.com/capabilities.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "694ce30266e8c0bde8173d590c3ac71e6d928eb730fad3555e6a1dd298e0a980",+ "note": "observational archive; page footer '© 2024 PCBWay' only; no vendor revision date"+ },+ {+ "url": "https://www.pcbway.com/helpcenter/Engineering_Questions/limited_holes_spacing.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "9cebdeed859c3c61d4e104185aa5e6a54fb1a5c6ac5864591fbd5993479145e1",+ "note": "official PCBWay Engineering Questions page; states last updated 2025-06-25"+ },+ {+ "url": "https://www.pcbway.com/pcb_prototype/PCB_Manufacturing_tolerances.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "51142afe99832cc0ee41af19bf7d4c552a2658da466f04850523fab09bb66948",+ "note": "official PCBWay tolerances page; PTH ring 0.20 and via ring 0.15 (PTH ring weaker than capabilities table, not used)"+ },+ {+ "url": "https://m.pcbway.com/capabilities.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "d7be6170136dad3df83304c5e34dab85775f7df80e632d8de8eae85969da3357",+ "note": "mobile capabilities page (summary only): drill 0.2 min, trace/spacing 4mil min with 6mil suggested, annular 0.15" }- ]+ ],+ "minHoleToInnerCopper": {+ "mm": 0.1778,+ "mil": 7.0,+ "condition": "4-layer inner-layer isolation ring (hole to inner layer conductor, before compensation) 7mil, per capabilities table 'Minimum isolation ring of Inner layer' 4L >= 7mil (archive sha 694ce302...)"+ },+ "silkMinHeightMm": {+ "mm": 0.8,+ "condition": "minimum legend character height 0.8mm (width:height 1:5), per capabilities page silkscreen row (archive sha 694ce302...)"+ },+ "kicadStrict": true }, { "process": "standard",⋯ 412 unchanged lines ⋯ "https://www.pcbway.com/advanced-pcb.html" ] }+@@ -1,46 +1,77 @@⋯ 1 unchanged line ⋯ # PCBWay 4-layer design rules (standard process) # -# Min trace width: 0.1016 mm (4.0 mil) - inner layer, 1oz (35um) copper, before compensation; inner 0.5oz: 4mil, 2oz: 6mil, 3oz: 8mil. Outer layer 1oz: 5mil-# Min spacing: 0.127 mm (5.0 mil) - inner layer, 1oz (35um) copper, before compensation; inner 0.5oz: 5mil (4/4mil class), 2oz: 8mil, 3oz: 11mil. Outer layer 1oz: 6mil+# Min trace width: 0.127 mm (5.0 mil) - 4L 1oz: outer conventional 5mil (0.127) applied to every layer; inner 4mil (0.1016) is looser, not used. Sources: capabilities table (std sha 694ce30266e8); mobile page suggests 6mil. +# Min spacing: 0.1524 mm (6.0 mil) - 4L 1oz: outer conventional 6mil (0.1524) applied to every layer; inner 5mil (0.127) looser, not used. Sources: capabilities table (std sha 694ce30266e8); mobile page suggests 6mil. # Min drill: 0.2 mm (7.87 mil)-# Min via: 0.2 mm hole / 0.454 mm pad-# Annular ring: via 0.127 mm+# Min via: 0.2 mm hole / 0.5 mm pad+# Annular ring: via 0.15 mm, pad 0.254 mm # Copper to board edge: 0.25 mm-# Hole to hole: 0.2794 mm+# Hole to hole: 0.45 mm # Board thickness options: 0.6 mm, 0.8 mm, 1.0 mm, 1.2 mm, 1.6 mm, 2.0 mm, 2.4 mm # Copper weight options: 0.5 oz, 1 oz, 1.5 oz, 2 oz, 3 oz, 4 oz # Surface finishes: HASL with lead, HASL lead free, Immersion gold (ENIG), OSP, Immersion Tin⋯ 3 unchanged lines ⋯ # # Sources: # - https://www.pcbway.com/capabilities.html (read 2026-09-03)+# - https://www.pcbway.com/capabilities.html (read 2026-11-02)+# - https://www.pcbway.com/helpcenter/Engineering_Questions/limited_holes_spacing.html (read 2026-11-02)+# - https://www.pcbway.com/pcb_prototype/PCB_Manufacturing_tolerances.html (read 2026-11-02)+# - https://m.pcbway.com/capabilities.html (read 2026-11-02) (rule "min-track-width"- (constraint track_width (min 0.1016mm))- (layer "*.Cu")- (condition "A.type == 'track'"))--(rule "min-clearance"- (constraint clearance (min 0.127mm))- (condition "A.type == 'track' && B.type == 'track'"))+ (severity error)+ (constraint track_width (min 0.127mm))) (rule "min-hole"- (constraint hole (min 0.2mm))- (condition "A.type == 'pad' || A.type == 'via'"))+ (severity error)+ (constraint hole_size (min 0.2mm))) +(rule "min-via-hole"+ (severity error)+ (constraint hole_size (min 0.2mm))+ (condition "A.Type == 'Via'"))+ (rule "min-via-diameter"- (constraint via_diameter (min 0.454mm))- (condition "A.type == 'via'"))+ (severity error)+ (constraint via_diameter (min 0.5mm))+ (condition "A.Type == 'Via'")) +(rule "min-via-annular-width"+ (severity error)+ (constraint annular_width (min 0.15mm))+ (condition "A.Type == 'Via'"))++(rule "min-pad-annular-width"+ (severity error)+ (constraint annular_width (min 0.254mm))+ (condition "A.Type == 'Pad' && A.Pad_Type == 'Through-hole'"))+ (rule "min-edge-clearance"- (constraint edge_clearance (min 0.25mm))- (condition "A.type == 'track'"))+ (severity error)+ (constraint edge_clearance (min 0.25mm))) +(rule "min-hole-to-hole"+ (severity error)+ (constraint hole_to_hole (min 0.45mm)))++(rule "min-hole-to-inner-copper"+ (severity error)+ (constraint hole_clearance (min 0.1778mm)))++(rule "min-silk-height"+ (severity error)+ (constraint text_height (min 0.8mm))+ (layer "*.SilkS")+ (condition "A.Type == 'Text' || A.Type == 'Text Box'"))+ (rule "min-silk-thickness"+ (severity error) (constraint text_thickness (min 0.15mm)) (layer "*.SilkS")- (condition "A.type == 'text' || A.type == 'graphic'"))+ (condition "A.Type == 'Text' || A.Type == 'Text Box'"))+@@ -1,25 +1,51 @@⋯ 2 unchanged lines ⋯ "process": "standard", "layerCount": 4, "boardSetupConstraints": {- "minTrackWidthMm": 0.1016,- "minClearanceMm": 0.127,+ "minTrackWidthMm": 0.127,+ "minClearanceMm": 0.1524,+ "minPadClearanceMm": null, "minViaDrillMm": 0.2,- "minViaDiameterMm": 0.454,+ "minViaDiameterMm": 0.5, "minHoleMm": 0.2, "copperEdgeClearanceMm": 0.25,- "holeToHoleMm": 0.2794,- "annularRingViaMm": 0.127,- "annularRingPadMm": null,+ "holeToHoleMm": 0.45,+ "annularRingViaMm": 0.15,+ "annularRingPadMm": 0.254, "silkMinLineWidthMm": 0.15, "maskExpansionMm": 0.0508 },- "notes": "Apply as Board Setup, Constraints. The matching .kicad_dru file carries the same limits as custom rules; the two are redundant on purpose so both the GUI constraints and kicad-cli DRC enforce them.",+ "notes": "Apply as Board Setup, Constraints. Apply the matching .kicad_dru alongside the board and project with the same stem. This JSON is an adapter contract, not a native .kicad_pro file. Separate pad/via rules and pad-pair clearance need custom rules. Confirm loaded source hashes and native negative-control findings before claiming enforcement.", "sources": [ { "url": "https://www.pcbway.com/capabilities.html", "dateRead": "2026-09-03"+ },+ {+ "url": "https://www.pcbway.com/capabilities.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "694ce30266e8c0bde8173d590c3ac71e6d928eb730fad3555e6a1dd298e0a980",+ "note": "observational archive; page footer '\u00a9 2024 PCBWay' only; no vendor revision date"+ },+ {+ "url": "https://www.pcbway.com/helpcenter/Engineering_Questions/limited_holes_spacing.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "9cebdeed859c3c61d4e104185aa5e6a54fb1a5c6ac5864591fbd5993479145e1",+ "note": "official PCBWay Engineering Questions page; states last updated 2025-06-25"+ },+ {+ "url": "https://www.pcbway.com/pcb_prototype/PCB_Manufacturing_tolerances.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "51142afe99832cc0ee41af19bf7d4c552a2658da466f04850523fab09bb66948",+ "note": "official PCBWay tolerances page; PTH ring 0.20 and via ring 0.15 (PTH ring weaker than capabilities table, not used)"+ },+ {+ "url": "https://m.pcbway.com/capabilities.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "d7be6170136dad3df83304c5e34dab85775f7df80e632d8de8eae85969da3357",+ "note": "mobile capabilities page (summary only): drill 0.2 min, trace/spacing 4mil min with 6mil suggested, annular 0.15" } ] }+@@ -1,71 +1,72 @@-description[PCBWay 4-layer design rules (standard process) | | Min trace width: 0.1016 mm (4.0 mil) - inner layer, 1oz (35um) copper, before compensation; inner 0.5oz: 4mil, 2oz: 6mil, 3oz: 8mil. Outer layer 1oz: 5mil | Min spacing: 0.127 mm (5.0 mil) - inner layer, 1oz (35um) copper, before compensation; inner 0.5oz: 5mil (4/4mil class), 2oz: 8mil, 3oz: 11mil. Outer layer 1oz: 6mil | Min drill: 0.2 mm (7.87 mil) | Min via: 0.2 mm hole / 0.454 mm pad | Annular ring: via 0.127 mm | Copper to board edge: 0.25 mm | Hole to hole: 0.2794 mm | Board thickness options: 0.6 mm, 0.8 mm, 1.0 mm, 1.2 mm, 1.6 mm, 2.0 mm, 2.4 mm | Copper weight options: 0.5 oz, 1 oz, 1.5 oz, 2 oz, 3 oz, 4 oz | Surface finishes: HASL with lead, HASL lead free, Immersion gold (ENIG), OSP, Immersion Tin | Max board size: 508 x 600 mm | | Min board thickness 0.6mm, max board thickness 3.2mm. Min inner layer isolation ring (hole to inner layer conductor, before compensation) 7mil (0.1778mm). Inner layer copper weight options 1oz or 1.5oz. Max aspect ratio 8:1. | | Sources: | - https://www.pcbway.com/capabilities.html (read 2026-09-03)]+description[PCBWay 4-layer design rules (standard process) | | Min trace width: 0.127 mm (5.0 mil) - 4L 1oz: outer conventional 5mil (0.127) applied to every layer; inner 4mil (0.1016) is looser, not used. Sources: capabilities table (std sha 694ce30266e8); mobile page suggests 6mil. | Min spacing: 0.1524 mm (6.0 mil) - 4L 1oz: outer conventional 6mil (0.1524) applied to every layer; inner 5mil (0.127) looser, not used. Sources: capabilities table (std sha 694ce30266e8); mobile page suggests 6mil. | Min drill: 0.2 mm (7.87 mil) | Min via: 0.2 mm hole / 0.5 mm pad | Annular ring: via 0.15 mm, pad 0.254 mm | Copper to board edge: 0.25 mm | Hole to hole: 0.45 mm | Board thickness options: 0.6 mm, 0.8 mm, 1.0 mm, 1.2 mm, 1.6 mm, 2.0 mm, 2.4 mm | Copper weight options: 0.5 oz, 1 oz, 1.5 oz, 2 oz, 3 oz, 4 oz | Surface finishes: HASL with lead, HASL lead free, Immersion gold (ENIG), OSP, Immersion Tin | Max board size: 508 x 600 mm | | Min board thickness 0.6mm, max board thickness 3.2mm. Min inner layer isolation ring (hole to inner layer conductor, before compensation) 7mil (0.1778mm). Inner layer copper weight options 1oz or 1.5oz. Max aspect ratio 8:1. | | Sources: | - https://www.pcbway.com/capabilities.html (read 2026-09-03) | - https://www.pcbway.com/capabilities.html (read 2026-11-02) | - https://www.pcbway.com/helpcenter/Engineering_Questions/limited_holes_spacing.html (read 2026-11-02) | - https://www.pcbway.com/pcb_prototype/PCB_Manufacturing_tolerances.html (read 2026-11-02) | - https://m.pcbway.com/capabilities.html (read 2026-11-02)] layerSetup = (1*2*15*16) mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm mtIsolate = 1.6mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm-mdWireWire = 5.0mil-mdWirePad = 5.0mil-mdWireVia = 5.0mil-mdPadPad = 5.91mil-mdPadVia = 5.0mil-mdViaVia = 5.0mil-mdSmdPad = 5.0mil-mdSmdVia = 5.0mil-mdSmdSmd = 5.0mil+mdWireWire = 6.0mil+mdWirePad = 6.0mil+mdWireVia = 6.0mil+mdPadPad = 6.0mil+mdPadVia = 6.0mil+mdViaVia = 6.0mil+mdSmdPad = 6.0mil+mdSmdVia = 6.0mil+mdSmdSmd = 6.0mil mdCopperDimension = 9.84mil-mdDrill = 11.0mil-msWidth = 4.0mil+mdDrill = 17.72mil+msWidth = 5.0mil msDrill = 7.87mil mdViaViaSameLayer = 6mil mdSmdStop = 0mil⋯ 6 unchanged lines ⋯ rvViaInner = 0 rvMicroViaOuter = 0 rvMicroViaInner = 0-rlMinPadTop = 7.09mil+rlMinPadTop = 10.0mil rlMaxPadTop = 80mil-rlMinPadInner = 7.09mil+rlMinPadInner = 10.0mil rlMaxPadInner = 20mil-rlMinPadBottom = 7.09mil+rlMinPadBottom = 10.0mil rlMaxPadBottom = 80mil-rlMinViaOuter = 5.0mil+rlMinViaOuter = 5.91mil rlMaxViaOuter = 20mil-rlMinViaInner = 5.0mil+rlMinViaInner = 5.91mil rlMaxViaInner = 20mil-rlMinMicroViaOuter = 5.0mil+rlMinMicroViaOuter = 5.91mil rlMaxMicroViaOuter = 20mil-rlMinMicroViaInner = 5.0mil+rlMinMicroViaInner = 5.91mil rlMaxMicroViaInner = 20mil psTop = -1 psBottom = -1⋯ 23 unchanged lines ⋯ checkPolygonWidth = 0 useDiameter = 13 maxErrors = 50+@@ -1,144 +1,149 @@⋯ 22 unchanged lines ⋯ <rulecategory type="Wire Stub" manualdrc="yes" livedrc="no"/> <rulecategory type="Matched Lengths" manualdrc="yes" livedrc="yes"/> <rulecategory type="Via Restrict Clearance" manualdrc="yes" livedrc="yes"/>- <rule type="Minimum Copper Width" enabled="yes" priority="0" onescope="classes=1" value="0.1016mm" preferredvalue="0.3048mm" check_polywidth="no" name="Trace size for Power"/>- <rule type="Minimum Copper Width" builtin_ruleid="14" enabled="yes" priority="1" value="0.1016mm" preferredvalue="0.2032mm" check_polywidth="no" name="minimum-copper-width-1"/>+ <rule type="Minimum Copper Width" enabled="yes" priority="0" onescope="classes=1" value="0.127mm" preferredvalue="0.381mm" check_polywidth="no" name="Trace size for Power"/>+ <rule type="Minimum Copper Width" builtin_ruleid="14" enabled="yes" priority="1" value="0.127mm" preferredvalue="0.254mm" check_polywidth="no" name="minimum-copper-width-1"/> <rule type="Minimum Drill Size" enabled="yes" priority="0" onescope="is_via" value="0.2mm" preferredvalue="0.4mm" name="Min Via hole size on 4-layer"/> <rule type="Minimum Drill Size" enabled="no" priority="1" onescope="all" value="0.5mm" preferredvalue="0.5mm" name="Min Non-plated holes"/> <rule type="Minimum Drill Size" builtin_ruleid="15" enabled="yes" priority="2" value="0.2mm" preferredvalue="0.4mm" name="minimum-drill-size-1"/>⋯ 2 unchanged lines ⋯ <rule type="Air-Wire" builtin_ruleid="19" enabled="yes" priority="0" name="air-wire-1"/> <rule type="Matched Lengths" builtin_ruleid="20" enabled="yes" priority="0" tolerance="10mm" gapfactor="2.5" name="matched-lengths-1"/> <rule type="Copper Clearance" enabled="no" priority="0" onescope="all" otherscope="all" value="0.25mm" preferredvalue="0.25mm" samesignal="yes" bothscope="all" name="Same-net track spacing"/>- <rule type="Copper Clearance" builtin_ruleid="0" enabled="yes" priority="1" onescope="is_wire_polygon" otherscope="is_wire_polygon" value="0.127mm" preferredvalue="0.254mm" samesignal="no" name="copper-clearance-1"/>- <rule type="Copper Clearance" builtin_ruleid="1" enabled="yes" priority="2" onescope="is_wire_polygon" otherscope="is_pad_smd" value="0.127mm" preferredvalue="0.254mm" samesignal="no" name="copper-clearance-2"/>- <rule type="Copper Clearance" builtin_ruleid="2" enabled="yes" priority="3" onescope="is_wire_polygon" otherscope="is_via" value="0.127mm" preferredvalue="0.254mm" samesignal="no" name="copper-clearance-3"/>- <rule type="Copper Clearance" builtin_ruleid="3" enabled="yes" priority="4" onescope="is_pad_smd" otherscope="is_pad_smd" value="0.15mm" preferredvalue="0.15mm" samesignal="no" name="copper-clearance-4"/>- <rule type="Copper Clearance" builtin_ruleid="4" enabled="yes" priority="5" onescope="is_pad_smd" otherscope="is_via" value="0.127mm" preferredvalue="0.254mm" samesignal="no" name="copper-clearance-5"/>- <rule type="Copper Clearance" builtin_ruleid="5" enabled="yes" priority="6" onescope="is_via" otherscope="is_via" value="0.127mm" preferredvalue="0.254mm" samesignal="no" name="copper-clearance-6"/>- <rule type="Copper Clearance" builtin_ruleid="6" enabled="yes" priority="7" onescope="is_smd" otherscope="is_pad" value="0.127mm" preferredvalue="0.254mm" samesignal="yes" name="copper-clearance-7"/>- <rule type="Copper Clearance" builtin_ruleid="7" enabled="yes" priority="8" onescope="is_smd" otherscope="is_via" value="0.127mm" preferredvalue="0.254mm" samesignal="yes" name="copper-clearance-8"/>- <rule type="Copper Clearance" builtin_ruleid="8" enabled="yes" priority="9" onescope="is_smd" otherscope="is_smd" value="0.127mm" preferredvalue="0.254mm" samesignal="yes" name="copper-clearance-9"/>+ <rule type="Copper Clearance" builtin_ruleid="0" enabled="yes" priority="1" onescope="is_wire_polygon" otherscope="is_wire_polygon" value="0.1524mm" preferredvalue="0.3048mm" samesignal="no" name="copper-clearance-1"/>+ <rule type="Copper Clearance" builtin_ruleid="1" enabled="yes" priority="2" onescope="is_wire_polygon" otherscope="is_pad_smd" value="0.1524mm" preferredvalue="0.3048mm" samesignal="no" name="copper-clearance-2"/>+ <rule type="Copper Clearance" builtin_ruleid="2" enabled="yes" priority="3" onescope="is_wire_polygon" otherscope="is_via" value="0.1524mm" preferredvalue="0.3048mm" samesignal="no" name="copper-clearance-3"/>+ <rule type="Copper Clearance" builtin_ruleid="3" enabled="yes" priority="4" onescope="is_pad_smd" otherscope="is_pad_smd" value="0.1524mm" preferredvalue="0.1524mm" samesignal="no" name="copper-clearance-4"/>+ <rule type="Copper Clearance" builtin_ruleid="4" enabled="yes" priority="5" onescope="is_pad_smd" otherscope="is_via" value="0.1524mm" preferredvalue="0.3048mm" samesignal="no" name="copper-clearance-5"/>+ <rule type="Copper Clearance" builtin_ruleid="5" enabled="yes" priority="6" onescope="is_via" otherscope="is_via" value="0.1524mm" preferredvalue="0.3048mm" samesignal="no" name="copper-clearance-6"/>+ <rule type="Copper Clearance" builtin_ruleid="6" enabled="yes" priority="7" onescope="is_smd" otherscope="is_pad" value="0.1524mm" preferredvalue="0.3048mm" samesignal="yes" name="copper-clearance-7"/>+ <rule type="Copper Clearance" builtin_ruleid="7" enabled="yes" priority="8" onescope="is_smd" otherscope="is_via" value="0.1524mm" preferredvalue="0.3048mm" samesignal="yes" name="copper-clearance-8"/>+ <rule type="Copper Clearance" builtin_ruleid="8" enabled="yes" priority="9" onescope="is_smd" otherscope="is_smd" value="0.1524mm" preferredvalue="0.3048mm" samesignal="yes" name="copper-clearance-9"/> <rule type="Dimension Clearance" builtin_ruleid="9" enabled="yes" priority="0" value="0.25mm" preferredvalue="0.4mm" name="dimension-clearance-1"/> <rule type="Via Restrict Clearance" builtin_ruleid="21" enabled="yes" priority="0" value="0mil" preferredvalue="0mil" name="via-restrict-clearance-1"/> <rule type="Restrict Clearance" builtin_ruleid="10" enabled="yes" priority="0" value="0mil" preferredvalue="0mil" name="restrict-clearance-1"/> <rule type="Small Gap" builtin_ruleid="18" enabled="yes" priority="0" name="small-gap-1"/> <rule type="Solder-Mask Clearance" builtin_ruleid="11" enabled="no" priority="0" value="0mil" preferredvalue="0mil" check_name="yes" check_value="no" name="solder-mask-clearance-1"/>- <rule type="Drill Distance" builtin_ruleid="12" enabled="yes" priority="0" value="0.2794mm" preferredvalue="0.2794mm" name="drill-distance-1"/>+ <rule type="Drill Distance" builtin_ruleid="12" enabled="yes" priority="0" value="0.45mm" preferredvalue="0.45mm" name="drill-distance-1"/> <rule type="Keepout Clearance" builtin_ruleid="13" enabled="yes" priority="0" value="0mil" preferredvalue="0mil" name="keepout-clearance-1"/> </rules>-<param name="mdWireWire" value="0.127mm"/>-<param name="mdWirePad" value="0.127mm"/>-<param name="mdWireVia" value="0.127mm"/>-<param name="mdPadPad" value="0.15mm"/>-<param name="mdPadVia" value="0.127mm"/>-<param name="mdViaVia" value="0.127mm"/>-<param name="mdSmdPad" value="0.127mm"/>-<param name="mdSmdVia" value="0.127mm"/>-<param name="mdSmdSmd" value="0.127mm"/>+<param name="mdWireWire" value="0.1524mm"/>+<param name="mdWirePad" value="0.1524mm"/>+<param name="mdWireVia" value="0.1524mm"/>+<param name="mdPadPad" value="0.1524mm"/>+<param name="mdPadVia" value="0.1524mm"/>+<param name="mdViaVia" value="0.1524mm"/>+<param name="mdSmdPad" value="0.1524mm"/>+<param name="mdSmdVia" value="0.1524mm"/>+<param name="mdSmdSmd" value="0.1524mm"/> <param name="mdCopperDimension" value="0.25mm"/>-<param name="mdDrill" value="0.2794mm"/>-<param name="msWidth" value="0.1016mm"/>+<param name="mdDrill" value="0.45mm"/>+<param name="msWidth" value="0.127mm"/> <param name="msDrill" value="0.2mm"/> <param name="dpMaxLengthDifference" value="10mm"/> <param name="dpGapFactor" value="2.5"/> <description language="en">PCBWay 4-layer design rules (standard process) -Min trace width: 0.1016 mm (4.0 mil) - inner layer, 1oz (35um) copper, before compensation; inner 0.5oz: 4mil, 2oz: 6mil, 3oz: 8mil. Outer layer 1oz: 5mil-Min spacing: 0.127 mm (5.0 mil) - inner layer, 1oz (35um) copper, before compensation; inner 0.5oz: 5mil (4/4mil class), 2oz: 8mil, 3oz: 11mil. Outer layer 1oz: 6mil+Min trace width: 0.127 mm (5.0 mil) - 4L 1oz: outer conventional 5mil (0.127) applied to every layer; inner 4mil (0.1016) is looser, not used. Sources: capabilities table (std sha 694ce30266e8); mobile page suggests 6mil. +Min spacing: 0.1524 mm (6.0 mil) - 4L 1oz: outer conventional 6mil (0.1524) applied to every layer; inner 5mil (0.127) looser, not used. Sources: capabilities table (std sha 694ce30266e8); mobile page suggests 6mil. Min drill: 0.2 mm (7.87 mil)-Min via: 0.2 mm hole / 0.454 mm pad-Annular ring: via 0.127 mm+Min via: 0.2 mm hole / 0.5 mm pad+Annular ring: via 0.15 mm, pad 0.254 mm Copper to board edge: 0.25 mm-Hole to hole: 0.2794 mm+Hole to hole: 0.45 mm Board thickness options: 0.6 mm, 0.8 mm, 1.0 mm, 1.2 mm, 1.6 mm, 2.0 mm, 2.4 mm Copper weight options: 0.5 oz, 1 oz, 1.5 oz, 2 oz, 3 oz, 4 oz Surface finishes: HASL with lead, HASL lead free, Immersion gold (ENIG), OSP, Immersion Tin⋯ 3 unchanged lines ⋯ Sources: - https://www.pcbway.com/capabilities.html (read 2026-09-03)+- https://www.pcbway.com/capabilities.html (read 2026-11-02)+- https://www.pcbway.com/helpcenter/Engineering_Questions/limited_holes_spacing.html (read 2026-11-02)+- https://www.pcbway.com/pcb_prototype/PCB_Manufacturing_tolerances.html (read 2026-11-02)+- https://m.pcbway.com/capabilities.html (read 2026-11-02) </description> <param name="layerSetup" value="(1*2*15*16)"/> <param name="mtCopper" value="0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm"/>⋯ 10 unchanged lines ⋯ <param name="rvViaInner" value="0"/> <param name="rvMicroViaOuter" value="0"/> <param name="rvMicroViaInner" value="0"/>-<param name="rlMinPadTop" value="0.18mm"/>+<param name="rlMinPadTop" value="0.254mm"/> <param name="rlMaxPadTop" value="80mil"/>-<param name="rlMinPadInner" value="0.18mm"/>+<param name="rlMinPadInner" value="0.254mm"/> <param name="rlMaxPadInner" value="20mil"/>-<param name="rlMinPadBottom" value="0.18mm"/>+<param name="rlMinPadBottom" value="0.254mm"/> <param name="rlMaxPadBottom" value="80mil"/>-<param name="rlMinViaOuter" value="0.127mm"/>+<param name="rlMinViaOuter" value="0.15mm"/> <param name="rlMaxViaOuter" value="20mil"/>-<param name="rlMinViaInner" value="0.127mm"/>+<param name="rlMinViaInner" value="0.15mm"/> <param name="rlMaxViaInner" value="20mil"/>-<param name="rlMinMicroViaOuter" value="0.127mm"/>+<param name="rlMinMicroViaOuter" value="0.15mm"/> <param name="rlMaxMicroViaOuter" value="20mil"/>-<param name="rlMinMicroViaInner" value="0.127mm"/>+<param name="rlMinMicroViaInner" value="0.15mm"/> <param name="rlMaxMicroViaInner" value="20mil"/> <param name="psTop" value="-1"/> <param name="psBottom" value="-1"/>⋯ 24 unchanged lines ⋯ <param name="maxErrors" value="50"/> </designrules> </eagle>+@@ -1,44 +1,45 @@⋯ 5 unchanged lines ⋯ RuleName=MinTraceWidth Scope1=All Scope2=-Attribute=MinWidth=0.1016mm|PreferredWidth=0.2032mm|MaxWidth=25.4mm+Attribute=MinWidth=0.127mm|PreferredWidth=0.254mm|MaxWidth=25.4mm [Rule2] RuleKind=Clearance RuleName=MinClearance Scope1=All Scope2=-Attribute=Clearance=0.127mm+Attribute=Clearance=0.1524mm [Rule3] RuleKind=RoutingViaStyle RuleName=MinVia Scope1=All Scope2=-Attribute=PreferredViaWidth=0.454mm|PreferredViaHoleWidth=0.2mm|MinViaWidth=0.454mm|MaxViaWidth=6.35mm|MinViaHoleWidth=0.2mm|MaxViaHoleWidth=6.35mm+Attribute=PreferredViaWidth=0.5mm|PreferredViaHoleWidth=0.2mm|MinViaWidth=0.5mm|MaxViaWidth=6.35mm|MinViaHoleWidth=0.2mm|MaxViaHoleWidth=6.35mm [Rule4] RuleKind=HoleSize⋯ 7 unchanged lines ⋯ RuleName=MinAnnularRing Scope1=All Scope2=-Attribute=MinAnnularRing=0.127mm+Attribute=MinAnnularRing=0.15mm [Rule6] RuleKind=BoardOutlineClearance⋯ 1 unchanged line ⋯ Scope1=All Scope2= Attribute=Clearance=0.25mm+@@ -1,1351 +1,1376 @@⋯ 1052 unchanged lines ⋯ { "url": "https://www.pcbway.com/capabilities.html", "dateRead": "2026-09-03"+ },+ {+ "url": "https://www.pcbway.com/capabilities.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "694ce30266e8c0bde8173d590c3ac71e6d928eb730fad3555e6a1dd298e0a980",+ "note": "observational archive; page footer '\u00a9 2024 PCBWay' only; no vendor revision date"+ },+ {+ "url": "https://www.pcbway.com/helpcenter/Engineering_Questions/limited_holes_spacing.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "9cebdeed859c3c61d4e104185aa5e6a54fb1a5c6ac5864591fbd5993479145e1",+ "note": "official PCBWay Engineering Questions page; states last updated 2025-06-25"+ },+ {+ "url": "https://www.pcbway.com/pcb_prototype/PCB_Manufacturing_tolerances.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "51142afe99832cc0ee41af19bf7d4c552a2658da466f04850523fab09bb66948",+ "note": "official PCBWay tolerances page; PTH ring 0.20 and via ring 0.15 (PTH ring weaker than capabilities table, not used)"+ },+ {+ "url": "https://m.pcbway.com/capabilities.html",+ "dateRead": "2026-11-02",+ "archiveSha256": "d7be6170136dad3df83304c5e34dab85775f7df80e632d8de8eae85969da3357",+ "note": "mobile capabilities page (summary only): drill 0.2 min, trace/spacing 4mil min with 6mil suggested, annular 0.15" } ] },⋯ 290 unchanged lines ⋯ } ] }+@@ -1,165 +1,166 @@⋯ 55 unchanged lines ⋯ | PCBWay | advanced | 4 | 0.0508 / 2.0 | 0.0508 / 2.0 | 0.15 / 5.91 | 0.15 / 0.3024 | 0.0762 / n/p | 0.2 | 0.3556 | https://www.pcbway.com/advanced-pcb-capabilities.html | | PCBWay | advanced | 6 | 0.0508 / 2.0 | 0.0508 / 2.0 | 0.15 / 5.91 | 0.15 / 0.3024 | 0.0762 / n/p | 0.2 | 0.3556 | https://www.pcbway.com/advanced-pcb-capabilities.html | | PCBWay | standard | 2 | 0.1016 / 4.0 | 0.1016 / 4.0 | 0.2 / 7.87 | 0.2 / 0.454 | 0.127 / n/p | 0.25 | 0.2794 | https://www.pcbway.com/capabilities.html |-| PCBWay | standard | 4 | 0.1016 / 4.0 | 0.127 / 5.0 | 0.2 / 7.87 | 0.2 / 0.454 | 0.127 / n/p | 0.25 | 0.2794 | https://www.pcbway.com/capabilities.html |+| PCBWay | standard | 4 | 0.127 / 5.0 | 0.1524 / 6.0 | 0.2 / 7.87 | 0.2 / 0.5 | 0.15 / 0.254 | 0.25 | 0.45 | https://www.pcbway.com/capabilities.html | | PCBWay | standard | 6 | 0.1016 / 4.0 | 0.127 / 5.0 | 0.2 / 7.87 | 0.2 / 0.454 | 0.127 / n/p | 0.25 | 0.2794 | https://www.pcbway.com/capabilities.html | | OSH Park | 2oz-0.8mm | 2 | 0.1524 / 6.0 | 0.1524 / 6.0 | 0.254 / 10.0 | 0.254 / 0.508 | 0.127 / n/p | 0.381 | 0.127 | https://docs.oshpark.com/services/two-layer-hhdc/ | | OSH Park | after-dark | 2 | 0.1524 / 6.0 | 0.1524 / 6.0 | 0.254 / 10.0 | 0.254 / 0.508 | 0.127 / n/p | 0.381 | 0.127 | https://docs.oshpark.com/services/afterdark/ |⋯ 100 unchanged lines ⋯ **1 oz finished surface copper is standard; 2 oz is available on request.** [Confirmed capability and scope](docs/3rdpartyfab-finished-copper.md). The existing 1 oz DRC conditions remain unchanged; confirm appropriate DFM limits for a 2 oz build. **3rd party fab: 0.085 mm minimum trace and space, up to 8 layers** (2026-10-30). Copper is patterned by UV fiber laser, so there is no etch undercut. [Confirmed capability and scope](docs/3rdpartyfab-trace-and-layers.md).+
Comments
Log in to comment.