ED02 - El modelo organizativo de las pymes: Tenants, esferas, roles

Problema

Un empresario funda una organización y se enfrenta a la pregunta: ¿Cómo estructuro mi organización para que las obligaciones de cumplimiento normativo queden reflejadas con una separación limpia, de forma comprensible y a prueba de auditoría?

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

Afirmación central

Estructurar una organización como federación GitCover significa: Tenant (organización), esfera (ámbito de actividad en entidades de utilidad pública) y rol (función del actor) se definen como campos obligatorios de cada artefacto, no como metadatos opcionales. Los hooks de Git comprueban en cada commit que la separación sea completa. Así surge Compliance by Design: la estructura de la organización está anclada en la estructura del repositorio.

Compliance by Design: el tenant, la esfera y el rol no son etiquetas añadidas a posteriori: son campos estructurales obligatorios sin los cuales un artefacto no se incorpora al repositorio.

El modelo de tres niveles: Tenant, esfera y 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 que tiene sus propias obligaciones de registro. En la federación GitCover, cada tenant se gestiona como una Organization propia (Git User) con repositorios Git asociados (o un namespace de ramas propio).

Tipo de tenant Ejemplo (marcador de posición) Obligaciones propias
Empresa individual ORG-1 (pyme) GoBD, AO, factura electrónica
Holding con filiales ORG-1 (Holding), ORG-1a/ORG-1b (filiales) Contabilidad propia y cuentas anuales propias por sociedad
Organización de utilidad pública ORG-1 (utilidad pública) Además: separación de esferas, § 52 AO, exención VBG
Consorcio / federación ORG-1, ORG-2, ORG-3 Un tenant propio por organización, referencias cruzadas mediante 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 repositorio. La holding tiene un meta-repositorio que enlaza las filiales mediante referencias V7GUID, pero los libros de las filiales permanecen separados.

Nivel 2 - Esfera (ámbito de actividad, solo en organizaciones de utilidad pública)

La esfera solo es relevante en organizaciones de utilidad pública, pero entonces es obligatoria. El Derecho fiscal (§ 51–68 AO) exige la separación de las cuatro esferas para no poner en riesgo la utilidad pública.

