ED06 - Documents, DMS, e-invoicing: Order, retrograde/progressive traceability
Problem
An entrepreneur starts with document filing — and faces the question: How do I organize documents in a GoBD-compliant way, and how do I make them traceable?
Today's practice in the SME sector:
- Paper documents in folders — not electronic, not machine-evaluable, not retrograde/progressively traceable
- 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 evidence chain
- 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; posting records have no document reference
- (Often) No retrograde traceability — from the posting record, the auditor cannot resolve to the document because the reference is missing
- (Often) No progressive traceability — from the document, it is not possible to resolve to the posting record because the cross-references are missing
Key statement
GoBD-compliant document filing means:
- Every document has a unique identity (DocID) — the
uuidV7(Object ID) is already on its own the unique identity of the document, regardless of the file name. In addition, every document receives a SHA-256 hash as cryptographic integrity verification. The composite keyV7GUID:uuidV7serves filing organization (e.g., by document type) and DB queries (e.g., with EF Core in a Vertical App) — not identity itself. - Every document has a sidecar —
.gc.mdwith classification (V7GUID), object identity (uuidV7), taxonomy, obsolescence status, capture time (inuuidV7as a 48-bit timestamp). Exception (from 261011): documents that are transferred into a signature process (digital Eigenbeleg, e.g., entertainment receipt) carry their sidecar metadata entirely in*.gcsig.md(integratedsourceblock, schemagcsig-1.4); a separate.gc.mdis omitted — no competing sidecars. - Every posting record references its document —
source_sha256in the journal entry → document - Retrograde traceability — resolvable from posting record → document →
journal entry →
uuidV7 - Progressive traceability — resolvable from document → posting record → general ledger → 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 through subsequent sorting, but through structural mandatory fields (SHA-256, V7GUID, sidecar) and pre-commit hooks that check every posting record for a document reference.
Document types and their GoBD specifics
(Scan erforderlich)"] B --> PDF["PDF-Beleg
(sonstige Rechnung)"] B --> EML["E-Mail
(EML + Anhang)"] B --> XML["E-Rechnung
(XML - Ur-Dokument)"] P --> S["Scan → SHA-256
+ Sidecar"] PDF --> SH["SHA-256
+ Sidecar"] EML --> EM["EML archiviert
+ Anhang extrahiert
+ Sidecar"] XML --> XV["XML unverändert
+ Sidecar
+ Validierung (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 specific | Retention period |
|---|---|---|
| Paper document | Scan required (§ 147 Abs. 2 AO); 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 — PDF is unstructured | 8 years |
| Email (EML + attachment) | An email inbox is not an archive; EML must be archived with 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-invoicing since 2025: Since January 1, 2025, e-invoicing has been 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 exists only if it is issued, transmitted, and received in a structured electronic format (XML, EN 16931). See ED01 "E-invoicing: XML formats are original documents in the AO".
Document classification in the Git repo
Directory structure
ORG-1/sources/ # Belegarchiv (Tenant: ORG-1)
├── eingangsrechnungen/ # Eingangsrechnungen (Lieferanten)
│ ├── 260815/ # Nach Datum (YYMMDD)
│ │ ├── rechnung_001.xml # E-Rechnung (XRechnung)
│ │ ├── rechnung_001.xml.gc.md # Sidecar
│ │ └── rechnung_002.pdf # Sonstige Rechnung (PDF)
│ │ └── rechnung_002.pdf.gc.md # Sidecar
├── ausgangsrechnungen/ # Ausgangsrechnungen (Kunden)
├── lohnbelege/ # Lohnabrechnungen
├── sv-bescheide/ # SV-Bescheide, VBG-Bescheide
├── vertraege/ # Verträge (periodenübergreifend)
├── korrespondenz/ # E-Mails, Briefe
└── sonstige/ # Sonstige Belege
Sidecar per document (mandatory)
Every document receives a .gc.md sidecar with the composite key
V7GUID:uuidV7:
{
"$schema": "https://gitcover.org/schemas/v7g-sidecar-2.0.schema.json",
"V7GUID": "<V7GUID-Class-aus-Registry>",
"docUid": "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": "Primärspeicherort"
}
],
"v7g_taxonomy": [
{
"v7guid": "019f2c6f-0900-7000-8000-000000000000",
"taxonomy": "ORG-1/Eingangsrechnung",
"valid_from": "260815",
"valid_to": null,
"note": "Tenant: ORG-1, Category: Eingangsrechnung, Sphäre: wirtschaftlich"
}
],
"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 on its own the unique identity (DocID) of the document, generated with a predefined timestamp, 48-bit timestamp anchored in the GUIDV7GUID(Class) — classifies the document type from the.gitcoverregistry (document type, filing organization, DB query for Vertical App with EF Core)v7g_taxonomy[].v7guid— object ID of the classified documentgcpn.prima_nota_ref/journal_entry_ref— cross-reference to general ledger/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 contained inuuidV7
Retrograde and progressive traceability
SKR04 6000 an 1600"] BS --> SR["source_sha256
im Tagebucheintrag"] SR --> BE["Beleg
(SHA-256 match)"] BE --> SC["Sidecar .gc.md
V7GUID:uuidV7"] SC --> DE["Tagebucheintrag
uuidV7"] end subgraph PRO["Progressiv (Prüfer vom Beleg vorwärts)"] direction LR BE2["Beleg
(SHA-256)"] BE2 --> SC2["Sidecar .gc.md
gcpn.journal_entry_ref"] SC2 --> BS2["Buchungssatz
SKR04"] BS2 --> GB["Grundbuch
(JSON)"] GB --> EB["Eröffnungsbilanz"] 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 | Posting record (SKR04) | source_sha256 → document → sidecar uuidV7 |
Journal entry | Rz. 146 (traceability) |
| Progressive | Document (SHA-256) | Sidecar gcpn.journal_entry_ref → posting record → general ledger |
Opening balance sheet | Rz. 147 (verifiability) |
GoBD reference: Retrograde traceability corresponds to GoBD Rz. 146 (traceability — "a knowledgeable 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.
Findability: docUid instead of name/path (261026)
Every document reference in an invoice carries the docUid of the original document, not the name or path:
in XML as cac:AdditionalDocumentReference/cbc:ID (uuidV7), in the sidecar/GCPN as docUid.
The DMS registry adopts the same docUid as object_id — it does not invent a second
identity. A document is therefore uniquely findable by docUid, even if it is renamed or
moved.
The action that creates or stores a document is maintained as a pgid (process gateway,
V7GUID class): produced_by_pgid for creation (e.g., invoice creation 180),
stored_by_pgid for DMS registration (e.g., 183). Catalog:
GCUV/TOP/compliance/process_gateways.json; normative 8-bit values:
OSS/TOP/.gitcover/dictionaries/gateway_ids.json.
Single-file GCPN: For every invoice there is one .gcpn.md that lists the XML (original doc) and
PDF (view) in documents[], contains the workflow
create→pdf→present→accept→sign→register as well as events and relations
(contract/expense documents). XML/PDF remain separate files; a separate
.gc.md is omitted. Progressively (Rz. 147), one reads from the GCPN to the documents;
in retrograde (Rz. 146), from the docUid in the DMS via the GCPN to the documents.
Promote rule: After repo scan and sidecar creation, a .gc.md can be enriched into the GCPN;
the sidecar JSON data is embedded (GCPN = superset,
.gc.md = subset). After that, the separate .gc.md is redundant and can be removed;
the Git history remains the GoBD evidence, the GCPN is SSoT.
Invoice identity: invoice_id is a uuidV7 (ordering/reference criterion);
invoice_no is only text. Seller/buyer are referenced via their party uuidV7
(creditor/vendor or debitor/customer), not via real names (PII).
E-invoice: XML is the original document
(XML oder ZUGFeRD)"] ER --> V["Validierung
EN 16931 / XRechnung-Schema"] V -->|gültig| A["Ablage im Git-Repo
XML unverändert"] V -->|ungültig| R["Fehler-Logging
+ manuelle Prüfung"] A --> S["Sidecar .gc.md
SHA-256 + V7GUID:uuidV7"] S --> B["Buchungssatz
source_sha256 → XML"] B --> N["Nachverfolgbarkeit
retrograd + progressiv"] 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 (display aid only) |
Important — ZUGFeRD since 2025: In case of deviations 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 leading. The sidecar must reference the XML as the original document, not the PDF.
Pre-commit hook for e-invoices
The pre-commit hook checks the following for e-invoices:
| Check | Error if |
|---|---|
| XML file has valid XRechnung/ZUGFeRD structure | Invalid XML structure |
Sidecar .gc.md present |
Missing sidecar |
sha256 in sidecar matches XML file |
Hash mismatch (file changed) |
v7g_taxonomy classified as e-invoice |
Missing classification |
No datetime/date field in 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 — that is a GoBD violation.
(EML/MBOX)"] EM --> EX["Anhang extrahiert
(PDF, XML)"] EM --> AR["EML archiviert
(unverändert)"] EX --> SH["SHA-256 pro Anhang"] AR --> SH2["SHA-256 der EML"] SH --> SC["Sidecar .gc.md
pro Beleg"] SH2 --> SC2["Sidecar .gc.md
für E-Mail"] 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 |
|---|---|---|
| Receive email | Store EML file unchanged | § 147 Abs. 1 Nr. 2 AO (received commercial letters) |
| Extract attachment | Store PDF/XML attachment separately + SHA-256 | Machine evaluability (§ 147 Abs. 6 AO) |
| Sidecar per document | .gc.md for EML and for each attachment |
Traceability (Rz. 146) |
| Sender verification | DKIM/SPF headers documented in sidecar | Evidentiary value of the email |
Practical tip: A Git repo can archive emails (EML/MBOX) and attachments (PDF, XML) in parallel — with clear separation by document type in the sidecar (
v7g_taxonomy). The pre-commit hook checks that every EML has a sidecar and every attachment is classified separately.
Document completeness (pre-commit hook)
vorhanden?"} P1 -->|nein| R1["Commit abgelehnt
Belegreferenz fehlt"] P1 -->|ja| P2{"Beleg existiert
im Repo?"} P2 -->|nein| R2["Commit abgelehnt
Beleg nicht gefunden"] P2 -->|ja| P3{"Sidecar .gc.md
vorhanden?"} P3 -->|nein| R3["Commit abgelehnt
Sidecar fehlt"] P3 -->|ja| P4{"SHA-256 match?"} P4 -->|nein| R4["Commit abgelehnt
Beleg verändert"] P4 -->|ja| OK["Commit akzeptiert
Beleg-Vollständigkeit 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 (traceability) |
| Document exists in repo | Document not archived | § 147 Abs. 1 Nr. 4 AO (accounting document) |
| Sidecar present | Missing classification | Rz. 146 (traceability) |
| SHA-256 match | Document subsequently changed | Rz. 146 (immutability) |
Risk leverage
| Today (cheap) | Tomorrow (audit-proof) | Risk mitigated |
|---|---|---|
| SHA-256 per document | Unique document ID, independent of file name | Challenge to document authenticity |
Sidecar with composite key V7GUID:uuidV7 |
Classification act traceable | Challenge to classification |
source_sha256 per posting record |
Retrograde traceability | Challenge to document allocation |
gcpn.journal_entry_ref in sidecar |
Progressive traceability | Challenge to posting |
| E-invoice XML unchanged + sidecar | § 14b UStG compliant (integrity) | Non-deductibility of input VAT |
| Email EML archived + sidecar | § 147 Abs. 1 Nr. 2 AO compliant | Loss of evidence in disputes with authorities |
| Pre-commit hook checks document completeness | No posting record without document | GoBD violation "incomplete" |
Harness requirement (preview)
Derivable from ED06:
| ID | Requirement | Priority |
|---|---|---|
| FA-2.1 | SHA-256 as document ID | MUST |
| FA-2.2 | Sidecar per document — *.gc.md or (for signed documents/Eigenbelege) integrated into *.gcsig.md |
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 is in Harness-Anforderungen.md.
Sources
- GoBD (BMF letter, Rz. 146 — traceability, Rz. 147 — verifiability)
- AO (§ 147 Abs. 1 Nr. 2/3 — commercial letters, § 147 Abs. 1 Nr. 4 — accounting documents, § 147 Abs. 2 — machine-evaluable, § 147 Abs. 3 — retention periods)
- UStG (§ 14 — e-invoice, § 14b — retention)
- BMF FAQ on e-invoicing (as of March 2026)
- EN 16931 (CEN/TC 434 — XRechnung, ZUGFeRD)
E1/agents/(anonymized) — SSoT concept with document archive, sidecars
Source topology and CDN reference links
| Role | Location | Purpose |
|---|---|---|
| Primary / SSoT | git.gitcover.org/GCC | Canonical repository (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 assignment 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.