[ADD] personalverrechnung: Lexis360 knowledge base (Batch 1)

Curated knowledge base from the first batch of Lexis 360 PDF exports
(LexisNexis "Lexis Briefings Personalrecht", 55 documents, source
Stands 2024-03 to 2026-09). Purpose: development reference alongside
RECHTSQUELLEN-*.md and a retrieval-ready corpus for a future
question-answering copilot.

Licensing split (decision D1): the PDF exports and the extracted full
texts stay local and unversioned (Lexis360/ gitignored, like
.firecrawl/); only the curation in own words with short quotes and
source citations is versioned.

- wissensbasis/dokumente/: one curated entry per briefing (55) with
  approved frontmatter (frozen lb-<cluster>-<nn> ids, English
  structural keys, German values, stand YYYY-MM, ASCII topic/tags
  slugs) and sections Zusammenfassung, Kernwerte & Fristen (Stand
  marked), Rechtsgrundlagen (only citations actually in the source,
  verified/plausible/open marks), Payroll-Relevanz (Odoo), Verweise
- clusters: altersteilzeit 15, lehrlinge 15, jugendliche 7,
  ferialpraktikanten 4, beschaftigungsformen 8, teilzeit 6
- kb.json + INDEX.md: generated from the frontmatter by --registry
  (single source of truth, schema-validated)
- tools/build_lexis_kb.py: stdlib-only pipeline - --extract
  (pdftotext, breadcrumb/stand parsing incl. dossier-style exports
  with wrapped breadcrumbs), --registry (frontmatter validation:
  required keys, id pattern, id prefix vs topic, stand format,
  dangling cross_refs), --check (layer 1 <-> layer 2 completeness);
  ids are frozen across batches, numbers never reused
- RUNBOOK.md: batch intake workflow, validation steps, known
  limitations

Corpus contradictions flagged in the entries (not silently resolved):
AMS replacement rate for blocked Altersteilzeit 2026 (lb-atz-07 28.5%
vs lb-atz-09/12 27.5%), DAG limit 2023 (751.36 vs 751.37 EUR),
Kurzarbeit for Lehrlinge (lb-leh-11 vs lb-leh-07); lehrlinge cluster
partly older Stands (2024-03/2025-08).

Validated: extract 55/55, registry 55 entries/6 clusters, check 0
problems, structural scan of all 55 curated entries, py_compile.
This commit is contained in:
2026-09-10 10:23:46 +02:00
parent 3a4e0dcd0f
commit 6a78b419ed
61 changed files with 9112 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
# Wissensbasis „Lexis Briefings Personalrecht" (Lexis360-Exporte)
Kuratierte Wissensbasis aus den LexisNexis-Briefings des Werks
*Lexis Briefings Personalrecht* (Export aus Lexis 360). Zweck:
1. **Entwicklungsreferenz** neben `personalverrechnung/RECHTSQUELLEN-*.md`
für die Personalverrechnungsmodule (`l10n_at_hr_payroll*`), und
2. **Copilot-Korpus**: Aufbau und Frontmatter sind retrieval-gerecht
(stabile IDs, maschinenlesbares `kb.json`), damit künftig ein
Frage-Antwort-Copilot darauf aufbauen kann.
## Schichten (Lizenz-Entscheidung D1, 2026-09-10)
| Schicht | Pfad | Versioniert? | Inhalt |
|---|---|---|---|
| PDF-Exporte | `Lexis360/Lexis360_*.pdf` | **nein** (gitignored) | lizensierte Original-PDFs |
| Layer 1 — Volltexte | `Lexis360/md/<slug>.md` | **nein** (gitignored) | vollständiger Extraktionstext + Metadaten-Frontmatter |
| Katalog | `Lexis360/md/_catalog.json` | **nein** (gitignored) | geparste Metadaten aller Quellen (Slug ↔ ID ↔ Stand ↔ Cluster) |
| Layer 2 — kuratierte Einträge | `personalverrechnung/wissensbasis/dokumente/<slug>.md` | **ja** | Kuratierung in eigenen Worten (Schema unten) |
| Registry | `personalverrechnung/wissensbasis/kb.json` | **ja** | **generiert** aus dem Layer-2-Frontmatter (`--registry`) |
Volltexte sind lizenzierter Inhalt (LexisNexis-Abonnement) und bleiben wie
`.firecrawl/` lokal + unversioniert. Nur die Kuratierung (eigene Worte,
kurze Zitate mit Quellenachweis) wird committet.
## Frontmatter-Schema (Layer 2 — verbindlich)
```yaml
id: lb-atz-07 # stabil, lb-<cluster>-<nn>, eingefroren
batch: 1 # Beschaffungs-Batch (manuell je Import)
title: "Altersteilzeit - Überblick"
work: "Lexis Briefings Personalrecht"
chapter: "Beschäftigungsverhältnisse" # Breadcrumb-Kapitel der Quelle
topic: altersteilzeit # ASCII-Cluster-Slug (s. Tabelle)
author: "Marek"
stand: 2026-01 # ISO-Monat des Quell-Stands
source:
pdf: "Lexis360/Lexis360_altersteilzeit_uberblick.pdf"
text: "Lexis360/md/altersteilzeit_uberblick.md"
legal_bases: ["AlVG", "AZG § 19e"] # nur im Quelltext genannte Normen
tags: [altersteilzeit, ams-foerderung] # ASCII-Slugs, retrieval-freundlich
cross_refs: ["lb-atz-09"] # verwandte KB-Einträge (dangling = Fehler)
```
Schlüsselkonvention (Entscheidung D2): **strukturelle Schlüssel
englisch** (konsistent mit `kv-catalog.json`/`chambers.json`),
**Werte deutsch** (UTF-8, Umlaute erlaubt). Zwei Ausnahmen: `stand`
(österreichischer Fachbegriff, ISO-Wert `YYYY-MM`) und `topic`/`tags`
als ASCII-Slugs. Die Frontmatter ist **Single Source of Truth**;
`kb.json` wird daraus generiert und schema-validiert
(`build_lexis_kb.py --registry`).
## Cluster (Batch 1)
| topic-Slug | Name | ID-Präfix | IDs | n |
|---|---|---|---|---|
| `altersteilzeit` | Altersteilzeit | `atz` | lb-atz-01 … 15 | 15 |
| `lehrlinge` | Lehrverhältnis / Lehrlinge | `leh` | lb-leh-01 … 15 | 15 |
| `jugendliche` | Jugendarbeit / Jugendschutz | `jug` | lb-jug-01 … 07 | 7 |
| `ferialpraktikanten` | Ferialpraktikanten, Volontäre, Au-pair | `pra` | lb-pra-01 … 04 | 4 |
| `beschaftigungsformen` | Beschäftigungsformen & Abgrenzung | `bes` | lb-bes-01 … 08 | 8 |
| `teilzeit` | Teilzeit & Bildungsteilzeit | `tzb` | lb-tzb-01 … 06 | 6 |
Frontmatter-`topic` = beschreibender ASCII-Slug (linke Spalte), das
ID-Präfix (`atz`, `leh`, …) nur im `id` selbst; das Tool prüft die
Konsistenz beider (`--registry`). Neue Cluster erweitern
`TOPIC_TO_PREFIX`/`CLUSTERS` im Tool.
IDs werden beim ersten `--extract` vergeben und danach **eingefroren**
(`load_previous_ids()`); neue Dokumente hängen hinten an, Nummern
ausscheidender Dokumente werden nie wiederverwendet. Dateiname eines
Layer-2-Eintrags = Layer-1-Slug (Lexis-Export-Stil: Umlaute **fallen**,
werden nicht transliteriert — `uberblick`, `beschaftigung`).
## Kurationskonventionen (verbindlich)
1. **Sprache:** deutsch, Fachsprache wie im Original; Metadaten-Werte
UTF-8. `topic`/`tags` ASCII.
2. **Eigene Worte:** Kuratierung ist keine Volltextkopie (Lizenz!).
Wörtliche Zitate nur kurz und mit Stand gekennzeichnet.
3. **Werte immer mit Stand.** Stammt der Wert aus einem Briefing mit
älterem Stand (z. B. Lehrlinge 2024-03, 2025-08), so ist
„(Stand YYYY-MM)" am Wert zu führen. Niemals Werte aus
Trainingswissen ergänzen — nur aus dem Quelltext oder aus
Batch-1-Dokumenten mit neuerem Stand (dann mit ID belegt).
4. **Statusmarken wie in RECHTSQUELLEN:** ✅ verifiziert · ⚠ plausibel,
Detailverifikation offen · ❓ bewusst offen. §-Zitate nur, wenn die
Quelle sie nennt; sonst ⚠ mit Verifikationshinweis (RIS).
5. **Dokumentstruktur:** `# <Titel>` → *Quellzeile (Werk, Autor, Stand,
ID)* → `## Zusammenfassung``## Kernwerte & Fristen (Stand YYYY-MM)`
(Tabelle) → `## Rechtsgrundlagen``## Payroll-Relevanz (Odoo)`
`## Verweise`.
6. **Payroll-Relevanz** benennt Odoo-19-Anknüpfungspunkte
(hr_payroll-Engine, Work Entries, `hr.rule.parameter`, SV-BG-Handling,
Meldewesen) als *Hinweise für die Umsetzung*, nicht als Spec.
7. **Verweise:** KB-IDs verwandter Briefings (Breadcrumb-Verweise der
Quelle beachten) + Projektdateien (`RECHTSQUELLEN-*.md`).
8. **Export-Artefakte ignorieren:** Footer „Page n", „Erstellt von …",
abgeschnittene Querverweise nicht rekonstruieren; vermerken, wenn eine
Verweisstelle im Export unvollständig ist.
9. Vorbild/Qualitätsmaßstab: `dokumente/altersteilzeit_uberblick.md`.
## Update-Zyklus (neue Lexis360-Batches)
1. Neue PDFs nach `Lexis360/` kopieren (Export-Namenskonvention
`Lexis360_<slug>.pdf` beibehalten).
2. In `tools/build_lexis_kb.py` die Konstante `BATCH` hochsetzen, dann
`--extract` ausführen: Layer 1 + Katalog neu; bestehende IDs bleiben
fix, neue Dokumente erhalten neue IDs + neue Batch-Nummer.
3. Neue Layer-2-Einträge kuratieren (Konventionen oben).
4. `--registry` (generiert/validiert `kb.json`), danach `--check`
(Layer-1↔Layer-2-Vollständigkeit, Quelldateien vorhanden).
5. `INDEX.md` aktualisieren, `personalverrechnung/RUNBOOK.md` und
`.agents/MEMORY.md` pflegen.
## Copilot-Konsum
`kb.json` listet jeden Eintrag mit ID, Titel, Stand, Cluster,
Rechtsgrundlagen, Tags und Pfaden auf Layer 1/Layer 2. Für
Retrieval/Skills: Eintrag = Chunk-Einheit; `id` als Zitatchlüssel;
`stand` für Aktualitätsfilter; `cross_refs` für Graph-Nachbarschaft.
Die Volltexte (Layer 1) sind lokal vorhanden, aber nicht Teil des
Versionskontroll-Korpus — ein Copilot-Deployment braucht daher einen
separaten, lizenzkonformen Bereitstellungspfad für Layer 1 (❓ offen).