# Fidelidade — Proteção e statut

> Auditoria de fidelidade MonumentosFR, dimensão **PROTEÇÃO e STATUT JURIDIQUE**.
> Data: 2026-09-01. Auditor: agente subordinado (derivação independente, sem reexecutar o código do projeto).
> Convenção: **[C]** = confirmado no documento/dados-fonte; **[I]** = inferido/julgamento semântico do auditor.

## Método

- **Fonte da verdade**: `raw/merimee.csv` (delimitador `|`, UTF-8-BOM, **46.760 linhas, 46.760 `Reference` únicos, 0 duplicados**) [C].
- **Dataset servido**: `www/explorer/merimee_data.json` — `total` = 46.760, 46.760 registos com `prc` (classe de proteção), `est` (état de conservation), `owt` (statut juridique/propriedade), `pr` (texto de Date_et_typologie) [C].
- **Pipelines auditados** [C]:
  - `tools/build_dataset.py` → `prc = prot_code(Typologie_de_la_protection)` com regra de **substring** («classé»/«classe» e «inscrit» em minúsculas; ambos → `classe_inscrit`; nenhum → `autre`); `est = etat_map.get(etat_raw, "inconnu")` (vazio OU fora do mapa → `inconnu`); `owt = statut_map.get(statut_raw, "autre")`; `pp=1` se «partiel» na tipologia.
  - `tools/classify_statut.py` → `ETAT_MAP` manual com leitura 1-a-1 de 47 valores de `etat_de_conservation`; statut por decomposição de componentes (PUB_RAW/PRIV_RAW, partes separadas por `;:,`, («?)» removido).
  - Mapas gerados: `tools/etat_map.json` (47 chaves), `tools/statut_map.json` (316 chaves + 1 «autre») [C].
- **Re-derivação independente (minha)** [C]:
  - `prc`: regras próprias por **token com fronteiras de palavra** (não substring) sobre `Typologie_de_la_protection`; vocabulário distinto verificado por varrimento de todos os tokens contendo «clas»/«inscr» → apenas {`classé`, `inscrit`, `inscription`}; os 41 valores distintos foram classificados manualmente.
  - Juízo semântico adicional cruzando `Date_et_typologie_de_la_protection`, `Nature_de_la_protection` e `Precision_de_la_protection` para os casos em que a tipologia está vazia ou ambígua.
  - `est`: re-cálculo de população inteira map(CSV) vs site + amostra sistemática de 40 não vazios (passo k=62).
  - `owt`: comparação valor-a-valor dos 317 valores distintos com classificação semântica própria + amostra de 62 registos (60 aleatórios com seed 42 + 2 refs de divergência forçadas).
- **Escrita**: apenas este ficheiro; `raw/` e `www/` só lidos [C].

## Derivação independente população inteira

### Concordância `prc` (46.760 registos)

Regra mecânica do auditor (só `Typologie_de_la_protection`, tokens com fronteiras de palavra): **concordância 46.760/46.760 = 100,000%** [C].

| minha derivação | site `prc` | n |
|---|---|---|
| inscrit | inscrit | 31.321 |
| classe | classe | 12.428 |
| classe_inscrit | classe_inscrit | 2.562 |
| autre (sem proteção) | autre | 449 |

### Distribuição da população [C]

| classe | n | % |
|---|---|---|
| inscrit | 31.321 | 66,97% |
| classe | 12.428 | 26,58% |
| classe_inscrit | 2.562 | 5,48% |
| **sem proteção (`autre`)** | **449** | **0,96%** |

Com juízo semântico (ver Divergências), 2 dos 449 `autre` são na verdade protegidos → sem proteção real ≈ 447 (0,9559%) [I].

- Bandeira `pp` (proteção parcial): 20.303 registos no site = exatamente os 20.303 registos com «partiel» na tipologia do CSV [C].
- Varrimento de falsos positivos («déclassé», «reclassé», «classement», «provisoire», «projet»): **0 ocorrências** na tipologia — a regra de substring do projeto não gerou falsos positivos nesta fonte [C].
- Valores «armadilha» classificados corretamente [C]: `classé MH pa;inscrit MH partiellement` (PA00082932 → classe_inscrit), `classé MH;inscrit MH partiellement;protection  totale` (duplo espaço, PA00101731 → classe_inscrit), `classé MH partiellement : inscrit MH partiellement;protection partielle` (PA00108354 → classe_inscrit).

