rfcxml 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/roundtrip.yml +79 -0
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +9 -3
  5. data/.rubocop_todo.yml +87 -17
  6. data/Gemfile +4 -2
  7. data/README.adoc +386 -18
  8. data/Rakefile +55 -0
  9. data/lib/rfcxml/v3/abstract.rb +2 -6
  10. data/lib/rfcxml/v3/address.rb +2 -7
  11. data/lib/rfcxml/v3/annotation.rb +2 -15
  12. data/lib/rfcxml/v3/area.rb +1 -1
  13. data/lib/rfcxml/v3/artset.rb +2 -3
  14. data/lib/rfcxml/v3/artwork.rb +13 -10
  15. data/lib/rfcxml/v3/aside.rb +2 -12
  16. data/lib/rfcxml/v3/author.rb +16 -12
  17. data/lib/rfcxml/v3/back.rb +2 -5
  18. data/lib/rfcxml/v3/bcp14.rb +1 -1
  19. data/lib/rfcxml/v3/blockquote.rb +2 -26
  20. data/lib/rfcxml/v3/boilerplate.rb +2 -3
  21. data/lib/rfcxml/v3/br.rb +1 -1
  22. data/lib/rfcxml/v3/c.rb +2 -7
  23. data/lib/rfcxml/v3/city.rb +1 -1
  24. data/lib/rfcxml/v3/cityarea.rb +1 -1
  25. data/lib/rfcxml/v3/code.rb +1 -1
  26. data/lib/rfcxml/v3/contact.rb +2 -4
  27. data/lib/rfcxml/v3/country.rb +1 -1
  28. data/lib/rfcxml/v3/cref.rb +2 -11
  29. data/lib/rfcxml/v3/date.rb +4 -4
  30. data/lib/rfcxml/v3/dd.rb +2 -25
  31. data/lib/rfcxml/v3/displayreference.rb +1 -1
  32. data/lib/rfcxml/v3/dl.rb +2 -7
  33. data/lib/rfcxml/v3/dt.rb +2 -14
  34. data/lib/rfcxml/v3/email.rb +1 -1
  35. data/lib/rfcxml/v3/eref.rb +1 -1
  36. data/lib/rfcxml/v3/extaddr.rb +1 -1
  37. data/lib/rfcxml/v3/facsimile.rb +1 -1
  38. data/lib/rfcxml/v3/figure.rb +17 -19
  39. data/lib/rfcxml/v3/format.rb +1 -1
  40. data/lib/rfcxml/v3/front.rb +2 -13
  41. data/lib/rfcxml/v3/iref.rb +4 -3
  42. data/lib/rfcxml/v3/keyword.rb +1 -1
  43. data/lib/rfcxml/v3/li.rb +2 -28
  44. data/lib/rfcxml/v3/link.rb +1 -1
  45. data/lib/rfcxml/v3/list.rb +3 -4
  46. data/lib/rfcxml/v3/middle.rb +2 -3
  47. data/lib/rfcxml/v3/name.rb +2 -14
  48. data/lib/rfcxml/v3/note.rb +2 -7
  49. data/lib/rfcxml/v3/ol.rb +5 -4
  50. data/lib/rfcxml/v3/organization.rb +10 -5
  51. data/lib/rfcxml/v3/phone.rb +1 -1
  52. data/lib/rfcxml/v3/pobox.rb +1 -1
  53. data/lib/rfcxml/v3/postal.rb +2 -12
  54. data/lib/rfcxml/v3/postal_line.rb +1 -1
  55. data/lib/rfcxml/v3/postamble.rb +2 -7
  56. data/lib/rfcxml/v3/preamble.rb +2 -15
  57. data/lib/rfcxml/v3/refcontent.rb +2 -4
  58. data/lib/rfcxml/v3/reference.rb +7 -10
  59. data/lib/rfcxml/v3/referencegroup.rb +2 -3
  60. data/lib/rfcxml/v3/references.rb +2 -5
  61. data/lib/rfcxml/v3/region.rb +1 -1
  62. data/lib/rfcxml/v3/relref.rb +1 -1
  63. data/lib/rfcxml/v3/rfc.rb +62 -14
  64. data/lib/rfcxml/v3/section.rb +11 -21
  65. data/lib/rfcxml/v3/series_info.rb +5 -4
  66. data/lib/rfcxml/v3/sortingcode.rb +1 -1
  67. data/lib/rfcxml/v3/sourcecode.rb +13 -9
  68. data/lib/rfcxml/v3/spanx.rb +1 -1
  69. data/lib/rfcxml/v3/street.rb +1 -1
  70. data/lib/rfcxml/v3/strong.rb +6 -8
  71. data/lib/rfcxml/v3/sub.rb +6 -15
  72. data/lib/rfcxml/v3/sup.rb +2 -3
  73. data/lib/rfcxml/v3/table.rb +1 -7
  74. data/lib/rfcxml/v3/tbody.rb +1 -3
  75. data/lib/rfcxml/v3/td.rb +23 -26
  76. data/lib/rfcxml/v3/text.rb +2 -20
  77. data/lib/rfcxml/v3/texttable.rb +12 -12
  78. data/lib/rfcxml/v3/tfoot.rb +1 -3
  79. data/lib/rfcxml/v3/th.rb +1 -3
  80. data/lib/rfcxml/v3/thead.rb +1 -3
  81. data/lib/rfcxml/v3/title.rb +3 -4
  82. data/lib/rfcxml/v3/toc.rb +1 -3
  83. data/lib/rfcxml/v3/tr.rb +3 -4
  84. data/lib/rfcxml/v3/tt.rb +5 -19
  85. data/lib/rfcxml/v3/ttcol.rb +4 -7
  86. data/lib/rfcxml/v3/u.rb +1 -1
  87. data/lib/rfcxml/v3/ul.rb +10 -6
  88. data/lib/rfcxml/v3/uri.rb +1 -1
  89. data/lib/rfcxml/v3/vspace.rb +1 -1
  90. data/lib/rfcxml/v3/workgroup.rb +1 -1
  91. data/lib/rfcxml/v3/xref.rb +2 -3
  92. data/lib/rfcxml/v3/xref_text.rb +7 -16
  93. data/lib/rfcxml/v3.rb +100 -2
  94. data/lib/rfcxml/version.rb +1 -1
  95. data/lib/rfcxml.rb +3 -4
  96. data/rfcxml.gemspec +3 -2
  97. data/scripts/README.md +110 -0
  98. data/scripts/roundtrip_test.rb +361 -0
  99. metadata +9 -6
  100. data/lib/rfcxml/v3/em.rb +0 -14
