app
AI Flow: Reverse Engineering
Public Made by Adomby adom
Photos of a PCB to a tagged KiCad copy: parts placed, copper and nets with their evidence, a schematic, a measured confidence score, bench tests and a video of the run.
main
Caleb
Version 0.3.0: new copper reader, dome via filter, every layer read from the photos, net evidence, measured confidence;…
e874d7d
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
{
"at": "2026-11-06T00:20:28Z",
"derived": "written by the program for reading; nothing reads it back",
"scores": {
"categories": {
"blocks": {
"audit": {
"detail": "all 31 of 42 ok from 137 (bound 61.5%, unchanged 100%)",
"failed": [
"a002 C31 (cannot_tell)",
"a007 C45 (cannot_tell)",
"a010 R31 (cannot_tell)",
"a013 J2 (cannot_tell)",
"a021 C52 (cannot_tell)",
"a022 C34 (cannot_tell)",
"a028 C42 (cannot_tell)",
"a030 H6 (cannot_tell)",
"a032 C32 (cannot_tell)",
"a037 R21 (wrong)",
"a040 R22 (cannot_tell)"
],
"items": 47,
"sample": "8de3533d37c544ce",
"status": "scored",
"strata": [
{
"audited": 42,
"needForTarget": 28,
"ok": 31,
"population": 137,
"staleVerdicts": 0,
"stratum": "all",
"unchangedShare": 1.0,
"value": 61.5,
"wilson95Lower": 0.615
}
],
"verdicts": 47
},
"ceilings": [
{
"inputs": "scored: all 31 of 42 ok from 137 (bound 61.5%, unchanged 100%)",
"name": "independent audit",
"value": 61.5
},
{
"inputs": "104 of 137 parts are in a block tagged SEEN, MEASURED or DATASHEET",
"name": "parts in a block seen on the board",
"value": 75.9
}
],
"heldByAudit": false,
"limit": "independent audit: scored: all 31 of 42 ok from 137 (bound 61.5%, unchanged 100%)",
"outside": null,
"raise": "fix the method behind the failed items (a002 C31 (cannot_tell), a007 C45 (cannot_tell), a010 R31 (cannot_tell), a013 J2 (cannot_tell), a021 C52 (cannot_tell), a022 C34 (cannot_tell)), then redraw",
"score": 61.5
},
"connectivity": {
"audit": {
"detail": "no sample drawn",
"failed": [],
"items": 0,
"sample": "",
"status": "none",
"strata": [],
"verdicts": 0
},
"ceilings": [
{
"inputs": "no independent evidence (none: no sample drawn): capped at 40",
"name": "independent audit",
"value": 40.0
},
{
"inputs": "4833 of 5359 mm2 of pour has a net",
"name": "copper with a net, by area",
"value": 90.1
},
{
"inputs": "85 of 338 connections (415 pins, 77 nets) are joined by seen copper; 253 routed by the program, not seen; outside-evidence bound 0.0",
"name": "connections the photos show or outside evidence proves",
"value": 25.1
},
{
"inputs": "455 of 1048 mm of track has a net",
"name": "copper with a net, by length",
"value": 43.3
},
{
"inputs": "7 of 89 joined pins disagree with the copper they touch; via net clashes: 4",
"name": "pins that agree with their copper",
"value": 92.1
},
{
"inputs": "441 of 338 missing per KiCad at the proposed stackup",
"name": "connections KiCad finds closed",
"value": 0.0
}
],
"heldByAudit": false,
"limit": "connections KiCad finds closed: 441 of 338 missing per KiCad at the proposed stackup",
"outside": "a continuity log per net on the real board, or a real netlist, attached to the pin verdicts with --evidence: photos cannot show what joins inside the board",
"raise": "close what the copy leaves open",
"score": 0.0
},
"copper": {
"audit": {
"detail": "bare 9 of 52 ok from 1334 (bound 9.5%, unchanged 100%); copper 22 of 53 ok from 5360 (bound 29.3%, unchanged 100%)",
"failed": [
"a001 pt:bottom:3:38 (cannot_tell)",
"a002 pt:top:5:43 (cannot_tell)",
"a004 pt:top:26:55 (cannot_tell)",
"a010 pt:bottom:42:33 (cannot_tell)",
"a018 pt:top:60:30 (cannot_tell)",
"a022 pt:bottom:40:0 (cannot_tell)",
"a025 pt:bottom:38:21 (cannot_tell)",
"a027 pt:bottom:42:32 (cannot_tell)",
"a028 pt:top:27:56 (cannot_tell)",
"a032 pt:bottom:34:60 (cannot_tell)",
"a037 pt:top:51:26 (cannot_tell)",
"a040 pt:top:11:49 (cannot_tell)",
"a044 pt:top:68:39 (cannot_tell)",
"a046 pt:bottom:44:28 (cannot_tell)",
"a049 pt:top:28:53 (cannot_tell)",
"a053 pt:top:8:55 (cannot_tell)",
"a054 pt:bottom:49:36 (cannot_tell)",
"a058 pt:bottom:25:14 (cannot_tell)",
"a060 pt:bottom:40:27 (cannot_tell)",
"a062 pt:bottom:50:37 (cannot_tell)",
"a065 pt:top:32:55 (cannot_tell)",
"a066 pt:bottom:50:23 (cannot_tell)",
"a073 pt:bottom:19:9 (cannot_tell)",
"a075 pt:top:51:8 (cannot_tell)",
"a076 pt:top:0:20 (wrong)",
"a078 pt:top:28:38 (cannot_tell)",
"a080 pt:bottom:45:56 (cannot_tell)",
"a082 pt:top:28:11 (cannot_tell)",
"a083 pt:top:48:27 (cannot_tell)",
"a084 pt:top:37:33 (cannot_tell)",
"a089 pt:bottom:18:35 (cannot_tell)",
"a091 pt:top:8:53 (cannot_tell)",
"a092 pt:top:28:14 (cannot_tell)",
"a093 pt:top:54:0 (cannot_tell)",
"a097 pt:top:53:26 (cannot_tell)",
"a100 pt:top:36:8 (cannot_tell)",
"a101 pt:top:2:33 (cannot_tell)",
"a102 pt:bottom:19:10 (wrong)",
"a103 pt:bottom:2:28 (cannot_tell)",
"a104 pt:top:60:31 (cannot_tell)",
"a106 pt:top:35:11 (cannot_tell)",
"a107 pt:top:34:33 (cannot_tell)",
"a109 pt:bottom:39:25 (cannot_tell)",
"a003 pt:bottom:66:50 (cannot_tell)",
"a009 pt:bottom:37:27 (cannot_tell)",
"a012 pt:bottom:39:50 (cannot_tell)",
"a015 pt:top:53:58 (cannot_tell)",
"a016 pt:bottom:15:45 (cannot_tell)",
"a017 pt:bottom:25:57 (cannot_tell)",
"a019 pt:top:30:41 (cannot_tell)",
"a021 pt:bottom:57:58 (cannot_tell)",
"a024 pt:bottom:60:24 (cannot_tell)",
"a026 pt:bottom:12:50 (cannot_tell)",
"a033 pt:top:68:13 (cannot_tell)",
"a035 pt:bottom:55:25 (cannot_tell)",
"a036 pt:top:49:25 (cannot_tell)",
"a038 pt:bottom:52:23 (cannot_tell)",
"a039 pt:bottom:66:23 (cannot_tell)",
"a041 pt:top:35:38 (cannot_tell)",
"a047 pt:top:51:58 (cannot_tell)",
"a048 pt:top:59:45 (cannot_tell)",
"a051 pt:bottom:54:41 (cannot_tell)",
"a056 pt:top:19:60 (cannot_tell)",
"a059 pt:top:43:21 (cannot_tell)",
"a061 pt:bottom:29:28 (cannot_tell)",
"a069 pt:bottom:60:29 (cannot_tell)",
"a074 pt:top:26:19 (cannot_tell)",
"a094 pt:top:34:39 (cannot_tell)",
"a098 pt:top:66:28 (cannot_tell)",
"a105 pt:bottom:35:41 (cannot_tell)",
"a108 pt:bottom:27:47 (cannot_tell)",
"a110 pt:bottom:2:47 (cannot_tell)",
"a115 pt:top:61:46 (cannot_tell)",
"a116 pt:top:14:50 (cannot_tell)"
],
"items": 116,
"sample": "5689ec71713feb7e",
"status": "scored",
"strata": [
{
"audited": 52,
"needForTarget": 34,
"ok": 9,
"population": 1334,
"staleVerdicts": 0,
"stratum": "bare",
"unchangedShare": 1.0,
"value": 9.4,
"wilson95Lower": 0.095
},
{
"audited": 53,
"needForTarget": 35,
"ok": 22,
"population": 5360,
"staleVerdicts": 0,
"stratum": "copper",
"unchangedShare": 1.0,
"value": 29.3,
"wilson95Lower": 0.293
}
],
"verdicts": 116
},
"ceilings": [
{
"inputs": "scored: bare 9 of 52 ok from 1334 (bound 9.5%, unchanged 100%); copper 22 of 53 ok from 5360 (bound 29.3%, unchanged 100%)",
"name": "independent audit",
"value": 9.4
},
{
"inputs": "top: 2001 mm2 drawn of 2599 mm2 read as islands; bottom: 3559 mm2 drawn of 3543 mm2 read as islands",
"name": "copper read that reached the copy",
"value": 77.0
},
{
"inputs": "fidelity.json: lowest of 1 figure(s) is 80.9 at /categories/copper/score",
"name": "layers against the photos",
"value": 80.9
}
],
"heldByAudit": false,
"limit": "independent audit: scored: bare 9 of 52 ok from 1334 (bound 9.5%, unchanged 100%); copper 22 of 53 ok from 5360 (bound 29.3%, unchanged 100%)",
"outside": "an X-ray, or a photo of the bare board with the mask stripped, where the photo is dark or a part hides the copper",
"raise": "fix the method behind the failed items (a001 pt:bottom:3:38 (cannot_tell), a002 pt:top:5:43 (cannot_tell), a004 pt:top:26:55 (cannot_tell), a010 pt:bottom:42:33 (cannot_tell), a018 pt:top:60:30 (cannot_tell), a022 pt:bottom:40:0 (cannot_tell)), then redraw",
"score": 9.4
},
"identity": {
"audit": {
"detail": "all 42 of 42 ok from 137 (bound 94.0%, unchanged 100%)",
"failed": [],
"items": 47,
"sample": "04ba581e0674b85f",
"status": "scored",
"strata": [
{
"audited": 42,
"needForTarget": 28,
"ok": 42,
"population": 137,
"staleVerdicts": 0,
"stratum": "all",
"unchangedShare": 1.0,
"value": 93.9,
"wilson95Lower": 0.94
}
],
"verdicts": 47
},
"ceilings": [
{
"inputs": "scored: all 42 of 42 ok from 137 (bound 94.0%, unchanged 100%)",
"name": "independent audit",
"value": 93.9
},
{
"inputs": "132 of 137 parts have an identity tagged SEEN, MEASURED or DATASHEET",
"name": "identity tagged as seen",
"value": 96.3
}
],
"heldByAudit": false,
"limit": "independent audit: scored: all 42 of 42 ok from 137 (bound 94.0%, unchanged 100%)",
"outside": "a bill of materials, or markings read under a microscope for the unmarked parts, attached to the verdicts with --evidence",
"raise": "a larger sample: no audited item failed",
"score": 93.9
},
"layers": {
"audit": {
"detail": "no sample drawn",
"failed": [],
"items": 0,
"sample": "",
"status": "none",
"strata": [],
"verdicts": 0
},
"ceilings": [
{
"inputs": "no independent evidence (none: no sample drawn): capped at 30",
"name": "independent audit",
"value": 30.0
},
{
"inputs": "photos never show an inner layer: cap 30",
"name": "photos alone",
"value": 30.0
},
{
"inputs": "45 of 253 connections stay open at 6 layers",
"name": "the proposed stackup closes",
"value": 82.2
}
],
"heldByAudit": false,
"limit": "independent audit: no independent evidence (none: no sample drawn): capped at 30",
"outside": "an edge micrograph, a cross-section or an X-ray that shows the copper layers, attached to the layer and plane verdicts with --evidence: photos never show an inner layer",
"raise": "attach outside evidence with `audit verdict --evidence`",
"score": 30.0
},
"placement": {
"audit": {
"detail": "all 40 of 42 ok from 137 (bound 86.6%, unchanged 100%)",
"failed": [
"a010 J6 (wrong)",
"a040 U5 (wrong)"
],
"items": 47,
"sample": "e2e0df98a782c0ae",
"status": "scored",
"strata": [
{
"audited": 42,
"needForTarget": 28,
"ok": 40,
"population": 137,
"staleVerdicts": 0,
"stratum": "all",
"unchangedShare": 1.0,
"value": 86.6,
"wilson95Lower": 0.866
}
],
"verdicts": 47
},
"ceilings": [
{
"inputs": "scored: all 40 of 42 ok from 137 (bound 86.6%, unchanged 100%)",
"name": "independent audit",
"value": 86.6
},
{
"inputs": "115 of 137 parts have snap.method by pads, body centre or hole centre",
"name": "parts located by a program measurement",
"value": 83.9
},
{
"inputs": "fidelity.json: lowest of 1 figure(s) is 55.6 at /categories/placement/score",
"name": "layers against the photos",
"value": 55.6
}
],
"heldByAudit": false,
"limit": "layers against the photos: fidelity.json: lowest of 1 figure(s) is 55.6 at /categories/placement/score",
"outside": null,
"raise": "make what the KiCad layers draw agree with the photos at /categories/placement/score",
"score": 55.6
},
"values": {
"audit": {
"detail": "no sample drawn",
"failed": [],
"items": 0,
"sample": "",
"status": "none",
"strata": [],
"verdicts": 0
},
"ceilings": [
{
"inputs": "no independent evidence (none: no sample drawn): capped at 40",
"name": "independent audit",
"value": 40.0
},
{
"inputs": "47 of 137 parts with a value have it tagged SEEN, MEASURED or DATASHEET",
"name": "values tagged as seen",
"value": 34.3
}
],
"heldByAudit": false,
"limit": "values tagged as seen: 47 of 137 parts with a value have it tagged SEEN, MEASURED or DATASHEET",
"outside": "an LCR reading of each unmarked part off the board, or a bill of materials, attached to the verdicts with --evidence",
"raise": "get values for the 90 parts with no readable value: unmarked ceramics cannot be read from a photo",
"score": 34.3
},
"vias": {
"audit": {
"detail": "dropped 26 of 35 ok from 69 (bound 63.0%, unchanged 100%); kept 48 of 52 ok from 1329 (bound 82.1%, unchanged 100%)",
"failed": [
"a001 dome:bottom:[122.096,104.009] (wrong)",
"a021 dome:bottom:[102.369,161.235] (wrong)",
"a027 dome:bottom:[103.048,160.993] (wrong)",
"a033 dome:bottom:[104.237,159.376] (wrong)",
"a038 dome:bottom:[113.972,124.212] (cannot_tell)",
"a052 dome:bottom:[113.566,124.79] (wrong)",
"a063 dome:bottom:[114.379,123.575] (wrong)",
"a076 dome:bottom:[144.3,155.275] (wrong)",
"a089 dome:bottom:[124.75,158.825] (cannot_tell)",
"a028 via:v1278 (cannot_tell)",
"a060 via:v828 (wrong)",
"a062 via:v1191 (cannot_tell)",
"a092 via:v1022 (wrong)"
],
"items": 96,
"sample": "17b98f42f4908eaf",
"status": "scored",
"strata": [
{
"audited": 35,
"needForTarget": 24,
"ok": 26,
"population": 69,
"staleVerdicts": 0,
"stratum": "dropped",
"unchangedShare": 1.0,
"value": 62.9,
"wilson95Lower": 0.63
},
{
"audited": 52,
"needForTarget": 34,
"ok": 48,
"population": 1329,
"staleVerdicts": 0,
"stratum": "kept",
"unchangedShare": 1.0,
"value": 82.0,
"wilson95Lower": 0.821
}
],
"verdicts": 96
},
"ceilings": [
{
"inputs": "scored: dropped 26 of 35 ok from 69 (bound 63.0%, unchanged 100%); kept 48 of 52 ok from 1329 (bound 82.1%, unchanged 100%)",
"name": "independent audit",
"value": 62.9
},
{
"inputs": "49 of 1329 kept vias sit on a patch more than a quarter pale (min(R,G,B) > 135 in the square reaching 0.35 mm around it, a rule from these photos and an upper bound on false vias); 0 seen on both faces",
"name": "vias not on pale pixels",
"value": 96.3
},
{
"inputs": "fidelity.json: lowest of 1 figure(s) is 69.4 at /categories/vias/score",
"name": "layers against the photos",
"value": 69.4
}
],
"heldByAudit": false,
"limit": "independent audit: scored: dropped 26 of 35 ok from 69 (bound 63.0%, unchanged 100%); kept 48 of 52 ok from 1329 (bound 82.1%, unchanged 100%)",
"outside": "an X-ray or a backlit photo of the bare board shows through vias directly, attached with --evidence",
"raise": "fix the method behind the failed items (a001 dome:bottom:[122.096,104.009] (wrong), a021 dome:bottom:[102.369,161.235] (wrong), a027 dome:bottom:[103.048,160.993] (wrong), a033 dome:bottom:[104.237,159.376] (wrong), a038 dome:bottom:[113.972,124.212] (cannot_tell), a052 dome:bottom:[113.566,124.79] (wrong)), then redraw",
"score": 62.9
}
},
"fullPass": true,
"overall": 0.0,
"overallRule": "the lowest category",
"target": 90.0
},
"verdict": "STALLED"
}