project
Adom Custom Electronic Load
Public Made by Adomby adom
Two-layer digitally controlled electronic-load prototype. Compact R11 is under active electrical, cooling and probe-access review; not a manufacturing release.
← Commit history
Land verified board 17 current-path review and update fan feedback evidence
10 files changed
+666−88
checkpoints/shunt-final-live/native-drc.json+262checkpoints/shunt-mesh-0p1/comparison.json+193design/shunt-final-live/saved-comparison.json+16docs/completion-plan.md+2−2docs/fan-feedback.md+1−1docs/shunt-final-review.md+18docs/status.md+16kicad/adom-custom-electronic-load.kicad_pcb+102−84tools/compare_saved_copper.py+31videos/inventory.json+25−1checkpoints/shunt-final-live/native-drc.jsonadded+262@@ -0,0 +1,262 @@+{ + "$schema": "https://schemas.kicad.org/drc.v1.json", + "coordinate_units": "mm", + "date": "2026-10-09T11:07:42", + "ignored_checks": [ + { + "description": "Footprint has no courtyard defined", + "key": "missing_courtyard" + }, + { + "description": "Track endpoint not centered on via", + "key": "track_not_centered_on_via" + }, + { + "description": "Tuning profile track geometries", + "key": "tuning_profile_track_geometries" + }, + { + "description": "Footprint doesn't match symbol's footprint filters", + "key": "footprint_filters_mismatch" + }, + { + "description": "Footprint component type doesn't match footprint pads", + "key": "footprint_type_mismatch" + } + ], + "included_severities": [ + "error", + "warning" + ], + "kicad_version": "10.0.5", + "schematic_parity": [], + "source": "adom-custom-electronic-load.kicad_pcb", + "unconnected_items": [], + "violations": [ + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint MP2", + "pos": { + "x": 160.0, + "y": 100.0 + }, + "uuid": "08489986-63c7-4cfe-ba45-67384ef79934" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint J6", + "pos": { + "x": 140.0, + "y": 100.0 + }, + "uuid": "0f2f475f-8a1f-4250-9e5f-96a617ceb70b" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint MP3", + "pos": { + "x": 100.0, + "y": 32.0 + }, + "uuid": "161d93fc-6ce8-463d-9fa1-016137c7ae90" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Load'", + "items": [ + { + "description": "Footprint RSH1", + "pos": { + "x": 138.0, + "y": 85.0 + }, + "uuid": "1b28c787-9318-4dde-92f8-6e710aa3f214" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint MP1", + "pos": { + "x": 100.0, + "y": 100.0 + }, + "uuid": "25251d59-4aaa-4d73-8a60-f16f3fee910a" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint J5", + "pos": { + "x": 136.0, + "y": 100.0 + }, + "uuid": "2efeacb9-e84f-4884-8900-42f70fb8d64e" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint J2", + "pos": { + "x": 112.0, + "y": 100.0 + }, + "uuid": "30ee7a6c-6b1c-4933-ba62-4f7a83e50956" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint J4", + "pos": { + "x": 124.0, + "y": 100.0 + }, + "uuid": "3bb8b85a-c230-405c-9d0a-dfd2caaa5eb9" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint MP4", + "pos": { + "x": 160.0, + "y": 32.0 + }, + "uuid": "515ee778-8175-412f-b3bf-3b8e5b10660b" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Load'", + "items": [ + { + "description": "Footprint U2", + "pos": { + "x": 118.0, + "y": 66.0 + }, + "uuid": "6de86714-f970-4490-9f2b-5fb47eb0b141" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint J3", + "pos": { + "x": 120.0, + "y": 100.0 + }, + "uuid": "8730c443-01a7-40e8-a338-20bb4d4719de" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Load'", + "items": [ + { + "description": "Footprint U4", + "pos": { + "x": 141.0, + "y": 77.0 + }, + "uuid": "b585e065-e8ac-43c3-9bea-a846c5f7a747" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint J7", + "pos": { + "x": 144.0, + "y": 100.0 + }, + "uuid": "e8f5ce02-a259-45e9-a4f1-ef182fb58bb6" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Load'", + "items": [ + { + "description": "Footprint L1", + "pos": { + "x": 144.0, + "y": 95.6 + }, + "uuid": "f710bbae-8af4-4faf-8c03-b1959083aa62" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + }, + { + "description": "The current configuration does not include the footprint library 'Molecule'", + "items": [ + { + "description": "Footprint J1", + "pos": { + "x": 108.0, + "y": 100.0 + }, + "uuid": "fca7a827-0407-443b-9729-c18bb9614a8c" + } + ], + "severity": "warning", + "type": "lib_footprint_issues" + } + ] +}
checkpoints/shunt-mesh-0p1/comparison.jsonadded+193@@ -0,0 +1,193 @@+{+ "status": "paired-current-screen-only",+ "startedUtc": "2026-10-09T15:55:05.229254+00:00",+ "seconds": 366.59,+ "pitchMm": 0.1,+ "inputsSha256": {+ "/home/adom/project/adom-fields-two-layer-work/target/release/load_power_paths": "47191026c687d21a9f9b87f9dd6fcc5a32d7530296d7d59c89960ff0f6211fa5",+ "kicad/adom-custom-electronic-load.kicad_pcb": "347fc37404eff3e81dfb3211f06e3da4fe036657e130fec4f0f64a7e6f494f09",+ "checkpoints/shunt-source-spread-v3/candidate.kicad_pcb": "1e3e1b23bc723f34e56341725aac2da7b604f6bf7c11662c664f30a94c2616ff",+ "design/spec-current-mesh.json": "e7e1d9c69e520c0253915c84eb74c542da54b05ac62a8e08bc806828cc58f76d"+ },+ "loadAmpsPerNet": 3,+ "sourceSinkMapping": [+ {+ "layers": [+ "F.Cu",+ "B.Cu"+ ],+ "net": "DUT_POS",+ "pad": "1",+ "ref": "J1",+ "role": "source",+ "x": 108.0,+ "y": 100.0+ },+ {+ "layers": [+ "F.Cu"+ ],+ "net": "DUT_POS",+ "pad": "1",+ "ref": "F1",+ "role": "sink",+ "x": 105.0,+ "y": 91.0+ },+ {+ "layers": [+ "F.Cu"+ ],+ "net": "DUT_FUSED",+ "pad": "2",+ "ref": "F1",+ "role": "source",+ "x": 107.80000000000001,+ "y": 91.0+ },+ {+ "layers": [+ "F.Cu"+ ],+ "net": "DUT_FUSED",+ "pad": "2",+ "ref": "D1",+ "role": "sink",+ "x": 110.6,+ "y": 91.0+ },+ {+ "layers": [+ "F.Cu"+ ],+ "net": "LOAD_POS",+ "pad": "1",+ "ref": "D1",+ "role": "source",+ "x": 117.4,+ "y": 91.0+ },+ {+ "layers": [+ "F.Cu",+ "B.Cu"+ ],+ "net": "LOAD_POS",+ "pad": "2",+ "ref": "Q1",+ "role": "sink",+ "x": 127.46,+ "y": 82.0+ },+ {+ "layers": [+ "F.Cu",+ "B.Cu"+ ],+ "net": "SHUNT_P",+ "pad": "3",+ "ref": "Q1",+ "role": "source",+ "x": 124.92,+ "y": 82.0+ },+ {+ "layers": [+ "F.Cu"+ ],+ "net": "SHUNT_P",+ "pad": "1",+ "ref": "RSH1",+ "role": "sink",+ "x": 136.625,+ "y": 85.7+ },+ {+ "layers": [+ "F.Cu"+ ],+ "net": "GND",+ "pad": "4",+ "ref": "RSH1",+ "role": "source",+ "x": 139.375,+ "y": 85.7+ },+ {+ "layers": [+ "F.Cu",+ "B.Cu"+ ],+ "net": "GND",+ "pad": "1",+ "ref": "J2",+ "role": "sink",+ "x": 112.0,+ "y": 100.0+ }+ ],+ "thermalQualification": false,+ "rows": [+ {+ "net": "DUT_FUSED",+ "baselinePeakAperMm2": 43.0,+ "candidatePeakAperMm2": 43.0,+ "baselineJouleW": 0.004,+ "candidateJouleW": 0.004,+ "candidatePeakAt": [+ 109.25,+ 90.05+ ],+ "candidatePeakLayer": "F.Cu"+ },+ {+ "net": "DUT_POS",+ "baselinePeakAperMm2": 42.0,+ "candidatePeakAperMm2": 42.0,+ "baselineJouleW": 0.015,+ "candidateJouleW": 0.015,+ "candidatePeakAt": [+ 104.05,+ 89.45+ ],+ "candidatePeakLayer": "F.Cu"+ },+ {+ "net": "GND",+ "baselinePeakAperMm2": 43.3,+ "candidatePeakAperMm2": 43.3,+ "baselineJouleW": 0.055,+ "candidateJouleW": 0.055,+ "candidatePeakAt": [+ 138.25,+ 92.05+ ],+ "candidatePeakLayer": "F.Cu"+ },+ {+ "net": "LOAD_POS",+ "baselinePeakAperMm2": 48.4,+ "candidatePeakAperMm2": 48.4,+ "baselineJouleW": 0.029,+ "candidateJouleW": 0.029,+ "candidatePeakAt": [+ 126.75,+ 83.25+ ],+ "candidatePeakLayer": "F.Cu"+ },+ {+ "net": "SHUNT_P",+ "baselinePeakAperMm2": 61.7,+ "candidatePeakAperMm2": 59.4,+ "baselineJouleW": 0.029,+ "candidateJouleW": 0.027,+ "candidatePeakAt": [+ 124.95,+ 82.14999999999999+ ],+ "candidatePeakLayer": "B.Cu"+ }+ ],+ "candidateIssues": []+}
design/shunt-final-live/saved-comparison.jsonadded+16@@ -0,0 +1,16 @@+{+ "candidateSha256": "1e3e1b23bc723f34e56341725aac2da7b604f6bf7c11662c664f30a94c2616ff",+ "savedSha256": "653e54e711552eb2f16b6d01cd144fd82645a52c30ff11e39699b760402af51a",+ "copperMultisetEqual": true,+ "missing": [],+ "extra": [],+ "zoneSymmetricDifferenceMm2": {+ "('GND', 'F.Cu')": 0.0,+ "('LOAD_POS', 'F.Cu')": 0.0,+ "('SHUNT_P', 'F.Cu')": 0.0,+ "('SHUNT_P', 'B.Cu')": 0.0,+ "('GND', 'B.Cu')": 0.0,+ "('LOAD_POS', 'B.Cu')": 0.0+ },+ "zoneKeysEqual": true+}
docs/completion-plan.md+2−2@@ -4,11 +4,11 @@ The active objective is to finish this electronic-load design through AIFlow, th ## Latest accepted board -Native-saved current-path rework SHA-256 `347fc37404eff3e81dfb3211f06e3da4fe036657e130fec4f0f64a7e6f494f09`, adopted and checked as AIFlow board-16. D1 rotation and parallel power paths are landed. Native DRC with project rules: zero errors/opens; saved physical copper exactly matches the candidate. The paired 0.1 mm explicit-terminal diagnostic reduces four power-path peaks but leaves SHUNT_P at 61.7 A/mm² against a 60 threshold. Ground rises to 43.3 A/mm². Current step: routing revisit; thermal-via shortfalls and case cooling remain unresolved. Portable protocol checks pass. The output-locked STM32 USB bring-up image compiles but is unflashed and its functional HAL is incomplete. See current-path-rework.md.+Native-saved board 17 SHA-256 `653e54e711552eb2f16b6d01cd144fd82645a52c30ff11e39699b760402af51a`. D1 rotation, parallel power paths, back-source expansion and a further shunt via are landed. Native DRC has zero errors/opens; saved physical copper matches the checked candidate. Explicit-terminal SHUNT_P peaks are 57.9 A/mm² at 0.2 mm mesh and 59.4 at 0.1 mm; all five reviewed nets are below 60 in this experimental diagnostic, with a small margin. Formal current/thermal gates and assembly cooling remain incomplete. Read shunt-final-review.md. Output-locked STM32 USB/tach bring-up compiles and host tests pass; hardware remains unflashed and unverified. ## Resume here -1. Inspect the live AdomLapper board and AIFlow run; current required step is routing revisit. Preserve other threads and project rules. Continue the isolated shunt copper experiment only after checking its current/DRC results; it is not yet adopted.+1. Inspect the live AdomLapper board and AIFlow run; current required step is routing revisit. Preserve other threads and project rules. The shunt experiment is adopted; continue the remaining thermal/cooling work after recording the routing proof. 2. Continue the compact 5 W prototype basis announced on 9 October. It follows the original size/cost priority and 5 V/1 A DUT. The prior 25 W assistant assumption is documented as a future option, not a blocker. Keep the 55 C trip and all validation requirements. 3. Solve the actual MOSFET case/interface/sink/fan assembly and probe clearance. The shunt-via candidate now passes only with the verified GND stitch at (133.018,77.818). Earlier candidates without that stitch disconnected ground; do not replay them. Via-count acknowledgements require actual engineering justification, not a desire to advance the timeline. 4. Complete and revalidate pours, outline, same-board current/thermal Fields screens, net tour, full fitted-model/silkscreen review, native 3D, finish and fabrication exports in the enforced sequence. Record significant real actions. Never mark these passed to bypass an unresolved gate.
docs/fan-feedback.md+1−1@@ -4,7 +4,7 @@ Selected candidate: Sunon MF40200V1-1000U-G99, 5 V, nominal 7000 RPM ±15%, thre The fan runs whenever auxiliary power is present. Keep the load disabled during spin-up. The portable policy now refuses ARM unless qualified RPM is valid and within a provisional 5000–10000 RPM window; it latches F_FAN and clears the DAC/enable when speed leaves that window, becomes invalid/nonfinite, or no tach edge arrives for 250 ms. Returning fan motion never automatically rearms the load. These limits are conservative bring-up settings, not a validated airflow rating. -The new portable fan_tach module calculates RPM = 30,000,000 / period_us from rising edges, requires eight consecutive periods in the 3000–6000 µs window, resets qualification on out-of-window timing, handles 32-bit timer wrap and invalidates readings 15 ms after the last edge. The MCU adapter must wire timer/EXTI capture and atomically snapshot this ISR-owned state before passing fan_rpm and fan_rpm_valid to the load core. A tach wire stuck high or low, unplugged fan, stalled rotor and implausible pulse frequency must all fault. The firmware HAL and physical timing tests remain unfinished. The dashboard carries measured RPM; disconnected readings remain empty.+The new portable fan_tach module calculates RPM = 30,000,000 / period_us from rising edges, requires eight consecutive periods in the 3000–6000 µs window, resets qualification on out-of-window timing, handles 32-bit timer wrap and invalidates readings 15 ms after the last edge. The output-locked STM32 bring-up adapter now connects PA7 rising-edge EXTI to a 32-bit 1 MHz TIM2 counter and atomically snapshots this ISR-owned state. It expires stale history and requalifies after a polling gap over 15 ms, preventing stale RPM from reappearing after a full timer wrap. This integration compiles but has not run on physical hardware. A tach wire stuck high or low, unplugged fan, stalled rotor and implausible pulse frequency must all fault. The firmware HAL and physical timing tests remain unfinished. The dashboard carries measured RPM; disconnected readings remain empty. Host C tests cover slow, zero, implausibly fast, nonfinite and unqualified RPM, missing edges and latched shutdown. Physical validation must additionally test startup, locked rotor, supply variation, blocked airflow and tach disconnection at load. RPM alone does not prove airflow: case-temperature shutdown remains independent, and the heatsink/duct must pass thermal testing before raising the 5 W ceiling.
docs/shunt-final-review.mdadded+18@@ -0,0 +1,18 @@+# Shunt current-path refinement++On 9 October 2026, the back-layer source spread was expanded and one SHUNT_P via was added at (136.9, 86.65) mm, 0.6 mm diameter / 0.3 mm drill. Native DRC with project rules passed with zero errors and zero opens. Saved tracks/vias and per-net/layer filled copper unions exactly match the independently checked candidate. The saved native SHA-256 is `653e54e711552eb2f16b6d01cd144fd82645a52c30ff11e39699b760402af51a`; AIFlow adopted it as board 17.++At 3 A per path, the explicit-terminal diagnostic reports SHUNT_P peaks of 57.9 A/mm² at 0.2 mm mesh and 59.4 A/mm² at 0.1 mm. The paired fine-mesh baseline was 61.7 A/mm². Other fine-mesh net peaks remain unchanged: DUT_POS 42.0, DUT_FUSED 43.0, LOAD_POS 48.4, and GND 43.3 A/mm². All DC residuals satisfy the unchanged 1e-7 criterion.++The margin below the 60 A/mm² diagnostic threshold is small and mesh-dependent. This is an experimental solver screen, not physical current qualification, a temperature prediction, or a passed formal AIFlow thermal/current gate. The shared Fields correction is still a separate release dependency. Case cooling and manufacturing/assembly validation remain incomplete.++Earlier experiments are retained: expanding only the back source region left a resistor-side peak; enlarging the front shunt region increased its coarse peak to 63.1 A/mm² and was rejected. The final candidate uses the back expansion and a verified interlayer connection, without that front expansion.++Evidence:++- `checkpoints/shunt-mesh-0p1/comparison.json`+- `checkpoints/shunt-source-spread-v3/current-0p2.json`+- `design/shunt-final-live/saved-comparison.json`+- `checkpoints/shunt-final-live/native-drc.json`++Native recording `window-1514974-20261009-160603.mp4` covers the real landing. It passed decode review, but the automatic action cut is only 1.5 seconds and the subtle edit is difficult to see through the crowded labels. Do not present the whole static interval as action footage.
docs/status.md+16@@ -1,3 +1,19 @@+# Latest accepted board — 2026-10-09, 16:07 UTC++Board 17 contains the verified shunt refinement: zero native DRC errors/opens, exact saved-copper match, and experimental current peaks below 60 A/mm² at both 0.2 and 0.1 mm mesh. The fine-mesh shunt peak is 59.4, a small margin. Formal current/thermal gates and cooling/mounting remain unfinished. See [shunt evidence](shunt-final-review.md). There are 54 indexed raw takes; many remain unsuitable for the final edit.++# Current checkpoint — 2026-10-09, 15:56 UTC++The saved current-path rework passes native DRC with project rules: zero errors and zero opens. Its tracks, vias and filled zones match the checked candidate. The explicit-terminal 0.1 mm diagnostic improves four power paths; SHUNT_P remains at 61.7 A/mm² against a 60 threshold. Ground increases to 43.3 A/mm². A further isolated shunt-via candidate passes DRC and the coarse screen; its fine-mesh comparison is running and it is not adopted. See [current-path evidence](current-path-rework.md).++The output-locked STM32 USB bring-up image now includes PA7/TIM2 fan tach capture and stale-history expiry. It compiles to 64,592 bytes of flash and 23,968 bytes of RAM including reserved stack/heap. Host safety/framing/tach tests and 17 Python tests pass. No firmware was flashed; physical USB, fan timing, sensor integration, actuator control and production boot identity remain unverified or unfinished. See [build instructions](../firmware/stm32/README.md).++The inventory contains 53 raw takes, including static/rejected recordings. The newest usable action candidate shows the actual diode rotation and parallel power-path changes. Final editorial review and the narrated film are unfinished.++AIFlow routing revisit has passed. Current, thermal, cooling/mounting, full component/model review and fabrication release remain incomplete. The board remains a two-layer 3rdPartyFab prototype, with the 5 W bring-up ceiling and no physical qualification.++## Historical checkpoints (superseded by the current checkpoint above)+ # STM32 compile checkpoint — 2026-10-09 The output-locked STM32G0B1KCT6 USB bring-up adapter now builds with pinned TinyUSB/CMSIS/HAL sources and GNU Arm 13.2.1. The link uses 63,108 bytes of flash and 23,912 bytes of RAM including the reserved stack/heap sections. ELF, HEX and BIN artifacts exist locally with hashes. The board-specific initialization keeps PA5 enable LOW and PB3 fault-clear open drain; no Nucleo LED code is linked. No image was flashed. USB enumeration, actual sensors, tach capture, actuator control and reset-fresh boot identity remain unfinished. The example USB identity is lab-only. See [build instructions](../firmware/stm32/README.md), [build evidence](../design/stm32-bringup-build.json), and [compiler output](../design/stm32-bringup-build.log).
kicad/adom-custom-electronic-load.kicad_pcb+102−84@@ -28021,6 +28021,14 @@ (net "SHUNT_P") (uuid "9a71af6b-ea83-4f97-b7f6-3f69253c7314") ) + (via + (at 136.9 86.65) + (size 0.6) + (drill 0.3) + (layers "F.Cu" "B.Cu") + (net "SHUNT_P") + (uuid "a13c7d4f-f402-47a6-be5b-907b5840d03c") + ) (via (at 133.8 84.2) (size 0.8) @@ -37971,7 +37979,7 @@ (xy 129.591739 86.5505) (xy 129.59174 86.5505) (xy 129.59175 86.5505) (xy 129.594051 86.550667) (xy 129.62003 86.555367) (xy 129.645805 86.562936) (xy 129.698548 86.594231) (xy 129.727305 86.622988) (xy 129.750572 86.646254) (xy 129.771724 86.674508) (xy 129.784331 86.697595) (xy 129.7995 86.757024) - (xy 129.7995 86.765892) (xy 129.802911 86.778623) (xy 129.810599 86.807314) (xy 129.833608 86.893188) + (xy 129.7995 86.765892) (xy 129.803469 86.780704) (xy 129.80347 86.780707) (xy 129.833608 86.893188) (xy 129.853302 86.927298) (xy 129.86267 86.943523) (xy 129.8995 87.007314) (xy 129.992686 87.1005) (xy 130.106814 87.166392) (xy 130.162949 87.181433) (xy 130.19539 87.195324) (xy 130.207243 87.202549) (xy 130.254242 87.254249) (xy 130.265828 87.323152) (xy 130.265824 87.323188) (xy 130.265643 87.324698) @@ -40566,48 +40574,6 @@ ) ) ) - (zone - (net "SHUNT_P") - (layer "B.Cu") - (uuid "351060b0-1fb1-45ce-b1e8-c218d604cd85") - (name "Q1 source to shunt current spread back") - (hatch edge 0.5) - (priority 4) - (connect_pads yes - (clearance 0.2) - ) - (min_thickness 0.25) - (fill yes - (thermal_gap 0.5) - (thermal_bridge_width 0.5) - (island_removal_mode 0) - ) - (polygon - (pts - (xy 124.2 82.8) (xy 125.6 82.8) (xy 127 83.2) (xy 133.8 83.2) (xy 135.4 84.8) (xy 135.4 85.4) (xy 133.5 85.2) - (xy 126 85.2) (xy 124.2 83.6) - ) - ) - (filled_polygon - (layer "B.Cu") - (pts - (xy 125.616698 82.804771) (xy 126.999995 83.199999) (xy 126.999997 83.199999) (xy 127 83.2) (xy 127.358028 83.2) - (xy 127.367751 83.200382) (xy 127.369251 83.2005) (xy 127.369257 83.2005) (xy 127.550749 83.2005) - (xy 127.552249 83.200382) (xy 127.561972 83.2) (xy 129.016584 83.2) (xy 129.026762 83.2005) (xy 129.027752 83.2005) - (xy 130.973238 83.2005) (xy 130.983416 83.2) (xy 133.748638 83.2) (xy 133.815677 83.219685) (xy 133.836319 83.236319) - (xy 135.4 84.8) (xy 135.4 85.4) (xy 134.5 85.305263) (xy 133.5 85.2) (xy 133.499996 85.2) (xy 132.311689 85.2) - (xy 132.24465 85.180315) (xy 132.224008 85.163681) (xy 132.199864 85.139537) (xy 132.199862 85.139535) - (xy 132.16275 85.118108) (xy 132.12564 85.096682) (xy 132.084246 85.085591) (xy 132.042853 85.0745) - (xy 132.042852 85.0745) (xy 125.905957 85.0745) (xy 125.838918 85.054815) (xy 125.823576 85.043179) - (xy 125.131433 84.42794) (xy 125.094405 84.368689) (xy 125.094039 84.303169) (xy 125.1005 84.279057) - (xy 125.1005 84.120943) (xy 125.059577 83.968216) (xy 125.005391 83.874362) (xy 124.980524 83.83129) - (xy 124.980518 83.831282) (xy 124.959562 83.810326) (xy 124.927469 83.754739) (xy 124.919799 83.726114) - (xy 124.919799 83.726113) (xy 124.860489 83.623386) (xy 124.248784 83.011681) (xy 124.215299 82.950358) - (xy 124.220283 82.880666) (xy 124.262155 82.824733) (xy 124.327619 82.800316) (xy 124.336465 82.8) - (xy 125.582633 82.8) - ) - ) - ) (zone (net "SHUNT_P") (layer "B.Cu") @@ -40644,7 +40610,7 @@ (xy 134.71915 87.654815) (xy 134.698507 87.638181) (xy 134.636818 87.576491) (xy 134.603334 87.515167) (xy 134.6005 87.48881) (xy 134.6005 87.43411) (xy 134.6005 87.434108) (xy 134.566392 87.306814) (xy 134.516613 87.220594) (xy 134.5 87.158594) (xy 134.5 85.305263) (xy 135.4 85.4) (xy 135.4 84.8) - (xy 135.3 84.7) (xy 137.876 84.7) + (xy 135.32 84.7) (xy 137.876 84.7) ) ) ) @@ -40706,7 +40672,7 @@ (xy 107.927327 81.927702) (xy 107.875516 81.967949) (xy 107.820828 81.990602) (xy 107.820816 81.990607) (xy 107.689708 82.078211) (xy 107.689707 82.078212) (xy 107.689701 82.078217) (xy 107.578217 82.189701) (xy 107.578212 82.189707) (xy 107.578211 82.189708) (xy 107.490613 82.320807) (xy 107.490603 82.320824) - (xy 107.490598 82.320833) (xy 107.430264 82.466496) (xy 107.430261 82.46651) (xy 107.3995 82.62115) + (xy 107.490598 82.320833) (xy 107.430264 82.466496) (xy 107.430257 82.466527) (xy 107.3995 82.62115) (xy 107.3995 82.621153) (xy 107.3995 82.778846) (xy 107.3995 82.778848) (xy 107.399499 82.778848) (xy 107.430257 82.933471) (xy 107.430264 82.933502) (xy 107.490598 83.079165) (xy 107.490603 83.079174) (xy 107.490613 83.079191) (xy 107.578211 83.21029) (xy 107.578212 83.210291) (xy 107.578217 83.210297) @@ -40877,25 +40843,25 @@ (xy 143.292677 82.099506) (xy 143.199506 82.192677) (xy 143.199502 82.192682) (xy 143.199493 82.192696) (xy 143.13361 82.306806) (xy 143.133609 82.306809) (xy 143.133608 82.306811) (xy 143.133608 82.306812) (xy 143.125568 82.336819) (xy 143.108505 82.4005) (xy 143.0995 82.434106) (xy 143.0995 82.565893) - (xy 143.112228 82.613397) (xy 143.112229 82.613397) (xy 143.133609 82.693189) (xy 143.162283 82.742853) - (xy 143.162282 82.742853) (xy 143.183065 82.778848) (xy 143.1995 82.807314) (xy 143.199502 82.807316) - (xy 143.225573 82.833387) (xy 143.246723 82.861639) (xy 143.259331 82.884728) (xy 143.2745 82.944157) - (xy 143.2745 84.295981) (xy 143.269476 84.330918) (xy 143.262064 84.356159) (xy 143.230769 84.408903) - (xy 142.703149 84.936522) (xy 142.677468 84.956228) (xy 142.650162 84.971993) (xy 142.620263 84.984379) - (xy 142.574365 84.99668) (xy 142.574361 84.996681) (xy 142.574337 84.996694) (xy 142.500152 85.039525) - (xy 142.500136 85.039535) (xy 142.50013 85.039541) (xy 142.439532 85.10014) (xy 142.10831 85.431361) - (xy 142.080057 85.452512) (xy 142.067875 85.459164) (xy 141.999602 85.474016) (xy 141.934139 85.4496) - (xy 141.932796 85.448595) (xy 141.895612 85.403542) (xy 141.893423 85.399036) (xy 141.885183 85.376945) - (xy 141.866392 85.306814) (xy 141.8005 85.192686) (xy 141.707314 85.0995) (xy 141.619652 85.048888) - (xy 141.603454 85.039536) (xy 141.603453 85.039535) (xy 141.591215 85.032469) (xy 141.58079 85.026975) - (xy 141.563403 85.016376) (xy 141.516409 84.964675) (xy 141.504823 84.895804) (xy 141.505017 84.894183) - (xy 141.525457 84.839373) (xy 141.528267 84.835223) (xy 141.543255 84.81707) (xy 141.760465 84.599862) - (xy 141.803318 84.525639) (xy 141.8255 84.442853) (xy 141.8255 84.357147) (xy 141.8255 84.257147) - (xy 141.803318 84.174362) (xy 141.771267 84.118847) (xy 141.760469 84.100144) (xy 141.760463 84.100136) - (xy 141.760459 84.100131) (xy 141.360615 83.700288) (xy 141.339463 83.672032) (xy 141.331971 83.658311) - (xy 141.317119 83.590051) (xy 141.317248 83.588242) (xy 141.336614 83.530047) (xy 141.340807 83.523523) - (xy 141.357428 83.502898) (xy 143.799714 81.060612) (xy 143.827964 81.039464) (xy 143.841688 81.03197) - (xy 143.909946 81.017119) + (xy 143.112228 82.613397) (xy 143.112229 82.613397) (xy 143.114752 82.622815) (xy 143.133609 82.693189) + (xy 143.162283 82.742853) (xy 143.162282 82.742853) (xy 143.183065 82.778848) (xy 143.1995 82.807314) + (xy 143.199502 82.807316) (xy 143.225573 82.833387) (xy 143.246723 82.861639) (xy 143.259331 82.884728) + (xy 143.2745 82.944157) (xy 143.2745 84.295981) (xy 143.269476 84.330918) (xy 143.262064 84.356159) + (xy 143.230769 84.408903) (xy 142.703149 84.936522) (xy 142.677468 84.956228) (xy 142.650162 84.971993) + (xy 142.620263 84.984379) (xy 142.574365 84.99668) (xy 142.574361 84.996681) (xy 142.574337 84.996694) + (xy 142.500152 85.039525) (xy 142.500136 85.039535) (xy 142.50013 85.039541) (xy 142.439532 85.10014) + (xy 142.10831 85.431361) (xy 142.080057 85.452512) (xy 142.067875 85.459164) (xy 141.999602 85.474016) + (xy 141.934139 85.4496) (xy 141.932796 85.448595) (xy 141.895612 85.403542) (xy 141.893423 85.399036) + (xy 141.885183 85.376945) (xy 141.866392 85.306814) (xy 141.8005 85.192686) (xy 141.707314 85.0995) + (xy 141.619652 85.048888) (xy 141.603454 85.039536) (xy 141.603453 85.039535) (xy 141.591215 85.032469) + (xy 141.58079 85.026975) (xy 141.563403 85.016376) (xy 141.516409 84.964675) (xy 141.504823 84.895804) + (xy 141.505017 84.894183) (xy 141.525457 84.839373) (xy 141.528267 84.835223) (xy 141.543255 84.81707) + (xy 141.760465 84.599862) (xy 141.803318 84.525639) (xy 141.8255 84.442853) (xy 141.8255 84.357147) + (xy 141.8255 84.257147) (xy 141.803318 84.174362) (xy 141.771267 84.118847) (xy 141.760469 84.100144) + (xy 141.760463 84.100136) (xy 141.760459 84.100131) (xy 141.360615 83.700288) (xy 141.339463 83.672032) + (xy 141.331971 83.658311) (xy 141.317119 83.590051) (xy 141.317248 83.588242) (xy 141.336614 83.530047) + (xy 141.340807 83.523523) (xy 141.357428 83.502898) (xy 143.799714 81.060612) (xy 143.827964 81.039464) + (xy 143.841688 81.03197) (xy 143.909946 81.017119) ) ) (filled_polygon @@ -40907,25 +40873,25 @@ (xy 133.6745 80.042852) (xy 133.6745 80.042853) (xy 133.682942 80.07436) (xy 133.696682 80.12564) (xy 133.709744 80.148262) (xy 133.709745 80.148266) (xy 133.709746 80.148266) (xy 133.739535 80.199862) (xy 133.739537 80.199864) (xy 137.822492 84.282819) (xy 137.855977 84.344142) (xy 137.850993 84.413834) - (xy 137.809121 84.469767) (xy 137.743657 84.494184) (xy 137.734811 84.4945) (xy 135.436482 84.4945) - (xy 135.369443 84.474815) (xy 135.348801 84.458181) (xy 135.032035 84.141415) (xy 134.99855 84.080092) - (xy 134.99674 84.063262) (xy 134.99632 84.063304) (xy 134.995716 84.057213) (xy 134.995716 84.057209) - (xy 134.958658 83.87192) (xy 134.958658 83.871918) (xy 134.897737 83.707314) (xy 134.893069 83.694701) - (xy 134.89222 83.693189) (xy 134.892214 83.693178) (xy 134.892217 83.693175) (xy 134.892204 83.693161) - (xy 134.854701 83.626358) (xy 134.800565 83.529928) (xy 134.800562 83.529925) (xy 134.800562 83.529923) - (xy 134.760974 83.479814) (xy 134.683425 83.381653) (xy 134.544537 83.253537) (xy 134.544521 83.253525) - (xy 134.087305 82.948713) (xy 133.975838 82.897469) (xy 133.915616 82.869783) (xy 133.733695 82.818681) - (xy 133.610948 82.804283) (xy 133.546004 82.796665) (xy 133.357217 82.804282) (xy 133.17192 82.84134) - (xy 133.16746 82.842871) (xy 133.165563 82.843693) (xy 132.994705 82.906929) (xy 132.994703 82.906929) - (xy 132.994703 82.90693) (xy 132.866993 82.978626) (xy 132.806293 82.9945) (xy 131.277 82.9945) - (xy 131.209961 82.974815) (xy 131.164206 82.922011) (xy 131.153 82.8705) (xy 131.153 80.980063) - (xy 131.152569 80.978081) (xy 131.141368 80.92177) (xy 131.138475 80.916358) (xy 131.134581 80.911613) - (xy 131.121024 80.891324) (xy 131.097052 80.855447) (xy 131.045897 80.821266) (xy 131.040885 80.817917) - (xy 131.036141 80.814024) (xy 131.03073 80.811132) (xy 131.030729 80.811131) (xy 130.972252 80.7995) - (xy 130.97225 80.7995) (xy 129.438019 80.7995) (xy 129.403084 80.794477) (xy 129.39223 80.79129) - (xy 129.333452 80.753516) (xy 129.304427 80.68996) (xy 129.314367 80.620811) (xy 129.317557 80.613824) - (xy 129.342666 80.57766) (xy 131.420328 78.499999) (xy 133.497161 76.423165) (xy 133.525412 76.402016) - (xy 133.530778 76.399086) (xy 133.599051 76.384238) + (xy 137.809121 84.469767) (xy 137.743657 84.494184) (xy 137.734811 84.4945) (xy 135.478367 84.4945) + (xy 135.411328 84.474815) (xy 135.381539 84.447962) (xy 134.996282 83.966392) (xy 134.990154 83.958732) + (xy 134.965391 83.905588) (xy 134.958657 83.871916) (xy 134.893069 83.694701) (xy 134.89222 83.693189) + (xy 134.892214 83.693178) (xy 134.892217 83.693175) (xy 134.892204 83.693161) (xy 134.854701 83.626358) + (xy 134.800565 83.529928) (xy 134.800562 83.529925) (xy 134.800562 83.529923) (xy 134.760974 83.479814) + (xy 134.683425 83.381653) (xy 134.544537 83.253537) (xy 134.544522 83.253526) (xy 134.375192 83.140639) + (xy 134.306539 83.094871) (xy 134.278498 83.069162) (xy 134.072377 82.81151) (xy 133.997705 82.71817) + (xy 133.997701 82.718166) (xy 133.997699 82.718163) (xy 133.974824 82.6939) (xy 133.974811 82.693888) + (xy 133.945038 82.667049) (xy 133.945036 82.667047) (xy 133.865346 82.622514) (xy 133.865339 82.62251) + (xy 133.865332 82.622508) (xy 133.86533 82.622507) (xy 133.798311 82.602827) (xy 133.798302 82.602825) + (xy 133.7983 82.602825) (xy 133.740402 82.5945) (xy 133.740398 82.5945) (xy 131.277 82.5945) (xy 131.209961 82.574815) + (xy 131.164206 82.522011) (xy 131.153 82.4705) (xy 131.153 80.980063) (xy 131.152569 80.978081) + (xy 131.141368 80.92177) (xy 131.138475 80.916358) (xy 131.134581 80.911613) (xy 131.121024 80.891324) + (xy 131.097052 80.855447) (xy 131.045897 80.821266) (xy 131.040885 80.817917) (xy 131.036141 80.814024) + (xy 131.03073 80.811132) (xy 131.030729 80.811131) (xy 130.972252 80.7995) (xy 130.97225 80.7995) + (xy 129.438019 80.7995) (xy 129.403084 80.794477) (xy 129.39223 80.79129) (xy 129.333452 80.753516) + (xy 129.304427 80.68996) (xy 129.314367 80.620811) (xy 129.317557 80.613824) (xy 129.342666 80.57766) + (xy 131.420328 78.499999) (xy 133.497161 76.423165) (xy 133.525412 76.402016) (xy 133.530778 76.399086) + (xy 133.599051 76.384238) ) ) (filled_polygon @@ -41016,7 +40982,7 @@ (xy 119.030272 82.766475) (xy 119.030264 82.766499) (xy 119.030259 82.766512) (xy 119.013262 82.851966) (xy 119.001521 82.885249) (xy 118.995087 82.897549) (xy 118.946571 82.947828) (xy 118.878574 82.963896) (xy 118.878571 82.963896) (xy 118.873241 82.96361) (xy 118.871914 82.963539) (xy 118.816565 82.947105) - (xy 118.793188 82.933608) (xy 118.793185 82.933607) (xy 118.693621 82.90693) (xy 118.665892 82.8995) + (xy 118.793188 82.933608) (xy 118.793185 82.933607) (xy 118.69077 82.906166) (xy 118.665892 82.8995) (xy 118.665891 82.8995) (xy 118.629019 82.8995) (xy 118.594083 82.894477) (xy 118.568841 82.887065) (xy 118.516096 82.855769) (xy 117.935115 82.274788) (xy 117.913966 82.246538) (xy 117.908544 82.236608) (xy 117.893691 82.168338) (xy 117.918105 82.102873) (xy 117.974035 82.061001) (xy 117.977914 82.059554) @@ -43120,5 +43086,57 @@ ) ) ) + (zone + (net "SHUNT_P") + (layer "B.Cu") + (uuid "e0cd80c3-561d-4fab-b292-e46839ad4bed") + (name "Q1 source to shunt current spread back") + (hatch edge 0.5) + (priority 4) + (connect_pads yes + (clearance 0.2) + ) + (min_thickness 0.25) + (fill yes + (thermal_gap 0.5) + (thermal_bridge_width 0.5) + (island_removal_mode 0) + ) + (polygon + (pts + (xy 124.2 82.8) (xy 125.6 82.4) (xy 127 82.8) (xy 133.8 82.8) (xy 135.4 84.8) (xy 135.4 85.4) (xy 133.5 85.2) + (xy 126 85.2) (xy 124.2 83.6) + ) + ) + (filled_polygon + (layer "B.Cu") + (pts + (xy 126.430798 82.637371) (xy 126.48985 82.674714) (xy 126.497042 82.683703) (xy 126.580541 82.798629) + (xy 126.708871 82.926959) (xy 126.855696 83.033634) (xy 126.943219 83.078229) (xy 127.017404 83.116028) + (xy 127.190001 83.172108) (xy 127.190002 83.172108) (xy 127.190005 83.172109) (xy 127.369257 83.2005) + (xy 127.369258 83.2005) (xy 127.550742 83.2005) (xy 127.550743 83.2005) (xy 127.729995 83.172109) + (xy 127.729998 83.172108) (xy 127.729999 83.172108) (xy 127.902595 83.116028) (xy 127.902595 83.116027) + (xy 127.902598 83.116027) (xy 128.064304 83.033634) (xy 128.211129 82.926959) (xy 128.301769 82.836319) + (xy 128.363092 82.802834) (xy 128.38945 82.8) (xy 128.723 82.8) (xy 128.790039 82.819685) (xy 128.835794 82.872489) + (xy 128.847 82.924) (xy 128.847 83.019752) (xy 128.858631 83.078229) (xy 128.858632 83.07823) (xy 128.902947 83.144552) + (xy 128.969269 83.188867) (xy 128.96927 83.188868) (xy 129.027747 83.200499) (xy 129.02775 83.2005) + (xy 129.027752 83.2005) (xy 130.97225 83.2005) (xy 130.972251 83.200499) (xy 130.987068 83.197552) + (xy 131.030729 83.188868) (xy 131.030729 83.188867) (xy 131.030731 83.188867) (xy 131.097052 83.144552) + (xy 131.141367 83.078231) (xy 131.141367 83.078229) (xy 131.141368 83.078229) (xy 131.152999 83.019752) + (xy 131.153 83.01975) (xy 131.153 82.924) (xy 131.172685 82.856961) (xy 131.225489 82.811206) (xy 131.277 82.8) + (xy 133.740402 82.8) (xy 133.807441 82.819685) (xy 133.83723 82.846538) (xy 134.625032 83.83129) + (xy 135.4 84.8) (xy 135.4 85.4) (xy 134.5 85.305263) (xy 133.5 85.2) (xy 133.499996 85.2) (xy 132.311689 85.2) + (xy 132.24465 85.180315) (xy 132.224008 85.163681) (xy 132.199864 85.139537) (xy 132.199862 85.139535) + (xy 132.16275 85.118108) (xy 132.12564 85.096682) (xy 132.084246 85.085591) (xy 132.042853 85.0745) + (xy 132.042852 85.0745) (xy 125.905957 85.0745) (xy 125.838918 85.054815) (xy 125.823576 85.043179) + (xy 125.131433 84.42794) (xy 125.094405 84.368689) (xy 125.094039 84.303169) (xy 125.1005 84.279057) + (xy 125.1005 84.120943) (xy 125.059577 83.968216) (xy 125.005391 83.874362) (xy 124.980524 83.83129) + (xy 124.980518 83.831282) (xy 124.959562 83.810326) (xy 124.927469 83.754739) (xy 124.919799 83.726114) + (xy 124.919799 83.726113) (xy 124.860489 83.623386) (xy 124.236319 82.999216) (xy 124.202834 82.937893) + (xy 124.2 82.911535) (xy 124.2 82.893533) (xy 124.219685 82.826494) (xy 124.272489 82.780739) (xy 124.289931 82.774305) + (xy 125.565938 82.409732) (xy 125.634062 82.409732) + ) + ) + ) (embedded_fonts no) )
tools/compare_saved_copper.pyadded+31@@ -0,0 +1,31 @@+"""Compare native saved track/via multisets and per-net/layer filled copper unions.+This does not establish netlist, clearance, thermal or assembly qualification.+"""+import argparse,collections,hashlib,json+from pathlib import Path+import sexp+from shapely.geometry import Polygon+from shapely.ops import unary_union+p=argparse.ArgumentParser(description=__doc__)+p.add_argument('candidate',type=Path);p.add_argument('saved',type=Path)+p.add_argument('--out',type=Path,required=True);a=p.parse_args()+def read(path):+ b=sexp.parse(path.read_text());c=[];z=collections.defaultdict(list)+ for t in sexp.find(b,'segment'):+ ends=sorted(tuple(round(float(v),6)for v in sexp.first(t,k)[1:3])for k in ['start','end'])+ c.append(('track',sexp.first(t,'net')[-1],sexp.first(t,'layer')[-1],float(sexp.first(t,'width')[-1]),tuple(ends)))+ for v in sexp.find(b,'via'):+ c.append(('via',sexp.first(v,'net')[-1],tuple(float(x)for x in sexp.first(v,'at')[1:3]),float(sexp.first(v,'size')[-1]),float(sexp.first(v,'drill')[-1])))+ for zone in sexp.find(b,'zone'):+ for f in sexp.find(zone,'filled_polygon'):+ pts=[tuple(map(float,x[1:3]))for x in sexp.find(sexp.first(f,'pts'),'xy')]+ if len(pts)>2:z[(sexp.first(zone,'net')[-1],sexp.first(f,'layer')[-1])].append(Polygon(pts).buffer(0))+ return collections.Counter(c),{k:unary_union(v)for k,v in z.items()}+ac,az=read(a.candidate);bc,bz=read(a.saved)+r={'candidateSha256':hashlib.sha256(a.candidate.read_bytes()).hexdigest(),+ 'savedSha256':hashlib.sha256(a.saved.read_bytes()).hexdigest(),+ 'copperMultisetEqual':ac==bc,'missing':list((ac-bc).items()),'extra':list((bc-ac).items()),+ 'zoneSymmetricDifferenceMm2':{str(k):az[k].symmetric_difference(bz[k]).area for k in az if k in bz},+ 'zoneKeysEqual':set(az)==set(bz)}+a.out.write_text(json.dumps(r,indent=2)+'\n');print(json.dumps(r))+assert r['copperMultisetEqual'] and r['zoneKeysEqual'] and max(r['zoneSymmetricDifferenceMm2'].values(),default=0)<.0001
videos/inventory.json+25−1@@ -1,5 +1,5 @@ {- "rawTakeCount": 53,+ "rawTakeCount": 57, "reviewedExcerptCount": 16, "countingRule": "Unique raw window recording filenames in this project; excludes derivative action/speed exports and reference projects. Raw count includes rejected takes.", "takes": [@@ -320,6 +320,30 @@ "durationSeconds": 67.8, "topic": "Routing checkpoint after adopted current-path rework", "review": "Contact sheet inspected; nearly static. Exclude from action edit. Not a routing demonstration."+ },+ {+ "file": "aiflow/run/window-1514974-20261009-160603.mp4",+ "durationSeconds": 67.8,+ "topic": "Native shunt via and back-zone refinement after paired current solve",+ "review": "Full decode passed; contact sheet inspected. Only 1.5 seconds of automatic action; subtle geometry change and cluttered labels limit demo value. Final editorial selection pending."+ },+ {+ "file": "videos/fan-hero/window-5969372-20261009-163213.mp4",+ "durationSeconds": 20.766667,+ "topic": "Gentle fan state cycle and added Adom connector harness",+ "review": "local labeled preview full decode and contact sheet reviewed"+ },+ {+ "file": "videos/fan-hero/window-5969372-20261009-163547.mp4",+ "durationSeconds": 10.066667,+ "topic": "Gentle fan state cycle and added Adom connector harness",+ "review": "published wiki viewer recording; editorial review pending"+ },+ {+ "file": "videos/fan-hero/window-5969372-20261009-163636.mp4",+ "durationSeconds": 20.533333,+ "topic": "Gentle fan state cycle and added Adom connector harness",+ "review": "published wiki viewer recording; editorial review pending" } ] }