ED02 - El modelo organizativo de PYME: Tenants, Esferas, Roles

Problema

Un empresario funda una organización - y se encuentra ante la pregunta: ¿Cómo estructuro mi organización para que las obligaciones de cumplimiento se reflejen de forma claramente separada, comprensible y a prueba de auditorías?

La práctica actual en el ámbito de las PYME no conoce una separación limpia:

Idea central

Estructurar una organización como consorcio GitCover significa: Tenant (organización), Esfera (ámbito de actividad con estatus sin ánimo de lucro) y Rol (función del actor) se definen como campos obligatorios de cada artefacto - no como metadatos opcionales. Los Git-Hooks comprueban en cada commit que la separación esté completa. Así surge Compliance by Design: la estructura de la organización queda anclada en la estructura del repo.

Compliance by Design: Tenant, Esfera y Rol no son etiquetas posteriores - son campos obligatorios estructurales, sin los cuales un artefacto no se incorpora al repo.

El modelo de tres niveles: Tenant, Esfera, Rol

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FBFAF7','primaryTextColor':'#0F1B33','primaryBorderColor':'#6B7280','lineColor':'#6B7280'}}}%% flowchart LR A["Artefakt
(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

Nivel 1 - Tenant (organización)

Un Tenant es una unidad organizativa jurídicamente independiente para la que existen obligaciones de registro propias. En el consorcio GitCover, cada Tenant se gestiona como Organization propia (Git User) con Git-Repos asignados (o un Branch-Namespace propio).

Tipo de Tenant Ejemplo (marcador de posición) Obligaciones propias
Empresa individual ORG-1 (PYME) GoBD, AO, E-Rechnung
Holding con filiales ORG-1 (holding), ORG-1a/ORG-1b (filiales) Contabilidad propia por sociedad, cuentas anuales propias
Organización sin ánimo de lucro ORG-1 (sin ánimo de lucro) Además: separación de esferas, § 52 AO, VBG-Freistellung
Consorcio / agrupación ORG-1, ORG-2, ORG-3 Tenant propio por organización, referencias cruzadas vía V7GUID

Ejemplo práctico: Un empresario (E1) dirige una holding (ORG-1) con dos filiales (ORG-1a, ORG-1b). Cada filial es un Tenant propio con su propio repo. La holding tiene un meta-repo que vincula a las filiales mediante referencias V7GUID - pero los libros de las filiales permanecen separados.

Nivel 2 - Esfera (ámbito de actividad, solo con estatus sin ánimo de lucro)

La Esfera solo es relevante en las organizaciones sin ánimo de lucro - pero entonces es obligatoria. El derecho fiscal (§ 51–68 AO) exige la separación de las cuatro esferas para no poner en peligro el estatus sin ánimo de lucro.

Esfera Significado Ejemplo
ideell Actividad conforme al fin estatutario, exenta de impuestos Serie de talleres, oferta formativa
vermögensverwaltend Administración del patrimonio fundacional, exenta de impuestos Intereses de inversiones, ingresos por alquiler
zweckbetrieblich Actividad económica que cumple el fin, exenta de impuestos (§ 65 AO) Cuotas de socios, tasas de admisión
wirtschaftlich Actividad económica que no cumple el fin, sujeta a impuestos Merchandising, ingresos por publicidad
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FBFAF7','primaryTextColor':'#0F1B33','primaryBorderColor':'#6B7280','lineColor':'#6B7280'}}}%% flowchart LR V["Geschäftsvorfall"] V --> I["ideell
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

Riesgo por falta de separación de esferas: la mezcla de patrimonios (§ 55 Abs. 1 Nr. 5 AO) es un motivo de revocación del estatus sin ánimo de lucro. Una organización sin ánimo de lucro que no separa las operaciones económicas y las ideales arriesga la revocación del estatus sin ánimo de lucro - y con ello la tributación retroactiva de las reservas (hasta 15(!) años hacia atrás).

Nivel 3 - Rol (función del actor)

El Rol documenta en qué función ha actuado un actor. Esto es importante porque en muchas organizaciones a menudo una persona ostenta varios roles (especialmente en las PYME) - y porque el rol determina qué obligaciones se aplican.

Rol Función Obligaciones típicas
GF (Geschäftsführer) Representación hacia el exterior, responsabilidad general GoBD, AO, plazos, poder de representación
Buchhalter Contabilidad, archivo de justificantes GoBD, E-Rechnung, conservación
Lohnverantwortlicher Liquidación de nóminas, comunicaciones a la seguridad social SGB IV, DEÜV, LStDV
F&E-Leiter Investigación, justificantes de horas FZul FZulG, BSFZ, F&E vs. administración
Administrator Administración del repo, hooks, accesos Git, GPG, derechos de acceso

Ejemplo práctico: El empresario E1 es a la vez GF, Buchhalter, investigador, desarrollador y F&E-Leiter. En el repo se documenta en cada artefacto en qué rol ha actuado - p. ej. role: "GF" en una resolución, role: "F&E-Leiter" en un justificante de horas FZul. Así queda claro si un registro surgió desde la perspectiva GF (administración) o desde la perspectiva F&E (investigación).

Implementación en el repositorio Git

Estructura de directorios

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}/

Artefacto JSON con Tenant, Esfera y Rol

