bagme Tightens ZUGFeRD Embedding and Stays on a Weekly Bump Cadence


bagme is the Go layer that turns HTML into PDF documents with electronic invoice metadata attached, built on the boxesandglue and htmlbag libraries from the same author. The last seven days brought eight commits, 15 files changed, and 107 insertions against 54 deletions. Most of the visible work is in the electronic invoice path: how Factur-X namespaces are written into XMP, and which ZUGFeRD profiles get embedded as file attachments.

The most consequential fix of the week is f947e73, “Write the Factur-X XMP namespace for ZUGFeRD”. ZUGFeRD and Factur-X are the same format on paper, but validators check the PDF/A extension schema and metadata stream for the Factur-X namespace prefix. If your generator omits it, strict validators reject the file even though the embedded XML is fine.

That is the classic failure mode for e invoicing: the document opens in a viewer, the extractable XML parses, and then a gateway like a government portal or a procurement system drops it. The fix lives in the document package, which accounts for two commits this window including tests in document/document_test.go. If you generate ZUGFeRD invoices through bagme and a trading partner complained about metadata, this is the commit to line up with the report.

1687885 changes how MINIMUM and BASIC WL profile invoices are attached: they are now embedded as a Data relationship rather than something else. The distinction is not cosmetic.

ZUGFeRD profiles sit on a spectrum. MINIMUM and BASIC WL are the lighter tiers, aimed at simple invoices, while BASIC and EN 16931 levels carry full line item detail. Spec conformance requires the embedded file to use the Data relationship name with the right AF subtype, and validators flag files that get this wrong. For callers using the lighter profiles, the change means output that should now survive a strict conformance check instead of only opening in a viewer. There is a real tradeoff worth naming: anyone who post processed bagme output expecting the previous attachment arrangement may need to adjust, though the previous behavior was the nonconforming one.

The bulk of the commits are version churn, and it is worth being precise about what that churn is. 53bc09a on October 14, 39fed12 the next day, 90420e1 two days later, 6db889f on October 18, and finally 4d0cc19 today landing boxesandglue v0.2.95 and htmlbag v0.0.97. In a seven day window that is boxesandglue moving from 0.2.89 to 0.2.95 and htmlbag from 0.0.92 to 0.0.97, plus baseline-pdf from 1.1.27 to 1.1.29.

boxesandglue  v0.2.89 -> v0.2.95
htmlbag       v0.0.92 -> v0.0.97
baseline-pdf  v1.1.27 -> v1.1.29

Three of the five touches on go.mod and go.sum confirm this. bagme is a thin integration layer over its sibling libraries, which cuts both ways: the diff volume here is small, but real behavior changes in rendering or PDF generation arrive through dependency bumps rather than local commits. Operators pinning bagme in a build should treat this week as six patch steps of upstream change compressed into one.

c406c2e refreshes Readme.md. This is minor activity by any measure and mainly a signal that the project is trying to keep the front door current as the dependency floors move. Not much to act on here.

  • The document/document.go changes around Factur-X metadata are the files to diff against your current pin. If you validate invoices through a strict gateway, pull past this week and retest MINIMUM and BASIC WL output first.
  • The 0.x version tags on boxesandglue and htmlbag mean no semver stability promise. A weekly cadence of six patch versions is normal here, so budget for periodic go get -u cycles rather than treating bumps as opt in.
  • Expect more conformance work. Two invoice specification fixes landed in a single day, and the test file grew alongside them, which usually indicates the author is iterating against a real validator. Watch for further metadata or attachment edits in the document package before assuming this area is settled.