ED06 - Documents, DMS, e-invoices: Order, retrograde/progressive traceability
Problem
An entrepreneur starts filing documents - and faces the question: How do I organize documents in a GoBD-compliant way, and how do I make them traceable?
Current practice in the SME sector:
- Paper documents in folders - not electronic, not machine-evaluable, not traceable retrogradely/progressively
- PDFs in cloud accounts - not GoBD-compliant (no immutability, no machine evaluability, dependency on the service provider)
- Emails with PDF attachments - not archived (an email inbox is not an archive), no document authenticity, no chain of evidence
- e-invoices (XML) not understood - many entrepreneurs do not know that since 2025 the XML file is the original document, not the PDF
- (Often) No order - documents are filed by date, not by transaction; booking entries have no document reference
- (Often) No retrograde traceability - from the booking entry, the auditor cannot resolve to the document because the reference is missing
- (Often) No progressive traceability - from the document, it cannot be resolved to the booking entry because the cross-references are missing
Core statement
GoBD-compliant document filing means:
- Every document has a unique identity (DocID) - the
uuidV7(Object ID) is already by itself the unique identity of the document, regardless of the file name. In addition, every document receives a SHA-256 hash as a cryptographic integrity check. The Composite KeyV7GUID:uuidV7serves the filing organization (e.g. by document type) and DB queries (e.g. with EF Core in a Vertical App) - not the identity itself. - Every document has a sidecar -
.v7g.mdwith classification (V7GUID), object identity (uuidV7), taxonomy, obsolescence status, capture time (inuuidV7as a 48-bit timestamp) - Every booking entry references its document -
source_sha256in the journal entry → document - Retrograde traceability - resolvable from the booking entry → document →
journal entry →
uuidV7 - Progressive traceability - resolvable from the document → booking entry → Grundbuch → opening balance sheet
- e-invoice: XML is the original document - not the PDF (since 2025, § 14 UStG, EN 16931)
Compliance by Design: Document order does not arise from retrospective sorting, but from structural mandatory fields (SHA-256, V7GUID, sidecar) and pre-commit hooks that check every booking entry for a document reference.
Document types and their GoBD specifics
(scan required)"] B --> PDF["PDF document
(other invoice)"] B --> EML["Email
(EML + attachment)"] B --> XML["e-invoice
(XML - original document)"] P --> S["Scan → SHA-256
+ sidecar"] PDF --> SH["SHA-256
+ sidecar"] EML --> EM["EML archived
+ attachment extracted
+ sidecar"] XML --> XV["XML unchanged
+ sidecar
+ validation (EN 16931)"] style B fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style P fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style PDF fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style EML fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style XML fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style S fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style SH fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style EM fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style XV fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33
| Document type | GoBD specifics | Retention period |
|---|---|---|
| Paper document | Scan required (§ 147 Abs. 2 AO); the original may be destroyed if the scan is GoBD-compliant | 8 years (§ 147 Abs. 3 AO) |
| PDF document ("other invoice") | Since 2025 no longer an "e-invoice"; SHA-256 + sidecar; machine-evaluable? No - the PDF is unstructured | 8 years |
| Email (EML + attachment) | An email inbox is not an archive; the EML must be archived together with the attachment; sender verification | 6 years (§ 147 Abs. 1 Nr. 2/3 AO) |
| e-invoice (XML) | XML is the original document (since 2025, § 14 UStG); retain unchanged; EN 16931 validation; machine-evaluable | 8 years |
Important - e-invoice since 2025: Since 1 January 2025, the e-invoice is mandatory for B2B transactions between domestic companies (§ 14 UStG). A simple PDF is no longer an e-invoice - it is an "other invoice". An e-invoice is only present if it is issued, transmitted and received in a structured electronic format (XML, EN 16931). See ED01 "e-invoice: XML formats are original documents under the AO".
Document classification in the Git repo
Directory structure
ORG-1/sources/ # document archive (Tenant: ORG-1)
├── eingangsrechnungen/ # incoming invoices (suppliers)
│ ├── 260815/ # by date (YYMMDD)
│ │ ├── rechnung_001.xml # e-invoice (XRechnung)
│ │ ├── rechnung_001.xml.v7g.md # sidecar
│ │ └── rechnung_002.pdf # other invoice (PDF)
│ │ └── rechnung_002.pdf.v7g.md # sidecar
├── ausgangsrechnungen/ # outgoing invoices (customers)
├── lohnbelege/ # payroll statements
├── sv-bescheide/ # SV notices, VBG notices
├── vertraege/ # contracts (cross-period)
├── korrespondenz/ # emails, letters
└── sonstige/ # other documents
Sidecar per document (mandatory)
Every document receives a .v7g.md sidecar with the Composite Key
V7GUID:uuidV7:
{
"$schema": "https://gitcover.org/schemas/v7g-sidecar-1.0.schema.json",
"V7GUID": "<V7GUID-Class-from-Registry>",
"uuidV7": "019f2c6f-0900-7001-8000-000000000001",
"sha256": "ab94670c0dd8499c27ef2feddd1d9c5925977d55a52150a6fca0f6567d2e5e79",
"title": "260815_Rechnung_001.xml",
"original_filename": "Rechnung_001.xml",
"locations": [
{
"unc_path": "./ORG-1/sources/eingangsrechnungen/260815/rechnung_001.xml",
"from": "260815",
"to": null,
"note": "Primary storage location"
}
],
"v7g_taxonomy": [
{
"v7guid": "019f2c6f-0900-7000-8000-000000000000",
"taxonomy": "ORG-1/Eingangsrechnung",
"valid_from": "260815",
"valid_to": null,
"note": "Tenant: ORG-1, Category: Eingangsrechnung, Sphere: economic"
}
],
"gcpn": {
"prima_nota_ref": "GB-2026-08-001",
"journal_entry_ref": "J-2026-08-001"
},
"obsolescence": {
"status": "active",
"superseded_by": null,
"superseded_at": null
}
}
Composite Key
V7GUID:uuidV7- filing organization and query:
uuidV7(Object ID) - is already by itself the unique identity (DocID) of the document, generated with a preset timestamp, 48-bit timestamp anchored in the GUIDV7GUID(Class) - classifies the document type from the.gitcoverregistry (document type, filing organization, DB query in a Vertical App with EF Core)v7g_taxonomy[].v7guid- Object ID of the classified documentgcpn.prima_nota_ref/journal_entry_ref- cross-reference to Grundbuch/journal (progressive traceability)- The Composite Key
V7GUID:uuidV7serves filing organization and query - the identity of the document is theuuidV7alone- No separate
datetimefield - the time is embedded inuuidV7
Retrograde and progressive traceability
SKR04 6000 to 1600"] BS --> SR["source_sha256
in the journal entry"] SR --> BE["Document
(SHA-256 match)"] BE --> SC["Sidecar .v7g.md
V7GUID:uuidV7"] SC --> DE["Journal entry
uuidV7"] end subgraph PRO["Progressive (auditor from the document forwards)"] direction LR BE2["Document
(SHA-256)"] BE2 --> SC2["Sidecar .v7g.md
gcpn.journal_entry_ref"] SC2 --> BS2["Booking entry
SKR04"] BS2 --> GB["Grundbuch
(JSON)"] GB --> EB["Opening balance sheet"] end style BS fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style SR fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style BE fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style SC fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style DE fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style BE2 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style SC2 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style BS2 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style GB fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style EB fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33
| Direction | Start | Resolution via | Target | GoBD reference |
|---|---|---|---|---|
| Retrograde | Booking entry (SKR04) | source_sha256 → document → sidecar uuidV7 |
Journal entry | Rz. 146 (comprehensibility) |
| Progressive | Document (SHA-256) | sidecar gcpn.journal_entry_ref → booking entry → Grundbuch |
Opening balance sheet | Rz. 147 (verifiability) |
GoBD reference: Retrograde traceability corresponds to GoBD Rz. 146 (comprehensibility - "expert third party within a reasonable time"). Progressive traceability corresponds to GoBD Rz. 147 (verifiability). Both are guaranteed by design through SHA-256 + V7GUID + sidecar - not through manual cross-references.
e-invoice: XML is the original document
(XML or ZUGFeRD)"] ER --> V["Validation
EN 16931 / XRechnung schema"] V -->|valid| A["Filing in the Git repo
XML unchanged"] V -->|invalid| R["Error logging
+ manual review"] A --> S["Sidecar .v7g.md
SHA-256 + V7GUID:uuidV7"] S --> B["Booking entry
source_sha256 → XML"] B --> N["Traceability
retrograde + progressive"] style ER fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style V fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style A fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style R fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style S fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style B fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style N fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33
XRechnung vs. ZUGFeRD
| Format | Structure | Original document | Visualization |
|---|---|---|---|
| XRechnung | Pure XML (EN 16931) | XML file | XML viewer required (e.g. ELSTER (e-rechnung.elster.de)[https://e-rechnung.elster.de] |
| ZUGFeRD | Hybrid: PDF + embedded XML | XML part (authoritative since 2025, BMF FAQ 12a) | PDF image (auxiliary display only) |
Important - ZUGFeRD since 2025: In the event of discrepancies between the XML part and the PDF image part, the structured (XML) part is authoritative since 2025 (BMF FAQ question 12a). The PDF image is no longer the leading version. The sidecar must reference the XML as the original document, not the PDF.
Pre-commit hook for e-invoices
For e-invoices, the pre-commit hook checks:
| Check | Error if |
|---|---|
| XML file has valid XRechnung/ZUGFeRD structure | Invalid XML structure |
Sidecar .v7g.md present |
Missing sidecar |
sha256 in the sidecar matches the XML file |
Hash mismatch (file modified) |
v7g_taxonomy classifies as e-invoice |
Missing classification |
No datetime/date field in the sidecar (time in uuidV7) |
Redundant field |
Email archiving
Emails are commercial or business letters within the meaning of § 147 Abs. 1 Nr. 2/3 AO and must therefore be retained for 6 years. Many entrepreneurs do not archive emails - this is a GoBD violation.
(EML/MBOX)"] EM --> EX["Attachment extracted
(PDF, XML)"] EM --> AR["EML archived
(unchanged)"] EX --> SH["SHA-256 per attachment"] AR --> SH2["SHA-256 of the EML"] SH --> SC["Sidecar .v7g.md
per document"] SH2 --> SC2["Sidecar .v7g.md
for the email"] style EM fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style EX fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style AR fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style SH fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style SH2 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style SC fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style SC2 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33
| Step | Action | GoBD reference |
|---|---|---|
| Email received | Store the EML file unchanged | § 147 Abs. 1 Nr. 2 AO (commercial letters received) |
| Extract attachment | Store the PDF/XML attachment separately + SHA-256 | Machine evaluability (§ 147 Abs. 6 AO) |
| Sidecar per document | .v7g.md for the EML and for each attachment |
Comprehensibility (Rz. 146) |
| Sender verification | DKIM/SPF headers documented in the sidecar | Evidentiary value of the email |
Practical tip: A Git repo can archive emails (EML/MBOX) and attachments (PDF, XML) in parallel - with a clear separation by document type in the sidecar (
v7g_taxonomy). The pre-commit hook checks that every EML has a sidecar and that every attachment is classified separately.
Document completeness (pre-commit hook)
present?"} P1 -->|no| R1["Commit rejected
document reference missing"] P1 -->|yes| P2{"Document exists
in the repo?"} P2 -->|no| R2["Commit rejected
document not found"] P2 -->|yes| P3{"Sidecar .v7g.md
present?"} P3 -->|no| R3["Commit rejected
sidecar missing"] P3 -->|yes| P4{"SHA-256 match?"} P4 -->|no| R4["Commit rejected
document modified"] P4 -->|yes| OK["Commit accepted
document completeness OK"] style C fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style H fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style P1 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style P2 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style P3 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style P4 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style R1 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style R2 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style R3 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style R4 fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style OK fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33
| Check | Error if | GoBD reference |
|---|---|---|
source_sha256 present |
Missing document reference | Rz. 146 (comprehensibility) |
| Document exists in the repo | Document not archived | § 147 Abs. 1 Nr. 4 AO (booking document) |
| Sidecar present | Missing classification | Rz. 146 (comprehensibility) |
| SHA-256 match | Document modified afterwards | Rz. 146 (immutability) |
Risk leverage
| Today (cheap) | Tomorrow (audit-proof) | Risk mitigated |
|---|---|---|
| SHA-256 per document | Unique document ID, independent of the file name | Dispute of document authenticity |
Sidecar with Composite Key V7GUID:uuidV7 |
Classification act comprehensible | Dispute of the classification |
source_sha256 per booking entry |
Retrograde traceability | Dispute of the document assignment |
gcpn.journal_entry_ref in the sidecar |
Progressive traceability | Dispute of the booking |
| e-invoice XML unchanged + sidecar | Compliant with § 14b UStG (integrity) | Non-deductibility of input tax |
| Email EML archived + sidecar | Compliant with § 147 Abs. 1 Nr. 2 AO | Loss of evidence in disputes with authorities |
| Pre-commit hook checks document completeness | No booking entry without a document | GoBD violation "not complete" |
Harness requirement (preview)
Derivable from ED06:
| ID | Requirement | Priority |
|---|---|---|
| FA-2.1 | SHA-256 as document ID | MUST |
| FA-2.2 | .v7g.md sidecar mandatory per document |
MUST |
| FA-2.3 | Sidecar with Composite Key V7GUID:uuidV7 |
MUST |
| FA-2.8 | DMS functionality: document classification | MUST |
| FA-2.9 | e-invoice integration: XRechnung/ZUGFeRD import, validation | SHOULD |
| FA-2.10 | Email archiving: EML + SHA-256 + sidecar | MUST |
| FA-2.11 | GoBD order: index per fiscal year | MUST |
| FA-2.12 | Retrograde traceability | MUST |
| FA-2.13 | Progressive traceability | MUST |
| FA-2.14 | Pre-commit hook: check document completeness | MUST |
| FA-2.15 | Scan workflow: paper → scan → SHA-256 → sidecar | SHOULD |
The complete list of requirements in Harness-Anforderungen.md.
Sources
- GoBD (BMF letter, Rz. 146 - comprehensibility, Rz. 147 - verifiability)
- AO (§ 147 Abs. 1 Nr. 2/3 - commercial letters, § 147 Abs. 1 Nr. 4 - booking documents, § 147 Abs. 2 - machine-evaluable, § 147 Abs. 3 - retention periods)
- UStG (§ 14 - e-invoice, § 14b - retention)
- BMF FAQ on e-invoices (as of March 2026)
- EN 16931 (CEN/TC 434 - XRechnung, ZUGFeRD)
AFJD/agents/(anonymized) - SSoT concept with document archive, sidecars
Source topology and CDN reference links
| Role | Location | Purpose |
|---|---|---|
| Primary / SSoT | git.gitcover.org/GCC | Canonical storage (GPG-signed, versioned) |
| Public OSS Mirror / CDN | codeberg.org/gitcover-commons | Read-only mirror; FLOSS discovery |
| Community Hub | github.com/gitcover-commons | Issues & Discussions; source code reference on Codeberg |
Note: This mapping of sources, mirror, and community hub reflects the current state and may change. Please check the respective canonical source on gitcover.org for the current state.