Esfera Significado Ejemplo
ideell Actividad de fin estatutario, exenta de impuestos Serie de talleres, oferta formativa
vermögensverwaltend Administración del patrimonio de la fundación, 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, cuotas de admisión
wirtschaftlich Actividad económica que no cumple el fin, sujeta a impuestos Merchandising, ingresos publicitarios
%%{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 de no separar las esferas: la mezcla de patrimonios (§ 55 Abs. 1 Nr. 5 AO) es un motivo de revocación de la utilidad pública. Una organización de utilidad pública que no separa operaciones económicas e ideales pone en riesgo la revocación de su estatus de utilidad pública y, con ello, la liquidación fiscal 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 desempeña varios roles (especialmente en pymes), y porque el rol determina qué obligaciones se aplican.

Rol Función Obligaciones típicas
GF (director general) Representación exterior, responsabilidad global GoBD, AO, plazos, poder de representación
Buchhalter Contabilidad, archivo de justificantes GoBD, factura electrónica, conservación
Lohnverantwortlicher Cálculo de nóminas, comunicaciones a la Seguridad Social SGB IV, DEÜV, LStDV
F&E-Leiter Investigación, registros horarios FZul FZulG, BSFZ, I+D frente a administración
Administrator Gestión del repositorio, hooks, accesos Git, GPG, derechos de acceso

Ejemplo práctico: El empresario E1 es al mismo tiempo GF, contable, investigador, desarrollador y responsable de I+D. En el repositorio se documenta para cada artefacto en qué rol ha actuado, p. ej. role: "GF" en una resolución, role: "F&E-Leiter" en un registro horario FZul. Así queda trazable si un registro se originó desde la perspectiva del GF (administración) o desde la perspectiva de I+D (investigación).

El rol no es la persona: el rol describe la función (y, en las declaraciones, la parte representada), no la identidad. La misma persona puede actuar o firmar un documento en varios roles; la identidad técnica de ejecución (cuenta, clave) es a su vez otro nivel. Los cinco niveles Persona · Función · parte representada · identidad de ejecución · acto de firma se describen en ED03.

Implementación en el repositorio Git

Estructura de directorios

ORG-1/                          # Tenant: KMU
├── .gitcover/                  # GitCover-Konfiguration
│   ├── LEGAL_ENTITY.gc.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/                   # .gc.md Sidecars
├── checks/                     # Fristen-Check, Sphären-Check
└── {weitere bei Bedarf}/

Artefacto JSON con Tenant, esfera y rol

Cada artefacto (entrada del diario, justificante, entrada del registro de la propiedad) contiene tenant, esfera y rol como campos obligatorios. Principio central de la trazabilidad temporal: el momento de registro no es un campo separado, sino que está anclado en la propia uuidV7, como marca temporal de 48 bits conforme a RFC 9562 §5.7. La uuidV7 puede generarse a partir de una marca temporal predefinida (no solo now()) mediante el helper de GitCover (gc-v7guid), y el resto se rellena con aleatoriedad. Así, el momento de registro queda vinculado criptográficamente a la identidad del artefacto y no puede modificarse a posteriori.

Importante: qué acaba en el repositorio Git: solo estos artefactos estructurados (entradas JSON, sidecars, justificantes) se incorporan al repositorio Git. Los documentos privados nunca se incorporan al repositorio, salvo que se hayan introducido y clasificado expresamente como artefacto. Lo que una vez está dentro, está dentro.

{
  "$schema": "https://gitcover.org/schemas/diary-entry-1.0.schema.json",
  "V7GUID": "<V7GUID-Class-aus-Registry>",
  "docUid": "<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 de la clave compuesta: V7GUID (Class Identifier) clasifica el documento/la acción según el registro .gitcover (qué/tipo). uuidV7 (Object ID) es el identificador concreto del objeto con la marca temporal predefinida (RFC 9562 §5.7, 48 bits Unix-ms). Ambos juntos forman la GCPN Sidecar Composite Key V7GUID:uuidV7. Una representación separada como cadena de datetime o date es redundante y no se mantiene en los hechos: la marca temporal de 48 bits ya está en la uuidV7. Las representaciones de cadena para transferencia DTO/HTMX son responsabilidad del harness, no del nivel de hechos.

Los hooks de Git 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
Pre-Commit Campo tenant presente y válido Tenant ausente o desconocido
Pre-Commit Campo sphere presente (solo utilidad pública) Esfera ausente en tenant de utilidad pública
Pre-Commit Valor de sphere válido (ideell/vermögensverwaltend/zweckbetrieblich/wirtschaftlich) Valor de esfera inválido
Pre-Commit Campo role presente y válido Rol ausente o desconocido
Post-Commit Generación automática de índices por tenant y esfera -

Federación 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

Una federación de tenants (holding con filiales, consorcio) se enlaza mediante referencias V7GUID, no mediante repositorios compartidos. Cada tenant conserva su propia contabilidad, pero el meta-repositorio de la holding puede referenciar justificantes y entradas de las filiales sin copiarlos.

Importante: el meta-repositorio no contiene asientos contables, solo referencias cruzadas. La contabilidad permanece en cada tenant. El meta-repositorio es un nivel de índice, no un nivel de contabilidad.

Apalancamiento de riesgos

Hoy (de bajo coste) Mañana (a prueba de auditoría) Riesgo mitigado
Campo tenant por artefacto Asignación clara en la revisión de la holding Mezcla de patrimonios entre sociedades
Campo sphere por entrada Estatus de utilidad pública defendido Revocación del § 55 AO (mezcla de patrimonios)
Campo role por entrada Trazabilidad de la función en la que se actuó Conflicto de roles, representación no autorizada
El hook pre-commit comprueba la esfera Separación de esferas sin lagunas Errores manuales de esfera
Referencia V7GUID en lugar de copia Asignación única sin duplicados Inconsistencia en las copias

Requisito del 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 (utilidad pública)
FA-3.2 Etiqueta de esfera obligatoria por entrada del registro de la propiedad y entrada del diario MUST (utilidad pública)
FA-3.3 El hook pre-commit comprueba la integridad de las etiquetas de esfera MUST (utilidad pública)
TA-2.3 Hook pre-commit: comprobación de etiquetas de esfera (solo utilidad pública) MUST (utilidad pública)
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 Ubicación Propósito
Principal / SSoT git.gitcover.org/GCC Almacenamiento canónico (firmado con GPG, versionado)
Espejo público OSS / CDN codeberg.org/gitcover-commons Espejo de solo lectura; descubrimiento FLOSS
Community Hub github.com/gitcover-commons Issues y Discussions; referencia al código fuente en Codeberg

Nota: esta asignación de fuentes, espejo y Community Hub refleja el estado actual y puede cambiar. Consulte la fuente canónica correspondiente en gitcover.org para conocer el estado actual.