lutaml-xsd 1.2.107 → 1.2.109

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: b843055f187b9adc7ae34af1339b816cb4b12ed2344a8f382834e71ef35a5b10
4
- data.tar.gz: 44f4c02f0f34551654141814cd66a6277f20798bde5ab41505af0d305b682e93
3
+ metadata.gz: 1b72159d7cf64cd93b73f0cc4e9801dfa46c57b4aba669421395ae0faa88cc6d
4
+ data.tar.gz: c6b1f7d7ecf76b6d9deb32ec13a261d70c87d7292c01be0f61e9b5ed0a1d0646
5
5
  SHA512:
6
- metadata.gz: 01dbddc2fa3db632db3b459bc999405304d58e1fc9bce88b634dd072e7f2f04b902e4c20d2ba38669ba759b98d190f060522d44ce155424b5443d2616d8125c0
7
- data.tar.gz: 64fbb3c90b06aa7cf43b921451377f8955c726f9c1ed600bfdf42cae73e994cfb1dd9c68dc279733be0e640d2dcc8f4d03386d457e4711ddcb84840b5adde6b1
6
+ metadata.gz: 6cfc032057ed3bbf9048ae3f0a8b8f9ff2b75eed8553e323089e3c79c1918ae883d3d16dd5dfb352e2f6ee63f2fee409865cbb93e7af36ed49d9ea41c9b1814f
7
+ data.tar.gz: d140656abba61dd935ae4ecc166d8f0dafa612d65a011c9acc56cf17e59393381dbcc5fe6888431094255e4b0762546da3f8320651c36fb3bd0eb01dc54d3585
data/TODO.conformance.md CHANGED
@@ -513,7 +513,110 @@ 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
+ - SCH R2 STACK OVERFLOW (2026-11-11): Schema_w3c/schR2/schR2.i
550
+ (expected invalid) crashes the assessment with a SystemStackError
551
+ in lutaml-model 0.8.167's Base#resolved_element_order/
552
+ delete_deletables — an unguarded recursion over the cyclic
553
+ redefine graph schR2's documents build (called from our
554
+ collect_particles). The crash ESCAPES measure()'s rescue
555
+ (SystemStackError is not a StandardError); in every prior ledger
556
+ the case silently recorded as a pass via the crash-as-invalid
557
+ convention on its expected-invalid expectation, so the ledger
558
+ number never moved. Files/gems/ruby verified identical to the
559
+ baseline era; the crash reproduces in fresh single-case runs on
560
+ origin/main on both trains today. Finding for lutaml-model: a
561
+ cycle guard in resolved_element_order (our org's repo; owner
562
+ decides the upstream action).
563
+ - TRAIN ADOPTION REGRESSION — CHARACTER REFERENCES (2026-11-11):
564
+ the 2026-11-10 adoption verdict ("conformance-IDENTICAL") was
565
+ WRONG for one class: moxml 0.6.4 stopped decoding numeric
566
+ character references in attribute values. Minimal repro:
567
+ `Moxml::Context.new.parse('<x a="&#x2190;"/>').root.attributes.
568
+ first.value` → "←" on moxml 0.6.2, literal "&#x2190;" on 0.6.4.
569
+ Downstream this breaks the whole UNICODE-BLOCK pattern-facet
570
+ class — Regex_w3c Arrows/MathematicalOperators/
571
+ ArabicPresentationForms-A/CJKCompatibilityForms/
572
+ HalfwidthandFullwidthForms/Specials etc. validate on
573
+ moxml 0.6.2 + leptris 1.9.406.0 and fail on 0.6.4/1.9.415.0
574
+ (attribute_pattern_violation on character-reference values,
575
+ e.g. Regex_w3c/Arrows/Arrows.v). The adoption's 94-batch diff
576
+ compared TOTALS against the old-train baseline; the per-batch
577
+ regression class slipped through (baseline_4641's batch_04400
578
+ was 50/50 old-train). The pattern facet path itself is our Ruby
579
+ XsdRegex — the drift sits in the ENGINE's attribute-value
580
+ parsing. VERDICT: the measurement train is PINNED BACK to
581
+ moxml 0.6.2 + leptris 1.9.406.0 (the baseline's train; untracked
582
+ Gemfile.lock) until moxml restores character-reference decoding;
583
+ the finding goes to our moxml/leptris repos with the minimal
584
+ repro for the owner to act on. The 2026-11-10 adoption entry
585
+ above is superseded by this one.
586
+ - TRAIN ADOPTION (2026-11-10): the measurement train moves to
587
+ moxml 0.6.4 + leptris 1.9.415.0 (from the pin-back's 0.6.2 +
588
+ 1.9.406.0; local Gemfile.lock only — untracked, and the gemspec
589
+ floors already admit both). VERDICT: conformance-IDENTICAL —
590
+ 4640/4696 = 98.81%, zero regressions and zero fixes against the
591
+ verified 4640 baseline across all 94 batches. The moxml team's
592
+ wave report (#529 5 cases + #522 attgD 16/16 "fixed") does NOT
593
+ translate through our pipeline — the attgD/attgC survivors remain
594
+ failing identically on the new train; their facade verdicts and
595
+ our pipeline reading still disagree (registered, not chased).
596
+ A first adoption attempt measured on a STALE branch (pre-rounds
597
+ A-G) produced 198 phantom regressions — the tree, not the train;
598
+ discarded with the branch. The remaining register is unchanged:
599
+ schD10 (owner decision), the disputed/contested set, the
600
+ moxml-rs engine arcs.
601
+
516
602
  'true' vs xsd:int — the per-child type plumbing under hint
603
+ - PARENT-CONTEXT ROUND G (2026-11-09): +1 Additional (addB188;
604
+ suite 4639->4640 = 98.81%, pending measure confirm). AN UNDECLARED
605
+ element anchored by a RESOLVABLE xsi:type assesses against that
606
+ named type (XSD assessment semantics; addB188: the root's
607
+ attributes check against t — xml:blah2 is undeclared and rejects,
608
+ while addB187's DECLARED xml:blah passes). The capability audit
609
+ the first dispatch attempt needed: resolver content_model_for +
610
+ attribute/structure/type rules tolerate ComplexType schema
611
+ arguments (the occurrence rule's schema_argument →
612
+ content_model_for was the crasher); the structure rule anchors the
613
+ instance's OWN name for assessed types; xml:-prefixed attribute
614
+ refs resolve through the imported xml-namespace schema (whose
615
+ documents carry NO target namespace — the declaration lives under
616
+ no namespace, so the exact-ns match admits it only for
617
+ xml-qualified instance attributes). PARKED: schD10 (chameleon
618
+ form-default owner decision).
619
+
517
620
  layering), full type-redefine body semantics.
518
621
  - PARENT-CONTEXT ROUND F (2026-11-09): +1 Element (QFE1700c1;
519
622
  suite 4638->4639 = 98.79%, pending measure confirm). THE
@@ -534,6 +637,15 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
534
637
  and the greedy walk receiving raw nodes while the memo keyed
535
638
  wrappers. PARKED: addB188 (ComplexType-capability audit),
536
639
  schD10 (chameleon form-default owner decision).
640
+ CORRECTION (2026-11-10): the claims mechanism below was LOST —
641
+ a concurrent reset --hard wiped the code commit before its push,
642
+ and only this registration rode out with PR #252. QFE1700c1 is
643
+ NOT fixed: the 1.2.107-era "pass" was a crash-as-invalid artifact
644
+ (the orphaned consult crashed skip-wildcard cases into
645
+ unassessable verdicts). The mechanism is RE-LANDED (round H,
646
+ 2026-11-10: the NFA records the leftmost assignment and the
647
+ suppression consults it — a correctness property; the 4640 score
648
+ was already delivered by the round G tree, QFE1700c1 included).
537
649
 
538
650
  - RIDE-407 PIN-BACK (2026-11-05): the leptris 1.9.407.0 + moxml
539
651
  - PARENT-CONTEXT ROUND E (2026-11-09): +2 (Schema schA1,
@@ -392,24 +392,6 @@
392
392
  "node": ">=12"
393
393
  }
394
394
  },
