@getpeppr/sdk 5.2.0 corrects a dangerous kind of validation bug in
validateSchematron(): a finding could cite a real Peppol rule while checking
something else. The ID existed, so a simple “does this rule exist?” test stayed
green — but the label still sent developers to the wrong requirement.
Validation decisions are unchanged. The same inputs produce findings with the
same severities and the same valid result. SchematronViolation.ruleId
changes, and two misleading warning sentences are corrected.
The scope is deliberately narrow: this release changes the schematron
result only. The separate structure result from validateInvoice() and the
country-specific result keep their existing identifiers; GPR-1267 tracks the
reverse audit of those two writers.
One exact network mapping
The SDK's “at least one invoice line” check used BR-08, which officially
means the seller postal address. Its exact Peppol rule is BR-16, and that is
the ID returned from 5.2.0 onward.
Ten checks are explicitly local
The other checks are useful pre-flight diagnostics, but none exactly matches
the official rule whose ID it borrowed. They now use a GETPEPPR-* prefix:
BR-03→GETPEPPR-ISSUE-DATE-DEFAULTEDBR-06→GETPEPPR-FROM-VAT-RECOMMENDEDBR-09→GETPEPPR-PAYMENT-TIMING-RECOMMENDEDBR-10→GETPEPPR-BUYER-OR-ORDER-REFERENCE-RECOMMENDEDBR-CO-10→GETPEPPR-LINE-NET-SANITYBR-CO-13→GETPEPPR-COMPUTED-VAT-SANITYBR-CO-15→GETPEPPR-TAX-INCLUSIVE-SANITYBR-CO-16→GETPEPPR-PAYABLE-SANITYPEPPOL-EN16931-R004→GETPEPPR-BUYER-PEPPOL-ID-REQUIREDPEPPOL-EN16931-R080→GETPEPPR-UNIT-CODE-RECOGNISED
Four of these — the issue-date, line-net, tax-inclusive and payable sanity checks — were found while building the behaviour lock for the seven IDs originally under investigation. They were the same reachable defect and are corrected in the same release.
The distinction matters. For example, the SDK's buyer-reference check is an
advisory warning, while the official PEPPOL-EN16931-R003 rule is fatal. The
unit warning checks the SDK's small convenience list, while official
BR-CL-23 accepts hundreds of Rec20/21 codes. Reusing those official IDs would
still overstate what the SDK had proved.
That unit warning also used to say every code outside the convenience list was
“not a known UN/ECE Rec20 code”. This was false for valid codes such as KWH.
It now says exactly what was measured: the code is absent from the SDK's common
unit list, and network validation decides whether it is legal.
The payable warning also blamed prepaidAmount whenever the computed result
was negative. Allowances and rounding can produce the same result, so the new
message names the values to inspect without asserting a cause it did not prove.
The lock compares behaviour, not spelling
A new test runs the SDK check and the graved Peppol Schematron engine on
equivalent documents. It proves BR-16 fires on both sides, and proves each
local diagnostic either has no exact fatal counterpart or is intentionally
broader or softer than the nearest network rule. A real rule ID that describes
different behaviour can no longer pass merely because its spelling exists in
the rulebook.
CLI 0.11.1
@getpeppr/cli bundles its own copy of the SDK. Version 0.11.1 rebundles SDK
5.2.0 so the command's schematron result reports the corrected IDs too. Its
separate structure and countryRules sections are unchanged. Validation exit
codes and the --json shape do not change. Human-readable output now says
Offline Checks (partial) and reports whether pre-flight checks passed or found
errors; it no longer claims that this partial pass proves invoice validity or
non-compliance.
Upgrading
npm install @getpeppr/sdk@5.2.0
npm install --global @getpeppr/cli@0.11.1
If your application or CI filters findings by ruleId or warning text, update
those filters using the mappings above. If it only reacts to valid, errors
or warnings, no decision-logic change is required.