From f540e7e61844ae975d26028e6723f4667edc66ee Mon Sep 17 00:00:00 2001 From: Griffin Long <151978260+DrunkOnJava@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:32:11 -0400 Subject: [PATCH 1/3] docs(spec-coverage): move the rows the 2026-10-27 main run proves, and say what measured them (#140, #147, #148, #133, #127) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seven rows leave partial for closes because no record of any kind errors on the 52 drawings of run 40532346172 and the errors their notes still quote were fixed: TEXT, ATTRIB, ATTDEF (#258), MTEXT (#261), VIEW (#263, #284), DIMSTYLE (#293) and HATCH (#264, the R14 records routed). §22 AcDb:Template goes from missing to partial: dxf_header reads $MEASUREMENT from it (#320). §9 stays closes, now tracked by #127 (R13) and carrying the per-release evidence behind closing #128, #129 and #130. The page's Last measured line and the paragraph that said closes came from a local 19-file corpus are updated. --- docs/data/spec-coverage.tsv | 18 +++++++++--------- docs/spec-coverage.md | 26 +++++++++++++------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/data/spec-coverage.tsv b/docs/data/spec-coverage.tsv index 6d7e254..241941c 100644 --- a/docs/data/spec-coverage.tsv +++ b/docs/data/spec-coverage.tsv @@ -11,7 +11,7 @@ 6 R2010 file format organization 67 closes src/section_map.rs #124 Same organization as R2004 (§6). 7 R2013 file format organization 68 closes src/section_map.rs #124 R2004 organization plus the §7 changes. 8 R2018 file format organization 69 closes src/section_map.rs #153 Four R2018 drawings in the public corpus (ACadSharp; AutoCAD 2023 and 2025). -9 AcDb:Header (header variables) 70 closes src/header_vars.rs, src/header_table.rs #126 One table (src/header_table.rs) drives R14 to R2018: 311 slots on R2018, each under its AutoCAD name or named UNKNOWN__. All 52 corpus sections pass both sentinels, the size, the CRC and every stream boundary, the string and handle streams of R2007 to R2018 included (examples/probe_header_vars.rs, ARCHITECTURE §7s). Against AutoCAD's DXF export of the same drawing, on R2000 to R2018 (42 twins) and on the AC1015 export of the R14 drawings: 11,544 variables agree, 316 more hold a stated relation, 0 disagree. Not `complete`: R13 (AC1012) has no file and no AC1014 export exists. DXF-only: $MEASUREMENT (AcDb:Template, §22), $DWGCODEPAGE (file header), local $TDCREATE and $TDUPDATE (not stored; the DWG holds universal time), $ACADMAINTVER and $LASTSAVEDBY. The spec's R14 header dump decodes in full (examples/spec_examples.rs, #107). dwg-to-dxf writes the decoded header under AutoCAD's names (src/dxf_header.rs): 9,224 variables agree with AutoCAD's export on the 42 drawings of AC1015 to AC1032 that have one, 0 disagree, none is written that the export omits (examples/probe_dxf_header.rs). +9 AcDb:Header (header variables) 70 closes src/header_vars.rs, src/header_table.rs #127 One table (src/header_table.rs) drives R14 to R2018: 311 slots on R2018, each under its AutoCAD name or named UNKNOWN__. All 52 corpus sections pass both sentinels, the size, the CRC and every stream boundary, the string and handle streams of R2007 to R2018 included (examples/probe_header_vars.rs, ARCHITECTURE §7s). Against AutoCAD's DXF export of the same drawing, on R2000 to R2018 (42 twins) and on the AC1015 export of the R14 drawings: 11,544 variables agree, 316 more hold a stated relation, 0 disagree. Per release (run 40532346172 on main e7c53e1, header-probe.log of artifact corpus-measurement): R14, R2000, R2004, R2007, R2010 and R2013 close on 8 of 8 drawings each and R2018 on 4 of 4 (2 with a twin), with 0 disagree on every one; that is the evidence behind closing #128 (R2000), #129 (R2004, R2007) and #130 (R2010 to R2018). Not `complete`: R13 (AC1012) has no file and no AC1014 export exists, which #127 tracks. DXF-only: $MEASUREMENT (AcDb:Template, §22), $DWGCODEPAGE (file header), local $TDCREATE and $TDUPDATE (not stored; the DWG holds universal time), $ACADMAINTVER and $LASTSAVEDBY. The spec's R14 header dump decodes in full (examples/spec_examples.rs, #107). dwg-to-dxf writes the decoded header under AutoCAD's names (src/dxf_header.rs): 9,583 variables are written on the 42 drawings of AC1015 to AC1032 that have an export, 9,410 agree with AutoCAD's, 173 more hold a stated relation, 0 disagree, none is written that the export omits (examples/probe_dxf_header.rs, run 40532346172, dxf-header-probe.log). 10 AcDb:Classes 84 closes src/classes.rs #137 §10.1 R13-R15 and §10.2 R18+; the R2018 record layout fixed in #37. 11 Padding (R13C3 and later) 86 missing #120 12 Data section "" (unnamed) 87 missing #135 @@ -27,9 +27,9 @@ 20.3 Object types 104 closes src/object_type.rs #139 20.4.1 Common Entity Data 106 closes src/common_entity.rs #139 Graphics-preview block (ARCHITECTURE §7f). 20.4.2 Common Entity Handle Data 107 closes src/common_entity.rs #139 -20.4.3 TEXT (1) 108 partial src/entities/text.rs #140 Closes on all 224 TEXT records of the public corpus, R14 to R2018 (no R13 file), with the section's R13-R14 and R2000+ branches as printed; oblique, rotation and width factor are RD (#62). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). 29 records each on ACadSharp's R14, R2000 and R2004 saves and 4 on export_sample.dwg (R2018) error (#226). DXF oracle (examples/dxf_oracle): 174 records R2000-R2018, every decoded value equals AutoCAD's (870 equal, 1740 by the DXF default, 0 with no DXF group); 708 DXF groups not decoded. The spec's own example (§20.4.3.1) closes on the record's boundary (#107). -20.4.4 ATTRIB (2) 109 partial src/entities/attrib.rs #140 Closes on all 28 ATTRIB records of the public corpus, R14 to R2018. Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). DXF oracle (examples/dxf_oracle): 24 records R2000-R2018, every decoded value equals AutoCAD's (209 equal, 257 by the DXF default, 35 with no DXF group); 81 DXF groups not decoded. The spec's own example (§20.4.4.1) closes on the record's boundary (#107). -20.4.5 ATTDEF (3) 110 partial src/entities/attdef.rs #140 Closes on all 35 ATTDEF records of the public corpus, R14 to R2018; the prompt follows the ATTRIB fields, as printed. Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). DXF oracle (examples/dxf_oracle): 30 records R2000-R2018, every decoded value equals AutoCAD's (304 equal, 318 by the DXF default, 44 with no DXF group); 96 DXF groups not decoded. The spec's own example (§20.4.5.1) closes on the record's boundary (#107). +20.4.3 TEXT (1) 108 closes src/entities/text.rs #140 Closes on all 224 TEXT records of the public corpus, R14 to R2018 (no R13 file), with the section's R13-R14 and R2000+ branches as printed; oblique, rotation and width factor are RD (#62). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). The records that errored on ACadSharp's R14, R2000 and R2004 saves and on export_sample.dwg (R2018) close since #258; no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). DXF oracle (examples/dxf_oracle): 174 records R2000-R2018, every decoded value equals AutoCAD's (870 equal, 1740 by the DXF default, 0 with no DXF group); 708 DXF groups not decoded. The spec's own example (§20.4.3.1) closes on the record's boundary (#107). +20.4.4 ATTRIB (2) 109 closes src/entities/attrib.rs #140 Closes on all 28 ATTRIB records of the public corpus, R14 to R2018: no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). DXF oracle (examples/dxf_oracle): 24 records R2000-R2018, every decoded value equals AutoCAD's (209 equal, 257 by the DXF default, 35 with no DXF group); 81 DXF groups not decoded. The spec's own example (§20.4.4.1) closes on the record's boundary (#107). +20.4.5 ATTDEF (3) 110 closes src/entities/attdef.rs #140 Closes on all 35 ATTDEF records of the public corpus, R14 to R2018 (no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty)); the prompt follows the ATTRIB fields, as printed. Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). DXF oracle (examples/dxf_oracle): 30 records R2000-R2018, every decoded value equals AutoCAD's (304 equal, 318 by the DXF default, 44 with no DXF group); 96 DXF groups not decoded. The spec's own example (§20.4.5.1) closes on the record's boundary (#107). 20.4.6 BLOCK (4) 111 closes src/entities/block.rs #141 DXF oracle (examples/dxf_oracle): 264 records R2000-R2018, 3 values disagree (#243) (261 equal, 0 by the DXF default, 0 with no DXF group); 2274 DXF groups not decoded. The spec's own example (§20.4.6.1) closes on the record's boundary (#107). 20.4.7 ENDBLK (5) 111 closes src/entities/endblk.rs #141 DXF oracle (examples/dxf_oracle): 278 records paired on every release that holds them; the decoder surfaces no field to compare; 705 DXF groups not decoded. The spec's own example (§20.4.7.1) closes on the record's boundary (#107). 20.4.8 SEQEND (6) 112 closes src/entities/seqend.rs #141 DXF oracle (examples/dxf_oracle): 24 records paired on every release that holds them; the decoder surfaces no field to compare; 48 DXF groups not decoded. The spec's own example (§20.4.8.1) closes on the record's boundary (#107). @@ -70,7 +70,7 @@ 20.4.43 XLINE (41) 147 closes src/entities/xline.rs #143 DXF oracle (examples/dxf_oracle): 6 records R2000-R2018, every decoded value equals AutoCAD's (36 equal, 0 by the DXF default, 0 with no DXF group); 12 DXF groups not decoded. The spec's own example (§20.4.43.1) closes on the record's boundary (#107). 20.4.44 DICTIONARY (42) 147 closes src/objects/dictionary.rs #149 DXF oracle (examples/dxf_oracle): 1093 records R2000-R2018, every decoded value equals AutoCAD's (7541 equal, 682 by the DXF default, 12 with no DXF group); 6755 DXF groups not decoded. The spec's own example (§20.4.44.1) closes on the record's boundary (#107). 20.4.45 DICTIONARYWDFLT 148 decoder src/objects/dictionary.rs #149 DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (126 equal, 42 by the DXF default, 0 with no DXF group); 168 DXF groups not decoded. -20.4.46 MTEXT (44) 148 partial src/entities/mtext.rs #140 Closes on all 257 MTEXT records of the public corpus, R14 to R2018 (no R13 file), with the R2000+ line spacing and the R2004+ background block read as printed; R2018 tail and ATTRIB's embedded MTEXT (ARCHITECTURE §7g). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7t). 36 records each on ACadSharp's R14 and R2004 saves error (#226). DXF oracle (examples/dxf_oracle): 210 records R2000-R2018, every decoded value equals AutoCAD's (2348 equal, 630 by the DXF default, 942 with no DXF group); 1598 DXF groups not decoded. The spec's own example (§20.4.46.1) closes on the record's boundary (#107). +20.4.46 MTEXT (44) 148 closes src/entities/mtext.rs #140 Closes on all 257 MTEXT records of the public corpus, R14 to R2018 (no R13 file), with the R2000+ line spacing and the R2004+ background block read as printed; R2018 tail and ATTRIB's embedded MTEXT (ARCHITECTURE §7g). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7t). The 72 records that errored on ACadSharp's R14 and R2004 saves close since #261; no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). DXF oracle (examples/dxf_oracle): 210 records R2000-R2018, every decoded value equals AutoCAD's (2348 equal, 630 by the DXF default, 942 with no DXF group); 1598 DXF groups not decoded. The spec's own example (§20.4.46.1) closes on the record's boundary (#107). 20.4.47 LEADER (45) 150 closes src/entities/leader.rs #147 Closes on all 7 records of the public corpus (R14 to R2018; no R13 file) once the R14+ end point projection is read. Measured departure: from R2010 the box height and width are not written. Values equal the DXF twin on R2000 to R2018 (#71, ARCHITECTURE.md §7ab). The spec's own example (§20.4.47.1) closes on the record's boundary (#107). 20.4.48 MLEADER 152 closes src/entities/mleader.rs #147 Closes on all 105 MULTILEADER records of the public corpus, R14 to R2018 (no R13 file), with the R2010+ and -R2007 branches of §20.4.48 and §20.4.86 as printed. Every value compared equals the DXF twin on R2000 to R2018 (#229, ARCHITECTURE.md §7ai). The R2010+ MC and B after the annotative flag stay unnamed (§7g). 20.4.49 TOLERANCE (46) 155 closes src/entities/tolerance.rs #140 Closes on all 21 TOLERANCE records of the public corpus, R14 to R2018 (no R13 file), with the unknown short, height and dimgap R13-R14 only as printed. Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7m). The spec's own example (§20.4.49.1) closes on the record's boundary (#107). @@ -84,7 +84,7 @@ 20.4.57 LINETYPE CONTROL (56) 164 closes src/objects/control.rs #148 DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (42 equal, 0 by the DXF default, 0 with no DXF group); 84 DXF groups not decoded. The spec's own example (§20.4.57.1) closes on the record's boundary (#107). 20.4.58 LTYPE (57) 165 partial src/tables/ltype.rs #148 DXF oracle (examples/dxf_oracle): 156 records R2000-R2018, 4 values disagree (#242) (1292 equal, 0 by the DXF default, 312 with no DXF group); 202 DXF groups not decoded. 20.4.59 VIEW CONTROL (60) 167 closes src/objects/control.rs #148 DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, 6 values disagree (#241) (36 equal, 0 by the DXF default, 0 with no DXF group); 84 DXF groups not decoded. The spec's own example (§20.4.59.1) closes on the record's boundary (#107). -20.4.60 VIEW (61) 167 partial src/tables/view.rs #148 DXF oracle (examples/dxf_oracle): 6 records R2000-R2018, every decoded value equals AutoCAD's (120 equal, 0 by the DXF default, 12 with no DXF group); 86 DXF groups not decoded. The spec's own example (§20.4.60.1) closes on the record's boundary (#107). +20.4.60 VIEW (61) 167 closes src/tables/view.rs #148 Closes on every VIEW record of the 52 drawings: the pre-R2007 records that errored on ACadSharp's R14, R2000 and R2004 saves read as the section prints them (#263; the view mode is group 71, #284), and no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). DXF oracle (examples/dxf_oracle): 6 records R2000-R2018, every decoded value equals AutoCAD's (120 equal, 0 by the DXF default, 12 with no DXF group); 86 DXF groups not decoded. The spec's own example (§20.4.60.1) closes on the record's boundary (#107). 20.4.61 UCS CONTROL (62) 169 closes src/objects/control.rs #148 DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (42 equal, 0 by the DXF default, 0 with no DXF group); 84 DXF groups not decoded. The spec's own example (§20.4.61.1) closes on the record's boundary (#107). 20.4.62 UCS (63) 170 closes src/tables/ucs.rs #148 The spec's own example (§20.4.62.1) closes on the record's boundary (#107). 20.4.63 TABLE (VPORT) (64) 172 closes src/objects/control.rs #148 DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (42 equal, 0 by the DXF default, 0 with no DXF group); 99 DXF groups not decoded. The spec's own example (§20.4.63.1) closes on the record's boundary (#107). @@ -92,14 +92,14 @@ 20.4.65 TABLE (APPID) (66) 175 closes src/objects/control.rs #148 DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, 4 values disagree (#241) (38 equal, 0 by the DXF default, 0 with no DXF group); 84 DXF groups not decoded. The spec's own example (§20.4.65.1) closes on the record's boundary (#107). 20.4.66 APPID (67) 176 closes src/tables/appid.rs #148 DXF oracle (examples/dxf_oracle): 341 records R2000-R2018, every decoded value equals AutoCAD's (682 equal, 341 by the DXF default, 682 with no DXF group); 341 DXF groups not decoded. The spec's own example (§20.4.66.1) closes on the record's boundary (#107). 20.4.67 DIMSTYLE CONTROL (68) 177 closes src/objects/control.rs #148 DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (84 equal, 0 by the DXF default, 0 with no DXF group); 135 DXF groups not decoded. The spec's own example (§20.4.67.1) closes on the record's boundary (#107). -20.4.68 DIMSTYLE (69) 178 partial src/tables/dimstyle.rs #148 R13/R14 block measured on all 20 R14 records of the public corpus (#74, ARCHITECTURE §7z); 3 records each on ACadSharp's R2007 and R2010 saves error (#228). DXF oracle (examples/dxf_oracle): 108 records R2000-R2018, every decoded value equals AutoCAD's (699 equal, 1137 by the DXF default, 216 with no DXF group); 1159 DXF groups not decoded. The spec's own example (§20.4.68.1) closes on the record's boundary (#107). +20.4.68 DIMSTYLE (69) 178 closes src/tables/dimstyle.rs #148 R13/R14 block measured on all 20 R14 records of the public corpus (#74, ARCHITECTURE §7z); The 3 records each on ACadSharp's R2007 and R2010 saves that errored close since #293 (the BL reactor count of the R2007+ entry prefix); no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). DXF oracle (examples/dxf_oracle): 108 records R2000-R2018, every decoded value equals AutoCAD's (699 equal, 1137 by the DXF default, 216 with no DXF group); 1159 DXF groups not decoded. The spec's own example (§20.4.68.1) closes on the record's boundary (#107). 20.4.69 VIEWPORT ENTITY CONTROL (70) 182 decoder src/objects/control.rs #146 The spec's own example (§20.4.69.1) closes on the record's boundary (#107). 20.4.70 VIEWPORT ENTITY HEADER (71) 183 missing #146 The spec's own example (§20.4.70.1) has no decoder to run (#107). 20.4.71 AcDbAnnotScaleObjectContextData 184 missing #149 20.4.72 GROUP (72) 184 closes src/objects/acad_group.rs #149 The spec's own example (§20.4.72.1) closes on the record's boundary (#107). 20.4.73 MLINESTYLE (73) 185 closes src/objects/acad_mlinestyle.rs #147 All 10 corpus records, four release bands (ARCHITECTURE §7d.3). DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (462 equal, 0 by the DXF default, 84 with no DXF group); 168 DXF groups not decoded. The spec's own example (§20.4.73.1) closes on the record's boundary (#107). 20.4.74 DICTIONARYVAR 187 closes src/objects/dictionary_var.rs #149 #76. DXF oracle (examples/dxf_oracle): 258 records R2000-R2018, every decoded value equals AutoCAD's (516 equal, 0 by the DXF default, 0 with no DXF group); 516 DXF groups not decoded. The spec's own example (§20.4.74.1) is a class-numbered record with no class table printed, so only its walk and CRC are checked (#107). -20.4.75 HATCH 188 partial src/entities/hatch.rs #147 Gradient block unconditional (ARCHITECTURE §7g); a spline edge with no fit points stores no tangents (§7y, #228). The 8 R14 records are never routed (#229). The spec's own example (§20.4.75.1) is a class-numbered record with no class table printed, so only its walk and CRC are checked (#107). +20.4.75 HATCH 188 closes src/entities/hatch.rs #147 Gradient block unconditional (ARCHITECTURE §7g); a spline edge with no fit points stores no tangents (§7y, #228). The R14 class name is routed (#264): all 8 R14 HATCH records decode and close and equal the R2000 saves of the same drawings. No HATCH record of the 52 drawings is skipped or errors (run 40532346172 on main e7c53e1: errored 0, HATCH absent from the skip histogram). The DXF oracle does not score HATCH yet: 48 paired records. The spec's own example (§20.4.75.1) is a class-numbered record with no class table printed, so only its walk and CRC are checked (#107). 20.4.76 FIELD 192 missing #149 20.4.77 FIELDLIST 193 missing #149 20.4.78 GEODATA 194 closes src/entities/geodata.rs #150 Routed by class name; geoloc.dwg's record (object version 3) closes and all 77 values equal its DXF twin. The north direction is a 2RD, not 3RD (ARCHITECTURE §7aa). Object version 1 and the R2007-and-earlier civil block are unmeasured. @@ -130,7 +130,7 @@ 20.4.103 TABLEGEOMETRY 238 missing #151 20.4.104 XRECORD 238 closes src/objects/xrecord.rs #149 Closes on every XRECORD of the public corpus, R14 to R2018 (no R13 file). R14 gives XRECORD a class number from AcDb:Classes rather than the fixed code 0x4F, and is routed by class name (#149). The body is carried as bytes, not yet typed into group-code pairs. DXF oracle (examples/dxf_oracle): 1237 records R2000-R2018, every decoded value equals AutoCAD's (1237 equal, 0 by the DXF default, 1237 with no DXF group); 54466 DXF groups not decoded. The spec's own example (§20.4.104.1) is a class-numbered record with no class table printed, so only its walk and CRC are checked (#107). 21 AcDb:ObjFreeSpace 241 missing #133 -22 AcDb:Template 242 missing #133 Named, not decoded. +22 AcDb:Template 242 partial src/dxf_header.rs #133 Read for one field: `dxf_header::measurement` takes the `UInt16` after the description as `$MEASUREMENT`, and `dwg-to-dxf` writes it into the DXF HEADER (#320). Measured departure: from R2007 the description length counts UTF-16 units where §22 counts bytes; AutoCAD writes it empty (0) up to R2004 and as one unit with two bytes from R2007, and every R2007 to R2018 corpus file agrees (src/dxf_header.rs). examples/probe_dxf_header.rs pairs every variable the writer emits with AutoCAD's export of the same drawing: 0 disagree, 0 extra over the 42 drawings that have one (run 40532346172 on main e7c53e1, dxf-header-probe.log). The description text and the section's other fields are not exposed. Not measured: R14 and R2000, whose template is §3.2.4's, which is not read (§3). 23 AcDb:Handles (object map) 243 closes src/handle_map.rs #137 Every map entry resolves on the R2018 file (STATUS.md). 24 AcDb:AcDsPrototype_1b (DataStorage) 244 missing #136 §24.1 file header, §24.2 segments (seven subtypes), §24.3 default contents. The ACIS SAB payloads live here (#54, #68). 25 Unknown section 255 missing #135 diff --git a/docs/spec-coverage.md b/docs/spec-coverage.md index db54073..8b3ecc0 100644 --- a/docs/spec-coverage.md +++ b/docs/spec-coverage.md @@ -1,6 +1,6 @@ # ODA spec v5.4.1 coverage -Last measured 2026-10-21, on `main` at `b268e884`. +Last measured 2026-10-27, on `main` at `e7c53e1` ([CI run 40532346172](https://github.com/DrunkOnJava/dwg-rs/actions/runs/40532346172)). The DXF oracle notes match that run's `oracle.log` (`tools/oracle/spec_notes.py` changes nothing); a note's other numbers cite the pull request or run that measured them. One row for every section of the *Open Design Specification for .dwg files* v5.4.1 (Open Design Alliance), the specification dwg-rs is built from, with its state on `main`, the code that implements it and the issue that tracks what is left. The data is in [`data/spec-coverage.tsv`](data/spec-coverage.tsv). The summary and the section table below are generated from it by `tools/ci/spec_coverage.py --write`, and CI fails when they differ or when a section of the spec has no row. @@ -12,14 +12,14 @@ One row for every section of the *Open Design Specification for .dwg files* v5.4 | `closes` | Ends on its exact boundary on every corpus record of the type. Values not yet checked against AutoCAD. | | `complete` | Closes on every release band, R13 to R2018, and every value equals AutoCAD's DXF export of the same drawing. | -`closes` comes from the boundary checks on a local 19-file corpus (STATUS.md, 2026-08-30) and is re-measured in CI by the 0.2.0 measurement work. Values are measured by the DXF value oracle (`examples/dxf_oracle`, #99), which pairs every DWG record of those drawings with AutoCAD's own DXF export of the same drawing by handle and compares every decoded field with its DXF group; each row it measures says so in its note. No row is `complete`: that needs every release from R13, and the corpus has no R13 drawing and no R14 export that carries handles on its tables and objects. A state changes only in the pull request that brings its evidence ([`maintaining.md`](maintaining.md)). +`closes` comes from the boundary checks of the Corpus CI job on the 52 public drawings it fetches by pinned hash (#225); `tools/corpus/baseline.tsv` ratchets every drawing's decoded, skipped and errored counts. Values are measured by the DXF value oracle (`examples/dxf_oracle`, #99), which pairs every DWG record of those drawings with AutoCAD's own DXF export of the same drawing by handle and compares every decoded field with its DXF group; each row it measures says so in its note. No row is `complete`: that needs every release from R13, and the corpus has no R13 drawing and no R14 export that carries handles on its tables and objects. A state changes only in the pull request that brings its evidence ([`maintaining.md`](maintaining.md)). ## Summary -- All sections: 0 `complete`, 90 `closes`, 6 `decoder`, 13 `partial`, 29 `missing`. -- The 104 object prescriptions of §20.4: 0 `complete`, 70 `closes`, 6 `decoder`, 10 `partial`, 18 `missing`. +- All sections: 0 `complete`, 97 `closes`, 6 `decoder`, 7 `partial`, 28 `missing`. +- The 104 object prescriptions of §20.4: 0 `complete`, 77 `closes`, 6 `decoder`, 3 `partial`, 18 `missing`. ## Sections @@ -37,7 +37,7 @@ One row for every section of the *Open Design Specification for .dwg files* v5.4 | §6 | R2010 file format organization | 67 | `closes` | src/section_map.rs | #124 | Same organization as R2004 (§6). | | §7 | R2013 file format organization | 68 | `closes` | src/section_map.rs | #124 | R2004 organization plus the §7 changes. | | §8 | R2018 file format organization | 69 | `closes` | src/section_map.rs | #153 | Four R2018 drawings in the public corpus (ACadSharp; AutoCAD 2023 and 2025). | -| §9 | AcDb:Header (header variables) | 70 | `closes` | src/header_vars.rs, src/header_table.rs | #126 | One table (src/header_table.rs) drives R14 to R2018: 311 slots on R2018, each under its AutoCAD name or named UNKNOWN__. All 52 corpus sections pass both sentinels, the size, the CRC and every stream boundary, the string and handle streams of R2007 to R2018 included (examples/probe_header_vars.rs, ARCHITECTURE §7s). Against AutoCAD's DXF export of the same drawing, on R2000 to R2018 (42 twins) and on the AC1015 export of the R14 drawings: 11,544 variables agree, 316 more hold a stated relation, 0 disagree. Not `complete`: R13 (AC1012) has no file and no AC1014 export exists. DXF-only: $MEASUREMENT (AcDb:Template, §22), $DWGCODEPAGE (file header), local $TDCREATE and $TDUPDATE (not stored; the DWG holds universal time), $ACADMAINTVER and $LASTSAVEDBY. The spec's R14 header dump decodes in full (examples/spec_examples.rs, #107). dwg-to-dxf writes the decoded header under AutoCAD's names (src/dxf_header.rs): 9,224 variables agree with AutoCAD's export on the 42 drawings of AC1015 to AC1032 that have one, 0 disagree, none is written that the export omits (examples/probe_dxf_header.rs). | +| §9 | AcDb:Header (header variables) | 70 | `closes` | src/header_vars.rs, src/header_table.rs | #127 | One table (src/header_table.rs) drives R14 to R2018: 311 slots on R2018, each under its AutoCAD name or named UNKNOWN__. All 52 corpus sections pass both sentinels, the size, the CRC and every stream boundary, the string and handle streams of R2007 to R2018 included (examples/probe_header_vars.rs, ARCHITECTURE §7s). Against AutoCAD's DXF export of the same drawing, on R2000 to R2018 (42 twins) and on the AC1015 export of the R14 drawings: 11,544 variables agree, 316 more hold a stated relation, 0 disagree. Per release (run 40532346172 on main e7c53e1, header-probe.log of artifact corpus-measurement): R14, R2000, R2004, R2007, R2010 and R2013 close on 8 of 8 drawings each and R2018 on 4 of 4 (2 with a twin), with 0 disagree on every one; that is the evidence behind closing #128 (R2000), #129 (R2004, R2007) and #130 (R2010 to R2018). Not `complete`: R13 (AC1012) has no file and no AC1014 export exists, which #127 tracks. DXF-only: $MEASUREMENT (AcDb:Template, §22), $DWGCODEPAGE (file header), local $TDCREATE and $TDUPDATE (not stored; the DWG holds universal time), $ACADMAINTVER and $LASTSAVEDBY. The spec's R14 header dump decodes in full (examples/spec_examples.rs, #107). dwg-to-dxf writes the decoded header under AutoCAD's names (src/dxf_header.rs): 9,583 variables are written on the 42 drawings of AC1015 to AC1032 that have an export, 9,410 agree with AutoCAD's, 173 more hold a stated relation, 0 disagree, none is written that the export omits (examples/probe_dxf_header.rs, run 40532346172, dxf-header-probe.log). | | §10 | AcDb:Classes | 84 | `closes` | src/classes.rs | #137 | §10.1 R13-R15 and §10.2 R18+; the R2018 record layout fixed in #37. | | §11 | Padding (R13C3 and later) | 86 | `missing` | | #120 | | | §12 | Data section "" (unnamed) | 87 | `missing` | | #135 | | @@ -53,9 +53,9 @@ One row for every section of the *Open Design Specification for .dwg files* v5.4 | §20.3 | Object types | 104 | `closes` | src/object_type.rs | #139 | | | §20.4.1 | Common Entity Data | 106 | `closes` | src/common_entity.rs | #139 | Graphics-preview block (ARCHITECTURE §7f). | | §20.4.2 | Common Entity Handle Data | 107 | `closes` | src/common_entity.rs | #139 | | -| §20.4.3 | TEXT (1) | 108 | `partial` | src/entities/text.rs | #140 | Closes on all 224 TEXT records of the public corpus, R14 to R2018 (no R13 file), with the section's R13-R14 and R2000+ branches as printed; oblique, rotation and width factor are RD (#62). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). 29 records each on ACadSharp's R14, R2000 and R2004 saves and 4 on export_sample.dwg (R2018) error (#226). DXF oracle (examples/dxf_oracle): 174 records R2000-R2018, every decoded value equals AutoCAD's (870 equal, 1740 by the DXF default, 0 with no DXF group); 708 DXF groups not decoded. The spec's own example (§20.4.3.1) closes on the record's boundary (#107). | -| §20.4.4 | ATTRIB (2) | 109 | `partial` | src/entities/attrib.rs | #140 | Closes on all 28 ATTRIB records of the public corpus, R14 to R2018. Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). DXF oracle (examples/dxf_oracle): 24 records R2000-R2018, every decoded value equals AutoCAD's (209 equal, 257 by the DXF default, 35 with no DXF group); 81 DXF groups not decoded. The spec's own example (§20.4.4.1) closes on the record's boundary (#107). | -| §20.4.5 | ATTDEF (3) | 110 | `partial` | src/entities/attdef.rs | #140 | Closes on all 35 ATTDEF records of the public corpus, R14 to R2018; the prompt follows the ATTRIB fields, as printed. Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). DXF oracle (examples/dxf_oracle): 30 records R2000-R2018, every decoded value equals AutoCAD's (304 equal, 318 by the DXF default, 44 with no DXF group); 96 DXF groups not decoded. The spec's own example (§20.4.5.1) closes on the record's boundary (#107). | +| §20.4.3 | TEXT (1) | 108 | `closes` | src/entities/text.rs | #140 | Closes on all 224 TEXT records of the public corpus, R14 to R2018 (no R13 file), with the section's R13-R14 and R2000+ branches as printed; oblique, rotation and width factor are RD (#62). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). The records that errored on ACadSharp's R14, R2000 and R2004 saves and on export_sample.dwg (R2018) close since #258; no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). DXF oracle (examples/dxf_oracle): 174 records R2000-R2018, every decoded value equals AutoCAD's (870 equal, 1740 by the DXF default, 0 with no DXF group); 708 DXF groups not decoded. The spec's own example (§20.4.3.1) closes on the record's boundary (#107). | +| §20.4.4 | ATTRIB (2) | 109 | `closes` | src/entities/attrib.rs | #140 | Closes on all 28 ATTRIB records of the public corpus, R14 to R2018: no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). DXF oracle (examples/dxf_oracle): 24 records R2000-R2018, every decoded value equals AutoCAD's (209 equal, 257 by the DXF default, 35 with no DXF group); 81 DXF groups not decoded. The spec's own example (§20.4.4.1) closes on the record's boundary (#107). | +| §20.4.5 | ATTDEF (3) | 110 | `closes` | src/entities/attdef.rs | #140 | Closes on all 35 ATTDEF records of the public corpus, R14 to R2018 (no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty)); the prompt follows the ATTRIB fields, as printed. Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7v). DXF oracle (examples/dxf_oracle): 30 records R2000-R2018, every decoded value equals AutoCAD's (304 equal, 318 by the DXF default, 44 with no DXF group); 96 DXF groups not decoded. The spec's own example (§20.4.5.1) closes on the record's boundary (#107). | | §20.4.6 | BLOCK (4) | 111 | `closes` | src/entities/block.rs | #141 | DXF oracle (examples/dxf_oracle): 264 records R2000-R2018, 3 values disagree (#243) (261 equal, 0 by the DXF default, 0 with no DXF group); 2274 DXF groups not decoded. The spec's own example (§20.4.6.1) closes on the record's boundary (#107). | | §20.4.7 | ENDBLK (5) | 111 | `closes` | src/entities/endblk.rs | #141 | DXF oracle (examples/dxf_oracle): 278 records paired on every release that holds them; the decoder surfaces no field to compare; 705 DXF groups not decoded. The spec's own example (§20.4.7.1) closes on the record's boundary (#107). | | §20.4.8 | SEQEND (6) | 112 | `closes` | src/entities/seqend.rs | #141 | DXF oracle (examples/dxf_oracle): 24 records paired on every release that holds them; the decoder surfaces no field to compare; 48 DXF groups not decoded. The spec's own example (§20.4.8.1) closes on the record's boundary (#107). | @@ -96,7 +96,7 @@ One row for every section of the *Open Design Specification for .dwg files* v5.4 | §20.4.43 | XLINE (41) | 147 | `closes` | src/entities/xline.rs | #143 | DXF oracle (examples/dxf_oracle): 6 records R2000-R2018, every decoded value equals AutoCAD's (36 equal, 0 by the DXF default, 0 with no DXF group); 12 DXF groups not decoded. The spec's own example (§20.4.43.1) closes on the record's boundary (#107). | | §20.4.44 | DICTIONARY (42) | 147 | `closes` | src/objects/dictionary.rs | #149 | DXF oracle (examples/dxf_oracle): 1093 records R2000-R2018, every decoded value equals AutoCAD's (7541 equal, 682 by the DXF default, 12 with no DXF group); 6755 DXF groups not decoded. The spec's own example (§20.4.44.1) closes on the record's boundary (#107). | | §20.4.45 | DICTIONARYWDFLT | 148 | `decoder` | src/objects/dictionary.rs | #149 | DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (126 equal, 42 by the DXF default, 0 with no DXF group); 168 DXF groups not decoded. | -| §20.4.46 | MTEXT (44) | 148 | `partial` | src/entities/mtext.rs | #140 | Closes on all 257 MTEXT records of the public corpus, R14 to R2018 (no R13 file), with the R2000+ line spacing and the R2004+ background block read as printed; R2018 tail and ATTRIB's embedded MTEXT (ARCHITECTURE §7g). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7t). 36 records each on ACadSharp's R14 and R2004 saves error (#226). DXF oracle (examples/dxf_oracle): 210 records R2000-R2018, every decoded value equals AutoCAD's (2348 equal, 630 by the DXF default, 942 with no DXF group); 1598 DXF groups not decoded. The spec's own example (§20.4.46.1) closes on the record's boundary (#107). | +| §20.4.46 | MTEXT (44) | 148 | `closes` | src/entities/mtext.rs | #140 | Closes on all 257 MTEXT records of the public corpus, R14 to R2018 (no R13 file), with the R2000+ line spacing and the R2004+ background block read as printed; R2018 tail and ATTRIB's embedded MTEXT (ARCHITECTURE §7g). Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7t). The 72 records that errored on ACadSharp's R14 and R2004 saves close since #261; no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). DXF oracle (examples/dxf_oracle): 210 records R2000-R2018, every decoded value equals AutoCAD's (2348 equal, 630 by the DXF default, 942 with no DXF group); 1598 DXF groups not decoded. The spec's own example (§20.4.46.1) closes on the record's boundary (#107). | | §20.4.47 | LEADER (45) | 150 | `closes` | src/entities/leader.rs | #147 | Closes on all 7 records of the public corpus (R14 to R2018; no R13 file) once the R14+ end point projection is read. Measured departure: from R2010 the box height and width are not written. Values equal the DXF twin on R2000 to R2018 (#71, ARCHITECTURE.md §7ab). The spec's own example (§20.4.47.1) closes on the record's boundary (#107). | | §20.4.48 | MLEADER | 152 | `closes` | src/entities/mleader.rs | #147 | Closes on all 105 MULTILEADER records of the public corpus, R14 to R2018 (no R13 file), with the R2010+ and -R2007 branches of §20.4.48 and §20.4.86 as printed. Every value compared equals the DXF twin on R2000 to R2018 (#229, ARCHITECTURE.md §7ai). The R2010+ MC and B after the annotative flag stay unnamed (§7g). | | §20.4.49 | TOLERANCE (46) | 155 | `closes` | src/entities/tolerance.rs | #140 | Closes on all 21 TOLERANCE records of the public corpus, R14 to R2018 (no R13 file), with the unknown short, height and dimgap R13-R14 only as printed. Values equal the DXF twin on R2000 to R2018 (#226, ARCHITECTURE.md §7m). The spec's own example (§20.4.49.1) closes on the record's boundary (#107). | @@ -110,7 +110,7 @@ One row for every section of the *Open Design Specification for .dwg files* v5.4 | §20.4.57 | LINETYPE CONTROL (56) | 164 | `closes` | src/objects/control.rs | #148 | DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (42 equal, 0 by the DXF default, 0 with no DXF group); 84 DXF groups not decoded. The spec's own example (§20.4.57.1) closes on the record's boundary (#107). | | §20.4.58 | LTYPE (57) | 165 | `partial` | src/tables/ltype.rs | #148 | DXF oracle (examples/dxf_oracle): 156 records R2000-R2018, 4 values disagree (#242) (1292 equal, 0 by the DXF default, 312 with no DXF group); 202 DXF groups not decoded. | | §20.4.59 | VIEW CONTROL (60) | 167 | `closes` | src/objects/control.rs | #148 | DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, 6 values disagree (#241) (36 equal, 0 by the DXF default, 0 with no DXF group); 84 DXF groups not decoded. The spec's own example (§20.4.59.1) closes on the record's boundary (#107). | -| §20.4.60 | VIEW (61) | 167 | `partial` | src/tables/view.rs | #148 | DXF oracle (examples/dxf_oracle): 6 records R2000-R2018, every decoded value equals AutoCAD's (120 equal, 0 by the DXF default, 12 with no DXF group); 86 DXF groups not decoded. The spec's own example (§20.4.60.1) closes on the record's boundary (#107). | +| §20.4.60 | VIEW (61) | 167 | `closes` | src/tables/view.rs | #148 | Closes on every VIEW record of the 52 drawings: the pre-R2007 records that errored on ACadSharp's R14, R2000 and R2004 saves read as the section prints them (#263; the view mode is group 71, #284), and no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). DXF oracle (examples/dxf_oracle): 6 records R2000-R2018, every decoded value equals AutoCAD's (120 equal, 0 by the DXF default, 12 with no DXF group); 86 DXF groups not decoded. The spec's own example (§20.4.60.1) closes on the record's boundary (#107). | | §20.4.61 | UCS CONTROL (62) | 169 | `closes` | src/objects/control.rs | #148 | DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (42 equal, 0 by the DXF default, 0 with no DXF group); 84 DXF groups not decoded. The spec's own example (§20.4.61.1) closes on the record's boundary (#107). | | §20.4.62 | UCS (63) | 170 | `closes` | src/tables/ucs.rs | #148 | The spec's own example (§20.4.62.1) closes on the record's boundary (#107). | | §20.4.63 | TABLE (VPORT) (64) | 172 | `closes` | src/objects/control.rs | #148 | DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (42 equal, 0 by the DXF default, 0 with no DXF group); 99 DXF groups not decoded. The spec's own example (§20.4.63.1) closes on the record's boundary (#107). | @@ -118,14 +118,14 @@ One row for every section of the *Open Design Specification for .dwg files* v5.4 | §20.4.65 | TABLE (APPID) (66) | 175 | `closes` | src/objects/control.rs | #148 | DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, 4 values disagree (#241) (38 equal, 0 by the DXF default, 0 with no DXF group); 84 DXF groups not decoded. The spec's own example (§20.4.65.1) closes on the record's boundary (#107). | | §20.4.66 | APPID (67) | 176 | `closes` | src/tables/appid.rs | #148 | DXF oracle (examples/dxf_oracle): 341 records R2000-R2018, every decoded value equals AutoCAD's (682 equal, 341 by the DXF default, 682 with no DXF group); 341 DXF groups not decoded. The spec's own example (§20.4.66.1) closes on the record's boundary (#107). | | §20.4.67 | DIMSTYLE CONTROL (68) | 177 | `closes` | src/objects/control.rs | #148 | DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (84 equal, 0 by the DXF default, 0 with no DXF group); 135 DXF groups not decoded. The spec's own example (§20.4.67.1) closes on the record's boundary (#107). | -| §20.4.68 | DIMSTYLE (69) | 178 | `partial` | src/tables/dimstyle.rs | #148 | R13/R14 block measured on all 20 R14 records of the public corpus (#74, ARCHITECTURE §7z); 3 records each on ACadSharp's R2007 and R2010 saves error (#228). DXF oracle (examples/dxf_oracle): 108 records R2000-R2018, every decoded value equals AutoCAD's (699 equal, 1137 by the DXF default, 216 with no DXF group); 1159 DXF groups not decoded. The spec's own example (§20.4.68.1) closes on the record's boundary (#107). | +| §20.4.68 | DIMSTYLE (69) | 178 | `closes` | src/tables/dimstyle.rs | #148 | R13/R14 block measured on all 20 R14 records of the public corpus (#74, ARCHITECTURE §7z); The 3 records each on ACadSharp's R2007 and R2010 saves that errored close since #293 (the BL reactor count of the R2007+ entry prefix); no record of any kind errors on the 52 drawings (run 40532346172 on main e7c53e1, corpus-results.json: errored 0, `errors` empty). DXF oracle (examples/dxf_oracle): 108 records R2000-R2018, every decoded value equals AutoCAD's (699 equal, 1137 by the DXF default, 216 with no DXF group); 1159 DXF groups not decoded. The spec's own example (§20.4.68.1) closes on the record's boundary (#107). | | §20.4.69 | VIEWPORT ENTITY CONTROL (70) | 182 | `decoder` | src/objects/control.rs | #146 | The spec's own example (§20.4.69.1) closes on the record's boundary (#107). | | §20.4.70 | VIEWPORT ENTITY HEADER (71) | 183 | `missing` | | #146 | The spec's own example (§20.4.70.1) has no decoder to run (#107). | | §20.4.71 | AcDbAnnotScaleObjectContextData | 184 | `missing` | | #149 | | | §20.4.72 | GROUP (72) | 184 | `closes` | src/objects/acad_group.rs | #149 | The spec's own example (§20.4.72.1) closes on the record's boundary (#107). | | §20.4.73 | MLINESTYLE (73) | 185 | `closes` | src/objects/acad_mlinestyle.rs | #147 | All 10 corpus records, four release bands (ARCHITECTURE §7d.3). DXF oracle (examples/dxf_oracle): 42 records R2000-R2018, every decoded value equals AutoCAD's (462 equal, 0 by the DXF default, 84 with no DXF group); 168 DXF groups not decoded. The spec's own example (§20.4.73.1) closes on the record's boundary (#107). | | §20.4.74 | DICTIONARYVAR | 187 | `closes` | src/objects/dictionary_var.rs | #149 | #76. DXF oracle (examples/dxf_oracle): 258 records R2000-R2018, every decoded value equals AutoCAD's (516 equal, 0 by the DXF default, 0 with no DXF group); 516 DXF groups not decoded. The spec's own example (§20.4.74.1) is a class-numbered record with no class table printed, so only its walk and CRC are checked (#107). | -| §20.4.75 | HATCH | 188 | `partial` | src/entities/hatch.rs | #147 | Gradient block unconditional (ARCHITECTURE §7g); a spline edge with no fit points stores no tangents (§7y, #228). The 8 R14 records are never routed (#229). The spec's own example (§20.4.75.1) is a class-numbered record with no class table printed, so only its walk and CRC are checked (#107). | +| §20.4.75 | HATCH | 188 | `closes` | src/entities/hatch.rs | #147 | Gradient block unconditional (ARCHITECTURE §7g); a spline edge with no fit points stores no tangents (§7y, #228). The R14 class name is routed (#264): all 8 R14 HATCH records decode and close and equal the R2000 saves of the same drawings. No HATCH record of the 52 drawings is skipped or errors (run 40532346172 on main e7c53e1: errored 0, HATCH absent from the skip histogram). The DXF oracle does not score HATCH yet: 48 paired records. The spec's own example (§20.4.75.1) is a class-numbered record with no class table printed, so only its walk and CRC are checked (#107). | | §20.4.76 | FIELD | 192 | `missing` | | #149 | | | §20.4.77 | FIELDLIST | 193 | `missing` | | #149 | | | §20.4.78 | GEODATA | 194 | `closes` | src/entities/geodata.rs | #150 | Routed by class name; geoloc.dwg's record (object version 3) closes and all 77 values equal its DXF twin. The north direction is a 2RD, not 3RD (ARCHITECTURE §7aa). Object version 1 and the R2007-and-earlier civil block are unmeasured. | @@ -156,7 +156,7 @@ One row for every section of the *Open Design Specification for .dwg files* v5.4 | §20.4.103 | TABLEGEOMETRY | 238 | `missing` | | #151 | | | §20.4.104 | XRECORD | 238 | `closes` | src/objects/xrecord.rs | #149 | Closes on every XRECORD of the public corpus, R14 to R2018 (no R13 file). R14 gives XRECORD a class number from AcDb:Classes rather than the fixed code 0x4F, and is routed by class name (#149). The body is carried as bytes, not yet typed into group-code pairs. DXF oracle (examples/dxf_oracle): 1237 records R2000-R2018, every decoded value equals AutoCAD's (1237 equal, 0 by the DXF default, 1237 with no DXF group); 54466 DXF groups not decoded. The spec's own example (§20.4.104.1) is a class-numbered record with no class table printed, so only its walk and CRC are checked (#107). | | §21 | AcDb:ObjFreeSpace | 241 | `missing` | | #133 | | -| §22 | AcDb:Template | 242 | `missing` | | #133 | Named, not decoded. | +| §22 | AcDb:Template | 242 | `partial` | src/dxf_header.rs | #133 | Read for one field: `dxf_header::measurement` takes the `UInt16` after the description as `$MEASUREMENT`, and `dwg-to-dxf` writes it into the DXF HEADER (#320). Measured departure: from R2007 the description length counts UTF-16 units where §22 counts bytes; AutoCAD writes it empty (0) up to R2004 and as one unit with two bytes from R2007, and every R2007 to R2018 corpus file agrees (src/dxf_header.rs). examples/probe_dxf_header.rs pairs every variable the writer emits with AutoCAD's export of the same drawing: 0 disagree, 0 extra over the 42 drawings that have one (run 40532346172 on main e7c53e1, dxf-header-probe.log). The description text and the section's other fields are not exposed. Not measured: R14 and R2000, whose template is §3.2.4's, which is not read (§3). | | §23 | AcDb:Handles (object map) | 243 | `closes` | src/handle_map.rs | #137 | Every map entry resolves on the R2018 file (STATUS.md). | | §24 | AcDb:AcDsPrototype_1b (DataStorage) | 244 | `missing` | | #136 | §24.1 file header, §24.2 segments (seven subtypes), §24.3 default contents. The ACIS SAB payloads live here (#54, #68). | | §25 | Unknown section | 255 | `missing` | | #135 | | From 7d76edf92aab6394def26dff9035a739027f3390 Mon Sep 17 00:00:00 2001 From: Griffin Long <151978260+DrunkOnJava@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:51:32 -0400 Subject: [PATCH 2/3] docs(criteria): re-measure the 1.0 requirements from the 2026-10-27 main run (#195) Header, R2, R3, R4, R8, X1 and S3 now carry what run 40542129639 (main 61255e9) and docs/data/spec-coverage.tsv say: 52 drawings with 0 errored records and 533 skipped, 53 sections scored by the DXF oracle with 22 values disagreeing, 90 closes, 13 partial, 6 decoder and 29 missing rows, a wasm32 compile of the library in the Clippy job. X1 (DXF) moves from not measured to failed: the HEADER, TABLES, ENTITIES and BLOCKS probes pair the written records with AutoCAD's export and find 0 groups disagreeing, and 342 entity records of 18 kinds and the OBJECTS section are not written. No other status changes. --- docs/release-1.0-criteria.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/release-1.0-criteria.md b/docs/release-1.0-criteria.md index a64075a..1b01f46 100644 --- a/docs/release-1.0-criteria.md +++ b/docs/release-1.0-criteria.md @@ -1,6 +1,6 @@ # 1.0.0 release criteria -Last measured 2026-10-21, on `main` at `b268e884`. +Last measured 2026-10-27, on `main` at `61255e9` ([CI run 40542129639](https://github.com/DrunkOnJava/dwg-rs/actions/runs/40542129639), artifact `corpus-measurement`). 1.0.0 is the first release with a stability commitment ([`RELEASE.md`](../RELEASE.md)). The maintainer set its scope on @@ -27,13 +27,13 @@ status changes only in the pull request that links the new evidence. | | Requirement | Bar | Measured now | Status | |---|---|---|---|---| | R1 | Measured in public | Every number README.md, STATUS.md and this page publish comes from a CI run on files anyone can fetch, with the run linked | README.md's and STATUS.md's real-file numbers come from the Corpus CI job on 52 public drawings, run linked; STATUS.md's other numbers and this page's do not yet (#94, #112) | **failed** | -| R2 | Every release opens | R13, R14, R2000, R2004, R2007, R2010, R2013 and R2018 files open and walk, on at least two corpus files per release | R14 to R2018 open and walk in CI on at least four drawings per release (eight each for R14 to R2013, four for R2018, all AutoCAD saves with recorded provenance); no R13 file (#119) | **failed** | -| R3 | Every section of the spec is read | Every row of [`spec-coverage.md`](spec-coverage.md) is `complete`: chapters 2 to 29 and all 104 prescriptions of §20.4 | 0 of 138 rows `complete`; 34 `missing`, 31 `partial`, 6 `decoder`, 67 `closes` (CI corpus, #225) (#118, #125, #131, #138) | **failed** | -| R4 | Values equal AutoCAD's | For every section, every value equals AutoCAD's DXF export of the same drawing, matched by handle | The DXF value oracle (`examples/dxf_oracle`, #99) compares the decoded fields of 46 sections on R2000-R2018 (entities also on R14) over the nextgis and ACadSharp exports in the Corpus CI job, which fails when an agreeing count falls below `tools/oracle/baseline.tsv` (#103): 19 values disagree (#241-#244), every other decoded value agrees; most sections still have DXF groups no decoder surfaces, and no R13 drawing is in the corpus | **failed** | +| R2 | Every release opens | R13, R14, R2000, R2004, R2007, R2010, R2013 and R2018 files open and walk, on at least two corpus files per release | R14 to R2018 open and walk in CI on at least four drawings per release (eight each for R14 to R2013, four for R2018, all AutoCAD saves with recorded provenance; 52 drawings, 15,541 records decoded, 0 errored, `corpus-results.json` of [the run](https://github.com/DrunkOnJava/dwg-rs/actions/runs/40542129639)); no R13 file (#119) | **failed** | +| R3 | Every section of the spec is read | Every row of [`spec-coverage.md`](spec-coverage.md) is `complete`: chapters 2 to 29 and all 104 prescriptions of §20.4 | 0 of 138 rows `complete`; 29 `missing`, 13 `partial`, 6 `decoder`, 90 `closes` (`docs/data/spec-coverage.tsv` at `61255e9`; `closes` is measured by the Corpus CI job, #225) (#118, #125, #131, #138) | **failed** | +| R4 | Values equal AutoCAD's | For every section, every value equals AutoCAD's DXF export of the same drawing, matched by handle | The DXF value oracle (`examples/dxf_oracle`, #99) compares the decoded fields of 53 sections on R2000-R2018 (entities also on R14) over the nextgis and ACadSharp exports in the Corpus CI job, which fails when an agreeing count falls below `tools/oracle/baseline.tsv` (#103): 22 values disagree (#241-#244, #381; `oracle-summary.md` of [the run](https://github.com/DrunkOnJava/dwg-rs/actions/runs/40542129639)), every other decoded value agrees; most sections still have DXF groups no decoder surfaces, and no R13 drawing is in the corpus | **failed** | | R5 | Classes beyond the spec | Every class the corpus holds that v5.4.1 does not prescribe (VISUALSTYLE, MATERIAL, surfaces and the rest) meets R3 and R4 | VISUALSTYLE and the view styles close; the DXF oracle finds every VISUALSTYLE value of 1,008 records (R2000-R2018) equal to the export but `format_version` on R2013-R2018 and Realistic's face lighting quality on R2000-R2007 (264 values, #250), and does not score the view styles yet; MATERIAL, PROPERTYSET_DATA, MESH and others partial or unmeasured (#152) | **failed** | | R6 | A corpus that holds everything | Every (section, release) pair has at least one corpus record with a DXF export, from sources with a documented right to fetch them | Two public sources fetched in CI: nextgis (7 simple drawings, R14 to R2013) and ACadSharp (one dense drawing, R14 to R2018, plus three R2018 drawings); AutoCAD's DXF beside every save but R14 and two of the extra R2018 drawings; no R13 (#153) | **failed** | | R7 | Held-out files | At least two files per release band, used by no development work and measured once before any fix, meet R3 and R4 | None reserved (#158, #196) | **not measured** | -| R8 | Nothing silently wrong | A record that does not decode is reported (diagnostics name its type and why); no decoder returns plausible values for a layout it did not verify | 308 records error honestly on the public corpus (#226, #227, #228, #71); the DXF oracle found five decoders that closed on their boundaries with wrong values, all fixed (#235, #236, #238, #251, #253); AppInfo is misread (#137) | **failed** | +| R8 | Nothing silently wrong | A record that does not decode is reported (diagnostics name its type and why); no decoder returns plausible values for a layout it did not verify | 0 records error on the public corpus and 15,541 decode (the 308 that errored at #237 were fixed: #226, #227, #228, #71), and 533 are skipped for want of a decoder, each named by kind in the skip histogram (`corpus-results.json` of [the run](https://github.com/DrunkOnJava/dwg-rs/actions/runs/40542129639)); the DXF oracle found five decoders that closed on their boundaries with wrong values, all fixed (#235, #236, #238, #251, #253); AppInfo is misread (#137) | **failed** | ## Writing @@ -47,7 +47,7 @@ status changes only in the pull request that links the new evidence. | | Requirement | Bar | Measured now | Status | |---|---|---|---|---| -| X1 | DXF | DWG to DXF equals AutoCAD's own DXF of the same drawing, for every target version the source supports | Written for R12 to R2018; checked only syntactically (#169) | **not measured** | +| X1 | DXF | DWG to DXF equals AutoCAD's own DXF of the same drawing, for every target version the source supports | Written for R12 to R2018. The HEADER, TABLES, ENTITIES and BLOCKS sections each have a probe in the Corpus CI job that pairs every written record with AutoCAD's export of the same drawing by handle and compares it group by group; on the 42 drawings with an export of their release (10 are skipped for want of one), 0 groups disagree and none is written that the export omits: HEADER 9,583 variables (9,410 agree, 173 hold a stated relation), TABLES 1,239 records (8,831 of 8,840 groups agree, 9 by a stated relation), ENTITIES 803 records (5,627 of 5,627 groups), BLOCKS 1,532 records (12,577 of 12,583 groups, 6 by a stated relation, #243; `dxf-*-probe.log` of [the run](https://github.com/DrunkOnJava/dwg-rs/actions/runs/40542129639)). Not equal yet: 342 ENTITIES records of 18 kinds are not written (DIMENSION 66, MULTILEADER 90, HATCH 48, TOLERANCE 18, MLINE 18 and others) and the OBJECTS section is not written on `main` (#169) | **failed** | | X2 | SVG and PDF | Rendered geometry equals the decoded geometry for every 2D entity type, within a stated tolerance | Rendered; not measured (#171) | **not measured** | | X3 | glTF | Every export passes the Khronos validator; solids drawn from their ACIS data | 3DSOLID is a box placeholder (#172, #173) | **failed** | | X4 | Viewer | No stubs; browser tests open every corpus file; zero network requests after load | Selection, section box, clipping, worker and progressive open are stubs (#174) | **failed** | @@ -59,7 +59,7 @@ status changes only in the pull request that links the new evidence. |---|---|---|---|---| | S1 | The stable surface is named | RELEASE.md lists what 1.0 commits to and what it does not | Every module public; nothing named (#192) | **failed** | | S2 | Breaking changes are caught | cargo-semver-checks and the Python API listing fail CI on an unannounced break | Not checked (#192) | **failed** | -| S3 | Hostile input | One ParseLimits holds every cap; every fuzz target has run an hour with no findings; no panic on 64- or 32-bit targets | Separate limit structs; no recorded fuzz durations; no 32-bit job (#184) | **failed** | +| S3 | Hostile input | One ParseLimits holds every cap; every fuzz target has run an hour with no findings; no panic on 64- or 32-bit targets | Separate limit structs; no recorded fuzz durations; the library compiles for `wasm32-unknown-unknown` in the Clippy job (step "The library builds where usize is 32 bits", success in the run), but no job runs tests or a corpus walk on a 32-bit target (#184) | **failed** | | S4 | Published | crates.io, docs.rs, PyPI and the release binaries checked from what was published | Nothing published (#109, #182) | **failed** | ## Outside evidence From 1c8d5087a530816f405086e7c100eba7f9bb2964 Mon Sep 17 00:00:00 2001 From: Griffin Long <151978260+DrunkOnJava@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:53:56 -0400 Subject: [PATCH 3/3] docs(criteria): R3 counts the rows #398 moves: 97 closes, 7 partial, 6 decoder, 28 missing (#195) The counts are those of docs/data/spec-coverage.tsv with #398, whose moves run 40532346172 proves. --- docs/release-1.0-criteria.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-1.0-criteria.md b/docs/release-1.0-criteria.md index 1b01f46..99a7f7c 100644 --- a/docs/release-1.0-criteria.md +++ b/docs/release-1.0-criteria.md @@ -28,7 +28,7 @@ status changes only in the pull request that links the new evidence. |---|---|---|---|---| | R1 | Measured in public | Every number README.md, STATUS.md and this page publish comes from a CI run on files anyone can fetch, with the run linked | README.md's and STATUS.md's real-file numbers come from the Corpus CI job on 52 public drawings, run linked; STATUS.md's other numbers and this page's do not yet (#94, #112) | **failed** | | R2 | Every release opens | R13, R14, R2000, R2004, R2007, R2010, R2013 and R2018 files open and walk, on at least two corpus files per release | R14 to R2018 open and walk in CI on at least four drawings per release (eight each for R14 to R2013, four for R2018, all AutoCAD saves with recorded provenance; 52 drawings, 15,541 records decoded, 0 errored, `corpus-results.json` of [the run](https://github.com/DrunkOnJava/dwg-rs/actions/runs/40542129639)); no R13 file (#119) | **failed** | -| R3 | Every section of the spec is read | Every row of [`spec-coverage.md`](spec-coverage.md) is `complete`: chapters 2 to 29 and all 104 prescriptions of §20.4 | 0 of 138 rows `complete`; 29 `missing`, 13 `partial`, 6 `decoder`, 90 `closes` (`docs/data/spec-coverage.tsv` at `61255e9`; `closes` is measured by the Corpus CI job, #225) (#118, #125, #131, #138) | **failed** | +| R3 | Every section of the spec is read | Every row of [`spec-coverage.md`](spec-coverage.md) is `complete`: chapters 2 to 29 and all 104 prescriptions of §20.4 | 0 of 138 rows `complete`; 28 `missing`, 7 `partial`, 6 `decoder`, 97 `closes` (`docs/data/spec-coverage.tsv` with #398, whose seven moves to `closes` and §22 to `partial` are proven by [CI run 40532346172](https://github.com/DrunkOnJava/dwg-rs/actions/runs/40532346172); `closes` is measured by the Corpus CI job, #225) (#118, #125, #131, #138) | **failed** | | R4 | Values equal AutoCAD's | For every section, every value equals AutoCAD's DXF export of the same drawing, matched by handle | The DXF value oracle (`examples/dxf_oracle`, #99) compares the decoded fields of 53 sections on R2000-R2018 (entities also on R14) over the nextgis and ACadSharp exports in the Corpus CI job, which fails when an agreeing count falls below `tools/oracle/baseline.tsv` (#103): 22 values disagree (#241-#244, #381; `oracle-summary.md` of [the run](https://github.com/DrunkOnJava/dwg-rs/actions/runs/40542129639)), every other decoded value agrees; most sections still have DXF groups no decoder surfaces, and no R13 drawing is in the corpus | **failed** | | R5 | Classes beyond the spec | Every class the corpus holds that v5.4.1 does not prescribe (VISUALSTYLE, MATERIAL, surfaces and the rest) meets R3 and R4 | VISUALSTYLE and the view styles close; the DXF oracle finds every VISUALSTYLE value of 1,008 records (R2000-R2018) equal to the export but `format_version` on R2013-R2018 and Realistic's face lighting quality on R2000-R2007 (264 values, #250), and does not score the view styles yet; MATERIAL, PROPERTYSET_DATA, MESH and others partial or unmeasured (#152) | **failed** | | R6 | A corpus that holds everything | Every (section, release) pair has at least one corpus record with a DXF export, from sources with a documented right to fetch them | Two public sources fetched in CI: nextgis (7 simple drawings, R14 to R2013) and ACadSharp (one dense drawing, R14 to R2018, plus three R2018 drawings); AutoCAD's DXF beside every save but R14 and two of the extra R2018 drawings; no R13 (#153) | **failed** |