395
- "node_modules/@esbuild/netbsd-arm64": {
396
- "version": "0.28.0",
397
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz",
398
- "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==",
399
- "cpu": [
400
- "arm64"
401
- ],
402
- "dev": true,
403
- "license": "MIT",
404
- "optional": true,
405
- "os": [
406
- "netbsd"
407
- ],
408
- "peer": true,
409
- "engines": {
410
- "node": ">=18"
411
- }
412
- },
413
395
  "node_modules/@esbuild/netbsd-x64": {
414
396
  "version": "0.21.5",
415
397
  "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
@@ -427,24 +409,6 @@
427
409
  "node": ">=12"
428
410
  }
429
411
  },
430
- "node_modules/@esbuild/openbsd-arm64": {
431
- "version": "0.28.0",
432
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz",
433
- "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==",
434
- "cpu": [
435
- "arm64"
436
- ],
437
- "dev": true,
438
- "license": "MIT",
439
- "optional": true,
440
- "os": [
441
- "openbsd"
442
- ],
443
- "peer": true,
444
- "engines": {
445
- "node": ">=18"
446
- }
447
- },
448
412
  "node_modules/@esbuild/openbsd-x64": {
449
413
  "version": "0.21.5",
450
414
  "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
@@ -462,24 +426,6 @@
462
426
  "node": ">=12"
463
427
  }
464
428
  },
465
- "node_modules/@esbuild/openharmony-arm64": {
466
- "version": "0.28.0",
467
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz",
468
- "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==",
469
- "cpu": [
470
- "arm64"
471
- ],
472
- "dev": true,
473
- "license": "MIT",
474
- "optional": true,
475
- "os": [
476
- "openharmony"
477
- ],
478
- "peer": true,
479
- "engines": {
480
- "node": ">=18"
481
- }
482
- },
483
429
  "node_modules/@esbuild/sunos-x64": {
484
430
  "version": "0.21.5",
485
431
  "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
@@ -2810,420 +2756,6 @@
2810
2756
  }
2811
2757
  }
2812
2758
  },
