# Werf: parallelclausule-mechanisme (sync of waarschuw over aktetypes heen)

**Opdracht van de notaris (2026-07-03):** bepaalde clausules lopen grotendeels
parallel voor een compromis, een verkoopakte, een onroerende schenkingsakte,
een akte van verdeling en andere vastgoedakten — maar niet helemaal. Wordt de
ene clausule aangepast, dan moeten de parallelle clausules mee worden
aangepast: **automatisch indien 100 % zekerheid**, of er komt **minstens een
waarschuwing (knipperlicht) voor de notaris**.

## Waarom dit nodig is

Voorbeelden van parallellen die vandaag al in de bibliotheek zitten:

- `feitelijke-toestand-gebreken` (kantoormodel akte) ↔ `ht-staat-goed`
  (compromis) ↔ `hta-staat-gebreken` (heldere-taal-akte) — de wet van de
  koopakte eist zelfs dat de clausules over toestand en gebreken *letterlijk*
  overeenstemmen tussen compromis en akte;
- de bodem-/asbest-/EPC-attesten per gewest bestaan telkens in een
  compromis- en een aktevariant (Fednot levert ze ook zo aan: "onderhandse
  overeenkomst" naast "authentieke akte");
- `beschrijving-onroerend-goed` is al de bestaande, geslaagde toepassing
  van hetzelfde principe binnen één clausule (één verplicht onderdeel, alle
  aktetypes, uitbreiding enkel via hypotheses) — maar tussen *verschillende*
  onderdelen bestaat er nog geen koppeling.

Zonder mechanisme divergeren die teksten stilzwijgend: een wetswijziging
wordt in de akteclausule verwerkt maar niet in de compromis- of
schenkingsvariant (of omgekeerd).

## Ontwerp (voorstel — nog te bouwen)

1. **Nieuw veld op `Modelonderdeel`** (data/modeldocumenten/types.ts):

   ```ts
   /**
    * Id's van onderdelen die inhoudelijk parallel lopen met dit onderdeel
    * (zelfde onderwerp in een ander aktetype/model). Symmetrisch bedoeld:
    * A vermeldt B ⇒ B vermeldt A (test bewaakt dit).
    */
   parallelMetIds?: string[];
   /**
    * Vingerafdruk (hash) van de tekst+varianten van elk parallel onderdeel
    * op het moment dat dit onderdeel laatst inhoudelijk werd nagekeken.
    * Wijkt de actuele vingerafdruk af, dan is de parallel gedivergeerd
    * sinds het laatste nazicht → knipperlicht.
    */
   parallelVingerafdrukken?: Record<string, string>;
   ```

2. **Divergentietest** (`data/modeldocumenten/parallelle-clausules.test.ts`,
   ratchet-stijl zoals `nl-fr-pariteit.test.ts`):
   - symmetrie: A↔B beide kanten aanwezig;
   - voor elk paar: bereken de actuele vingerafdruk van de partner; wijkt
     die af van de opgeslagen `parallelVingerafdrukken`, dan **faalt de test**
     met de boodschap "onderdeel X is gewijzigd; parallel onderdeel Y is niet
     mee nagekeken — pas Y aan of bevestig bewust door de vingerafdruk te
     verversen". Zo kan een wijziging nooit stilzwijgend passeren: de bouwer
     moet de parallel ofwel mee aanpassen (automatisch bij 100 % zekerheid),
     ofwel de divergentie uitdrukkelijk motiveren in `nazicht.aandachtspunten`.

3. **Knipperlicht naar de notaris**: bij het genereren van een ontwerp
   (samenstellen.ts) krijgt een onderdeel waarvan een parallel gedivergeerd
   is een geel gearceerde melding "⚠ parallelle clausule <id> werd recenter
   gewijzigd — laat nakijken", zolang de vingerafdruk niet ververst is.

4. **Eerste te koppelen paren** (na de bouw van het mechanisme):
   - staat/gebreken: kantoormodel ↔ ht ↔ hta;
   - bodem per gewest: compromis- ↔ aktevariant;
   - asbest Vlaanderen: ht ↔ hta ↔ attesten.ts;
   - EPC/EPB per gewest: ht ↔ hta;
   - eigendomsoverdracht/genot, risico/verzekering, prijs/betaling:
     compromis ↔ akte;
   - mede-eigendom art. 3.94 BW: compromis-informatie ↔ akteclausule;
   - bos/natuur Vlaanderen: `natuurwetgeving-bos-natuur-duinendecreet` (akte,
     officiële Vlanot-varianten) ↔ `ht-natuur-bos-herstelvordering-vlaanderen`
     (compromis) ↔ de voorkooprecht-passage in
     `wettelijke-voorkooprechten-overzicht`;
   - EPC/EPB/renovatieplicht Vlaanderen: `epc-renovatieplicht-vlaanderen` (akte,
     officiële Vlanot-varianten) ↔ de beknopte ENERGIEPRESTATIE-passage in
     `administratieve-attesten` (variant vlaanderen) ↔ `ht-energieprestatie` /
     `ht-renovatieplicht` (compromis) ↔ de hta-gewestrubrieken;
   - stookolietank: `veiligheidsattesten-stookolie-klim` (nu met 5 officiële
     Vlanot-varianten) ↔ de STOOKOLIETANK-passage in `administratieve-attesten`
     ↔ eventuele compromisclausules over dezelfde tank;
   - stedenbouw-detail: `stedenbouw-detailclausules-vlaanderen-brussel` ↔ de
     STEDENBOUW-passage in `administratieve-attesten` (vlaanderen/brussel);
   - bodem per gewest: `bodem-vlaanderen` (=bodemdecreet-vlaanderen) ↔
     `bodemdecreet-brussel` — zelfde onderwerp, ander gewest/andere
     Ordonnantie/Decreet, geen automatische synchronisatie maar wel dezelfde
     onderwerpcategorie;
   - waterparagraaf/signaalgebied: `waterparagraaf-signaalgebied-vlaanderen`
     ↔ de beknopte WATER-passage in `administratieve-attesten` (vlaanderen);
   - vertegenwoordiging/kwijting publiekrechtelijke rechtspersonen:
     `vertegenwoordiging-publiekrechtelijke-rechtspersonen-vlaanderen` ↔
     `kwijting-publiekrechtelijke-rechtspersonen-vlaanderen` (dezelfde
     rechtspersoon-varianten moeten gelijk lopen);
   - t.z.t. de schenkings- en verdelingsvarianten van dezelfde onderwerpen.

## Ontwerpbeslissingen (backlog punt 13 — vastgelegd 2026-07-04)

De kern is gebouwd in `data/modeldocumenten/parallelle-clausules.ts` (puur,
dependency-vrij) en bewaakt door `parallelle-clausules.test.ts`. De centrale
afwegingen zijn beslecht als volgt:

1. **Genormaliseerde vingerafdruk, geen exacte-tekst-hash.** De afweging
   vals-positief (ruis → mechanisme sterft) versus vals-negatief (stille
   divergentie) is beslecht met een genormaliseerde hash: opmaak-markers,
   redactionele `[...]`-commentaren en invul-placeholders (`{{…}}`, `***`, `…`)
   worden verwijderd, witruimte samengevouwen, alles verkleind. Stabiel onder
   herformatteren/placeholder-hernoeming/commentaarwijziging; gevoelig voor elke
   wijziging aan de eigenlijke clausulewoorden (incl. artikelnummer/decreetdatum,
   want die staan in de bewaarde tekst). Bewust naar de veilige kant: een
   substantiële herwoording markeert de parallel voor nazicht.
2. **Symmetrisch drift-protocol.** `parallelMetIds` is symmetrisch (A↔B, test
   bewaakt het). Elk onderdeel bewaart in `parallelVingerafdrukken` de
   vingerafdruk van elke partner *zoals laatst nagekeken*. Wijzigt B, dan wijkt
   A's opgeslagen vingerafdruk van B af → de test faalt met een actiegerichte
   melding én de nieuwe vingerafdruk als hersteltip. De bouwer past de parallel
   mee aan (automatisch bij zekerheid) of bevestigt bewust door de vingerafdruk
   te verversen — een wijziging passeert nooit stil.
3. **FNV-1a (32-bit), geen `crypto`.** Enkel drift-detectie nodig, en de
   datalaag blijft puur; een korte deterministische stringhash volstaat.

## Status

- [x] Ontwerp vastgelegd (de drie beslissingen hierboven) — nazicht door de
      notaris blijft welkom, maar het mechanisme is neutraal tot er paren
      gekoppeld zijn
- [x] Veld + test gebouwd (`parallelMetIds`/`parallelVingerafdrukken` op
      `Modelonderdeel`; `berekenParallelVingerafdruk` +
      `detecteerParallelDivergentie` + ratchet-test over de seed-bibliotheek)
- [x] Knipperlicht in de generator (2026-07-06): `parallelWaarschuwingen` in
      samenstellen.ts; `genereerDocument` zet een geel gearceerde melding
      "⚠ PARALLELLE CLAUSULE GEWIJZIGD: …" in het werkdocument zolang een
      partner gedivergeerd is (FR-uitvoer: "⚠ CLAUSE PARALLÈLE MODIFIÉE :").
      Omdat de seed-bibliotheek door de ratchet-test altijd in balans is,
      vuurt dit knipperlicht in de praktijk bij gebruikersbewerkingen
      (IndexedDB-overrides via `combineerMetSeed`).
- [x] Eerste paren gekoppeld en vingerafdrukken gezet (2026-07-06): 16 groepen
      (cliques) uit het lijstje hierboven, samen 41 gekoppelde NL-onderdelen —
      staat/gebreken, bodem per gewest én cross-gewest, asbest, EPC/EPB
      (Vlaanderen + Wallonië), stookolietank, stedenbouw, waterparagraaf,
      eigendomsoverdracht/genot, risico/verzekering, prijs/betaling,
      mede-eigendom (art. 3.94 BW), bos/natuur, en vertegenwoordiging/kwijting
      publiekrechtelijke rechtspersonen. De ratchet-test faalt voortaan bij
      elke stille divergentie binnen die groepen.

Wie een clausule aanpast die een parallel heeft, past de parallel(len) in
dezelfde commit aan of bevestigt de divergentie bewust door de vingerafdruk
te verversen (de falende test geeft de exacte waarde). Voor onderwerpen die
nog niet gekoppeld zijn blijft de tijdelijke discipline gelden: parallel mee
aanpassen of de divergentie noteren in `nazicht.aandachtspunten`.

## Opvolgwerven (na de eerste koppeling)

- ~~FR-spiegels koppelen~~ — gedaan (2026-07-06): dezelfde 16 groepen zijn ook
  tussen de FR-vertalingen gekoppeld (41 FR-onderdelen, `…-fr` ↔ `…-fr`), zodat
  tekstdrift tussen FR-parallellen dezelfde ratchet heeft als de NL-kant.
- **Bijkomende groepen**: voorkooprechten (`ht-voorkooprecht-algemeen` ↔
  `hta-voorkoop-premies-vlaanderen-brussel` ↔ `voorkooprechten-conventioneel`),
  asbest gemene delen, de schenkings- en verdelingsvarianten van dezelfde
  onderwerpen zodra die er zijn.
