- README, roadmap: XSTS status quad and gates table now read the enforced
0/43/0/31 (Tests/XSTSSuiteTests.swift); test count 986/169 to 1448/258;
encoding list and the remaining-work section reflect shipped reality;
check-all expansion lists the validation and changelog gates
- GEMINI.md, onboarding-antigravity.md: valid-schemas-rejected 1 to 0 and the
pinned baselines updated to current
- SECURITY.md: complete the reporting address
- Parsing.InputEncoding: doc comment lists the full shipped encoding set
- Schema.XSDParserUnion: guard the localName interpolation with ?? "" to match
the same line and silence an optional-interpolation warning (internal dedup
key, behavior preserving)
- CHANGELOG: Unreleased entries for the above
Companion to production-readiness.md and roadmap.md. Characterizes, with code
evidence, the two biggest hurdles. (1) The invalid-accepted tail concentrates in
ParticleRestriction.violation's deliberately under-approximated clauses (MapAndSum,
RecurseAsIfGroup, NameAndTypeOK): a single high-fan-in oracle where tightening
risks a false positive. (2) ContentMatcher unrolls occurrence values into NFA
states, so the occursUnrollCap/totalStateCap/positionCap caps are band-aids that
silently degrade to star; a counting automaton is what turns the cap into a proven
bound.
Make public/rules-swift the canonical source (per project direction) and adopt
its opt-in lint rules that PureXML lacked: empty_count, explicit_init, first_where,
sorted_first_last, unused_import, plus its todo disable. All pass with zero
violations on the existing sources.
PureXML keeps its coherent, stricter tuning where the canon is a self-described
'starting point': force_unwrapping/force_try/force_cast = error (safety), and
trailing commas mandated in both swiftformat (--commas always) and swiftlint
(mandatory_comma) to resolve the canon's formatter-adds vs linter-flags mismatch.
docs/rules/README.md now points at public/rules-swift and documents the tuning.
Adds a dated accounting to the XSTS deviation worklist: the labelled-suite
ratchet stands at 0/74/0/133 with false positives held at 0 across the campaign.
Partitions the remaining 74 into fixable-but-intricate debt (redefine
restriction, NameAndTypeOK union membership, wildcard UPA, chameleon/cross-ns
composition, heterogeneous particle edges) and irreducible-by-design or disclosed
items (RecurseAsIfGroup spec ambiguities, the deliberate regex-tolerance), with
the root cause and false-positive risk for each so the burndown is driven by
understanding. Records that the adversarial critic loop caught three genuine
false positives this session that the suite and differential both missed.
Consolidates the in-progress #146 work; valid-instances-rejected reaches 4
on the 2006-11-06 XSTS archive (buckets now 1/262/4/147).
Regex: match Unicode scalars rather than grapheme clusters; the empty
pattern matches only the empty string; pin the category repertoire to
Unicode 3.2, the version the corpus is consistent at, so code points added
in 3.2 (Tagalog, Cyrillic Komi) are word characters while later additions
(the Tamil digit zero) stay unassigned and match \D. New XSDCategory and a
3.2 assignment table derived from DerivedAge, replacing the old Unicode31
files.
Content model: assess each child against the particle the content automaton
matched, not a by-name lookup (#180). Two same-named particles keep their
own fixed values, and an element matching a skip wildcard is no longer
validated against its global declaration. Selection is made reproducible
when an ambiguous schema slips past the UPA check.
XSTS runner: compile and merge every schemaDocument in a schemaTest, not
just the first; this also surfaced one previously-masked invalid-instance
acceptance (recorded in the baselines).
Also folds in attribute-group anyAttribute inheritance, extension wildcard
union, namespace-qualified type tables for multi-document
xsi:schemaLocation, per-container elementFormDefault, strict and lax
attribute wildcard validation, built-in type resolution, and xs:redefine
simpleType overrides.
Ship the OpenAPIKit-style validation layer (builtin rules, warnings channel,
Validator tiers, coverage gates) and wire XSD compile checks through it. Advance
#161 with chameleon include validation, multi-container reference resolution,
and include targetNamespace composition rules so merged schema sets compile
correctly when a schemaLoader is provided.
Document the restructured GitHub issue hierarchy (epic #167, gates,
milestones M1-M5, task labels) and point README Status at the current
production-readiness focus and v0.2.0 XSTS baselines.
Cut the second pre-release: schema-validity burn-down to XSTS baselines
1/266/171/155, component child-content shape checks, and synced conformance
docs. CHANGELOG updated for v0.2.0.
Require that any restricted attribute has a type validly derived by restriction from its base counterpart. Validates atomic built-in derivation, list item type restrictions, and union member/subset relationships recursively. Updates baseline to 362 accepted invalid schemas.
Reject top level declarations that omit a name attribute. Disallow derivation by restriction of xs:anySimpleType inside simpleType definitions. Require restriction facets length, minLength, maxLength, totalDigits, and fractionDigits to restrict or equal the base type facets. Updates the conformance baseline to 383 accepted invalid schemas.
In a complexContent restriction, an attribute the restriction redeclares that the
base type marks use="required" may not be made optional or prohibited. Only
attributes explicitly redeclared that also exist in the base are checked; an
omitted attribute is inherited unchanged. The base reference must resolve to the
schema's own target namespace, and the check stands down for a schema that
composes other documents.
The matching fixed-value clause is deliberately not enforced: it requires
comparing the two fixed values in the attribute type's value space, not lexically
(a list-typed fixed value differing only in whitespace is the same value), so a
string comparison wrongly rejects valid schemas. That clause is left for a later
change (a disclosed under-rejection).
XSTS: invalid schemas accepted 394 to 390, no other bucket raised.
A simpleType nested inside a restriction/list/union/element/attribute is the
anonymous localSimpleType (no name), and a nested attributeGroup is always a
reference; named simpleType and attributeGroup definitions are top-level only (a
direct child of schema or redefine). A nested definition declaring a name was
accepted; it is now rejected. A nested anonymous simpleType, an attributeGroup
reference, and a top-level named definition are unaffected.
XSTS: invalid schemas accepted 403 to 394, no other bucket raised.
An xs:all group in a complexContent extension of a base that already has element
content was accepted. The effective content model of such an extension is
sequence(base content, extension content), which nests the all and violates the
rule that an all group must be the whole content model. The base type is read
from the compiled model: rejected only when the base resolves, in the schema's
own target namespace, to a complex type with element-only or mixed content. An
explicitly-empty base (an empty model group with mixed=false) has effectively
empty content and may still be extended by an all (the all becomes the whole
content); a simple-content, empty, foreign, or unresolved base is left alone.
Checked for a self-contained schema.
XSTS: invalid schemas accepted 411 to 403, no other bucket raised.
A simple type whose final contains list (or #all) may not be a list itemType,
and one whose final contains union (or #all) may not be a union memberType.
finalRespected already covered restriction and extension; the list and union
directions were unchecked because the derivation-method set does not model
final="list"/"union", so the final attribute is read directly. The itemType /
memberTypes reference is matched only when it resolves to the schema's own target
namespace, so a list or union of a built-in (whose final is empty) is not
confused with a user type of the same local name. Checked for a self-contained
schema.
XSTS: invalid schemas accepted 413 to 411, no other bucket raised.
A whiteSpace facet that relaxed its base type's effective whiteSpace was
accepted; XSD Part 2 4.3.6 permits only strengthening, ordered
preserve < replace < collapse. A base fixed to collapse admits only collapse,
and a replace base admits replace or collapse; relaxing it (e.g. replace over a
collapse base, or restricting xs:token to replace) is now rejected. The base's
effective whiteSpace is its own facet falling back to its built-in intrinsic;
the check is atomic-only and, when a base's own whiteSpace has not yet resolved,
can only under-detect (an unresolved base defaults to preserve, the weakest), so
it never rejects a valid restriction.
XSTS: invalid schemas accepted 422 to 413, no other bucket raised.
A top-level xs:element declaration (a direct child of schema, or of redefine) was
accepted with ref, form, minOccurs, or maxOccurs. A global element is a
declaration, never a particle or a reference, so those local-use attributes are
prohibited by the schema-for-schemas topLevelElement. The top-level-attribute
applicability scan is generalized into topLevelDeclarationErrors, driven by a
per-kind forbidden-attribute map, covering both attribute and element. A local
element particle inside a content model is unaffected.
XSTS: invalid schemas accepted 424 to 422, no other bucket raised.
An element ref carrying nillable/default/fixed/form/block, or an element or
attribute ref carrying an inline type definition, was accepted. A ref is a use
of a global declaration, not a declaration, so beyond ref it admits only
minOccurs, maxOccurs, and id (src-element.2.2). The applicability check already
excluded name and type from a ref; this extends the exclusion to the remaining
declaration-only properties and to an inline simpleType/complexType child.
minOccurs/maxOccurs, a group/attributeGroup ref, and an attribute ref's
use/default/fixed (which override on the use) are unaffected.
XSTS: invalid schemas accepted 439 to 424, no other bucket raised. Disclosed
under-detection: a key/unique/keyref child under a ref is not yet flagged.
A top-level xs:attribute declaration (a direct child of schema, or of redefine)
was accepted with use, form, or ref. Those belong to a local attribute use, not
a global declaration: the schema-for-schemas topLevelAttribute marks ref, form,
and use as prohibited, allowing only default, fixed, id, name, type and an inline
simpleType. The per-component applicability table is the permissive global/local
union, so it could not draw the distinction; a focused scan of the direct
attribute children of schema and redefine supplies the global-only constraint. A
local attribute use inside a complex type or attribute group is unaffected.
The existing test_validAttributeValues asserted a top-level attribute with use
compiles, which is itself invalid; corrected to a local attribute use.
XSTS: invalid schemas accepted 454 to 439, no other bucket raised.
A default/fixed value on an element or attribute whose type names a user-declared
type in the schema's own target namespace must be a valid value of that type
(XSD 1.0 e-props-correct.2 / a-props-correct.2). The check runs after the named
types are compiled and validates with the compiled SimpleType validator (the one
instance validation uses), so whitespace and facet handling match. Built-ins are
handled at structure time; imported, foreign, and inline anonymous types are left
alone via a namespace gate.
This exposed a pre-existing compile defect: a simpleType restriction read its base
only from the base attribute, so an inline anonymous <simpleType> base (a list or
union with no base attribute) was dropped and the type collapsed to an atomic
string, making a length facet count characters instead of list items. The
restriction branch now resolves the inline child as its base, preserving list and
union variety. This corrects both schema-time value checking and instance
validation.
XSTS: invalid schemas accepted 462 to 454; invalid instances accepted 160 to 158;
no other bucket raised.
An xs:attribute declaration carrying a default value constraint was accepted
alongside use="required" or use="prohibited"; XSD 1.0 src-attribute.2 requires
use to be optional when default is present (a default makes the attribute
optional). The check rides the existing value-constraint walk, gated to
XSD-namespace attribute declarations reading the unprefixed default/use, and is
per declaration. Only fixed (not default) may pair with use="required".
XSTS: invalid schemas accepted 469 to 462, no other bucket raised. Disclosed
under-rejection: a whitespace-padded use=" required " (NMTOKEN actual value
"required") is not flagged.
An xs:element or xs:attribute declaration carrying both a default and a fixed
value constraint was accepted; XSD 1.0 src-element.1 / src-attribute.1 make the
two mutually exclusive. The check rides the existing value-constraint structure
walk, gated to XSD-namespace declarations and reading the unprefixed
default/fixed (a foreign same-local-name attribute is not the value
constraint). It is per declaration, so a default on a global declaration and a
fixed on a reference to it (two separate items) remains valid.
XSTS: invalid schemas accepted 479 to 469, no other bucket raised.
An element declaring substitutionGroup="head" whose own type is unrelated to
the head's type was accepted; XSD 1.0 e-props-correct.4 requires the member's
type be validly derived from the head's. The check runs after named types
resolve and reuses the restriction/extension + built-in-lattice derivation
oracle (an ur-type head admits any member).
It is conservative so it never rejects a valid member: it runs only for a
self-contained schema (no import/include/redefine, where the derivation table
is complete and single-namespace names are unambiguous), reads the member's
type from its own type attribute and the head's from the top-level element
declarations only (so a local element of the same name supplies neither), and
stands down when either type is a list or union (cos-st-derived-ok clauses
2.3/2.4 union-member derivation is not modelled).
The post-namedTypes consistency calls move into a postNamedTypeErrors
aggregator alongside consistencyErrors. XSTS: invalid schemas accepted
480 to 479, no other bucket raised.