2813
- "node_modules/vitest/node_modules/@esbuild/aix-ppc64": {
2814
- "version": "0.28.0",
2815
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz",
2816
- "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==",
2817
- "cpu": [
2818
- "ppc64"
2819
- ],
2820
- "dev": true,
2821
- "license": "MIT",
2822
- "optional": true,
2823
- "os": [
2824
- "aix"
2825
- ],
2826
- "peer": true,
2827
- "engines": {
2828
- "node": ">=18"
2829
- }
2830
- },
2831
- "node_modules/vitest/node_modules/@esbuild/android-arm": {
2832
- "version": "0.28.0",
2833
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz",
2834
- "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==",
2835
- "cpu": [
2836
- "arm"
2837
- ],
2838
- "dev": true,
2839
- "license": "MIT",
2840
- "optional": true,
2841
- "os": [
2842
- "android"
2843
- ],
2844
- "peer": true,
2845
- "engines": {
2846
- "node": ">=18"
2847
- }
2848
- },
2849
- "node_modules/vitest/node_modules/@esbuild/android-arm64": {
2850
- "version": "0.28.0",
2851
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz",
2852
- "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==",
2853
- "cpu": [
2854
- "arm64"
2855
- ],
2856
- "dev": true,
2857
- "license": "MIT",
2858
- "optional": true,
2859
- "os": [
2860
- "android"
2861
- ],
2862
- "peer": true,
2863
- "engines": {
2864
- "node": ">=18"
2865
- }
2866
- },
2867
- "node_modules/vitest/node_modules/@esbuild/android-x64": {
2868
- "version": "0.28.0",
2869
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz",
2870
- "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==",
2871
- "cpu": [
2872
- "x64"
2873
- ],
2874
- "dev": true,
2875
- "license": "MIT",
2876
- "optional": true,
2877
- "os": [
2878
- "android"
2879
- ],
2880
- "peer": true,
2881
- "engines": {
2882
- "node": ">=18"
2883
- }
2884
- },
2885
- "node_modules/vitest/node_modules/@esbuild/darwin-arm64": {
2886
- "version": "0.28.0",
2887
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz",
2888
- "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==",
2889
- "cpu": [
2890
- "arm64"
2891
- ],
2892
- "dev": true,
2893
- "license": "MIT",
2894
- "optional": true,
2895
- "os": [
2896
- "darwin"
2897
- ],
2898
- "peer": true,
2899
- "engines": {
2900
- "node": ">=18"
2901
- }
2902
- },
2903
- "node_modules/vitest/node_modules/@esbuild/darwin-x64": {
2904
- "version": "0.28.0",
2905
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz",
2906
- "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==",
2907
- "cpu": [
2908
- "x64"
2909
- ],
2910
- "dev": true,
2911
- "license": "MIT",
2912
- "optional": true,
2913
- "os": [
2914
- "darwin"
2915
- ],
2916
- "peer": true,
2917
- "engines": {
2918
- "node": ">=18"
2919
- }
2920
- },
2921
- "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": {
2922
- "version": "0.28.0",
2923
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz",
2924
- "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==",
2925
- "cpu": [
2926
- "arm64"
2927
- ],
2928
- "dev": true,
2929
- "license": "MIT",
2930
- "optional": true,
2931
- "os": [
2932
- "freebsd"
2933
- ],
2934
- "peer": true,
2935
- "engines": {
2936
- "node": ">=18"
2937
- }
2938
- },
2939
- "node_modules/vitest/node_modules/@esbuild/freebsd-x64": {
2940
- "version": "0.28.0",
2941
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz",
2942
- "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==",
2943
- "cpu": [
2944
- "x64"
2945
- ],
2946
- "dev": true,
2947
- "license": "MIT",
2948
- "optional": true,
2949
- "os": [
2950
- "freebsd"
2951
- ],
2952
- "peer": true,
2953
- "engines": {
2954
- "node": ">=18"
2955
- }
2956
- },
2957
- "node_modules/vitest/node_modules/@esbuild/linux-arm": {
2958
- "version": "0.28.0",
2959
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz",
2960
- "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==",
2961
- "cpu": [
2962
- "arm"
2963
- ],
2964
- "dev": true,
2965
- "license": "MIT",
2966
- "optional": true,
2967
- "os": [
2968
- "linux"
2969
- ],
2970
- "peer": true,
2971
- "engines": {
2972
- "node": ">=18"
2973
- }
2974
- },
2975
- "node_modules/vitest/node_modules/@esbuild/linux-arm64": {
2976
- "version": "0.28.0",
2977
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz",
2978
- "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==",
2979
- "cpu": [
2980
- "arm64"
2981
- ],
2982
- "dev": true,
2983
- "license": "MIT",
2984
- "optional": true,
2985
- "os": [
2986
- "linux"
2987
- ],
2988
- "peer": true,
2989
- "engines": {
2990
- "node": ">=18"
2991
- }
2992
- },
2993
- "node_modules/vitest/node_modules/@esbuild/linux-ia32": {
2994
- "version": "0.28.0",
2995
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz",
2996
- "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==",
2997
- "cpu": [
2998
- "ia32"
2999
- ],
3000
- "dev": true,
3001
- "license": "MIT",
3002
- "optional": true,
3003
- "os": [
3004
- "linux"
3005
- ],
3006
- "peer": true,
3007
- "engines": {
3008
- "node": ">=18"
3009
- }
3010
- },
3011
- "node_modules/vitest/node_modules/@esbuild/linux-loong64": {
3012
- "version": "0.28.0",
3013
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz",
3014
- "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==",
3015
- "cpu": [
3016
- "loong64"
3017
- ],
3018
- "dev": true,
3019
- "license": "MIT",
3020
- "optional": true,
3021
- "os": [
3022
- "linux"
3023
- ],
3024
- "peer": true,
3025
- "engines": {
3026
- "node": ">=18"
3027
- }
3028
- },
3029
- "node_modules/vitest/node_modules/@esbuild/linux-mips64el": {
3030
- "version": "0.28.0",
3031
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz",
3032
- "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==",
3033
- "cpu": [
3034
- "mips64el"
3035
- ],
3036
- "dev": true,
3037
- "license": "MIT",
3038
- "optional": true,
3039
- "os": [
3040
- "linux"
3041
- ],
3042
- "peer": true,
3043
- "engines": {
3044
- "node": ">=18"
3045
- }
3046
- },
3047
- "node_modules/vitest/node_modules/@esbuild/linux-ppc64": {
3048
- "version": "0.28.0",
3049
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz",
3050
- "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==",
3051
- "cpu": [
3052
- "ppc64"
3053
- ],
3054
- "dev": true,
3055
- "license": "MIT",
3056
- "optional": true,
3057
- "os": [
3058
- "linux"
3059
- ],
3060
- "peer": true,
3061
- "engines": {
3062
- "node": ">=18"
3063
- }
3064
- },
3065
- "node_modules/vitest/node_modules/@esbuild/linux-riscv64": {
3066
- "version": "0.28.0",
3067
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz",
3068
- "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==",
3069
- "cpu": [
3070
- "riscv64"
3071
- ],
3072
- "dev": true,
3073
- "license": "MIT",
3074
- "optional": true,
3075
- "os": [
3076
- "linux"
3077
- ],
3078
- "peer": true,
3079
- "engines": {
3080
- "node": ">=18"
3081
- }
3082
- },
3083
- "node_modules/vitest/node_modules/@esbuild/linux-s390x": {
3084
- "version": "0.28.0",
3085
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz",
3086
- "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==",
3087
- "cpu": [
3088
- "s390x"
3089
- ],
3090
- "dev": true,
3091
- "license": "MIT",
3092
- "optional": true,
3093
- "os": [
3094
- "linux"
3095
- ],
3096
- "peer": true,
3097
- "engines": {
3098
- "node": ">=18"
3099
- }
3100
- },
3101
- "node_modules/vitest/node_modules/@esbuild/linux-x64": {
3102
- "version": "0.28.0",
3103
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz",
3104
- "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==",
3105
- "cpu": [
3106
- "x64"
3107
- ],
3108
- "dev": true,
3109
- "license": "MIT",
3110
- "optional": true,
3111
- "os": [
3112
- "linux"
3113
- ],
3114
- "peer": true,
3115
- "engines": {
3116
- "node": ">=18"
3117
- }
3118
- },
3119
- "node_modules/vitest/node_modules/@esbuild/netbsd-x64": {
3120
- "version": "0.28.0",
3121
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz",
3122
- "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==",
3123
- "cpu": [
3124
- "x64"
3125
- ],
3126
- "dev": true,
3127
- "license": "MIT",
3128
- "optional": true,
3129
- "os": [
3130
- "netbsd"
3131
- ],
3132
- "peer": true,
3133
- "engines": {
3134
- "node": ">=18"
3135
- }
3136
- },
3137
- "node_modules/vitest/node_modules/@esbuild/openbsd-x64": {
3138
- "version": "0.28.0",
3139
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz",
3140
- "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==",
3141
- "cpu": [
3142
- "x64"
3143
- ],
3144
- "dev": true,
3145
- "license": "MIT",
3146
- "optional": true,
3147
- "os": [
3148
- "openbsd"
3149
- ],
3150
- "peer": true,
3151
- "engines": {
3152
- "node": ">=18"
3153
- }
3154
- },
3155
- "node_modules/vitest/node_modules/@esbuild/sunos-x64": {
3156
- "version": "0.28.0",
3157
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz",
3158
- "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==",
3159
- "cpu": [
3160
- "x64"
3161
- ],
3162
- "dev": true,
3163
- "license": "MIT",
3164
- "optional": true,
3165
- "os": [
3166
- "sunos"
3167
- ],
3168
- "peer": true,
3169
- "engines": {
3170
- "node": ">=18"
3171
- }
3172
- },
3173
- "node_modules/vitest/node_modules/@esbuild/win32-arm64": {
3174
- "version": "0.28.0",
3175
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz",
3176
- "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==",
3177
- "cpu": [
3178
- "arm64"
3179
- ],
3180
- "dev": true,
3181
- "license": "MIT",
3182
- "optional": true,
3183
- "os": [
3184
- "win32"
3185
- ],
3186
- "peer": true,
3187
- "engines": {
3188
- "node": ">=18"
3189
- }
3190
- },
3191
- "node_modules/vitest/node_modules/@esbuild/win32-ia32": {
3192
- "version": "0.28.0",
3193
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz",
3194
- "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==",
3195
- "cpu": [
3196
- "ia32"
3197
- ],
3198
- "dev": true,
3199
- "license": "MIT",
3200
- "optional": true,
3201
- "os": [
3202
- "win32"
3203
- ],
3204
- "peer": true,
3205
- "engines": {
3206
- "node": ">=18"
3207
- }
3208
- },
3209
- "node_modules/vitest/node_modules/@esbuild/win32-x64": {
3210
- "version": "0.28.0",
3211
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz",
3212
- "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==",
3213
- "cpu": [
3214
- "x64"
3215
- ],
3216
- "dev": true,
3217
- "license": "MIT",
3218
- "optional": true,
3219
- "os": [
3220
- "win32"
3221
- ],
3222
- "peer": true,
3223
- "engines": {
3224
- "node": ">=18"
3225
- }
3226
- },
3227
2759
  "node_modules/vitest/node_modules/@vitest/mocker": {
3228
2760
  "version": "4.1.8",
3229
2761
  "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.8.tgz",
@@ -3251,50 +2783,6 @@
3251
2783
  }