Cada artefacto (entrada de diario, justificante, entrada del registro de la propiedad) contiene Tenant, Esfera y Rol como campos obligatorios. Principio central de la trazabilidad temporal: el tiempo de captura no es un campo separado, sino que está anclado en la propia uuidV7 - como marca de tiempo de 48 bits conforme a RFC 9562 §5.7. La uuidV7 puede generarse a partir de una marca de tiempo predeterminada (no solo now()) mediante el GitCover Helper (UuidV7Gen), rellenando el resto de forma aleatoria. De este modo, el tiempo de captura queda vinculado criptográficamente a la identidad del artefacto y no puede modificarse posteriormente.

Importante - Qué entra en el Git-Repo: solo estos artefactos estructurados (entradas JSON, sidecars, justificantes) se incorporan al Git-Repo. Los documentos privados nunca se incorporan al repo, a menos que hayan sido introducidos y clasificados explícitamente como artefacto. Lo que una vez está dentro, dentro queda.

{
  "$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"]
}

Explicación del Composite Key: V7GUID (Class Identifier) clasifica el documento/la acción según la Registry .gitcover (qué/qué tipo). uuidV7 (Object ID) es el identificador concreto del objeto con la marca de tiempo predeterminada (RFC 9562 §5.7, Unix-ms de 48 bits). Ambos juntos forman el GCPN Sidecar Composite Key V7GUID:uuidV7. Una representación separada como cadena datetime o date es redundante y no se mantiene en los hechos - la marca de tiempo de 48 bits ya está contenida en la uuidV7. Las representaciones como cadena para la transferencia DTO/HTMX son responsabilidad del Harness, no de la capa de hechos.

Los Git-Hooks comprueban la separación

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FBFAF7','primaryTextColor':'#0F1B33','primaryBorderColor':'#6B7280','lineColor':'#6B7280'}}}%% flowchart TD C["Commit"] C --> H1["Pre-Commit-Hook"] H1 --> P1{"Tenant
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 Comprobación Error en caso de
Pre-Commit campo tenant presente y válido Tenant ausente o desconocido
Pre-Commit campo sphere presente (solo sin ánimo de lucro) Esfera ausente en un Tenant sin ánimo de lucro
Pre-Commit valor de sphere válido (ideell/vermögensverwaltend/zweckbetrieblich/wirtschaftlich) Valor de esfera no válido
Pre-Commit campo role presente y válido Rol ausente o desconocido
Post-Commit Generación automática de índice por Tenant y esfera -

Consorcio de Tenants: varias organizaciones

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FBFAF7','primaryTextColor':'#0F1B33','primaryBorderColor':'#6B7280','lineColor':'#6B7280'}}}%% flowchart TD H["ORG-1 (Holding)
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 consorcio de Tenants (holding con filiales, consorcio) se vincula mediante referencias V7GUID - no mediante repos compartidos. Cada Tenant conserva su propia contabilidad, pero el meta-repo de la holding puede remitir a los justificantes y entradas de las filiales sin copiarlos.

Importante: el meta-repo no contiene asientos contables - solo referencias cruzadas. La contabilidad permanece en cada Tenant. El meta-repo es una capa de índice, no una capa de contabilidad.

Apalancamiento de riesgo

Hoy (barato) Mañana (a prueba de auditorías) Riesgo mitigado
campo tenant por artefacto Asignación clara en una inspección de la holding Mezcla de patrimonios entre sociedades
campo sphere por entrada Estatus sin ánimo de lucro defendido Revocación § 55 AO (mezcla de patrimonios)
campo role por entrada Queda claro en qué función se actuó Conflicto de roles, representación no autorizada
El Pre-Commit-Hook comprueba la esfera Separación de esferas sin lagunas errores manuales de esfera
Referencia V7GUID en lugar de copia Asignación unívoca sin duplicados Inconsistencia en las copias

Requisito para el Harness (vista previa)

Derivable de ED02:

ID Requisito Prioridad
FA-1.4 Asignación de Tenant (tenant: "ORG-1") por entrada MUST
FA-3.1 Etiquetas de esfera: ideell/vermögensverwaltend/zweckbetrieblich/wirtschaftlich MUST (sin ánimo de lucro)
FA-3.2 Etiqueta de esfera obligatoria por entrada del registro de la propiedad y entrada del Diary MUST (sin ánimo de lucro)
FA-3.3 El Pre-Commit-Hook comprueba la completitud de las etiquetas de esfera MUST (sin ánimo de lucro)
TA-2.3 Pre-Commit-Hook: comprobación de etiquetas de esfera (solo sin ánimo de lucro) MUST (sin ánimo de lucro)
FA-1.3 V7GUID por entrada (unicidad entre Tenants) MUST

La lista completa de requisitos en Harness-Anforderungen.md.

Fuentes

Topología de fuentes y enlaces de referencia CDN

Rol Lugar Propósito
Primary / SSoT git.gitcover.org/GCC Depósito canónico (firmado con GPG, versionado)
Public OSS Mirror / CDN codeberg.org/gitcover-commons Réplica de solo lectura; descubrimiento FLOSS
Community Hub github.com/gitcover-commons Issues & Discussions; referencia del código fuente en Codeberg

Nota: esta asignación de fuentes, mirror y community hub refleja el estado actual y puede cambiar. Por favor, compruebe la fuente canónica correspondiente en gitcover.org para conocer el estado actual.