moxml 0.5.158 → 0.5.160

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: a173c6faca10ad59c37096bc873999f16f7e5b05ae7afb9f2eba6041ec8147a2
4
- data.tar.gz: e430658fbe932063794a0a04d2c05224a367da83ebc2f55c9eef8d7e67e431af
3
+ metadata.gz: 3baac5f598cb14a214bcf65d8f19f7d73d6d70c7f3fc0b53766f07bac4f2d176
4
+ data.tar.gz: 54e53fb3aa363edd679bca122996d5a224bfa58a99e656a35acc59182dd66f45
5
5
  SHA512:
6
- metadata.gz: a68cad1dab561fa57921867cf856f9222e21f0413e7e4611dce3fa7f91e23b6ae52dc260921e03c8a0f83185ce1d7a6bd66f26e394151c55d08fe63b1b310686
7
- data.tar.gz: 63ffc8a538f79c85bbc3179875d489f0ee20b8c36ae2498eac1694f0e1538e0ecf07e796a8364613fbe54d9a656da34965e87e9c1165960bd7815c19939e0669
6
+ metadata.gz: 705c62afbefc4678ad231e380644023416a5e0cf19e94dd59437c0570abca635e4570db661272490ed1f37804230623d9836e5cc2b8e70619bea1cc16f2fe0a6
7
+ data.tar.gz: e40cf23891b36aaca41bb1c62d01b0e7479c5c1c5eada2fa9563f315399d943a170381d5467019e7e956f06940b71aad59db2d19099a545ebf67d7d4603168c8
@@ -3,12 +3,23 @@ name: performance-release
3
3
  # Every release re-measures the scoreboard and appends the table to
4
4
  # the release notes (TODO.sota/04). Triggered by the release
5
5
  # workflow's completion; idempotent — a re-run replaces the marked
6
- # section instead of stacking it.
6
+ # section instead of stacking it. Manual dispatch can backfill any
7
+ # release: `ref` pins the measured tree, `tag` pins the notes
8
+ # target (both default to the automatic release-run behavior).
7
9
  on:
8
10
  workflow_run:
9
11
  workflows: ["release"]
10
12
  types: [completed]
11
13
  workflow_dispatch:
14
+ inputs:
15
+ ref:
16
+ description: "Tree to measure (branch/tag/SHA); default: the released tree"
17
+ required: false
18
+ type: string
19
+ tag:
20
+ description: "Release whose notes receive the section; default: the triggering release"
21
+ required: false
22
+ type: string
12
23
 
13
24
  concurrency:
14
25
  group: ${{ github.workflow }}
@@ -30,8 +41,9 @@ jobs:
30
41
  with:
31
42
  # Pin to the exact tree the release run published, so the
32
43
  # measured scoreboard describes the released code even when
33
- # main moves between the release and this report.
34
- ref: ${{ github.event.workflow_run.head_sha || 'main' }}
44
+ # main moves between the release and this report. A manual
45
+ # dispatch may pin any tree (backfills).
46
+ ref: ${{ inputs.ref || github.event.workflow_run.head_sha || 'main' }}
35
47
  submodules: "recursive"
36
48
 
37
49
  - name: Set up Ruby
@@ -99,11 +111,15 @@ jobs:
99
111
  # run — NOT "latest" (a rerun of an old run would mis-aim)
100
112
  # and NOT the gemspec at the pinned tree (the checkout is
101
113
  # the pre-bump tree; the bump lands on main during the