3252
2784
  }
3253
2785
  },
3254
- "node_modules/vitest/node_modules/esbuild": {
3255
- "version": "0.28.0",
3256
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz",
3257
- "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==",
3258
- "dev": true,
3259
- "hasInstallScript": true,
3260
- "license": "MIT",
3261
- "optional": true,
3262
- "peer": true,
3263
- "bin": {
3264
- "esbuild": "bin/esbuild"
3265
- },
3266
- "engines": {
3267
- "node": ">=18"
3268
- },
3269
- "optionalDependencies": {
3270
- "@esbuild/aix-ppc64": "0.28.0",
3271
- "@esbuild/android-arm": "0.28.0",
3272
- "@esbuild/android-arm64": "0.28.0",
3273
- "@esbuild/android-x64": "0.28.0",
3274
- "@esbuild/darwin-arm64": "0.28.0",
3275
- "@esbuild/darwin-x64": "0.28.0",
3276
- "@esbuild/freebsd-arm64": "0.28.0",
3277
- "@esbuild/freebsd-x64": "0.28.0",
3278
- "@esbuild/linux-arm": "0.28.0",
3279
- "@esbuild/linux-arm64": "0.28.0",
3280
- "@esbuild/linux-ia32": "0.28.0",
3281
- "@esbuild/linux-loong64": "0.28.0",
3282
- "@esbuild/linux-mips64el": "0.28.0",
3283
- "@esbuild/linux-ppc64": "0.28.0",
3284
- "@esbuild/linux-riscv64": "0.28.0",
3285
- "@esbuild/linux-s390x": "0.28.0",
3286
- "@esbuild/linux-x64": "0.28.0",
3287
- "@esbuild/netbsd-arm64": "0.28.0",
3288
- "@esbuild/netbsd-x64": "0.28.0",
3289
- "@esbuild/openbsd-arm64": "0.28.0",
3290
- "@esbuild/openbsd-x64": "0.28.0",
3291
- "@esbuild/openharmony-arm64": "0.28.0",
3292
- "@esbuild/sunos-x64": "0.28.0",
3293
- "@esbuild/win32-arm64": "0.28.0",
3294
- "@esbuild/win32-ia32": "0.28.0",
3295
- "@esbuild/win32-x64": "0.28.0"
3296
- }
3297
- },
3298
2786
  "node_modules/vitest/node_modules/estree-walker": {
3299
2787
  "version": "3.0.3",
3300
2788
  "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
@@ -52,11 +52,23 @@ module Lutaml
52
52
  end
53
53
  @memo.compare_by_identity
54
54
  @state = 0
55
+ # Global compile order of each transition (tuple-identity
56
+ # keyed) — the deterministic claims walk picks the earliest
57
+ # compiled accepting transition across the state set.
58
+ @transition_seq = {}.compare_by_identity
55
59
  entry, exit_state = compile_particles(particles)
56
60
  @accepting << exit_state
57
61
  @start = entry
58
62
  end
59
63
 
64
+ # Compile-order sequence number of a transition tuple.
65
+ #
66
+ # @return [Integer]
67
+ def transition_order(kind, particle, to)
68
+ @transition_seq[[kind, particle, to]] ||=
69
+ (@transition_seq.size + 1)
70
+ end
71
+
60
72
  def match(children)
61
73
  current = closure([@start])
62
74
  children.each_with_index do |child, index|
@@ -74,6 +86,42 @@ module Lutaml
74
86
  end
75
87
  end
76
88
 
89
+ # The deterministic leftmost assignment: at each child the
90
+ # EARLIEST-COMPILED accepting transition (model order) claims
91
+ # it, occurrence bounds included — the graph structure encodes
92
+ # them, so a 1..1 skip wildcard stops claiming after its single
93
+ # consumption and a later element particle claims the next
94
+ # match. Only transitions match() already DECIDED count — the
95
+ # memo is the authority and the match predicates are never
96
+ # re-invoked. The skip-suppression walk consults it so a child
97
+ # a declared particle claims is assessed rather than shadowed
98
+ # (QFE1700c1).
99
+ #
100
+ # @param children [Array] the SAME wrapper objects match() saw
101
+ # @return [Hash] child → [kind, particle] (identity-keyed)
102
+ def deterministic_claims(children)
103
+ claims = {}.compare_by_identity
104
+ current = closure([@start])
105
+ children.each do |child|
106
+ candidates = []
107
+ current.each do |from|
108
+ @transitions[from].each do |tuple|
109
+ kind, particle, to = tuple
110
+ next unless @memo[particle][child]
111
+
112
+ candidates << [transition_order(kind, particle, to),
113
+ kind, particle, to]
114
+ end
115
+ end
116
+ next if candidates.empty?
117
+
118
+ _, kind, particle, to = candidates.min_by(&:first)
119
+ claims[child] = [kind, particle]
120
+ current = closure([to])
121
+ end
122
+ claims
123
+ end
124
+
77
125
  private
78
126
 
79
127
  def advance(states, child)
@@ -216,8 +264,9 @@ module Lutaml
216
264
  (0...(1 << members.size)).each do |mask|
217
265
  next if mask[index] == 1
218
266
 
219
- @transitions[states[mask]] << [kind, member,
220
- states[mask | (1 << index)]]
267
+ transition = [kind, member, states[mask | (1 << index)]]
268
+ transition_order(*transition)
269
+ @transitions[states[mask]] << transition
221
270
  end
222
271
  end
223
272
  entry = states[0]
@@ -231,7 +280,9 @@ module Lutaml
231
280
  def leaf_fragment(kind, particle)
232
281
  entry = next_state
233
282
  exit_state = next_state
234
- @transitions[entry] << [kind, particle, exit_state]
283
+ transition = [kind, particle, exit_state]
284
+ transition_order(*transition)
285
+ @transitions[entry] << transition
235
286
  [entry, exit_state]
236
287
  end
237
288
 
@@ -38,8 +38,16 @@ module Lutaml
38
38
  @errors = []
39
39
  @warnings = []
40
40
  @infos = []
41
+ # The content matcher's deterministic child→particle claims
42
+ # (native node keyed), published for the engine's
43
+ # skip-suppression walk (QFE1700c1).
44
+ @content_claims = {}.compare_by_identity
41
45
  end
42
46
 
47
+ # The content matcher's deterministic claims for the last
48
+ # matched content model (native node → [kind, particle]).
49
+ attr_accessor :content_claims
50
+
43
51
  # Add an error to the collection
44
52
  #
45
53
  # @param error [ValidationError] The error to add
@@ -65,6 +65,16 @@ module Lutaml
65
65
  schema_def = resolver.resolve(
66
66
  xml_element.name, xml_element.namespace_uri
67
67
  )
68
+ # An UNDECLARED element anchored by xsi:type assesses
69
+ # against the named type (XSD assessment semantics,
70
+ # addB188: the root's attributes must be checked against t
71
+ # even though no global declaration names the element).
72
+ if schema_def.nil?
73
+ override_type = resolver.resolve_named_type(
74
+ xsi_type_local(xml_element).to_s,
75
+ )
76
+ schema_def = override_type if override_type
77
+ end
68
78
  if parent
69
79
  parent_declaration =
70
80
  resolver.resolve(parent.name, parent.namespace_uri)
@@ -223,6 +233,18 @@ module Lutaml
223
233
  end
224
234
  end
225
235
 
236
+ # The local part of the element's xsi:type attribute.
237
+ #
238
+ # @return [String, nil]
239
+ def xsi_type_local(xml_element)
240
+ override = xml_element.attributes.find do |attribute|
241
+ attribute.name == "type" &&
242
+ attribute.namespace_uri ==
243
+ ValidationRule::XSI_NAMESPACE
244
+ end
245
+ override && override.value.to_s.split(":").last
246
+ end
247
+
226
248
  # The child's position among its same-named siblings — the index
227
249
  # the positional binding (duplicate same-named declarations,
228
250
  # isDefault079) binds to. Computed on the RAW moxml nodes: the
@@ -243,11 +265,19 @@ module Lutaml
243
265
  # Whether the parent's content model holds a processContents
244
266
  # skip wildcard whose namespace range admits the child — the
245
267
  # child subtree then escapes assessment entirely (addB125).
268
+ # The content matcher's deterministic assignment overrides it:
269
+ # a child a DECLARED particle claims in the leftmost reading is
270
+ # assessed even though a skip wildcard could also admit it
271
+ # (QFE1700c1: the ref claims the second e2; its content must be
272
+ # validated).
246
273
  #
247
274
  # @return [Boolean]
248
275
  def skip_wildcard_subtree?(parent, child, resolver)
249
276
  return false unless parent
250
277
 
278
+ claim = @collector.content_claims[claim_key(child)]
279
+ return false if claim && claim.first != :wildcard
280
+
251
281
  declaration = resolver.resolve(parent.name, parent.namespace_uri)
252
282
  return false unless declaration
253
283
 
@@ -143,8 +143,15 @@ module Lutaml
143
143
  local = parts.last
144
144
  declaration =
145
145
  if parts.size == 2 && parts.first == "xml"
146
- # xml:base and friends are declared by the spec itself.
147
- XmlBuiltins.attribute(local)
146
+ # xml:base and friends are declared by the spec itself;
147
+ # a NON-builtin xml: reference (addB187's xml:blah)
148
+ # resolves through the imported xml-namespace schema —
149
+ # whose documents carry no target namespace, so the
150
+ # declaration lives under no namespace.
151
+ XmlBuiltins.attribute(local) ||
152
+ repository&.resolve_attribute(local,
153
+ XmlBuiltins::NAMESPACE) ||
154
+ repository&.resolve_attribute(local, nil)
148
155
  else
149
156
  repository&.resolve_attribute(local, nil)
150
157
  end
@@ -312,9 +319,13 @@ module Lutaml
312
319
 
313
320
  # Resolve type from element
314
321
  #
315
- # @param element [Lutaml::Xsd::Element] Schema element
322
+ # @param element [Lutaml::Xsd::Element, Lutaml::Xsd::ComplexType]
323
+ # Schema element — an override-dispatched ComplexType passes
324
+ # through (addB188's assessed root)
316
325
  # @return [Lutaml::Xsd::ComplexType, nil]
317
326
  def resolve_type(element, repository = nil)
327
+ return element if element.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType)
328
+
318
329
  return element.complex_type if element.complex_type