data/lib/rfcxml/v3/tt.rb CHANGED
@@ -2,38 +2,24 @@
2
2
 
3
3
  require "lutaml/model"
4
4
 
5
- require_relative "bcp14"
6
- require_relative "br"
7
- require_relative "cref"
8
- require_relative "em"
9
- require_relative "eref"
10
- require_relative "iref"
11
- require_relative "relref"
12
- require_relative "strong"
13
- require_relative "sub"
14
- require_relative "sup"
15
- require_relative "xref"
16
-
17
5
  module Rfcxml
18
6
  module V3
19
- class Cref < Lutaml::Model::Serializable; end
20
-
21
7
  class Tt < Lutaml::Model::Serializable
22
8
  attribute :content, :string
23
9
  attribute :bcp14, Bcp14, collection: true
24
10
  attribute :br, Br, collection: true
25
11
  attribute :cref, Cref, collection: true
26
- attribute :em, Em, collection: true
12
+ attribute :em, "Rfcxml::V3::Em", collection: true
27
13
  attribute :eref, Eref, collection: true
28
14
  attribute :iref, Iref, collection: true
29
15
  attribute :relref, Relref, collection: true
30
- attribute :strong, Strong, collection: true
31
- attribute :sub, Sub, collection: true
32
- attribute :sup, Sup, collection: true
16
+ attribute :strong, "Rfcxml::V3::Strong", collection: true
17
+ attribute :sub, "Rfcxml::V3::Sub", collection: true
18
+ attribute :sup, "Rfcxml::V3::Sup", collection: true
33
19
  attribute :xref, Xref, collection: true
34
20
 
35
21
  xml do
36
- root "tt"
22
+ element "tt"
37
23
 
38
24
  map_content to: :content
39
25
  map_element "bcp14", to: :bcp14
@@ -2,24 +2,21 @@
2
2
 
3
3
  require "lutaml/model"
4
4
 
5
- require_relative "cref"
6
- require_relative "eref"
7
- require_relative "iref"
8
- require_relative "xref"
9
-
10
5
  module Rfcxml
11
6
  module V3
12
7
  class Ttcol < Lutaml::Model::Serializable
13
8
  attribute :content, :string
14
9
  attribute :width, :string
15
- attribute :align, :string, default: -> { "left" }
10
+ attribute :align, :string,
11
+ values: %w[left center right],
12
+ default: -> { "left" }
16
13
  attribute :cref, Cref, collection: true
17
14
  attribute :eref, Eref, collection: true
18
15
  attribute :iref, Iref, collection: true
19
16
  attribute :xref, Xref, collection: true
20
17
 
21
18
  xml do
22
- root "ttcol"
19
+ element "ttcol"
23
20
 
24
21
  map_content to: :content
25
22
  map_attribute "width", to: :width
data/lib/rfcxml/v3/u.rb CHANGED
@@ -12,7 +12,7 @@ module Rfcxml
12
12
  attribute :pn, :string
13
13
 
14
14
  xml do
15
- root "u"
15
+ element "u"
16
16
 
17
17
  map_content to: :content
18
18
  map_attribute "anchor", to: :anchor
data/lib/rfcxml/v3/ul.rb CHANGED
@@ -4,19 +4,23 @@ require "lutaml/model"
4
4
 
5
5
  module Rfcxml
6
6
  module V3
7
- class Li < Lutaml::Model::Serializable; end
8
-
9
7
  class Ul < Lutaml::Model::Serializable
10
8
  attribute :anchor, :string
11
- attribute :spacing, :string, default: -> { "normal" }
12
- attribute :empty, :string, default: -> { "false" }
13
- attribute :bare, :string, default: -> { "false" }
9
+ attribute :spacing, :string,
10
+ values: %w[normal compact],
11
+ default: -> { "normal" }
12
+ attribute :empty, :string,
13
+ values: %w[true false],
14
+ default: -> { "false" }
15
+ attribute :bare, :string,
16
+ values: %w[true false],
17
+ default: -> { "false" }
14
18
  attribute :indent, :string, default: -> { "3" }
15
19
  attribute :pn, :string
16
20
  attribute :li, Li, collection: true
17
21
 
18
22
  xml do
19
- root "ul"
23
+ element "ul"
20
24
 
21
25
  map_attribute "anchor", to: :anchor
22
26
  map_attribute "spacing", to: :spacing
data/lib/rfcxml/v3/uri.rb CHANGED
@@ -8,7 +8,7 @@ module Rfcxml
8
8
  attribute :content, :string
9
9
 
10
10
  xml do
11
- root "uri"
11
+ element "uri"
12
12
 
13
13
  map_content to: :content
14
14
  end
@@ -8,7 +8,7 @@ module Rfcxml
8
8
  attribute :blank_lines, :string, default: -> { "0" }
9
9
 
10
10
  xml do
11
- root "vspace"
11
+ element "vspace"
12
12
 
13
13
  map_attribute "blankLines", to: :blank_lines
14
14
  end
@@ -8,7 +8,7 @@ module Rfcxml
8
8
  attribute :content, :string
9
9
 
10
10
  xml do
11
- root "workgroup"
11
+ element "workgroup"
12
12
 
13
13
  map_content to: :content
14
14
  end
@@ -2,8 +2,6 @@
2
2
 
3
3
  require "lutaml/model"
4
4
 
5
- require_relative "xref_text"
6
-
7
5
  module Rfcxml
8
6
  module V3
9
7
  class Xref < Lutaml::Model::Serializable
@@ -19,7 +17,8 @@ module Rfcxml
19
17
  include XrefText
20
18
 
21
19
  xml do
22
- root "xref"
20
+ element "xref"
21
+ mixed_content
23
22
 
24
23
  map_content to: :content
25
24
  map_attribute "target", to: :target
@@ -1,28 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # require_relative "em"
4
- # require_relative "strong"
5
- # require_relative "sub"
6
- # require_relative "sup"
7
- # require_relative "tt"
8
3
  require "lutaml/model"
9
4
 
10
5
  module Rfcxml
11
6
  module V3
12
- class Strong < Lutaml::Model::Serializable; end
13
- class Em < Strong; end
14
- class Sub < Lutaml::Model::Serializable; end
15
- class Sup < Sub; end
16
- class Tt < Lutaml::Model::Serializable; end
17
-
7
+ # Mixin module for common text formatting elements
8
+ # Included by Xref, Refcontent, and other elements
18
9
  module XrefText