102
- # release run itself).
103
- TRIGGERED_AT="${{ github.event.workflow_run.created_at }}"
104
- TAG=$(gh api "repos/${GITHUB_REPOSITORY}/releases" \
105
- --jq "map(select(.created_at >= \"${TRIGGERED_AT}\")) | sort_by(.created_at) | last | .tag_name")
106
- TAG=${TAG:-$(gh release view --json tagName --jq .tagName)}
114
+ # release run itself). A manual dispatch may pin the tag
115
+ # directly (backfills).
116
+ TAG="${{ inputs.tag }}"
117
+ if [ -z "$TAG" ]; then
118
+ TRIGGERED_AT="${{ github.event.workflow_run.created_at }}"
119
+ TAG=$(gh api "repos/${GITHUB_REPOSITORY}/releases" \
120
+ --jq "map(select(.created_at >= \"${TRIGGERED_AT}\")) | sort_by(.created_at) | last | .tag_name")
121
+ TAG=${TAG:-$(gh release view --json tagName --jq .tagName)}
122
+ fi
107
123
  echo "Reporting against $TAG"
108
124
  gh release view "$TAG" --json body --jq .body > /tmp/body.md
109
125
  ruby -e '
@@ -39,6 +39,8 @@ Generated by `bundle exec rake docs:coverage` from the coverage matrix and the d
39
39
  | XSLT | equivalent | loud (NotImplementedError) | loud (NotImplementedError) | loud (NotImplementedError) | loud (NotImplementedError) | loud (NotImplementedError) | equivalent
40
40
  | SAX | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
41
41
  | materialization | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
42
+ | validation | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
43
+ | validation under-detections | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
42
44
  | loud capability contracts | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent | equivalent
43
45
  |===
44
46
 
@@ -253,6 +253,23 @@ Pins:: `spec/moxml/plan_conformance_spec.rb`
253
253
  matching is global; unmatched subtrees are dropped per the pinned
254
254
  semantics.
255
255
 
256
+ === Validation
257
+
258
+ Pins:: `spec/moxml/xsd_spec.rb`, `spec/moxml/xsd_underdetection_spec.rb`
259
+
260
+ XSD validation through engines that ship a validator (libxml2;
261
+ leptris tier-1: recognized roots, one-level content descent, lexical
262
+ checks). `validate` returns accumulated `ValidationError` entries —
263
+ message always; line/column/path where the engine reports them, nil
264
+ where it does not; `[]` means valid. Documents outside the engine's
265
+ scope validate laxly, except that strict `xs:any` /
266
+ `xs:anyAttribute` wildcard matches and `xsi:nil` are re-checked from
267
+ the schema source on every adapter — the re-check can only
268
+ under-report, never false-report. Unsupported adapters raise
269
+ `Moxml::NotImplementedError` at compile; `Moxml::XSD.supported?`
270
+ answers without raising. RELAX NG rides engines with an RNG face
271
+ (the same shapes).
272
+
256
273
  === Errors and loud degradation
257
274
 
258
275
  Pins:: `spec/consistency/loud_degradation_spec.rb`
@@ -555,6 +555,11 @@ module Moxml
555
555
  # face is a C method at 50-84ns).
556
556
  ELEMENT = Class.new(::Leptris::XML::NativeNode) do
557
557
  alias_method :native_name, :name
558
+ # The C nn_document (the BINDING document handle) is
559
+ # captured before Moxml::Node#document shadows it —
560
+ # the construction fast path needs the binding doc,
561
+ # not a facade wrapper (TODO.sota/04 bridge tax).
562
+ alias_method :native_document, :document
558
563
  include ::Moxml::Node
559
564
  include ::Moxml::Element
560
565
 
@@ -2623,6 +2628,35 @@ module Moxml
2623
2628
  def create_element_with_attrs(parent, name, attrs)
2624
2629
  drop_columnar_children(parent)
2625
2630
  validate_element_name(name)