319
330
  return nil unless element.type
320
331
 
@@ -631,6 +642,17 @@ module Lutaml
631
642
  end
632
643
  end
633
644
 
645
+ # The xml-namespace convention (addB187): a schema imported
646
+ # AS the xml namespace declares its attributes with no
647
+ # target namespace — a name match whose expected namespace
648
+ # is absent serves the xml-qualified instance attribute.
649
+ if xml_attr.namespace_uri == XmlBuiltins::NAMESPACE
650
+ xml_decl = matches.find do |sa|
651
+ repository&.expected_attribute_namespace(sa).nil?
652
+ end
653
+ return xml_decl if xml_decl
654
+ end
655
+
634
656
  nil
635
657
  end
636
658
 
@@ -159,6 +159,14 @@ module Lutaml
159
159
  )
160
160
  result = matcher.match(children)
161
161
  if result.matched
162
+ # Publish the deterministic assignment — the engine's
163
+ # skip-suppression walk consults which particle claimed
164
+ # each child (QFE1700c1). Keyed by the NATIVE node: moxml
165
+ # wrappers are not identity-stable across accessor calls.
166
+ claims = matcher.deterministic_claims(children)
167
+ collector.content_claims = claims.each_with_object(
168
+ {}.compare_by_identity,
169
+ ) { |(node, claim), map| map[claim_key(node)] = claim }
162
170
  scan_wildcard_strict_usage(xml_element, particles, collector,
163
171
  repository, owner_ns)
