KV/RIS-Erweiterung: 614 WKO-KV-Dokumente + 59 RIS-Gesetze (D9)

- Korpus 601 -> 1274 Layer-2-Eintraege: kv-kvt-001...614 (ein Cluster
  kollektivvertraege, Branche als Tag) und ris-<cluster-prefix>-nn auf
  der bestehenden Cluster-Map + 7 neue Cluster (zvr/avr/agg/lst/abo/
  nso/kvt); LAW_MAP dokumentiert die 59 Gesetz-Zuordnungen.
- kv/ris-Eintraege sind quellentreu generiert (D9) - Gesetze sind
  amtliche Werke, KV-Lohntabellen zahlenexakt; Tool-Output in
  tools/ (ingest_sources.py, build_registry.py, kb_common.py),
  eingefrorene ID-Kataloge tools/catalogs/*.json (nur Metadaten).
- kb.json/INDEX.md regeneriert (1274 Eintraege, 76 Cluster);
  agent/kb.py: ID-Raeume kv|ris, source akzeptiert html-only.
- Tests 41 -> 49 (Konverter, LAW_MAP-Abdeckung, neue ID-Raeume,
  Korpus-Integrationszahl).
This commit is contained in:
2026-09-15 07:44:56 +02:00
parent eb1a768876
commit ac060c4977
684 changed files with 275146 additions and 16605 deletions
+23 -1
View File
@@ -14,6 +14,7 @@ Cluster oder landen bewusst im Sammel-Cluster `normen-sonstige`.
from __future__ import annotations
import re
from pathlib import Path
# Alle ID-Räume des Korpus (Schema-Beschreibung für kb.json).
ID_SPACES = {
@@ -87,7 +88,7 @@ LAW_MAP: dict[str, tuple[str, str, int]] = {
"GSVG": ("gsvg-fsvg", "Sozialversicherungsrecht", 1),
"GewO": ("gewerbe", "Gewerberecht", 1),
"GlBG": ("gleichbehandlung", "Arbeitsrecht", 1),
"GmbHH_PLACEHOLDER": ("geschaftsfuhrer", "Gesellschaftsrecht", 1),
"GmbHG": ("geschaftsfuhrer", "Gesellschaftsrecht", 1),
"IESG": ("insolvenz-betriebsubergang", "Insolvenzrecht", 1),
"KJBG": ("jugendliche", "Jugendschutz", 1),
"LSD-BG": ("lohndumping", "Arbeitsrecht", 1),
@@ -107,6 +108,27 @@ DATE_RE = re.compile(r"(\d{1,2})\.\s*(\d{1,2})\.\s*(\d{4})")
YEAR_RE = re.compile(r"(20\d\d)")
def load_topic_prefix_map(kb_json_path) -> dict[str, str]:
"""topic -> ID-Präfix über ALLE Cluster: aus den bestehenden Layer-2-
Einträgen (kb.json) abgeleitet, ergänzt um die neuen Cluster."""
import json
kb = json.loads(Path(kb_json_path).read_text(encoding="utf-8"))
mapping: dict[str, str] = {}
for e in kb["entries"]:
prefix = e["id"].split("-")[1]
known = mapping.get(e["topic"])
if known is not None and known != prefix:
raise SystemExit(
f"inkonsistente Cluster-Map: topic '{e['topic']}' hat Präfixe "
f"{known} und {prefix}"
)
mapping[e["topic"]] = prefix
for slug, (prefix, _name) in NEW_CLUSTERS.items():
mapping[slug] = prefix
return mapping
def ascii_slug(text: str) -> str:
"""Wissensbasis-Konvention: Umlaute auf Basisbuchstabe (ü→u, nicht ue),
ß→ss, Rest klein; alles außer a-z0-9 und Bindestrich fällt weg."""