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:
- Todo mezclado - documentos privados y comerciales se mezclan en un buzón, una unidad de disco, una cuenta en la nube.
- Sin separación de tenants - una holding con varias sociedades lleva todos los libros en una sola instancia, sin que esté claro qué registro pertenece a qué sociedad.
- Sin separación de esferas - en el ámbito de utilidad pública se mezclan operaciones ideell, vermögensverwaltend, zweckbetrieblich y wirtschaftlich en una cuenta, una carpeta, un repositorio.
- Sin separación de roles - el empresario lo hace todo él mismo (GF, contabilidad, nóminas, I+D), pero el repositorio no sabe en qué rol está actuando en cada momento.
- Sin identidad clara - los registros no tienen un identificador único que los asigne a una organización, una esfera o un rol.
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
(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 |
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
E1es 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 KeyV7GUID:uuidV7. Una representación separada como cadena dedatetimeodatees redundante y no se mantiene en los hechos: la marca temporal de 48 bits ya está en lauuidV7. 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
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
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
- AO (§§ 51–68 - utilidad pública, separación de esferas, § 55 Abs. 1 Nr. 5 - mezcla de patrimonios)
- EStG (§ 3 Nr. 26/26a - importes a tanto alzado, relación con la esfera)
- GoBD (escrito del BMF, documentación del procedimiento, separación de tenants)
E1/agents/(anonimizado) - concepto SSoT con tenant, esfera y rol
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.