164
172
  return
@@ -105,10 +105,13 @@ module Lutaml
105
105
  # Validate element name matches schema definition
106
106
  #
107
107
  # @param xml_element [XmlElement] The XML element
108
- # @param schema_element [Lutaml::Xsd::Element] Schema element
108
+ # @param schema_element [Lutaml::Xsd::Element, Lutaml::Xsd::ComplexType] Schema element
109
109
  # @param collector [ResultCollector] Result collector
110
110
  # @return [void]
111
111
  def validate_element_name(xml_element, schema_element, collector)
112
+ # An override-dispatched ComplexType anchors the instance's
113
+ # OWN name — assessment semantics (addB188's root).
114
+ return if schema_element.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType)
112
115
  return if names_match?(xml_element, schema_element)
113
116
 
114
117
  report_error(
@@ -420,9 +420,14 @@ module Lutaml
420
420
 
421
421
  # Resolve the type definition for an element
422
422
  #
423
- # @param schema_element [Lutaml::Xsd::Element] Schema element
423
+ # @param schema_element [Lutaml::Xsd::Element, Lutaml::Xsd::ComplexType] Schema element
424
424
  # @return [Lutaml::Xsd::SimpleType, Lutaml::Xsd::ComplexType, nil]
425
425
  def resolve_element_type(schema_element, repository = nil)
426
+ # An override-dispatched ComplexType IS the type
427
+ # (addB188's assessed root).
428
+ return schema_element if
429
+ schema_element.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType)
430
+
426
431
  # Check for inline type definition