19
10
  def self.included(base)
20
11
  base.class_eval do
21
- attribute :em, ::Rfcxml::V3::Em, collection: true
22
- attribute :strong, V3::Strong, collection: true
23
- attribute :sub, V3::Sub, collection: true
24
- attribute :sup, V3::Sup, collection: true
25
- attribute :tt, V3::Tt, collection: true
12
+ attribute :em, "Rfcxml::V3::Em", collection: true
13
+ attribute :strong, "Rfcxml::V3::Strong", collection: true
14
+ attribute :sub, "Rfcxml::V3::Sub", collection: true
15
+ attribute :sup, "Rfcxml::V3::Sup", collection: true
16
+ attribute :tt, "Rfcxml::V3::Tt", collection: true
26
17
  end
27
18
  end
28
19
  end
data/lib/rfcxml/v3.rb CHANGED
@@ -1,8 +1,106 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "v3/rfc"
4
-
5
3
  module Rfcxml
6
4
  module V3
5
+ # Core document structure
6
+ autoload :Rfc, "#{__dir__}/v3/rfc"
7
+ autoload :Front, "#{__dir__}/v3/front"
8
+ autoload :Middle, "#{__dir__}/v3/middle"
9
+ autoload :Back, "#{__dir__}/v3/back"
10
+
11
+ # Front matter elements
12
+ autoload :Abstract, "#{__dir__}/v3/abstract"
13
+ autoload :Annotation, "#{__dir__}/v3/annotation"
14
+ autoload :Area, "#{__dir__}/v3/area"
15
+ autoload :Author, "#{__dir__}/v3/author"
16
+ autoload :Contact, "#{__dir__}/v3/contact"
17
+ autoload :Date, "#{__dir__}/v3/date"
18
+ autoload :Keyword, "#{__dir__}/v3/keyword"
19
+ autoload :Note, "#{__dir__}/v3/note"
20
+ autoload :Organization, "#{__dir__}/v3/organization"
21
+ autoload :Title, "#{__dir__}/v3/title"
22
+ autoload :Workgroup, "#{__dir__}/v3/workgroup"
23
+
24
+ # Address elements
25
+ autoload :Address, "#{__dir__}/v3/address"
26
+ autoload :City, "#{__dir__}/v3/city"
27
+ autoload :Cityarea, "#{__dir__}/v3/cityarea"
28
+ autoload :Country, "#{__dir__}/v3/country"
29
+ autoload :Email, "#{__dir__}/v3/email"
30
+ autoload :Extaddr, "#{__dir__}/v3/extaddr"
31
+ autoload :Facsimile, "#{__dir__}/v3/facsimile"
32
+ autoload :Phone, "#{__dir__}/v3/phone"
33
+ autoload :Pobox, "#{__dir__}/v3/pobox"
34
+ autoload :Postal, "#{__dir__}/v3/postal"
35
+ autoload :PostalLine, "#{__dir__}/v3/postal_line"
36
+ autoload :Region, "#{__dir__}/v3/region"
37
+ autoload :Sortingcode, "#{__dir__}/v3/sortingcode"
38
+ autoload :Street, "#{__dir__}/v3/street"
39
+ autoload :Uri, "#{__dir__}/v3/uri"
40
+
41
+ # Body elements
42
+ autoload :Section, "#{__dir__}/v3/section"
43
+ autoload :Aside, "#{__dir__}/v3/aside"
44
+ autoload :Blockquote, "#{__dir__}/v3/blockquote"
45
+ autoload :Boilerplate, "#{__dir__}/v3/boilerplate"
46
+ autoload :Figure, "#{__dir__}/v3/figure"
47
+ autoload :Ol, "#{__dir__}/v3/ol"
48
+ autoload :Ul, "#{__dir__}/v3/ul"
49
+ autoload :Li, "#{__dir__}/v3/li"
50
+ autoload :Dl, "#{__dir__}/v3/dl"
51
+ autoload :Dt, "#{__dir__}/v3/dt"
52
+ autoload :Dd, "#{__dir__}/v3/dd"
53
+ autoload :Table, "#{__dir__}/v3/table"
54
+ autoload :Tbody, "#{__dir__}/v3/tbody"
55
+ autoload :Tfoot, "#{__dir__}/v3/tfoot"
56
+ autoload :Thead, "#{__dir__}/v3/thead"
57
+ autoload :Tr, "#{__dir__}/v3/tr"
58
+ autoload :Td, "#{__dir__}/v3/td"
59
+ autoload :Th, "#{__dir__}/v3/th"
60
+
61
+ # Inline text elements
62
+ autoload :Bcp14, "#{__dir__}/v3/bcp14"
63
+ autoload :Br, "#{__dir__}/v3/br"
64
+ autoload :C, "#{__dir__}/v3/c"
65
+ autoload :Code, "#{__dir__}/v3/code"
66
+ autoload :Cref, "#{__dir__}/v3/cref"
67
+ autoload :Em, "#{__dir__}/v3/strong" # Em is defined in strong.rb
68
+ autoload :Eref, "#{__dir__}/v3/eref"
69
+ autoload :Iref, "#{__dir__}/v3/iref"
70
+ autoload :Name, "#{__dir__}/v3/name"
71
+ autoload :Postamble, "#{__dir__}/v3/postamble"
72
+ autoload :Preamble, "#{__dir__}/v3/preamble"
73
+ autoload :Relref, "#{__dir__}/v3/relref"
74
+ autoload :Spanx, "#{__dir__}/v3/spanx"
75
+ autoload :Strong, "#{__dir__}/v3/strong"
76
+ autoload :Sub, "#{__dir__}/v3/sub"
77
+ autoload :Sup, "#{__dir__}/v3/sup"
78
+ autoload :Tt, "#{__dir__}/v3/tt"
79
+ autoload :U, "#{__dir__}/v3/u"
80
+ autoload :Xref, "#{__dir__}/v3/xref"
81
+ autoload :XrefText, "#{__dir__}/v3/xref_text"
82
+
83
+ # Artwork and code elements
84
+ autoload :Artset, "#{__dir__}/v3/artset"
85
+ autoload :Artwork, "#{__dir__}/v3/artwork"
86
+ autoload :Sourcecode, "#{__dir__}/v3/sourcecode"
87
+
88
+ # References
89
+ autoload :Displayreference, "#{__dir__}/v3/displayreference"
90
+ autoload :Refcontent, "#{__dir__}/v3/refcontent"
91
+ autoload :Reference, "#{__dir__}/v3/reference"
92
+ autoload :Referencegroup, "#{__dir__}/v3/referencegroup"
93
+ autoload :References, "#{__dir__}/v3/references"
94
+
95
+ # Other elements
96
+ autoload :Format, "#{__dir__}/v3/format"
97
+ autoload :Link, "#{__dir__}/v3/link"
98
+ autoload :List, "#{__dir__}/v3/list"
99
+ autoload :SeriesInfo, "#{__dir__}/v3/series_info"
100
+ autoload :Text, "#{__dir__}/v3/text"
101
+ autoload :Texttable, "#{__dir__}/v3/texttable"
102
+ autoload :Toc, "#{__dir__}/v3/toc"
103
+ autoload :Ttcol, "#{__dir__}/v3/ttcol"
104
+ autoload :Vspace, "#{__dir__}/v3/vspace"
7
105
  end
8
106
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rfcxml
4
- VERSION = "0.2.1"
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/rfcxml.rb CHANGED
@@ -1,17 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
+ require "lutaml/xml"
4
5
 
5
6
  Lutaml::Model::Config.configure do |config|
6
- require "lutaml/model/xml_adapter/nokogiri_adapter"
7
- config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter
7
+ config.xml_adapter_type = :nokogiri
8
8
  end
9
9
 
10
10
  module Rfcxml
11
11
  class Error < StandardError; end
12
12
 
13
- # Your code goes here...
13
+ autoload :Version, "#{__dir__}/rfcxml/version"
14
14
  end
15
15
 
16
- require_relative "rfcxml/version"
17
16
  require_relative "rfcxml/v3"
data/rfcxml.gemspec CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.metadata["homepage_uri"] = spec.homepage
17
17
  spec.metadata["source_code_uri"] = spec.homepage
18
18
  spec.metadata["changelog_uri"] = "https://github.com/metanorma/rfcxml/releases"
19
+ spec.metadata["rubygems_mfa_required"] = "true"
19
20
 
20
21
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
21
22
  `git ls-files -z`
@@ -26,8 +27,8 @@ Gem::Specification.new do |spec|
26
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
28
  spec.require_paths = ["lib"]
28
29
 
