ED02 - Le modèle organisationnel des PME : Tenants, Sphères, Rôles
Problème
Un entrepreneur crée une organisation - et se trouve confronté à la question : Comment structurer mon organisation afin que les obligations de conformité soient représentées de manière clairement séparée, traçable et à l'épreuve des audits ?
La pratique actuelle dans le secteur des PME ne connaît aucune séparation propre :
- Tout dans le même pot - les documents privés et professionnels se mélangent dans une boîte mail, un lecteur, un compte cloud.
- Aucune séparation par tenant - une holding avec plusieurs sociétés tient tous les livres dans une seule instance, sans qu'il soit clair quel enregistrement appartient à quelle société.
- Aucune séparation des sphères - en cas d'utilité publique, les opérations ideell, vermögensverwaltend, zweckbetrieblich et wirtschaftlich se mélangent dans un compte, un dossier, un repo.
- Aucune séparation des rôles - l'entrepreneur fait tout lui-même (GF, Buchhalter, Lohn, F&E), mais le repo ne sait pas dans quel rôle il agit actuellement.
- Aucune identité claire - les enregistrements n'ont aucun identifiant unique qui les rattache à une organisation, une sphère, un rôle.
Message clé
Structurer une organisation en tant que GitCover-Verbund signifie : Tenant (organisation), Sphère (domaine d'activité en cas d'utilité publique) et Rôle (fonction de l'acteur) sont définis comme champs obligatoires de chaque artefact - et non comme métadonnées optionnelles. Les Git-Hooks vérifient à chaque commit que la séparation est complète. Ainsi naît la Compliance by Design : la structure de l'organisation est ancrée dans la structure du repo.
Compliance by Design : Tenant, Sphère et Rôle ne sont pas des étiquettes ajoutées après coup - ce sont des champs obligatoires structurels, sans lesquels un artefact n'est pas admis dans le repo.
Le modèle à trois niveaux : Tenant, Sphère, Rôle
(Beleg, Tagebucheintrag, Grundbuch-Eintrag)"] A --> T["Tenant
Welche Organisation?"] A --> S["Sphäre
Welcher Tätigkeitsbereich?
(nur gemeinnützig)"] A --> R["Rolle
In welcher Funktion handelt der Akteur?"] T --> T1["ORG-1 (KMU)"] T --> T2["ORG-1a (Tochter)"] T --> T3["ORG-1b (Tochter)"] S --> S1["ideell"] S --> S2["vermögensverwaltend"] S --> S3["zweckbetrieblich"] S --> S4["wirtschaftlich"] R --> R1["GF (Geschäftsführer)"] R --> R2["Buchhalter"] R --> R3["Lohnverantwortlicher"] R --> R4["F&E-Leiter"] R --> R5["Administrator"] style A fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style T fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style S fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style R fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style T1 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style T2 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style T3 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style S1 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style S2 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style S3 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style S4 fill:#D1FAE5,stroke:#0A7F5C,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 R5 fill:#FDBA74,stroke:#C2410C,color:#0F1B33
Niveau 1 - Tenant (Organisation)
Un Tenant est une unité organisationnelle juridiquement indépendante, pour laquelle existent des obligations d'enregistrement propres. Dans le GitCover-Verbund, chaque tenant est géré comme sa propre Organization (Git User) avec les Git-Repos qui lui sont associés (ou son propre Branch-Namespace).
| Type de tenant | Exemple (placeholder) | Obligations propres |
|---|---|---|
| Entreprise individuelle | ORG-1 (PME) |
GoBD, AO, E-Rechnung |
| Holding avec filiales | ORG-1 (Holding), ORG-1a/ORG-1b (filiales) |
Pour chaque société : comptabilité propre, propres comptes annuels |
| Organisation d'utilité publique | ORG-1 (utilité publique) |
En plus : séparation des sphères, § 52 AO, VBG-Freistellung |
| Consortium / Verbund | ORG-1, ORG-2, ORG-3 |
Un tenant propre par organisation, références croisées via V7GUID |
Exemple pratique : un entrepreneur (
E1) dirige une holding (ORG-1) avec deux filiales (ORG-1a,ORG-1b). Chaque filiale est un tenant propre avec son propre repo. La holding dispose d'un Meta-Repo qui relie les filiales via des références V7GUID - mais les livres des filiales restent séparés.
Niveau 2 - Sphère (domaine d'activité, uniquement en cas d'utilité publique)
La Sphère n'est pertinente que pour les organisations d'utilité publique - mais elle y est alors obligatoire. Le droit fiscal (§ 51–68 AO) exige la séparation des quatre sphères afin de ne pas mettre en danger le statut d'utilité publique.
| Sphère | Signification | Exemple |
|---|---|---|
| ideell | Zweckbetrieb au sens des statuts, exonéré d'impôt | Série d'ateliers, offre de formation |
| vermögensverwaltend | Gestion du patrimoine de la fondation, exonéré d'impôt | Intérêts des placements, revenus locatifs |
| zweckbetrieblich | Exploitation économique qui sert l'objet, exonérée d'impôt (§ 65 AO) | Cotisations des membres, droits d'adhésion |
| wirtschaftlich | Exploitation économique qui ne sert pas l'objet, imposable | Merchandising, revenus publicitaires |
steuerfrei
§ 52 AO"] V --> VV["vermögensverwaltend
steuerfrei"] V --> Z["zweckbetrieblich
steuerfrei
§ 65 AO"] V --> W["wirtschaftlich
steuerpflichtig
§ 64 AO"] I --> F["Freibetrag
§ 3 Nr. 26/26a EStG"] Z --> F W --> ST["USt/KSt
pflichtig"] style V fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style I fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style VV fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style Z fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style W fill:#FDBA74,stroke:#C2410C,color:#0F1B33 style F fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style ST fill:#FDBA74,stroke:#C2410C,color:#0F1B33
Risque en cas d'absence de séparation des sphères : le mélange de patrimoines (§ 55 Abs. 1 Nr. 5 AO) est un motif de retrait du statut d'utilité publique. Une organisation d'utilité publique qui ne sépare pas les opérations wirtschaftlich et ideell risque le retrait du statut d'utilité publique - et donc une imposition rétroactive des réserves (jusqu'à 15(!) ans en arrière).
Niveau 3 - Rôle (fonction de l'acteur)
Le Rôle documente la fonction dans laquelle un acteur a agi. C'est important, car dans de nombreuses organisations, une même personne occupe souvent plusieurs rôles (surtout dans les PME) - et parce que le rôle détermine quelles obligations s'appliquent.
| Rôle | Fonction | Obligations typiques |
|---|---|---|
| GF (Geschäftsführer) | Représentation vers l'extérieur, responsabilité globale | GoBD, AO, délais, pouvoir de représentation |
| Buchhalter | Comptabilité, archive des justificatifs | GoBD, E-Rechnung, conservation |
| Lohnverantwortlicher | Paie, déclarations SV | SGB IV, DEÜV, LStDV |
| F&E-Leiter | Recherche, justificatifs d'heures FZul | FZulG, BSFZ, F&E vs. administration |
| Administrator | Administration du repo, hooks, accès | Git, GPG, droits d'accès |
Exemple pratique : l'entrepreneur
E1est à la fois GF, Buchhalter, chercheur, développeur et F&E-Leiter. Dans le repo, il est documenté pour chaque artefact dans quel rôle il a agi - p. ex.role: "GF"pour une décision,role: "F&E-Leiter"pour un justificatif d'heures FZul. Ainsi reste-t-il traçable si un enregistrement est issu de la perspective GF (administration) ou de la perspective F&E (recherche).
Mise en œuvre dans le repo Git
Structure des répertoires
ORG-1/ # Tenant: KMU
├── .gitcover/ # GitCover-Konfiguration
│ ├── LEGAL_ENTITY.v7g.json # Tenant-Identität (V7GUID)
│ ├── dictionaries/ # Sphären, Rollen, Beleg-Typen
│ └── schemas/ # JSON-Schemata für Artefakte
├── diary/ # Tagebuch (SSoT)
│ ├── entries/ # Tages-Einträge
│ └── tenants/ # Tenant-Sichten (Symlinks)
├── registry/ # Behörden-Identifikatoren
├── sources/ # Belegarchiv (PDF, XML, EML)
├── sidecars/ # .v7g.md Sidecars
├── checks/ # Fristen-Check, Sphären-Check
└── {weitere bei Bedarf}/
Artefact JSON avec Tenant, Sphère, Rôle
Chaque artefact (entrée de journal, justificatif, entrée au registre foncier) contient Tenant, Sphère et Rôle comme champs obligatoires. Principe central de la traçabilité temporelle : l'heure de saisie n'est pas un champ séparé, mais elle est ancrée dans la uuidV7 elle-même - comme horodatage de 48 bits conformément à la RFC 9562 §5.7. La uuidV7 peut être générée à partir d'une marque temporelle prédéfinie (pas seulement now()) via le helper GitCover (UuidV7Gen), le reste étant complété de manière aléatoire. Ainsi, l'heure de saisie est liée cryptographiquement à l'identité de l'artefact et ne peut pas être modifiée a posteriori.
Important - Ce qui entre dans le repo Git : seuls ces artefacts structurés (entrées JSON, Sidecars, justificatifs) sont intégrés au repo Git. Les documents privés ne sont jamais intégrés au repo, sauf s'ils ont été expressément introduits et classifiés comme artefacts. Ce qui est dedans reste dedans.
{
"$schema": "https://gitcover.org/schemas/diary-entry-1.0.schema.json",
"V7GUID": "<V7GUID-Class-aus-Registry>",
"uuidV7": "<uuidV7-Object-mit-vorgegebener-Zeitmarke>",
"author": "E1",
"role": "GF",
"tenant": "ORG-1",
"sphere": "ideell",
"source": "E1",
"source_sha256": "<SHA-256-...>",
"tags": ["lohnabrechnung", "sv-meldung"]
}
Explication du Composite Key :
V7GUID(Class Identifier) classifie le document/l'action sur la base de la.gitcoverRegistry (quoi/quel type).uuidV7(Object ID) est l'identifiant concret de l'objet avec la marque temporelle prédéfinie (RFC 9562 §5.7, Unix-ms 48 bits). Les deux ensemble forment le GCPN Sidecar Composite KeyV7GUID:uuidV7. Une représentationdatetimeoudatesous forme de chaîne séparée est redondante et n'est pas maintenue au niveau des faits - l'horodatage de 48 bits est déjà contenu dans lauuidV7. Les représentations sous forme de chaîne pour le transfert DTO/HTMX relèvent de la responsabilité du Harness, pas de la couche des faits.
Les Git-Hooks vérifient la séparation
vorhanden?"} P1 -->|nein| R1["Commit abgelehnt
Tenant fehlt"] P1 -->|ja| P2{"Sphäre
vorhanden?
(nur gemeinnützig)"} P2 -->|nein| R2["Commit abgelehnt
Sphäre fehlt"] P2 -->|ja| P3{"Rolle
vorhanden?"} P3 -->|nein| R3["Commit abgelehnt
Rolle fehlt"] P3 -->|ja| P4{"Sphäre
gültig?"} P4 -->|nein| R4["Commit abgelehnt
ungültige Sphäre"] P4 -->|ja| OK["Commit akzeptiert"] style C fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style H1 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
| Hook | Vérification | Erreur en cas de |
|---|---|---|
| Pre-Commit | Champ tenant présent et valide |
Tenant manquant ou inconnu |
| Pre-Commit | Champ sphere présent (uniquement utilité publique) |
Sphère manquante pour un tenant d'utilité publique |
| Pre-Commit | Valeur sphere valide (ideell/vermögensverwaltend/zweckbetrieblich/wirtschaftlich) |
Valeur de sphère invalide |
| Pre-Commit | Champ role présent et valide |
Rôle manquant ou inconnu |
| Post-Commit | Génération automatique de l'index par tenant et par sphère | - |
Tenant-Verbund : plusieurs organisations
Meta-Repo"] H --> R1["ORG-1a (Tochter 1)
eigenes Repo"] H --> R2["ORG-1b (Tochter 2)
eigenes Repo"] H --> R3["ORG-1c (Tochter 3)
eigenes Repo"] R1 --> V1["V7GUID-Referenz
auf ORG-1"] R2 --> V2["V7GUID-Referenz
auf ORG-1"] R3 --> V3["V7GUID-Referenz
auf ORG-1"] H --> M["Meta-Repo
Querverweise über V7GUID
keine Buchungen"] style H fill:#0F1B33,stroke:#0F1B33,color:#FBFAF7 style R1 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style R2 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style R3 fill:#DBEAFE,stroke:#1D4ED8,color:#0F1B33 style V1 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style V2 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style V3 fill:#D1FAE5,stroke:#0A7F5C,color:#0F1B33 style M fill:#10A987,stroke:#0A7F5C,color:#FBFAF7
Un Tenant-Verbund (holding avec filiales, consortium) est relié via des références V7GUID - et non via des repos communs. Chaque tenant conserve sa propre comptabilité, mais le Meta-Repo de la holding peut renvoyer aux justificatifs et aux entrées des filiales sans les copier.
Important : le Meta-Repo ne contient aucune écriture comptable - uniquement des références croisées. La comptabilité reste chez chaque tenant. Le Meta-Repo est une couche d'index, pas une couche comptable.
Levier de risque
| Aujourd'hui (cheap) | Demain (à l'épreuve des audits) | Risque atténué |
|---|---|---|
Champ tenant par artefact |
Affectation claire lors d'un contrôle de la holding | Mélange de patrimoines entre sociétés |
Champ sphere par entrée |
Statut d'utilité publique défendu | Retrait § 55 AO (mélange de patrimoines) |
Champ role par entrée |
Traçabilité de la fonction dans laquelle on a agi | Conflit de rôles, représentation non autorisée |
| Le Pre-Commit-Hook vérifie la sphère | Séparation des sphères sans lacune | erreurs de sphère manuelles |
| Référence V7GUID au lieu d'une copie | Affectation univoque sans doublons | Incohérence des copies |
Exigence Harness (aperçu)
Déductible d'ED02 :
| ID | Exigence | Priorité |
|---|---|---|
| FA-1.4 | Affectation du tenant (tenant: "ORG-1") par entrée |
MUST |
| FA-3.1 | Tags de sphère : ideell/vermögensverwaltend/zweckbetrieblich/wirtschaftlich |
MUST (utilité publique) |
| FA-3.2 | Tag de sphère obligatoire par entrée au registre foncier et par entrée de diary | MUST (utilité publique) |
| FA-3.3 | Le Pre-Commit-Hook vérifie l'exhaustivité des tags de sphère | MUST (utilité publique) |
| TA-2.3 | Pre-Commit-Hook : vérification des tags de sphère (uniquement utilité publique) | MUST (utilité publique) |
| FA-1.3 | V7GUID par entrée (unicité inter-tenants) | MUST |
La liste complète des exigences dans Harness-Anforderungen.md.
Sources
- AO (§§ 51–68 - utilité publique, séparation des sphères, § 55 Abs. 1 Nr. 5 - mélange de patrimoines)
- EStG (§ 3 Nr. 26/26a - forfaits, lien avec les sphères)
- GoBD (lettres du BMF, documentation des procédures, séparation des tenants)
AFJD/agents/(anonymisé) - concept SSoT avec Tenant, Sphère, Rôle
Topologie des sources et liens de référence CDN
| Rôle | Emplacement | Objectif |
|---|---|---|
| Primary / SSoT | git.gitcover.org/GCC | Dépôt canonique (signé GPG, versionné) |
| Public OSS Mirror / CDN | codeberg.org/gitcover-commons | Miroir en lecture seule ; découverte FLOSS |
| Community Hub | github.com/gitcover-commons | Issues & Discussions ; référence du code source sur Codeberg |
Remarque : cette attribution des sources, du miroir et du Community Hub reflète l'état actuel et peut changer. Veuillez vérifier la source canonique respective sur gitcover.org pour connaître l'état actuel.