## Divergências (com refs)

**Categoria 1 — «inscription» escapa à regra «inscrit»** (1 registo) [C]:
- `PA95000004` — CSV: `Typologie_de_la_protection` = «inscription MH», `Date_et_typologie` = «1926/06/16 : inscription MH»; site `prc` = `autre`. «inscription» não contém a substring «inscrit», logo o site diz **sem proteção** para um monumento inscrito desde 1926 [C]. Semanticamente deveria ser `inscrit` [I]. (Nota: é o mesmo ref com lat/lng trocadas corrigido no pipeline — `COORD_FIXES`.)

**Categoria 2 — tipologia vazia mas proteção provada em `Date_et_typologie`** (1 registo) [C]:
- `PA00085775` — CSV: tipologia vazia, mas `Date_et_typologie` = «2024/07/22 : inscrit MH»; site `prc` = `autre` (embora `pr` mostre o texto). Semanticamente `inscrit` [I]. A regra do site usa apenas a coluna tipologia [C].

**Categoria 3 — fonte sem tipologia (fiel ao CSV, não é erro do site)** (448 registos com tipologia vazia) [C]:
- 354 sem qualquer texto de proteção [C];
- 94 com `Nature_de_la_protection` = «arrêté» (91), «décret» (2), «arrêté;décret» (1) — instrumento de proteção sem tipologia nem data; indeterminável a partir da fonte [C][I];
- 340 com `Precision_de_la_protection` tipo «Voir commune de : La Ferté-sur-Chiers» — proteção descrita noutra ficha (duplicado comunal); `autre` é fiel à fonte [C][I].

**Categoria 4 — statut: «propriété publique et privée» classificada «publique»** (1 registo) [C]:
- `PA35000085` — CSV: «propriété publique et privée»; `statut_map.json` e site → `publique`. A função `classify_part` testa PUB antes de PRIV e devolve à primeira correspondência, nunca vendo «privée» na mesma parte. Semanticamente é **mixte** [I].

**Casos limítrofes julgados DEFENSÁVEIS (não contam como erro)** [I]:
- `PA00080664` «propriété d'une personne morale de droit public à statut particulier» → `publique` — correto (a minha regra ingénua diria mixte; o projeto acerta porque «personne morale de droit public» está em PUB_RAW).
- `PA75090009` «propriété d’une personne morale» (sem qualificação) → `autre` — genuinamente ambíguo, aceite.
- 5 registos «société (anonyme) d'économie mixte…» (ex.: PA00099693, PA97400068, PA97600015, PA97600016, PA13000129) → `privee` — SEM são pessoas coletivas de direito privado com capital público maioritário; `privee` é defensável, mas literalmente «mistério» [I].
- Erros de fonte tolerados corretamente: «proprété privée» (typo, PA78000483) → `privee`; separadores mistos «,» «:» «;» «\xa0» todos decompostos [C].

## État

- **O default «inconnu» corresponde sempre a CSV vazio?** Sim [C]: 44.245 registos com `etat_de_conservation` vazio = exatamente os 44.245 registos com `est=inconnu` no site; **0 valores não vazios caem em `inconnu`** [C].
- **Valores fora do ETAT_MAP**: não existem [C] — os 47 valores não vazios distintos do CSV estão todos nas 47 chaves de `etat_map.json`; cobertura 100%; **0 não mapeados** (daí não haver 3 exemplos não mapeados — a lista é vazia) [C].
- Re-cálculo de população inteira map(CSV)→esperado vs site: **0 discrepâncias em 46.760** [C]. Distribuição do site: inconnu 44.245, ruins 1.715, disused 506, demolished 89, threatened 81, standing 66, restored 58 (soma 46.760) [C].
- **Amostra de 40** (sistemática, k=62, não vazios): **40/40 OK** [C]. Exemplos mapeados (10):

