Conformance report
From the conformance report, regenerated by npm run conformance on every CI run.
Our runtime validator (the code validate() runs in Node and, minus XSD, in a browser) compared with the official validators on the official sample files.
Pinned inputs
| Artefact | Version | Pin |
|---|---|---|
| kosit-xrechnung-config | 2026-08-31 (XRechnung 3.0.2) | 2530cd107c41 |
| kosit-validator | 1.6.3 | 799e64befca9 |
| cen-en16931 | validation-1.3.17 | 6e35e0ab8b09 |
| peppol-bis-3 | 3.0.22 | 38d693d71d28 |
| schxslt2 | 1.11.3 | 8afe545678c2 |
| factur-x-wheel | 6.8 | 02b57dd57f59 |
| xrechnung-testsuite | v2026-08-31 | 44c3905c69ca |
| saxonjs-runtime | 2.7 | 13cbd2e6eb0a |
| ksef-docs | main@ce3670e (FA(3) schema v1-0E) | ce3670ea042d |
| mustang-cli | 2.26.0 | 42d7868cb682 |
How to read this
- Reference agreement: for every file, the rule sets our engine chose (from the root element and BT-24) are run by Saxon-HE on the same publisher XSLT; XSD by lxml. We require the same failed rule ids, the same advisory rule ids and the same number of fired rules per rule set, and the same XSD verdict.
- KoSIT agreement: the official KoSIT validator (java, validator-configuration-xrechnung) says ACCEPTABLE or not; compared where KoSIT has a scenario for the document (XRechnung and plain EN 16931). Our
validmust equal KoSIT's acceptance. - Round trip (valid documents only): parse to our model, write it back in the same syntax and profile, validate again, read it again (must be identical to the first read), and compare the document's stated totals with the totals computed from the model.
Summary
| Corpus | Files | Not CII/UBL | Reference agreement | Rule expectation | KoSIT agreement | Round trip: revalidates | fixed point | totals |
|---|---|---|---|---|---|---|---|---|
| KoSIT XRechnung test suite | 86 | 0 | 86/86 (100.0%) | n/a | 86/86 (100.0%) | 86/86 | 86/86 | 85/86 |
| Peppol BIS Billing 3.0 examples | 10 | 0 | 10/10 (100.0%) | n/a | 0/0 (n/a) | 10/10 | 10/10 | 10/10 |
| CEN EN 16931 example files | 63 | 0 | 63/63 (100.0%) | n/a | 28/28 (100.0%) | 35/35 | 34/35 | 34/35 |
| IBAN arithmetic checks (generated: BR-DE-19 / BR-DE-20, XRechnung CII and UBL) | 18 | 0 | 18/18 (100.0%) | n/a | 18/18 (100.0%) | 0/0 | 0/0 | 0/0 |
| KoSIT scenario selection (generated: BT-24 identifiers, XRechnung CII, UBL Invoice, UBL CreditNote) | 30 | 0 | 30/30 (100.0%) | n/a | 30/30 (100.0%) | 0/0 | 0/0 | 0/0 |
| CEN EN 16931 rule unit tests (one failing document per rule) | 907 | 0 | 907/907 (100.0%) | 907/907 | 0/0 (n/a) | 0/0 | 0/0 | 0/0 |
Overall reference agreement: 1114/1114 (100.0%).
Sources:
- KoSIT XRechnung test suite: itplr-kosit/xrechnung-testsuite v2026-08-31
- Peppol BIS Billing 3.0 examples: OpenPEPPOL/peppol-bis-invoice-3 3.0.22
- CEN EN 16931 example files: ConnectingEurope/eInvoicing-EN16931 validation-1.3.17
- IBAN arithmetic checks (generated: BR-DE-19 / BR-DE-20, XRechnung CII and UBL): generated by tools/conformance/run.ts from fixtures/xrechnung-public-sector.json
- KoSIT scenario selection (generated: BT-24 identifiers, XRechnung CII, UBL Invoice, UBL CreditNote): generated by tools/conformance/run.ts from fixtures/xrechnung-public-sector.json
- CEN EN 16931 rule unit tests (one failing document per rule): ConnectingEurope/eInvoicing-EN16931 validation-1.3.17
Runtime patches
Conformo runs the publishers' rule files in SaxonJS (Node and browser). SaxonJS 2.7 implements xs:integer with JavaScript doubles, which are exact only up to 2^53 (about 16 digits); Saxon-HE, which the KoSIT validator and the reference column above use, has arbitrary precision. The following exact source edits are applied to the publisher's XSLT before it is compiled for SaxonJS. A patch must match exactly the stated number of times or the build fails, so a changed publisher rule is noticed. The reference column runs the unpatched publisher XSLT in Saxon-HE, so agreement above is measured against the original rules.
| Patch | Rule sets (matches) | Edit | Why |
|---|---|---|---|
iban-mod97-decimal | xrechnung-cii (1), xrechnung-ubl (1), peppol-ubl (3) | xs:integer(string-join(for $cp in string-to-codepoints(concat( becomes xs:decimal(string-join(for $cp in string-to-codepoints(concat( | SaxonJS computes xs:integer with doubles; the IBAN mod-97 check needs up to 34 digits |
The generated corpus "IBAN arithmetic checks" covers this: valid and invalid IBANs of 22 to 32 characters, payment means 58 and 59, XRechnung CII and UBL, none of which the official test invoices combine.
The generated corpus "KoSIT scenario selection" covers which KoSIT scenario a document gets: KoSIT matches BT-24 by exact text equality, so a wrong identifier, extra whitespace or another letter case finds no scenario and the file is rejected. The official test invoices only carry correct identifiers. In this corpus a "no scenario" answer counts as a rejection and must match our verdict.
Not covered, and why: the official FeRD/ZUGFeRD sample set and the Factur-X samples are published on sites this build environment could not reach (see KNOWN-GAPS.md), so PDF samples are not part of this report.
Comparison with Mustangproject (informative)
Mustangproject is a widely used Java library for ZUGFeRD/Factur-X and XRechnung. Mustang-CLI 2.26.0 (--action validate) was run on the same official files as Conformo's validate() with full rule sets including XSD. Mustang ships its own copies of the rules, which can be older or newer than the pins above, and adds checks of its own (for example a recalculation of totals). Where the two verdicts differ, the official KoSIT validator decides. This is informative, not a CI gate: it is recorded with npm run compare:mustang -- --corpora --record and rendered here by the conformance run.
| Corpus | Files | Same verdict | Both valid | Both invalid | Same failed rule ids |
|---|---|---|---|---|---|
| KoSIT XRechnung test suite (v2026-08-31) | 86 | 82/86 | 82 | 0 | 82/86 |
| CEN EN 16931 example files (validation-1.3.17) | 63 | 29/63 | 29 | 0 | 29/63 |
Different verdicts on 38 file(s). The official KoSIT validator had a scenario for 7 of them and agreed with Conformo on 7, with Mustang on 0.
Mustang reports rule failures that the rules Conformo runs for this document (CEN's release and the KoSIT configuration) do not raise as errors. (3 files)
kosit-testsuite/src/test/business-cases/extension/04.05a-INVOICE_uncefact.xml: Conformo valid, Mustang invalid, Mustang only: BR-CL-10, BR-CL-21 (KoSIT: agrees with Conformo)kosit-testsuite/src/test/business-cases/extension/05.01a-INVOICE_ubl.xml: Conformo valid, Mustang invalid, Mustang only: BR-CO-16 (KoSIT: agrees with Conformo)kosit-testsuite/src/test/technical-cases/cvd/02.01a-cvd_INVOICE_uncefact.xml: Conformo valid, Mustang invalid, Mustang only: BR-CL-13 (KoSIT: agrees with Conformo)
Mustang stopped with an internal Java exception while checking the file, and reports it invalid. (3 files)
kosit-testsuite/src/test/technical-cases/cvd/02.01a-cvd_INVOICE_ubl.xml: Conformo valid, Mustang invalid, Mustang only: BR-CL-13, mustang-exception-22 (KoSIT: agrees with Conformo)cen-examples/cii/examples/CII_example5.xml: Conformo valid, Mustang invalid, Mustang only: mustang-exception-22 (KoSIT: agrees with Conformo)cen-examples/cii/examples/huf_example_cii.xml: Conformo valid, Mustang invalid, Mustang only: mustang-exception-22 (KoSIT: agrees with Conformo)
The document declares Peppol BIS Billing 3.0 in BT-24, so Conformo also applies the OpenPeppol rules, which the document fails; Mustang does not apply the Peppol BIS rules. (28 files)
cen-examples/ubl/examples/issue116.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-DataIT.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Elhandel.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R040, PEPPOL-COMMON-R049 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Elnat.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Factoring.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Forskott_(ej moms).xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Forskott_slutreglering.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Hyrbil.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Inkopskort.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Kreditering_(urspr_faktura).xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R040, PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Kreditering_med_kreditnota.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R040, PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Kreditering_med_negativ_faktura.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R040, PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-OmvandSkattskyldighet.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Rabatter_och_avgifter.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R040, PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Rantefaktura_Enkel.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Rantefaktura_Saml.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Resor_Bokning.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Resor_Taxi.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Telefoni.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Tjanster_Bevakning.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R040, PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Tjanster_Kopiering.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/BIS_Billing_30-Valutor i faktura.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/CreditNote-Max_content.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/CreditNote-Min_content_with_VAT.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/CreditNote-Min_content_without_VAT.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/Invoice-Max_content.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/Invoice-Min_content_with_VAT.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/test/testfiles/Invoice-Min_content_without_VAT.xml: Conformo invalid, Mustang valid, Conformo only: PEPPOL-COMMON-R049, SE-R-013 (no KoSIT scenario; the publisher's own rule files agree with Conformo)
Mustang does not support the profile the document declares (ZUGFeRD 1.0), and reports it invalid. (3 files)
cen-examples/cii/examples/CII-BR-CO-10-RoundingIssue.xml: Conformo valid, Mustang invalid, Mustang only: mustang-type-25 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/cii/examples/CII_business_example_02.xml: Conformo valid, Mustang invalid, Mustang only: mustang-type-25 (no KoSIT scenario; the publisher's own rule files agree with Conformo)cen-examples/cii/examples/CII_business_example_Z.xml: Conformo valid, Mustang invalid, Mustang only: mustang-type-25 (no KoSIT scenario; the publisher's own rule files agree with Conformo)
**Mustang also applies its own Factur-X Schematron (FX-SCH-*) to a plain CII document.** (1 file)
cen-examples/cii/examples/XRechnung-O.xml: Conformo valid, Mustang invalid, Mustang only: FX-SCH-A-000589, FX-SCH-A-000616 (KoSIT: agrees with Conformo)
Mismatches and failures
3 finding(s); 0 unexplained.
kosit-testsuite/src/test/business-cases/extension/05.01a-INVOICE_ubl.xml— roundtrip-totals: due: document 36686 vs computed 33690- Explanation: XRechnung extension scenario with third-party payment (BG-DEX-09, cac:PrepaidPayment, two prepaid amounts). The model has no BG-DEX-09, so on re-reading the amount due is computed without them; the conversion reports this in parse().totalsCheck instead of hiding it. Extension-only terms are out of scope.
cen-examples/cii/examples/XRechnung-O.xml— roundtrip-fixpoint: buyer.electronicAddressScheme: EM -> (absent)- Explanation: The document has an empty buyer electronic address element that carries only schemeID="EM". There is no address to preserve, so the writer emits nothing and the scheme is gone on the second read. No business value is lost.
cen-examples/cii/examples/huf_example_cii.xml— roundtrip-totals: taxTotal: document 1867900 vs computed 1867860; grand: document 8785900 vs computed 8785860; due: document 8785900 vs computed 8785860- Explanation: Hungarian invoice in HUF that states VAT rounded to the nearest 100 forint (1,867,900 where 27% of the taxable amount is 1,867,860). The CEN rules accept it; Conformo recomputes totals from the lines to the minor unit and reports the difference (parse().totalsCheck, and a warning on convert). Hungarian national rounding is not implemented.
Files not processed
None.