Commit Graph

5 Commits

Author SHA1 Message Date
85d435d035 fix(schema,regex): bound NFA state explosion and class-subtraction crash; land XSTS baseline
Running the full W3C XSTS archive to completion exposed three crash and hang
classes, now fixed with regression tests, which unblocked the #129 first
measurement.

- Content-model and regex NFA builders now cap total state count (2^20),
  degrading further occurrence/quantifier repetition to star, so nested
  high-maxOccurs schemas no longer OOM (was 8 GB on the MS Particles set).
- Content-model validation advances one active state-set per child instead of
  re-walking the prefix each time, removing the O(children^2) spin.
- Regex class subtraction [abc-[b]] no longer traps on a reversed range, and a
  reversed range such as [z-a] is rejected cleanly.

XSTS first measurement baselined: 75 valid schemas rejected, 2467 invalid
schemas accepted, 604 valid instances rejected, 582 invalid instances accepted
across 14383 groups. The suite runs green in 8s, opt-in via XSTS_ROOT.

Refs #129, #122.
2026-06-13 18:04:25 +02:00
4e0bd218db feat(schema): W3C XSTS runner and occurrence-unroll cap
The W3C XML Schema Test Suite (2006-11-06, ~13k groups; W3C Document
License, never vendored) runs opt-in via XSTS_ROOT: schemaTests must
compile or be rejected per their expected validity, instanceTests
validate against their group's schema, hrefs resolve against the
referencing file, and include/import locations from disk relative to
the schema. Disagreement counts are asserted exactly; baselines are
pending the first measurement (scheduled 2026-06-14), and failures
are written to /tmp/xsts-failures.txt for the burn-down. Building the
runner immediately caught a denial of service: maxOccurs in the
trillions (groupF009v) OOM-killed the process because the content
automaton unrolled occurrence counts literally; unrolling is capped
at 16384 with larger repetitions treated as unbounded, the libxml2
posture. Roadmap mermaid records the closed behavioral-parity set
(#141-#144, collation), the #139 performance epic, and XSTS moving
to runner-in. Advances #129.
2026-06-11 08:47:16 +02:00
b01499743c feat(schema): XSD wildcards and list built-in datatypes
Add xs:any and xs:anyAttribute wildcards with namespace and
processContents constraints (skip/lax/strict), and resolve the
list built-in datatypes (IDREFS, ENTITIES, NMTOKENS) to their
item types so each list item validates.

WildcardNamespace models ##any/##other/enumerated URI sets;
Wildcard.admits gates undeclared attributes and wildcard-matched
children. ContentNFA.follow exposes the follow set for completions.

Closes #77
2026-06-08 13:53:22 +02:00
b3e126c430 feat(editor): schema-driven completions and what-is-missing
Slice 3 of #94. From the compiled schema, compute exactly what is allowed at an
element, for autocomplete and "what's missing".

- ContentNFA.follow(after:) returns the precise follow-set: the element-name
  labels the content automaton can accept next after the children already
  present, plus whether the content may legally end there.
- Schema.Completions reports the allowed next elements, the complete flag (false
  means a required child is still expected), a wildcard flag, and each declared
  attribute with its required and present status.
- CompletionEngine resolves an element's declared type along a coding path (the
  global declaration, then each parent's content model) and computes the
  completions; Schema.Document.completions(at:in:) is the entry over a ranged
  tree.

Tests pin the follow-set as the children accumulate (name then qty then the
optional note, complete flipping true), the attribute required/present status,
and resolution for a nested element by its coding path.
2026-06-08 13:27:37 +02:00
135f9c5cb8 feat(schema): XSD complex types and particles
Add ComplexValidator validating an element against a ComplexType: attribute
uses (required, typed, unknown-attribute rejection) and the content model
(empty, simpleContent, elementOnly, mixed). Particles compile to a Thompson
NFA over element names honoring minOccurs/maxOccurs with sequence and choice
compositors; all groups are validated order-independently by counting. Child
elements are validated recursively against their declared types.

Closes #9
2026-06-08 06:33:51 +02:00