| ref | CSV `etat_de_conservation` | site `est` |
|---|---|---|
| PA00078014 | désaffecté | disused |
| PA00080429 | fragment | ruins |
| PA00081579 | vestiges | ruins |
| PA00084045 | bon état | standing |
| PA00094251 | désaffecté;vestiges | ruins |
| PA00110688 | établissement industriel désaffecté | disused |
| PA64000030 | vestiges | ruins |
| PA18000012 | désaffecté | disused |
| PA62000031 | désaffecté | disused |
| PA00108859 | fragment | ruins |

- Não mapeados: **nenhum** (0/47) [C].
- Caso extremo tratado bem: `PA03000066` tem na fonte um caráter de controlo `\x02` dentro de «garde␂corps» («fissures et des aciers apparents rouillés…»); a chave do mapa mantém o mesmo caráter e o site devolve `threatened` — correto [C].
- Juízo semântico sobre leituras do ETAT_MAP (1 registo cada, zonas cinzentas, não contam como erro) [I]: «médiocre;travaux de réhabilitation…en cours» → `restored` (otimista; seria defensável `threatened`); «Moyen ; mauvais pour les décors intérieurs» → `standing` (teor dominante, mas «mauvais» nos interiores); «désaffecté;restauré» → `restored` vs «désaffecté;bon état» → `disused` — critério de desempate não uniforme entre combinações.

## Statut juridique

- Chave presente no dataset: `owt` [C]. Os 317 valores distintos do CSV estão **todos** em `statut_map.json` (0 em falta → nenhum valor não vazio cai em `autre` por omissão) [C]. Aplicação do mapa no site: 0 discrepâncias em 46.760 [C]. Distribuição: publique 22.249 (47,6%), privee 21.742 (46,5%), mixte 1.199 (2,6%), autre 1.570 (3,4%) [C]. O «autre» = 1.569 vazios + 1 «propriété d’une personne morale» [C].
- **Amostra de 62** (60 aleatórios seed 42 + 2 refs de divergência): **62/62 OK** ao nível da aplicação do mapa [C]. Exemplos com casos difíceis todos corretos ao nível lookup: PA00080694 «propriété privé ; propriété publique» → mixte; PA00089458 (separador «:») → mixte; PA21000063 (separador «,») → mixte; PA13000087 «personne privée ; propriété de l'Etat» → mixte; PA00100357 «propriété de la Banque de France» → publique; PA97200009 «Office national des forêts» → publique; PA06000070 «pays étranger» → publique; PA78000505 «propriété de la Commune du Pecq» → publique; PA00089284 «propriété de la commune (?)» → publique (o «(?)» é removido pelo pipeline) [C].
- Concordância semântica a nível de registo: **46.759/46.760 = 99,998%** (a única divergência é PA35000085, Categoria 4) [I].

## Veredicto

**Conformidade global: ≈ 99,997%** (3 registos divergentes com juízo semântico em 140.280 comparações de campo; 100,000% de concordância mecânica nas três dimensões) [C][I].

- `prc`: 100% mecânica; 99,996% semântica — 2 falsos «sem proteção» (PA95000004 «inscription MH», PA00085775 «inscrit MH 2024»), ambos visíveis no campo de texto `pr` mas ausentes dos filtros de proteção [C].
- `est`: 100% — correspondência exata vazio↔inconnu, cobertura 47/47, zero não mapeados, caso `\x02` tratado [C].
- `owt`: 100% lookup; 1 erro semântico (PA35000085 «publique et privée» → deveria ser mixte) [C][I].

**Severidade: MUITO BAIXA.** Os 3 desvios são registos únicos, não afetam agregados visíveis (0,006% dos 46.760), e 2 deles decorrem de lacunas da própria fonte. Correção barata: no `prot_code`, aceitar «inscription» como `inscrit` (e opcionalmente derivar `prc` de `Date_et_typologie` quando a tipologia estiver vazia); no `classify_part`, classificar `mixte` quando PUB e PRIV coexistem na mesma parte.

## Fontes

- Locais (repo MonumentosFR): `raw/merimee.csv`; `www/explorer/merimee_data.json`; `tools/build_dataset.py`; `tools/classify_statut.py`; `tools/statut_map.json`; `tools/etat_map.json`.
- Remota: dataset Mérimée (Ministère de la Culture, Licence Ouverte 2.0) — https://www.data.gouv.fr/api/1/datasets/r/3a52af4a-f9da-4dcc-8110-b07774dfb3bc
