test(schema): reclassify mgO013.i as a contested XSTS test, not a deviation (#382)

mgO013 redefines a model group `group` to `all{e1(1,1)}`, redefining a base
`all{e1(0,0)}` (e1 forbidden) without referencing itself. The suite pairs a
`valid` schemaTest with an `invalid` instanceTest, but the two are mutually
exclusive for a consistent conformant processor.

src-redefine clause 6.2.2 makes a no-self-reference group redefine a restriction
obligation: the redefined group must be a valid restriction of the original.
`all{e1(1,1)}` is not a valid restriction of `all{e1(0,0)}` (Particle Valid
(Restriction), Occurrence Range OK: derived max 1 > base max 0), so enforcing
6.2.2 rejects the schema, a valid-schema-rejected false positive against the
schemaTest's own `valid` verdict. Yet §4.2.2 makes the referencing type's group
reference resolve to the redefined `all{e1(1,1)}`, against which the single-e1
instance is valid. There is no third path: reaching instance-invalid requires
rejecting the schema. libxml2 accepts both, agreeing with PureXML and the
schemaTest. An adversarial analysis confirmed no reading yields valid-schema +
invalid-instance.

Exclude mgO013.i via specDivergentInstances with the spec-grounded justification
in code and docs/xsts-deviations.md. invalid-instances-accepted 7 -> 6; full XSTS
in release now 0/8/0/6, both false-positive buckets at 0. No library behaviour
change: matching the suite would introduce the false positive the production bar
forbids.
This commit is contained in:
Mihaela Mihaljevic 2026-06-29 09:36:02 +02:00 committed by GitHub
parent 8f2725b62a
commit 0e782737a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 5 deletions

View File

@ -89,7 +89,9 @@ struct XSTSSuiteTests {
/// 8 -> 7: an identity-constraint field that selects a node whose declared type is
/// not simple (the ur-type anyType, no xsi:type rescue) is rejected per
/// cvc-identity-constraint.3 (idZ010). See ``XSDParser/identityNonSimpleFieldKeys``.
private let knownInstanceInvalidAccepted = 7
/// 7 -> 6: mgO013.i reclassified as contested (see the excluded set). Its
/// `invalid` is unsatisfiable jointly with its own `valid` schemaTest.
private let knownInstanceInvalidAccepted = 6
/// Instance tests excluded from the counts because their expected validity is not
/// authoritative, mirroring how the suite's own `status="queried"` entries are
/// skipped. Each must carry a spec-grounded justification; this is never a place to
@ -125,7 +127,18 @@ struct XSTSSuiteTests {
/// collection's declarations on conflict) is conformant. Confirmed by an
/// adversarial analysis that separated these from schA7.i, whose `invalid` IS
/// spec-grounded (a genuine policy deviation, left in the count).
private static let specDivergentInstances: Set<String> = ["anyURI_a004_1339.i", "schA2.i", "schA5.i"]
///
/// - `mgO013.i`: a `redefine` whose group `all{e1(1,1)}` redefines a base
/// `all{e1(0,0)}` without referencing itself. `src-redefine` clause 6.2.2 makes
/// that a restriction obligation, and `all{e1(1,1)}` is not a valid restriction
/// of `all{e1(0,0)}` (Occurrence Range OK: derived max 1 > base max 0), so
/// enforcing it rejects the schema, contradicting the `valid` schemaTest and
/// producing a valid-schema-rejected false positive. Yet §4.2.2 makes the type's
/// `group` reference resolve to the redefined `all{e1(1,1)}`, against which the
/// single-`e1` instance is valid. The `valid` schema and `invalid` instance
/// expectations are mutually exclusive; libxml2 accepts both. Confirmed by an
/// adversarial analysis that found no third path.
private static let specDivergentInstances: Set<String> = ["anyURI_a004_1339.i", "schA2.i", "schA5.i", "mgO013.i"]
@Test("Every XSTS case behaves: compile, reject, validate, invalidate")
func test_suite() throws {

View File

@ -130,11 +130,26 @@ separated the contested from the genuine):
the reference on a construct whose composition order in a cycle the spec does not
pin down. Tracked as deferred scope, not excluded.
`mgO013.i` is reclassified as contested (`invalid-instances-accepted` 7 -> 6).
A `redefine` defines `group = all{e1(1,1)}`, redefining a base `all{e1(0,0)}`
without referencing itself. `src-redefine` clause 6.2.2 makes a no-self-reference
group redefine a restriction obligation, and `all{e1(1,1)}` is not a valid
restriction of `all{e1(0,0)}` (Occurrence Range OK fails: derived max 1 > base
max 0), so enforcing it rejects the schema, a valid-schema-rejected false positive
against the `valid` schemaTest. Yet §4.2.2 makes the referencing type resolve to
the redefined `all{e1(1,1)}`, against which the single-`e1` instance is valid. The
`valid` schema and `invalid` instance expectations are mutually exclusive; libxml2
accepts both. An adversarial analysis found no third path. The identity-field
case `idZ010` (a `key`/`keyref` field selecting a non-simple `anyType` node) was a
genuine bug and is fixed (reject per cvc-identity-constraint.3).
Takeaway: on the schema side, libxml2 parity is reached except the one case now
fixed; the remaining nine are a deliberate choice to exceed the reference. On the
instance side the Ethiopic-digit `\d`/`\D` and `\i`/`\c` name-class cases are now
fixed (reference-aligned) and `anyURI_a004_1339` is shown contested; the remaining
reference-aligned cases are real but each needs its own analysis, not a sweep.
instance side the Ethiopic-digit `\d`/`\D` and `\i`/`\c` name-class cases and the
identity-field `idZ010` are now fixed (reference-aligned); `anyURI_a004`, `schA2`,
`schA5`, and `mgO013` are shown contested; the remaining cases (`schA7` policy,
`schU3/4/5` circular redefine that exceeds libxml2, `particlesZ001` which the suite
itself marks ambiguous, `targetns00101m`) are real but each needs its own analysis.
## Category A: genuine correctness bugs