2631
+ # NativeNode parents need NO FFI twin (TODO.sota/04 bridge
2632
+ # tax): the bridge existed only to obtain c_address +
2633
+ # document, and the NativeNode answers both natively
2634
+ # (address / document). The twin mint per building parent
2635
+ # (FFI::Pointer + binding Node.wrap + registry insert) is
2636
+ # pure construction overhead.
2637
+ if parent.is_a?(::Leptris::XML::NativeNode)
2638
+ doc = parent.respond_to?(:native_document) &&
2639
+ parent.native_document or return nil
2640
+ return nil unless ::Leptris::XML::Native.respond_to?(:create_element_with_attrs)
2641
+
2642
+ flat = attrs.flatten
2643
+ if NATIVE_C_MINT &&
2644
+ ::Leptris::XML::Native.respond_to?(:create_element_with_attrs_wrapped)
2645
+ minted = ::Leptris::XML::Native.create_element_with_attrs_wrapped(
2646
+ doc, parent.address, name.to_s, flat
2647
+ )
2648
+ return minted unless minted.nil?
2649
+ end
2650
+
2651
+ addr = ::Leptris::XML::Native.create_element_with_attrs(
2652
+ doc.c_address, parent.address, name.to_s, flat
2653
+ )
2654
+ return nil if addr.nil? || addr.zero?
2655
+
2656
+ return native_twin(
2657
+ doc, ::Leptris::XML::Node.wrap(::FFI::Pointer.new(addr), doc)
2658
+ )
2659
+ end
2626
2660
  binding_parent = to_binding(parent)
2627
2661
  doc = binding_parent.document or return nil
2628
2662
  return nil unless ::Leptris::XML::Native.respond_to?(:create_element_with_attrs)
data/lib/moxml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
- VERSION = "0.5.158"
4
+ VERSION = "0.5.160"
5
5
  end
data/lib/moxml/xsd.rb CHANGED
@@ -5,7 +5,10 @@ module Moxml
5
5
  # an XSD validator (currently leptris, tier-1: named+typed
6
6
  # top-level elements, one-level content-model descent, lexical
7
7
  # builtin/simpleType checks — see docs/c14n for the sibling
8
- # pattern).
8
+ # pattern). Beside the engine, SchemaRules re-checks strict
9
+ # wildcards and xsi:nil from the schema source on every adapter —
10
+ # engines that miss those shapes stay model-conformant, and
11
+ # engines that already detect them get no duplicate findings.
9
12
  #
10
13
  # ctx = Moxml.new(:leptris)
11
14
  # schema = ctx.xsd(<<~XSD)
@@ -24,7 +27,8 @@ module Moxml
24
27
  # Adapters without an engine raise Moxml::NotImplementedError at
25
28
  # compile; Moxml::XSD.supported?(context) answers without
26
29
  # raising. The tier-1 scope is the engine's: documents outside it
27
- # validate laxly (see the binding's xsd_validate_spec).
30
+ # validate laxly, except for the re-checked shapes above (which
31
+ # can only under-report, never false-report).
28
32
  module XSD
29
33
  SUPPORTED_ADAPTERS = %i[leptris nokogiri].freeze
30
34
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
+ # Processing model §Validation (normative): pinned here.
5
6
  # Moxml::XSD contract (leptris tier-1 faces): compile + validate
6
7
  # with accumulated errors; unsupported adapters raise
7
8
  # NotImplementedError at compile.
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
+ # Processing model §Validation (normative): pinned here.
5
6
  # #452: tier-1 engines can accept, inside their recognized scope,
6
7
  # instances that violate strict wildcards or xsi:nil. The
7
8
  # Ruby-side SchemaRules post-validation closes those gaps from the
@@ -77,6 +77,14 @@ module ModelCoverage
77
77
  section: "Materialization",
78
78
  pin: "spec/moxml/plan_conformance_spec.rb",
79
79
  },
80
+ "validation" => {
81
+ section: "Validation",
82
+ pin: "spec/moxml/xsd_spec.rb",
83
+ },
84
+ "validation under-detections" => {
85
+ section: "Validation",
86
+ pin: "spec/moxml/xsd_underdetection_spec.rb",
87
+ },
80
88
  "loud capability contracts" => {
81
89
  section: "Errors and loud degradation",
82
90
  pin: "spec/consistency/loud_degradation_spec.rb",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.158
4
+ version: 0.5.160
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-10-23 00:00:00.000000000 Z
11
+ date: 2026-10-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Moxml is a unified XML manipulation library that provides a common API