Skip to content

v0.0.58

Choose a tag to compare

@github-actions github-actions released this 28 Jul 22:39
v0.0.58
a8b6618

Pain001 Release v0.0.58

Release Date: 2026-07-29
Tag: v0.0.58
Python: 3.10+
Status: Stable

Executive Summary

A correctness release, and the most important one this package has
shipped. Two of the schemas it validated against were not ISO publications
but hand-authored placeholders permissive enough to accept documents ISO
does not allow. One of them was hiding a defect in the direct-debit
generator: every pain.008.001.02 file Pain001 has ever produced placed
<SeqTp> where the standard forbids it, and would have been rejected by the
receiving bank.
The placeholder schema validated those files as correct.

Anyone generating direct debits should upgrade. Anyone who has had a
pain.008 batch rejected without an obvious cause now has an explanation.

Alongside the fix: pain.001.001.13 support, real ISO schemas for every
bundled version, pain.002 response validation, and version migration
between modern versions.

Fixed

  • pain.008.001.02: <SeqTp> was emitted in the wrong place. ISO
    defines SeqTp inside PaymentTypeInformation20 — that is, within
    <PmtTpInf>. Pain001 emitted it as a bare child of
    <DrctDbtTxInf>. Real bank validators reject that. The 12 KB
    hand-authored schema this package shipped did not, which is why the defect
    survived. SeqTp now follows SvcLvl inside PmtTpInf, and the
    direct-debit preparer reads sequence_type from the data (defaulting to
    RCUR) rather than assuming it.

  • pain.001.001.12 was a 475-byte stub that accepted any document.
    --xml-message-type pain.001.001.12 reported successful schema validation
    without performing any. The genuine ISO schema now ships, so that
    validation is real. Files that previously "passed" may now fail; those
    failures are accurate.

  • Migration between modern versions was unsupported. VersionMapper
    refused v09 → v12, v10 → v09 and every other modern-to-modern pair with a
    DataSourceError. Modern-to-modern migration now works. Modern → legacy
    is still refused deliberately: the newer versions carry structured data
    the legacy schemas have nowhere to put, and silently dropping it would be
    worse than declining.

  • bundled_schema_versions and schema_for_namespace are exported.
    Both were documented as the way to check response-schema coverage but
    lived only in pain001.pain002.parser, so the documented import failed.

Added

  • pain.001.001.13 support — templates, schema and registry entry.
    Twelve message definitions now ship.

  • pain.002 response validation. parse_pain002_report(..., validate=True)
    checks a bank's status report against the bundled ISO schema for its
    namespace before parsing it. Bundled response schemas: pain.002.001.03
    (the version most SEPA banks reply with), .12, .14 and .15. When a
    bank replies in a version this package does not bundle, validation is
    refused explicitly rather than skipped silently.

  • tests/test_schema_completeness.py — the gate that would have caught
    all of the above. Every shipped schema must exceed 10 KB, define at least
    five complex types, and behaviourally reject a junk document. The
    structural checks alone would have passed the old pain.008 schema; the
    rejection test is what makes the gate meaningful. KNOWN_PLACEHOLDER_SCHEMAS
    is now empty, and adding to it requires a dated reason.

  • scripts/preflight_release.py (make release-check, FULL=1 for the
    slow checks) — an executable form of the RELEASING.md checklist, written
    after a missing release note failed the first v0.0.57 tag. It runs before
    tagging; the publish job checks the same things, but only after a tag has
    been pushed and must then be deleted from two places.

Changed

  • Every bundled schema is now a genuine ISO publication carrying a Standards
    Editor header. Four were replaced in this release.
  • SLSA provenance is generated by the provenance job inside ci.yml.
    A release created with GITHUB_TOKEN emits no events, so the previous
    on: release: published workflow could never fire for this pipeline — it
    looked armed and produced nothing. slsa.yml is now dispatch-only backfill.
  • The top-level LICENSE carries the full Apache-2.0 text with a trailing
    dual-licence note. A pointer file naming the dual licence satisfied the
    Best Practices badge but made GitHub report NOASSERTION.

Upgrading

pip install --upgrade pain001

No API changes. If you generate pain.008 files, regenerate them: output
from 0.0.57 and earlier carries the misplaced <SeqTp>. If you generate
pain.001.001.12, re-run validation — it now actually runs.