427
432
  return schema_element.simple_type if
428
433
  schema_element.simple_type
@@ -549,7 +549,13 @@ module Lutaml
549
549
  # @param schema_element [Lutaml::Xml::Schema::Xsd::Element]
550
550
  # @return [Object, nil]
551
551
  def content_model_for(schema_element)
552
- type = schema_element.complex_type || resolve_type(schema_element)
552
+ type = if schema_element.is_a?(Lutaml::Xml::Schema::Xsd::ComplexType)
553
+ # An override-dispatched ComplexType IS the type
554
+ # (addB188's assessed root).
555
+ schema_element
556
+ else
557
+ schema_element.complex_type || resolve_type(schema_element)
558
+ end
553
559
  particle_for_type(type)
554
560
  end
555
561
 
@@ -1031,27 +1037,30 @@ module Lutaml
1031
1037
  end
1032
1038
 
1033
1039
  def index_schema(index, schema, held_signatures = [],
1034
- chameleon_namespace = nil,
1035
- chameleon_includer = nil)
1040
+ chameleon_namespace = nil)
1036
1041
  # A no-namespace document reached through xs:include is a
1037
- # chameleon: its declarations adopt the includer's target
1038
- # namespace AND form/derivation defaults (ctE018).
1042
+ # chameleon: ONLY its absent target namespace converts to the
1043
+ # includer's (XSD 1.0 §4.2.1 clause 3.2). Form and derivation
1044
+ # defaults are read from each declaration's OWN <schema>
1045
+ # ancestor — the chameleon document — because §3.2.2/§3.3.2
1046
+ # map form against the <schema> ancestor of the declaration,
1047
+ # which the namespace conversion never replaces (schD10:
1048
+ # unprefixed group members of a defaults-absent chameleon
1049
+ # stay unqualified beside a qualified includer).
1039
1050
  raw_namespace = schema.target_namespace
