lutaml-xsd 1.2.108 → 1.2.110

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: def3662a0159985a83f7dfe3244fcf778009f73059f3f91546d27c82028c428d
4
- data.tar.gz: 8e6407ce1e77da3ad839336277b24261be296780deab6fd46e63a220e9839909
3
+ metadata.gz: 16069a6293538146b585e29cf696a42e1294e9f8c211d075bcc8f03f44adcb8f
4
+ data.tar.gz: 1049c160550ac6905f09ecc512e06536137d9d4b13cade090cc83fc24b9c355c
5
5
  SHA512:
6
- metadata.gz: e6edc35350a096757383191fde7c38feb709c9dcc456375aab169b55b82d86ad8d9eb56c21879b31c1f5cac455da9fdfe756b76c269e30698af711deeb409ef9
7
- data.tar.gz: 6716b5ade73417dfe2b9726f092fb823e8cd8c63052481a85542c62eaec6771b1efa3f42287ccd07238836ab414595a526dba467589bea499690ce406aa68dd5
6
+ metadata.gz: 95556f997483a0c1b5b606c0047c7cfcb39f75b3dae29350a61b4613d78cfa7ec7c961fa4f6fe040e84000110aa92b1b87203cdb94cebcbc580ca6055f65c389
7
+ data.tar.gz: 689fa0a66e8cf18fe44bdaa7081095e631a1b49e6d67d44ba0f49edc6fcf1aaf35f5458ac0d12b901be4435240ecf9cd429b2b2bc7ff42dd94366dee3995db00
data/TODO.conformance.md CHANGED
@@ -513,6 +513,106 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
513
513
  extension-base walks thread the deriving type namespace through.
