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

The W3C XSTS group anyURI_a004_1339 pairs a `valid` schemaTest with an `invalid`
instanceTest, but the two expectations are mutually inconsistent, so PureXML's
acceptance of the instance is spec-correct rather than an under-rejection.

The schema's include, import, and redefine carry unresolvable schemaLocations
(ftp://, gopher://, mailto:). XSD 1.0 §4.2.1 makes an unresolvable include "not
an error" (no inclusion performed), the import likewise, and the empty redefine
imposes no resolution requirement (src-redefine clause 1 gates that on
non-annotation children), so the schema is conformantly valid, agreeing with the
schemaTest. The only components the instance exercises (root, bar, st, att) are
fully locally defined, and every instance value is byte-identical to one of the
type's six anyURI enumeration members, so a strict assessment of the document
element is valid. There is no spec path to valid-schema + invalid-instance.

libxml2 is no authority here: it non-conformantly fails to compile the schema on
the unresolvable include, so it disagrees with the suite's valid-schema verdict
too. Matching the suite's invalid-instance expectation would mean rejecting a
valid instance whenever an include cannot be resolved, a false positive an IDE
editing loop hits constantly, which the production bar forbids.

Exclude it from the counts via specDivergentInstances, mirroring how the suite's
own status="queried" entries are skipped, with the spec-grounded justification
recorded in code and docs/xsts-deviations.md. invalid-instances-accepted 11 -> 10;
full XSTS in release now 0/8/0/10, both false-positive buckets at 0. Two
independent adversarial analyses failed to refute the instance's validity.
This commit is contained in:
Mihaela Mihaljevic 2026-06-29 07:30:00 +02:00 committed by GitHub
parent 2eb9f83958
commit 35e52f26cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 7 deletions

View File

@ -78,11 +78,31 @@ struct XSTSSuiteTests {
/// not the parser's Fifth Edition production, so a Fifth-Edition-only name char
/// (the combining mark U+0346) no longer matches `\c` (reZ006i now rejects). See
/// ``XSDNameCharacter``.
private let knownInstanceInvalidAccepted = 11
/// Instance tests excluded from the counts. Empty: the Ethiopic-digit `\d` cases
/// (reS17.v, reS38.v, reZ004v.v) were not divergent but a 3.2-repertoire bug, now
/// fixed, so they are counted as ordinary agreements rather than excluded.
private static let specDivergentInstances: Set<String> = []
/// 11 -> 10: anyURI_a004_1339.i reclassified as a contested test, not a bug (see
/// the excluded set below). PureXML's acceptance is spec-correct; the suite's
/// expectation is internally inconsistent.
private let knownInstanceInvalidAccepted = 10
/// 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
/// hide a real deviation.
///
/// - `anyURI_a004_1339.i`: the suite pairs a `valid` schemaTest with an `invalid`
/// instanceTest, but the two are mutually inconsistent. The schema's `include`,
/// `import`, and `redefine` have unresolvable schemaLocations; XSD 1.0 §4.2.1
/// makes an unresolvable `include` "not an error" (no inclusion performed), the
/// `import` likewise, and the empty `redefine` imposes no resolution requirement
/// (`src-redefine` clause 1 gates that on non-annotation children), so the schema
/// is conformantly valid (agreeing with the schemaTest). The only components the
/// instance exercises (`root`, `bar`, `st`, `att`) are fully locally defined, and
/// every instance value is byte-identical to one of the type's six anyURI
/// `enumeration` members, so a strict assessment of the document element is
/// valid. There is no spec path to valid-schema + invalid-instance. Confirmed by
/// two independent adversarial analyses; libxml2 is no authority here (it
/// non-conformantly fails to compile the schema on the unresolvable include).
/// Matching the suite would mean rejecting a valid instance whenever an include
/// cannot be resolved, a false positive an IDE editing loop hits constantly.
private static let specDivergentInstances: Set<String> = ["anyURI_a004_1339.i"]
@Test("Every XSTS case behaves: compile, reject, validate, invalidate")
func test_suite() throws {

View File

@ -86,11 +86,27 @@ rule is marked ambiguous by the suite itself (RecurseAsIfGroup); `mgO013` is an
non-absolute namespace URIs. The multi-document `sch*` / `targetns` cases need
per-schema pairing before a verdict.
`anyURI_a004_1339.i` is reclassified as a contested test, not a deviation
(`invalid-instances-accepted` 11 -> 10, now excluded like the suite's `queried`
entries). The suite pairs a `valid` schemaTest with an `invalid` instanceTest, but
the two are mutually inconsistent: the schema's `include`/`import`/`redefine` have
unresolvable schemaLocations, which XSD 1.0 §4.2.1 makes "not an error" (no
inclusion performed; the empty `redefine` imposes no resolution requirement per
`src-redefine` clause 1), so the schema is conformantly valid, and the only
components the instance exercises (`root`/`bar`/`st`/`att`) are fully locally
defined with every value byte-identical to one of the type's six anyURI
`enumeration` members, so the instance is valid. There is no spec path to
valid-schema + invalid-instance. Two independent adversarial analyses failed to
refute this; libxml2 is no authority (it non-conformantly fails to compile the
schema on the unresolvable include). Matching the suite would reject a valid
instance whenever an include cannot be resolved, a false positive an IDE hits
constantly. Recorded in `XSTSSuiteTests.specDivergentInstances`.
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); the remaining reference-aligned cases are real but each
needs its own analysis, not a sweep.
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.
## Category A: genuine correctness bugs