1040
1051
  chameleon = raw_namespace.to_s.empty? && chameleon_namespace
1041
1052
  namespace = chameleon ? chameleon_namespace : raw_namespace
1042
- defaults_schema = chameleon ? chameleon_includer : schema
1043
1053
  register_ref_namespaces(schema)
1044
1054
  Array(schema.element).each do |element|
1045
- index_element(index, element, namespace, :top, defaults_schema)
1055
+ index_element(index, element, namespace, :top, schema)
1046
1056
  # A global element's INLINE complexType carries local
1047
1057
  # attribute declarations too — their form resolution was
1048
1058
  # only indexed for named types (idG027/idH025).
1049
- index_local_attributes(element.complex_type, namespace,
1050
- defaults_schema)
1059
+ index_local_attributes(element.complex_type, namespace, schema)
1051
1060
  end
1052
1061
  Array(schema.complex_type).each do |complex_type|
1053
1062
  index_type(index, complex_type, namespace, schema)
1054
- index_local_attributes(complex_type, namespace, defaults_schema)
1063
+ index_local_attributes(complex_type, namespace, schema)
1055
1064
  end
1056
1065
  Array(schema.attribute).each do |attribute|
1057
1066
  index_attribute(attribute, namespace)
@@ -1064,13 +1073,12 @@ module Lutaml
1064
1073
  # (wildZ013c), a named document's against its own.
1065
1074
  @namespaces[group] = namespace unless name.empty?
1066
1075
  Array(group.attribute).each do |member|
1067
- index_local_attribute(member, namespace, defaults_schema)
1076
+ index_local_attribute(member, namespace, schema)
1068
1077
  end
1069
1078
  end
1070
1079
  Array(schema.group).each do |group|
1071
1080
  each_particle_element(group, schema) do |element|
1072
- index_element(index, element, namespace, :inline,
1073
- defaults_schema)
1081
+ index_element(index, element, namespace, :inline, schema)
1074
1082
  end
1075
1083
  end
1076
1084
  # lutaml-model nests resolved xs:import / xs:include targets
@@ -1082,8 +1090,7 @@ module Lutaml
1082
1090
  next unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
1083
1091
  next if held_signatures.include?(schema_signature(nested))
1084
1092
 
1085
- index_schema(index, nested, held_signatures, namespace,
1086
- defaults_schema)
1093
+ index_schema(index, nested, held_signatures, namespace)
1087
1094
  end
1088
1095
  Array(schema.import).each do |nested|
1089
1096
  next unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
@@ -1101,8 +1108,7 @@ module Lutaml
1101
1108
  # indexed under the name (attgC007/attgD036). Runs after the
1102
1109
  # nested descent so included declarations are already in.
1103
1110
  Array(schema.redefine).each do |red|
1104
- index_redefine(index, schema, red, held_signatures, namespace,
1105
- defaults_schema)
1111
+ index_redefine(index, schema, red, held_signatures, namespace)
1106
1112
  end
1107
1113
  end
1108
1114
 
@@ -1114,8 +1120,7 @@ module Lutaml
1114
1120
  # declaration is kept for that hook and the redefining body
1115
1121
  # indexed under the name (attgC007/attgD036). Runs after the
1116
1122
  # nested descent so included declarations are already in.
1117
- def index_redefine(index, schema, red, held_signatures, namespace,
1118
- defaults_schema)
1123
+ def index_redefine(index, schema, red, held_signatures, namespace)
1119
1124
  target_path = nil
1120
1125
  base = begin
1121
1126
  File.dirname(@repository.source_path_for(schema))
@@ -1132,8 +1137,7 @@ module Lutaml
1132
1137
  File.read(target_path), location: target_path
1133
1138
  )
1134
1139
  @redefined_targets << target
1135
- index_schema(index, target, held_signatures, namespace,
1136
- defaults_schema)
1140
+ index_schema(index, target, held_signatures, namespace)
1137
1141
  rescue StandardError
1138
1142
  nil
1139
1143
  end
@@ -101,6 +101,22 @@ module Lutaml
101
101
  declaration = repository.resolve(parent.name, parent.namespace_uri)
102
102
  repository.target_namespace_for(declaration) if declaration
103
103
  end
104
+
105
+ # The stable identity a content claim is keyed by: the NATIVE
106
+ # node for pipeline elements (moxml wrappers are not
107
+ # identity-stable across accessor calls), the node itself for
108
+ # anything else.
109
+ #
110
+ # @param node [Object]
111
+ # @return [Object]
112
+ def claim_key(node)
113
+ inner = if node.is_a?(Lutaml::Xsd::Validation::XmlElement)
114
+ node.moxml_element
115
+ else
116
+ node
117
+ end
118
+ inner.is_a?(Moxml::Node) ? inner.native : inner
119
+ end
104
120
  end
105
121
  end
106
122
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.107"
5
+ VERSION = "1.2.109"
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.107
4
+ version: 1.2.109
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-09 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