514
514
  STILL OPEN: schA1/schD10 (the hinted composition's CHILD value
515
515
  checks bind the no-ns int ct-A to the ns-b boolean children —
516
+ - CHAMELEON FORM-DEFAULT ROUND (2026-11-11): +1 Schema (schD10;
517
+ suite 4641-effective of 4696 with 5 measurement-budget exclusions,
518
+ zero regressions from this round; rspec 1662 green; rubocop clean).
519
+ RESOLVED BY THE SPEC, not by owner coin-flip: XSD 1.0 §4.2.1
520
+ clause 3.2 converts ONLY the absent target namespace on a
521
+ chameleon include (an exhaustive enumeration: named components'
522
+ {target namespace} + wildcard {namespace constraint}); §3.2.2 and
523
+ §3.3.2 read elementFormDefault/attributeFormDefault from each
524
+ declaration's OWN <schema> ancestor — the chameleon document — so
525
+ the includer's form defaults NEVER apply (schD10: the
526
+ defaults-absent chameleon's group members stay unqualified beside
527
+ a qualified includer). index_schema threads the adopted namespace
528
+ down includes unchanged and every declaration now reads its own
529
+ document's defaults; the includer-defaults threading is removed.
530
+ ctE018 unaffected (its documents share identical defaults — only
531
+ the namespace adoption ever mattered). New resolver specs pin both
532
+ properties (namespace adoption + own-document defaults).
533
+ MEASUREMENT PROVENANCE for this round's ledger: batch 4400 was
534
+ assembled from a per-case subprocess sweep with a 90s watchdog —
535
+ 45/45 measured pass, 5 excluded on budget
536
+ (Regex_w3c/reZ003v/005v/005i/006v/006i — the nested-repeat
537
+ instances drive our per-element walk into minutes-long quadratic
538
+ cost; reZ003v's verdict is probe-established true at 125s warm/
539
+ 410s cold; the others unestablished). Batches 200 and 300 needed
540
+ re-runs: the morning worker's attO009/011 + attZ014a/b failures
541
+ were TRANSIENTS (fresh re-runs 50/50; isolated probes pass with
542
+ this round's tree) — most plausibly poisoned by the mid-run
543
+ lockfile churn. NON-ROUND FINDINGS registered below: the moxml
544
+ 0.6.4 character-reference regression (train pinned back), the
545
+ schR2 stack overflow (masked by its expected-invalid expectation),
546
+ and the schG1/G4/G7 drift (fail in fresh isolation on origin/main
547
+ stash-verified — inputs/gems/ruby verified identical to the 4641
548
+ era; mechanism not isolated in-round; owner follow-up).
549
+ - NESTED-TYPE-CANDIDATES ROUND (2026-11-11): +2 (schG2 — a baseline
550
+ parked failure — and the schG1/G4/G7 "drift" trio resolved as REAL
551
+ DEFECTS, not environment: named_type_candidates appended only ONE
552
+ nested candidate per root schema — find_nested_named_type returned
553
+ the first depth-first match and stopped, so a composition importing
554
+ same-named types two levels deep (schG1: a→b→c) NEVER listed the
555
+ deepest candidate; the owner-ns preference missed and list.first
556
+ (ns-a's ct-A) typed the ns-c element — the '123'-is-not-boolean
557
+ swap. find_nested_named_types now collects EVERY match across the
558
+ whole nested tree in document order). SUITE 4637/4696 measured +
559
+ 5 budget exclusions (reZ nested-repeat, unchanged), ZERO
560
+ regressions (stash-attributed per row), rspec 1663 green,
561
+ rubocop clean. schR2 stack-overflow note unchanged (crash masked
562
+ by expected-invalid, counted per convention).
563
+ - SCH R2 STACK OVERFLOW (2026-11-11): Schema_w3c/schR2/schR2.i
564
+ (expected invalid) crashes the assessment with a SystemStackError
565
+ in lutaml-model 0.8.167's Base#resolved_element_order/
566
+ delete_deletables — an unguarded recursion over the cyclic
567
+ redefine graph schR2's documents build (called from our
568
+ collect_particles). The crash ESCAPES measure()'s rescue
569
+ (SystemStackError is not a StandardError); in every prior ledger
570
+ the case silently recorded as a pass via the crash-as-invalid
571
+ convention on its expected-invalid expectation, so the ledger
572
+ number never moved. Files/gems/ruby verified identical to the
573
+ baseline era; the crash reproduces in fresh single-case runs on
574
+ origin/main on both trains today. Finding for lutaml-model: a
575
+ cycle guard in resolved_element_order (our org's repo; owner
576
+ decides the upstream action).
577
+ - TRAIN ADOPTION REGRESSION — CHARACTER REFERENCES (2026-11-11):
578
+ the 2026-11-10 adoption verdict ("conformance-IDENTICAL") was
579
+ WRONG for one class: moxml 0.6.4 stopped decoding numeric
580
+ character references in attribute values. Minimal repro:
581
+ `Moxml::Context.new.parse('<x a="&#x2190;"/>').root.attributes.
582
+ first.value` → "←" on moxml 0.6.2, literal "&#x2190;" on 0.6.4.
583
+ Downstream this breaks the whole UNICODE-BLOCK pattern-facet
584
+ class — Regex_w3c Arrows/MathematicalOperators/
585
+ ArabicPresentationForms-A/CJKCompatibilityForms/
586
+ HalfwidthandFullwidthForms/Specials etc. validate on
587
+ moxml 0.6.2 + leptris 1.9.406.0 and fail on 0.6.4/1.9.415.0
588
+ (attribute_pattern_violation on character-reference values,
589
+ e.g. Regex_w3c/Arrows/Arrows.v). The adoption's 94-batch diff
590
+ compared TOTALS against the old-train baseline; the per-batch
591
+ regression class slipped through (baseline_4641's batch_04400
592
+ was 50/50 old-train). The pattern facet path itself is our Ruby
593
+ XsdRegex — the drift sits in the ENGINE's attribute-value
594
+ parsing. VERDICT: the measurement train is PINNED BACK to
595
+ moxml 0.6.2 + leptris 1.9.406.0 (the baseline's train; untracked
596
+ Gemfile.lock) until moxml restores character-reference decoding;
597
+ the finding goes to our moxml/leptris repos with the minimal
598
+ repro for the owner to act on. The 2026-11-10 adoption entry
599
+ above is superseded by this one.
600
+ - TRAIN ADOPTION (2026-11-10): the measurement train moves to
601
+ moxml 0.6.4 + leptris 1.9.415.0 (from the pin-back's 0.6.2 +
602
+ 1.9.406.0; local Gemfile.lock only — untracked, and the gemspec
603
+ floors already admit both). VERDICT: conformance-IDENTICAL —
604
+ 4640/4696 = 98.81%, zero regressions and zero fixes against the
605
+ verified 4640 baseline across all 94 batches. The moxml team's
606
+ wave report (#529 5 cases + #522 attgD 16/16 "fixed") does NOT
607
+ translate through our pipeline — the attgD/attgC survivors remain
608
+ failing identically on the new train; their facade verdicts and
609
+ our pipeline reading still disagree (registered, not chased).
610
+ A first adoption attempt measured on a STALE branch (pre-rounds
611
+ A-G) produced 198 phantom regressions — the tree, not the train;
612
+ discarded with the branch. The remaining register is unchanged:
613
+ schD10 (owner decision), the disputed/contested set, the
614
+ moxml-rs engine arcs.
615
+
516
616
  'true' vs xsd:int — the per-child type plumbing under hint
517
617
  - PARENT-CONTEXT ROUND G (2026-11-09): +1 Additional (addB188;
518
618
  suite 4639->4640 = 98.81%, pending measure confirm). AN UNDECLARED
@@ -290,8 +290,8 @@ module Lutaml
290
290
  end
291
291
  list << found if found
292
292
 
293
- nested = find_nested_named_type(local_name, schema)
294
- list << nested if nested
293
+ nested = find_nested_named_types(local_name, schema)
294
+ list.concat(nested)
295
295
  end
296
296
  unless @redefined_body_names.include?(local_name)
297
297
  @redefined_targets.each do |schema|
@@ -307,16 +307,18 @@ module Lutaml
307
307
  cache[local_name] = list.uniq
308
308
  end
309
309
 
310
- # Named types declared in documents reached through resolved
311
- # includes/imports — chameleon types (ctE018) live in a
312
- # no-namespace include target.
310
+ # EVERY same-named type across the whole nested include/import
311
+ # tree, in document order. The single-match walk stopped at the
312
+ # FIRST hit (schG1: ns-b's ct-A shadowed ns-c's two imports
313
+ # deep, so the owner-ns preference missed and ns-a's type won
314
+ # for the ns-c element — a same-local-name swap).
313
315
  #
314
- # @return [Object, nil]
315
- def find_nested_named_type(local_name, schema, depth = 0)
316
- return nil if depth > 8
316
+ # @return [Array<Object>]
317
+ def find_nested_named_types(local_name, schema, depth = 0)
318
+ return [] if depth > 8
317
319
 
318
- (Array(schema.include) + Array(schema.import)).each do |nested|
319
- next unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
320
+ (Array(schema.include) + Array(schema.import)).flat_map do |nested|
321
+ next [] unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
320
322
 
321
323
  found = Array(nested.complex_type).find do |ct|
322
324
  ct.name == local_name
@@ -324,12 +326,9 @@ module Lutaml
324
326
  found ||= Array(nested.simple_type).find do |st|
325
327
  st.name == local_name
326
328
  end
327
- return found if found
328
-
329
- found = find_nested_named_type(local_name, nested, depth + 1)
330
- return found if found
329
+ [found, *find_nested_named_types(local_name, nested, depth + 1)]
330
+ .compact
331
331
  end
332
- nil
333
332
  end
334
333
 
335
334
  # Builtin numeric types: values compare in the numeric value
@@ -1037,27 +1036,30 @@ module Lutaml
1037
1036
  end
1038
1037
 
1039
1038
  def index_schema(index, schema, held_signatures = [],
1040
- chameleon_namespace = nil,
1041
- chameleon_includer = nil)
1039
+ chameleon_namespace = nil)
1042
1040
  # A no-namespace document reached through xs:include is a
1043
- # chameleon: its declarations adopt the includer's target
1044
- # namespace AND form/derivation defaults (ctE018).
1041
+ # chameleon: ONLY its absent target namespace converts to the
1042
+ # includer's (XSD 1.0 §4.2.1 clause 3.2). Form and derivation
1043
+ # defaults are read from each declaration's OWN <schema>
1044
+ # ancestor — the chameleon document — because §3.2.2/§3.3.2
1045
+ # map form against the <schema> ancestor of the declaration,
1046
+ # which the namespace conversion never replaces (schD10:
1047
+ # unprefixed group members of a defaults-absent chameleon
1048
+ # stay unqualified beside a qualified includer).
1045
1049
  raw_namespace = schema.target_namespace
1046
1050
  chameleon = raw_namespace.to_s.empty? && chameleon_namespace
1047
1051
  namespace = chameleon ? chameleon_namespace : raw_namespace
1048
- defaults_schema = chameleon ? chameleon_includer : schema
1049
1052
  register_ref_namespaces(schema)
1050
1053
  Array(schema.element).each do |element|
1051
- index_element(index, element, namespace, :top, defaults_schema)
1054
+ index_element(index, element, namespace, :top, schema)
1052
1055
  # A global element's INLINE complexType carries local
1053
1056
  # attribute declarations too — their form resolution was
1054
1057
  # only indexed for named types (idG027/idH025).
1055
- index_local_attributes(element.complex_type, namespace,
1056
- defaults_schema)
1058
+ index_local_attributes(element.complex_type, namespace, schema)
1057
1059
  end
1058
1060
  Array(schema.complex_type).each do |complex_type|
1059
1061
  index_type(index, complex_type, namespace, schema)
1060
- index_local_attributes(complex_type, namespace, defaults_schema)
1062
+ index_local_attributes(complex_type, namespace, schema)
1061
1063
  end
1062
1064
  Array(schema.attribute).each do |attribute|
1063
1065
  index_attribute(attribute, namespace)
@@ -1070,13 +1072,12 @@ module Lutaml
1070
1072
  # (wildZ013c), a named document's against its own.
1071
1073
  @namespaces[group] = namespace unless name.empty?
1072
1074
  Array(group.attribute).each do |member|
1073
- index_local_attribute(member, namespace, defaults_schema)
1075
+ index_local_attribute(member, namespace, schema)
1074
1076
  end
1075
1077
  end
1076
1078
  Array(schema.group).each do |group|
1077
1079
  each_particle_element(group, schema) do |element|
1078
- index_element(index, element, namespace, :inline,
1079
- defaults_schema)
1080
+ index_element(index, element, namespace, :inline, schema)
1080
1081
  end
1081
1082
  end
1082
1083
  # lutaml-model nests resolved xs:import / xs:include targets
@@ -1088,8 +1089,7 @@ module Lutaml
1088
1089
  next unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
1089
1090
  next if held_signatures.include?(schema_signature(nested))
1090
1091
 
1091
- index_schema(index, nested, held_signatures, namespace,
1092
- defaults_schema)
1092
+ index_schema(index, nested, held_signatures, namespace)
1093
1093
  end
1094
1094
  Array(schema.import).each do |nested|
1095
1095
  next unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
@@ -1107,8 +1107,7 @@ module Lutaml
1107
1107
  # indexed under the name (attgC007/attgD036). Runs after the
1108
1108
  # nested descent so included declarations are already in.
1109
1109
  Array(schema.redefine).each do |red|
1110
- index_redefine(index, schema, red, held_signatures, namespace,
1111
- defaults_schema)
1110
+ index_redefine(index, schema, red, held_signatures, namespace)
1112
1111
  end
1113
1112
  end
1114
1113
 
@@ -1120,8 +1119,7 @@ module Lutaml
1120
1119
  # declaration is kept for that hook and the redefining body
1121
1120
  # indexed under the name (attgC007/attgD036). Runs after the
1122
1121
  # nested descent so included declarations are already in.
1123
- def index_redefine(index, schema, red, held_signatures, namespace,
1124
- defaults_schema)
1122
+ def index_redefine(index, schema, red, held_signatures, namespace)
1125
1123
  target_path = nil
1126
1124
  base = begin
1127
1125
  File.dirname(@repository.source_path_for(schema))
@@ -1138,8 +1136,7 @@ module Lutaml
1138
1136
  File.read(target_path), location: target_path
1139
1137
  )
1140
1138
  @redefined_targets << target
1141
- index_schema(index, target, held_signatures, namespace,
1142
- defaults_schema)
1139
+ index_schema(index, target, held_signatures, namespace)
1143
1140
  rescue StandardError
1144
1141
  nil
1145
1142
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.108"
5
+ VERSION = "1.2.110"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-xsd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.108
4
+ version: 1.2.110
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-11-10 00:00:00.000000000 Z
11
+ date: 2026-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid