agentsclimarketplace

Citation grounding pl

Skill matematicsolutions/awesome-matematic-skills-pl/fundament-weryfikacyjny/skills/citation-grounding-pl

Polish hub of legal-AI skills - 41 skills in 8 Claude Code / Cowork bundles (LLM output verification, PL/EU case law, DOCX redline, AI Act audit bundle). GDPR-safe, vendor-neutral, MIT.

Install
npx -y skills add matematicsolutions/awesome-matematic-skills-pl --skill citation-grounding-pl

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Mechaniczny weryfikator cytatu dla tekstów prawnych po polsku z GRADIENTEM weryfikacji (ISTNIENIE / TREŚĆ / FRAGMENT) - sprawdza string-matchem, czy każdy cytat z orzeczenia, ustawy, umowy lub pisma faktycznie istnieje w dokumencie źródłowym, czy sygnatura jest realna i czy parafraza oddaje stanowisko sądu, zamiast wierzyć modelowi "na oko". Przeciwdziała halucynacjom modelu (w tym problemowi "prawdziwy-cytat-fałszywa-teza"), RODO-safe (działa lokalnie), spina się z saos-orzecznictwo, szukaj-orzeczen-v2 i eu-sparql-search. Używaj gdy: weryfikacja cytatów w opinii prawnej / memo / piśmie procesowym, sprawdzenie czy AI nie zmyśliło fragmentu wyroku, przepisu lub sygnatury, czy parafraza nie przekręca holdingu, kontrola cytatu przed wysłaniem deliverable do klienta, audyt grounding outputu LLM, "sprawdź czy ten cytat jest prawdziwy", "zweryfikuj cytaty", "czy ten fragment wyroku istnieje", "grounding", "anti-halucynacja", "citation check", "czy AI to zmyśliło", "czy SN to naprawdę orzekł".

The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

16.7 KB, as published. Nobody here has run it

Citation Grounding PL - mechaniczny weryfikator cytatu (gradient)

Filozofia

Cytat niezweryfikowany mechanicznie = cytat zmyślony, dopóki nie udowodnisz inaczej.

Model językowy potrafi wygenerować fragment wyroku, który brzmi idealnie - sygnatura, ton, słownictwo sądu - a którego w orzeczeniu nigdy nie było. Dla opinii prawnej cytującej nieistniejący fragment SN to katastrofa zawodowa i ryzyko odpowiedzialności (art. 6 Prawa o adwokaturze, należyta staranność).

Zasada: weryfikacja jest mechaniczna, nie semantyczna. Nie pytamy modelu „czy ten cytat pasuje". Robimy string-match znormalizowanego cytatu wobec znormalizowanego źródła. Match albo go nie ma. Odwrotny ciężar dowodu - to cytat musi się znaleźć w źródle.

Co nowego w v2 - gradient weryfikacji

v1 sprawdzał tylko jedną rzecz: czy dosłowny cytat istnieje w źródle. To zostawiało dwie ślepe plamy, które v2 zamyka:

  1. Zmyślona sygnatura. v1 mówił „BRAK ŹRÓDŁA" = luka do uzupełnienia. v2 traktuje nierozwiązaną lub rozbieżną kotwicę jako sygnał możliwego fałszerstwa. v2.1 dokłada guard STRONY: sygnatura może być realna, ale doczepiona do INNEJ sprawy - gdy nazwy stron zadeklarowane rozjeżdżają się ze stronami rozwiązanego źródła (Jaccard tokenów nośnych < 0.30), to 🔴 blokada („prawdziwy cytat, fałszywa teza" już na poziomie kotwicy, nie dopiero w treści).
  2. Prawdziwy cytat, fałszywa teza (problem Stanford „false-under-true"). Cytat może być dosłownie obecny (FRAGMENT zielony), a otaczające twierdzenie - „SN uznał, że…" - przekręca to, co sąd faktycznie orzekł. v1 wprost zwalniał parafrazy z weryfikacji. To była największa luka. v2 wciąga parafrazy w zakres na poziomie TREŚĆ.

Trzy poziomy (adaptacja Existence/Content/Paragraph z biblioteki Jeanne Sulzer, CC BY 4.0):

PoziomCo potwierdzaStosuj do
ISTNIENIEKotwica - sygnatura/CELEX, data, organ - jest realna i zgadza się z deklaracją„wyrok z 12.03.2019, II CSK…", „por. II CSK 123/19"
TREŚĆŹródło CO DO ISTOTY zawiera to, co twierdzi output„SN przyjął, że…", parafraza holdingu
FRAGMENTCytowany akapit/zdanie istnieje dosłownie w źródlekażdy cytat w cudzysłowie, każdy pinpoint akapitu

Reguła kalibracji (rdzeń v2): dopasuj siłę twierdzenia do osiągniętego poziomu. Jeśli output twierdzi na poziomie FRAGMENT (dosłowny cytat), a weryfikacja dochodzi tylko do TREŚĆ (źródło dotyczy tematu, ale cytatu dosłownie nie ma) → status KALIBRACJA: złagodź do parafrazy ALBO oznacz pinpoint jako prowizoryczny. Pełna doktryna i macierz typów twierdzeń: references/gradient-weryfikacji.md.

Kontrakt generacyjny - znakuj przy pisaniu, nie tylko weryfikuj po

Grounding post-hoc łapie halucynację na końcu. Taniej jest nie wyprodukować jej wcale. Gdy generujesz tekst prawny (a nie tylko weryfikujesz cudzy), obowiązują trzy klasy z tagiem przy linii, której dotyczy - nie zbiorczo na końcu akapitu:

KlasaKiedyJak znakować
ZweryfikowaneŹródło sprawdzone w tej sesji (SAOS/EUR-Lex/ISAP/dokument lokalny)pełna kotwica przy tezie: (wyrok SN II CSK NN/RR, SAOS)
Do sprawdzeniaPrawdopodobne, ale z pamięci modelu: przepis, termin, wyliczenietag przy linii: [z pamięci - sprawdź w SAOS/ISAP], [wyliczenie modelu - sprawdź]
Nie używaćSygnatura/numer/cytat, którego nie da się rozwiązaćfail-closed: nie produkuj wcale. Napisz „zgodnie z utrwalonym orzecznictwem SN [uzupełnij sygnaturę]" zamiast zmyślać numer

Reguły domknięcia pętli generacja→weryfikacja:

  • Klasa Zweryfikowane ma pokrycie 1:1 w rekordach zadania dla skryptu - każda taka kotwica trafia do items[] i musi wyjść 🟢/🟡. Zweryfikowane, które nie przechodzi skryptu, to błąd klasyfikacji, nie pech.
  • Klasa Do sprawdzenia nigdy nie jest cytatem w cudzysłowie ani pinpointem - najwyżej parafrazą z tagiem. Cudzysłów zobowiązuje do poziomu FRAGMENT.
  • W szablonach i przykładach używaj jawnych placeholderów (II CSK NN/RR, sygn. akt [uzupełnij]) - realistyczne sygnatury z przykładów wyciekają do prawdziwych outputów (audyt niemieckiego zbioru skilli prawnych: ~58% z 3228 sygnatur w outputach było błędnych, w dużej części przeniesionych z materiałów przykładowych).

Kiedy odpalać

Zawsze przed wysłaniem do klienta / sądu:

  • Opinia prawna lub memo cytujące orzecznictwo, ustawy, umowę
  • Pismo procesowe powołujące fragmenty wyroków
  • Każdy output LLM zawierający cytaty, parafrazy holdingów lub powołania sygnatur

Co teraz JEST w zakresie (zmiana wobec v1): parafrazy i powołania samej sygnatury - oznacz je claim_type i poddaj weryfikacji na właściwym poziomie. Bez cudzysłowu ≠ bez kontroli.

Workflow

  1. Zbierz źródła i rozwiąż kotwice - tekst dokumentu źródłowego dostępny lokalnie:

    • Orzeczenia: saos-orzecznictwo / szukaj-orzeczen-v2 (zwracają też datę i organ → kotwica)
    • Akty EU: eu-sparql-search (CELEX → kotwica)
    • Ustawy PL / umowy / pisma: dostarcza użytkownik (.txt/.md/.docx → markitdown)
    • Gdy bezpośredni fetch zawiedzie, pracuj drabinkę źródeł: references/drabinka-zrodel-pl.md
    • Bez źródła nie ma weryfikacji TREŚĆ/FRAGMENT - status BRAK ŹRÓDŁA, nie „prawdopodobnie ok".
  2. Sklasyfikuj każde twierdzenie - dla każdego powołania ustal claim_type (patrz macierz w references/gradient-weryfikacji.md). To ustawia WYMAGANY poziom weryfikacji:

    • cytat_doslowny, teza_pinpoint → FRAGMENT
    • stanowisko_sadu, parafraza → TREŚĆ
    • fakt_proceduralny, powolanie → ISTNIENIE
  3. Zbuduj zadanie - jeden rekord na twierdzenie (format niżej): quote dla FRAGMENT, claim_text dla TREŚĆ, anchor + anchor_resolved dla ISTNIENIA.

  4. Weryfikacja mechaniczna - uruchom skrypt:

    node scripts/ground-citations.mjs <plik-zadania.json>
    

    Skrypt liczy osiągnięty poziom, porównuje z wymaganym, kalibruje. Exit 1 = twarda blokada.

  5. Klasyfikuj wynik (skrypt robi to automatycznie):

    • 🟢 ZWERYFIKOWANY - osiągnięty poziom ≥ wymagany (podaje offset dla FRAGMENT)
    • 🟡 ZMODYFIKOWANY - cytat znaleziony z drobną różnicą (interpunkcja, diakrytyki) - diff
    • 🟡 WYMAGA_OSADU - poziom TREŚĆ: terminy nośne obecne, substancję potwierdza człowiek / paraphrase-judge
    • 🟠 KALIBRACJA - osiągnięto niżej niż twierdzono (cytat dosłowny nieobecny, temat pokryty) - złagodź tezę
    • 🔴 NIEZWERYFIKOWANY - brak trafienia / rozbieżna kotwica = potencjalna halucynacja, BLOKUJ
    • BRAK ŹRÓDŁA - nie dostarczono dokumentu / nierozwiązana sygnatura tam, gdzie wymagana
  6. Raport - zwróć tabelę (niżej). 🔴 i ⛔ = twarda blokada (exit 1). 🟠 i 🟡 = decyzja człowieka przed publikacją (miękka). Nigdy nie przepuszczaj 🔴 milcząco.

Format zadania (input skryptu)

Wszystkie sygnatury, strony i cytaty w przykładach tego pliku są fikcyjne - ilustrują format, nie realne sprawy. Nie przenoś ich do zadań ani deliverable.

{
  "items": [
    {
      "id": "C1",
      "source_id": "II CSK 123/19",
      "claim_type": "cytat_doslowny",
      "quote": "sąd związany jest granicami zaskarżenia",
      "source_text": "<pełny znormalizowany tekst orzeczenia>"
    },
    {
      "id": "C2",
      "source_id": "I CSK 50/18",
      "claim_type": "stanowisko_sadu",
      "claim_text": "SN przyjął, że klauzula waloryzacyjna w umowie kredytu jest dopuszczalna",
      "source_text": "<pełny tekst orzeczenia>"
    },
    {
      "id": "C3",
      "source_id": "II CSK 123/19",
      "claim_type": "fakt_proceduralny",
      "anchor":          { "sygnatura": "II CSK 123/19", "data": "12.03.2019", "organ": "SN Izba Cywilna", "strony": "Kowalski przeciwko Bank Millennium S.A." },
      "anchor_resolved": { "sygnatura": "II CSK 123/19", "data": "2019-03-12", "organ": "Sąd Najwyższy Izba Cywilna", "strony": "Nowak przeciwko Skarb Państwa" }
    }
  ]
}

anchor = co twierdzi output. anchor_resolved = co zwrócił resolver (SAOS/EUR-Lex). Skrypt porównuje mechanicznie (rozwija skróty: SNsąd najwyższy, NSA, TK, TSUE…, normalizuje daty DD.MM.YYYYYYYY-MM-DD). Brak claim_type → domyślnie cytat_doslowny (zachowanie v1).

Pole strony (opcjonalne, string „X przeciwko Y" albo tablica nazw) uruchamia guard STRONY: gdy sygnatura się zgadza, ale nazwy stron zadeklarowane vs rozwiązane rozjeżdżają się (Jaccard tokenów nośnych < 0.30 przy ≥2 tokenach) → 🔴 blokada („prawdziwy cytat, fałszywa teza" na poziomie kotwicy). Częściowa zgodność (0.30–0.50) → 🟡 miękka uwaga. Stop-lista odsiewa formy prawne (sp. z o.o., S.A., przeciwko, v., i inni), więc Bank Millennium S.A.Bank Millennium Spółka Akcyjna. anchor_resolved.strony dostarcza resolver (SAOS zwraca strony postępowania).

Reguły normalizacji (co robi skrypt)

Aby uniknąć fałszywych 🔴 z powodu kosmetyki, przed porównaniem skrypt:

  • sprowadza do lowercase, zwija białe znaki, ujednolica cudzysłowy ( " »") i myślniki ( -)
  • usuwa myślniki przenoszenia (praw-\nnikprawnik)
  • traktuje [...] / ... w cytacie jako dozwoloną lukę
  • przy kotwicy: rozwija skróty organów, normalizuje formaty dat, porównuje sygnatury bez kropek
  • przy TREŚCI: wyciąga terminy nośne (≥4 znaki, bez stopwords), liczy pokrycie w źródle (próg 0.7)

Normalizacja NIE zmienia treści merytorycznej - jeśli słowo nośne jest inne, to nadal 🔴.

Raport (dla użytkownika)

## Raport grounding (gradient) - <nazwa deliverable>

| ID | Źródło        | Typ              | Wym.→Osiąg.        | Status            | Uwaga                                   |
|----|---------------|------------------|--------------------|-------------------|-----------------------------------------|
| C1 | II CSK 123/19 | cytat_doslowny   | FRAGMENT→FRAGMENT  | 🟢 ZWERYFIKOWANY  | znak 4821                               |
| C2 | I CSK 50/18   | stanowisko_sadu  | TREŚĆ→TREŚĆ        | 🟡 WYMAGA_OSADU   | terminy 86% - potwierdź substancję      |
| C3 | III CZP 5/21  | cytat_doslowny   | FRAGMENT→ISTNIENIE | 🔴 NIEZWERYFIKOWANY| brak w źródle - BLOKADA                 |
| C4 | I CSK 50/18   | cytat_doslowny   | FRAGMENT→TREŚĆ     | 🟠 KALIBRACJA     | złagodź do parafrazy lub oznacz prowizor.|
| C5 | II CSK 999/19 | fakt_proceduralny| ISTNIENIE→BRAK     | 🔴 NIEZWERYFIKOWANY| rozbieżna sygnatura - możliwe falszerstwo|

Wynik: 1/5 zweryfikowane. 2 blokady (C3, C5), 1 kalibracja (C4), 1 do osądu (C2).
NIE publikuj dopóki C3 i C5 nie zostaną poprawione lub usunięte. C4 wymaga złagodzenia tezy.

Ochrona danych (RODO)

  • Skill działa w całości lokalnie - normalizacja i string-match w Node, bez wywołań sieciowych. (Rozwiązywanie kotwic przez SAOS/EUR-Lex robi agent osobnym krokiem - skrypt dostaje gotowy anchor_resolved.)
  • Dla materiałów objętych tajemnicą zawodową: pseudonimizuj wcześniej przez let-it-be.
  • Skrypt nie zapisuje logów poza katalogiem zadania.

Integracja z AI Act

Mechaniczny grounding to dowód należytej staranności i element dokumentacji z art. 12 (rejestrowanie zdarzeń) oraz nadzoru człowieka z art. 14. Gradient dodaje wymiar kalibracji ryzyka: poziom weryfikacji per twierdzenie to ślad, jak mocno każda teza jest osadzona. Raport grounding wkładaj do legal-ai-audit-bundle obok deliverable.

Integracja z innymi skillami

  • legal-request-router-pl routuje TU, gdy zapytanie zawiera powołania. Wysoka stawka → rozwiąż wszystkie kotwice (ISTNIENIE) + paraphrase-judge na 🟡.
  • saos-orzecznictwo / eu-sparql-search = resolver kotwic (dają anchor_resolved) i źródło tekstu.
  • deliverable-fidelity-pl pyta „czy nic nie wypadło z podsumowania"; ten skill pyta „czy to, co zostało, jest prawdziwe". Komplementarne - oba przed wysłaniem high-stakes.
  • 🟡 WYMAGA_OSADU to dokładnie wejście dla warstwy paraphrase-judge (kaskada PATRON) - mechanika robi tani pre-filtr, osąd substancji robi człowiek lub model.

Atrybucja

  • Pattern mechanicznego groundingu (v1) zainspirowany AnttiHero/lavern (Apache 2.0, ADR-011).
  • Guard STRONY (v2.1): wzorzec porównania nazw stron (Jaccard name-mismatch) zainspirowany funkcją _is_name_mismatch z john-walkoe/courtlistener_citations_mcp (MIT, 2026). Zaadaptowano ideę (parse → porównaj nazwy stron zadeklarowane vs rozwiązane → flaguj rozbieżność); kod, stop-lista form prawnych PL/EU i progi napisane od zera. Logika walidacji reporterów US z tamtego repo NIE jest przenoszona - żyje po stronie serwera CourtListener (wywołanie sieciowe + token), co łamie kontrakt zero-cloud; z repo bierzemy tylko lokalną, jurysdykcyjnie-neutralną heurystykę nazw stron.
  • Kontrakt generacyjny (v2.2): trójklasa znakowania przy generacji (Zweryfikowane / Do sprawdzenia / Nie używać, tag przy linii, fail-closed dla klasy 3) - adaptacja „kolmiportainen varmuusmerkintä" z akunikkola/claude-for-legal-finland (MIT, references/viittaustyyli.md). Stamtąd też lekcja dyscypliny placeholderów w przykładach (audyt siostrzanego projektu DE: ~58% złych sygnatur).
  • Dyskonto języka szablonowego (v2.3): wzorzec COMMON_LEGAL_PHRASES z AnttiHero/lavern (Apache 2.0, src/mcp/tools/grounding-verifier.ts) - trafiona fraza-wytrych liczy się 0.5 zamiast 1.0, żeby boilerplate nie zawyżał dowodu. Lista polskich fraz („z zastrzeżeniem", „w szczególności", „chyba że umowa stanowi inaczej"...) i kod napisane od zera.
  • Zbieżność fragmentu (v2.3): wzorzec citation-content-matcher z chrisryugj/korean-law-mcp (MIT) - n-gram-Jaccard twierdzenia z najlepszym oknem źródła łapie „prawdziwe słowa, fałszywa teza" (terminy obecne, ale rozproszone; żaden zwarty fragment nie odpowiada tezie). Tam bigramy znakowe (koreański: 1 znak = sylaba); tu TRIGRAMY dla polskiego alfabetu łacińskiego (zmierzone na fixture: bigram dawał szum 0.33 na rozproszeniu, trigram 0.15 przy parafrazie 0.45-0.78). Wyłącznie sygnał (uwaga dla człowieka), nigdy samodzielna blokada. Kod i progi od zera.
  • Gradient weryfikacji (v2): ISTNIENIE/TREŚĆ/FRAGMENT to adaptacja Existence/Content/Paragraph z jeannesulzer/international-criminal-tribunals-skills (CC BY 4.0, Jeanne Sulzer / Impact Litigation Lab, 2026). Zaadaptowano ideę gradientu i regułę kalibracji, nie kod ani treść - ich biblioteka to dyscyplina promptowa pod web_fetch publicznych archiwów; tutaj to mechaniczny silnik string-match pod lokalne źródła PL (RODO, zero-egress). Kod, prompty i reguły normalizacji napisane od zera pod polskie realia (cudzysłowy „…", sygnatury SN/NSA/TSUE, CELEX).

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.