Metadata-Version: 2.4
Name: entity-core
Version: 0.1.0
Summary: Brique de résolution d'entités (CDC-ENTITY-CORE-v1) — source unique du canon court fermé + carte d'alias + normalisation fail-closed. Niveau plateforme / stateless (canon global, ne se sépare pas).
Author: Holding MAPFARM
License: Proprietary
Keywords: canon,entites,mapfarm,multitenant,normalisation,referentiel
Requires-Python: >=3.11
Provides-Extra: test
Requires-Dist: pytest>=8; extra == 'test'
Description-Content-Type: text/markdown

# entity-core

**Brique de résolution d'entités** — la **source unique** du **canon** d'entités, de la **carte
d'alias** long→court et de la **normalisation fail-closed**. Toutes les briques de la plateforme
(cockpit · corpus · harvest · factory · iaos · `fin-core` · `client-core` · `catalog-core`)
l'appellent pour résoudre une identité d'entité, au lieu de re-coder leur propre liste.

Spécifiée par `CDC-ENTITY-CORE-v1` (Holding MAPFARM ; `docs/`). Grounded sur l'audit entités du
2026-06-21 (finding #1 : aucune bibliothèque de normalisation partagée → listes divergentes, fracture
long/court, typo `maissonkir` load-bearing).

> **Niveau plateforme / stateless.** À la différence de `fin-core`/`client-core`/`catalog-core`
> (**données par app**, séparables), `entity-core` est du **substrat** : le canon est **un**,
> **global**, **versionné**, **embarqué**. Il **ne se sépare pas** (comme iaos). C'est l'**IDENTITÉ**
> sur laquelle les autres briques calent leur isolation — le **mécanisme** (RLS / schéma-par-app /
> scope) restant une décision par-archi (R5).

> Ce dépôt = **Livrable 0** du CDC : la brique seule (canon §4, alias §4, `normalize` fail-closed
> §5, gardes §4, garde de cohérence §5/§7). L'adoption par les consommateurs (corpus L1, cockpit/
> harvest/factory/iaos L2, `fin-core` L3, garde CI L4) est hors de ce dépôt (§8/§9).

## Principes (non négociables — CDC §5/§6)

| # | Règle |
|---|---|
| R1 / P4 | **Une seule source** du canon + alias : `entity-core`. Aucune liste re-codée par dépôt. |
| R2 | Toute frontière d'entrée d'entité **normalise via `entity-core`** (route, RAG, INSERT, allow-list). |
| R3 / G2 | **Fail-closed** : forme inconnue → **REFUS** ; jamais de devinette ni de pass-through. |
| G3 | **Typo non bénie** : `maissonkir` (et toute faute) → refus, **jamais** d'alias ; correction à la source. |
| R4 / P2 | **Stateless / plateforme** : pas de données par app, **ne se sépare pas**. |
| R5 | Fournit l'**IDENTITÉ** ; n'applique **pas** l'isolation (les briques le font, mécanisme par-archi). |
| R6 / G4 | **Cohérence garantie en CI** entre `entity-core`, le registre (ADR-006) et les enums DB. |
| R7 | `harvest`/`corpus` ne sont **jamais** des entités ; `mapfarm` est une **société**, pas une entité. |

## Le canon (§4)

Canon **court fermé** (l'unité d'isolation) : `mlc · map · mkir · cap · it · hold`.

| Entrée (alias/historique) | → Canon | Entrée (non-entité) | Verdict |
|---|---|---|---|
| `maisonkir` | `mkir` | `harvest` | marque de `hold` → `resolve_marque_owner` |
| `support_capital`, `ahp` | `cap` | `corpus` | socle (hors axe entité) |
| `support_it` | `it` | `mapfarm` | société (`fin-core`) |
| `holding` | `hold` | **`maissonkir`** (typo) | **REFUS** (non aliasée) |

## Installation (registre PyPI Gitea)

```bash
pip install entity-core --extra-index-url https://git.mapfarm.cloud/api/packages/mapfarm/pypi/simple/
```

## Usage

```python
from entity_core import normalize, is_entity, resolve_marque_owner, assert_canon, CANON

normalize("holding")            # -> "hold"
normalize("maisonkir")          # -> "mkir"
normalize("maissonkir")         # -> lève UnknownEntity (fail-closed : la typo se révèle)
is_entity("harvest")            # -> False (c'est une marque)
resolve_marque_owner("harvest") # -> "hold"
assert_canon(registre_tenants)  # -> True | lève CanonDivergence (garde CI)
```

## Développement

```bash
make install      # pip install -e ".[test]"
make lint         # ruff check + format --check
make test         # pytest (unitaires purs — la brique est stateless)
make build        # sdist + wheel
```