29
- spec.required_ruby_version = ">= 2.7.0"
30
+ spec.required_ruby_version = ">= 3.2.0"
30
31
 
31
- spec.add_dependency "lutaml-model", "~> 0.7"
32
+ spec.add_dependency "lutaml-model", "~> 0.8.0"
32
33
  spec.add_dependency "nokogiri"
33
34
  end
data/scripts/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # RFC XML Round-Trip Test Script
2
+
3
+ ## Purpose
4
+
5
+ Test round-trip parsing of RFC XML v3 files using Canon gem for semantic comparison.
6
+
7
+ **Process:** XML → Parse → Serialize → Compare
8
+
9
+ ## Usage
10
+
11
+ ```bash
12
+ # Test single file
13
+ ruby scripts/roundtrip_test.rb spec/xmlsource-rfc8650-latest/rfc8704.xml
14
+
15
+ # Test multiple files
16
+ ruby scripts/roundtrip_test.rb file1.xml file2.xml file3.xml
17
+
18
+ # Test all files in directory
19
+ ruby scripts/roundtrip_test.rb spec/xmlsource-rfc8650-latest/
20
+
21
+ # Test with glob pattern
22
+ ruby scripts/roundtrip_test.rb "spec/xmlsource-rfc8650-latest/rfc87*.xml"
23
+
24
+ # Test all 920 files (default)
25
+ ruby scripts/roundtrip_test.rb
26
+ ```
27
+
28
+ ## Environment Variables
29
+
30
+ | Variable | Default | Description |
31
+ |-----------|---------|--------------------------------|
32
+ | `THREADS` | 8 | Number of worker threads |
33
+ | `VERBOSE` | false | Show per-file progress |
34
+
35
+ ```bash
36
+ THREADS=1 VERBOSE=1 ruby scripts/roundtrip_test.rb file.xml
37
+ ```
38
+
39
+ ## Output
40
+
41
+ Test results are written to `tmp/roundtrip-results-{timestamp}/`:
42
+
43
+ ```
44
+ tmp/roundtrip-results-20260318_200000/
45
+ SUMMARY.yml # Overall summary (YAML)
46
+ PASS_{filename} # Empty marker for passed tests
47
+ FAIL_{filename}.yml # Structured failure details
48
+ ERROR_{filename}.yml # Structured error details
49
+ SOURCE_{filename} # Round-tripped output for debugging
50
+ ```
51
+
52
+ ### SUMMARY.yml Structure
53
+
54
+ ```yaml
55
+ timestamp: "2026-03-18T20:00:00+08:00"
56
+ configuration:
57
+ threads: 8
58
+ files_tested: 920
59
+ elapsed_seconds: 664.75
60
+ results:
61
+ passed: 833
62
+ failed: 83
63
+ errors: 4
64
+ pass_rate: "90.5%"
65
+ failed_files:
66
+ - rfc8704.xml
67
+ - rfc8705.xml
68
+ error_files:
69
+ - rfc8650.xml
70
+ ```
71
+
72
+ ### FAIL_*.yml Structure
73
+
74
+ ```yaml
75
+ source_file: spec/xmlsource-rfc8650-latest/rfc8704.xml
76
+ status: failed
77
+ normative_differences: 1
78
+ total_differences: 267
79
+ differences:
80
+ - path: /rfc[1]/back[1]/references/reference/front/author
81
+ dimension: attribute_presence
82
+ reason: "only in first: initials, surname"
83
+ normative: true
84
+ formatting:
85
+ attributes_before: { initials: "", surname: "" }
86
+ attributes_after: {}
87
+ ```
88
+
89
+ ## Known Issues
90
+
91
+ ### Threading Bug (4 files)
92
+
93
+ When using `THREADS > 1`, some files fail with:
94
+ ```
95
+ NoMethodError: undefined method 'transform' for nil
96
+ ```
97
+
98
+ Affected files: rfc8650.xml, rfc8651.xml, rfc8654.xml, rfc8657.xml
99
+
100
+ **Workaround:** Use `THREADS=1` for these files.
101
+
102
+ ### Empty Attribute Handling
103
+
104
+ Some models need `value_map: { to: { empty: :empty } }` to preserve empty string attributes during round-trip.
105
+
106
+ ## Dependencies
107
+
108
+ - `rfcxml` gem - RFC XML parsing
109
+ - `canon` gem - Semantic XML comparison
110
+ - `lutaml-model` - XML serialization