Rekoncyliacja faza 5 etap 1 (kb-m5-faza5-wiki.md §4), krok 2 z 3. Trzy decyzje z kb/audits/wiki-kompilat-recon-2026-08-26.md, już wypracowane i zastosowane w bootstrapie sesyjnym (~/kb-wiki-etap1-sesja-2026-08-27/ _meta/conventions.md §5/§7/§8), scalone tu bez duplikowania tego, co w tym repo już było (6 typów wliczając `meta` i sekcja "Brak danych w KB" — obie już scalone wcześniej, commity156925ci3bd2441): (d) Fallback envelope-only w przypisach — `[^envelope_id]` bez `#chunk_id`, gdy dowód nie ma konkretnego chunka albo chunk przestał istnieć po re-chunkingu (`document_chunk.id` niestabilny między przebiegami embeddingu). Dopisane do sekcji "Przypisy inline i cytowanie faktów". (e) Sekcja "Niepewne / sprzeczne" jako nazwana sekcja końca strony (już używana de facto na żywych stronach: pzu.md, warta.md, mbank.md — teraz sformalizowana pisemnie) + polityka aktualizacji "dopisz, nie nadpisuj" przy nowym sprzecznym dowodzie, z wyjątkiem dla jawnych aktualizacji tego samego faktu. Nowa sekcja, między "Sprzeczności między źródłami" a "Wersjonowanie dokumentów źródłowych". (f) Inwariant 7 — izolacja retrievalu kompilacji od source='wiki' (mitygacja self-citation/citogenesis), CC/API-only jako wykonawca kompilacji. Nowa sekcja przed "Integracja z retrievalem". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7AnxL6pbgySpEgcCwAfww
13 KiB
| title | type | status | tags | sources | compiled_by | compiled_at | updated_at |
|---|---|---|---|---|---|---|---|
| Konwencje kb-wiki | meta | active | claude-sonnet-5 | 2026-07-21 | 2026-08-27 |
Konwencje kb-wiki
Ten dokument definiuje format stron tej wiki. Rozwinięcie decyzji architektonicznych
z homelab-codex-ws, docs/kb/modules/05-faza3-plan.md §8 (szkic operatora, NIE
zmieniamy stamtąd decyzji — tylko doprecyzowujemy wykonanie). To repo jest read-write
tylko dla kompilatora (CC/API); baza źródłowa (kb-postgres@PIHA) jest zawsze
read-only z tej strony.
Struktura katalogów
Typy stron = katalogi; płasko wewnątrz każdego, graf robią linki [[...]], nie
hierarchia plików.
| Katalog | Zawartość |
|---|---|
podmioty/ |
Firmy i instytucje: ubezpieczyciele, banki, urzędy — encje trwałe, nie procesy |
osoby/ |
Tożsamości/aliasy osób fizycznych |
sprawy/ |
Procesy w czasie: sezony, remonty, procesy decyzyjne, porównania ofert |
umowy/ |
Konkretne, zawarte kontrakty/polisy — jeden dokument prawny lub jego wersje |
tematy/ |
Przekrojowe kategorie łączące wiele podmiotów/spraw (np. „ubezpieczenia auto”) |
_meta/ |
Ten plik, raporty lintu |
Wybór katalogu dla nowej strony: jeśli encja to firma/instytucja → podmioty/;
jeśli to coś co się dzieje/działo w czasie (sezon, spór, zakup) → sprawy/; jeśli to
konkretna umowa prawna → umowy/; jeśli łączy wiele podmiotów pod wspólnym parasolem
tematycznym → tematy/.
Frontmatter
---
title: <nazwa strony, czytelna>
type: podmiot # podmiot | osoba | sprawa | umowa | temat | meta
status: active # active | archived
tags: [ubezpieczenie] # słownik wspólny z jobs/documents-ingest/tags-vocab.yaml
# (homelab-codex-ws) — nie wymyślamy nowego słownika dla wiki
sources:
- envelope_id: paperless:119
chunks: [4211, 4213] # document_chunk.id (klucz PK), NIE chunk_index
- envelope_id: "CABtrY-...@mail.gmail.com"
chunks: [] # koperta bez chunków (np. sam manifest)
compiled_by: claude-sonnet-5 # model/sesja, która skompilowała/ostatnio zmieniła stronę
compiled_at: 2026-07-20 # data pierwszej kompilacji
updated_at: 2026-07-20 # data ostatniej zmiany
---
sources agreguje wszystkie koperty, z których cokolwiek na stronie pochodzi —
niezależnie od tego, ile razy dana koperta jest cytowana w treści. To jest poziom
audytu „skąd strona czerpie w ogóle”; poziom „ten konkretny fakt” robią przypisy
inline (niżej).
Przypisy inline i cytowanie faktów
Każdy fakt liczbowy lub identyfikujący (kwota, data, numer polisy/umowy, adres, próg punktowy) dostaje przypis w miejscu użycia:
składka 1 234 zł/rok [^paperless:119#4212]
Format: [^<envelope_id>#<document_chunk.id>]. Jeden fakt może mieć więcej niż
jeden przypis, jeśli potwierdzają go niezależnie różne chunki/koperty — wtedy oba
się wypisuje: [^paperless:14#965][^paperless:22#2081].
Fallback envelope-only (decyzja d, audyt 08-26): document_chunk.id jest
kruchy — re-chunking (zmiana chunk_size/modelu embeddingu) usuwa i wstawia
wiersze na nowo, stary id przestaje istnieć. Gdy dowód nie ma konkretnego
chunka (sam nagłówek koperty) albo chunk już nie istnieje po re-chunkingu,
przypis degraduje się do samej koperty: [^<envelope_id>], bez #<chunk_id>.
envelope_id jest stabilny (Message-ID/sha256-…, nigdy nie zmienia się po
insercie) — degradacja zostaje audytowalna, tylko mniej precyzyjna. Lint
raportuje liczbę zdegradowanych przypisów jako osobną metrykę (sygnał, że
re-chunking coś ruszył); re-chunking jest triggerem do ręcznego przeglądu
stron, nie do automatycznego remapowania (wymagałby ponownego embeddingu i
ryzykowałby przypisanie faktu do złego fragmentu po cichu).
Fakty opisowe/narracyjne (np. „PZU oferuje kilka wariantów ubezpieczenia") niosące niską specyficzność mogą dzielić jeden przypis na koniec akapitu zamiast przypisu po każdym zdaniu — przypis jest obowiązkowy per sekcja, nie per zdanie, ale musi dawać się prześledzić do konkretnego chunka.
Zakaz dopowiadania: jeśli fakt nie występuje w żadnym pobranym chunku/streszczeniu, strona pisze wprost „brak danych w KB" zamiast go zgadywać z wiedzy ogólnej modelu.
Sprzeczności między źródłami
Gdy dwa dokumenty (typowo: dwie wersje tego samego OWU z różnymi datami obowiązywania, albo dwie oferty konkurencyjne) podają różne wartości dla tego samego faktu, strona nie wybiera cicho jednej wersji. Sprzeczność jest flagowana jawnie w tekście, z obiema wartościami i obu przypisami, np.:
Udział własny w AC: 300 zł wg OWU obowiązującego od 21.03.2026 [^paperless:14#871],
ale 500 zł wg wcześniejszej wersji OWU [^paperless:17#XXXX] — **rozbieżność między
wersjami, nie literówka**; przy sporze o odszkodowanie decyduje wersja obowiązująca
w dniu zdarzenia.
Sekcja „Niepewne / sprzeczne" i polityka aktualizacji (decyzja e, audyt 08-26)
Sekcja wyżej pokazuje jak flagować sprzeczność w treści. To formalizuje ją
jako nazwaną sekcję na końcu strony (już używana na żywych stronach: pzu.md,
warta.md, mbank.md, ...), gdy sprzeczności nie da się rozstrzygnąć przy
kompilacji — nazwa i miejsce ujednolicone, żeby czytelnik/lint wiedział, gdzie
szukać:
## Niepewne / sprzeczne
- Składka OC: [^paperless:24#N] podaje kwotę roczną bez liczby, [^<msg-id>#M]
(mail 2025-03) wspomina "1 450 zł" — nie jest jasne, czy to ta sama polisa
czy poprzedni rok. **Nie rozstrzygane automatycznie** — do potwierdzenia
przy następnej kompilacji tej strony.
Kolejność na końcu strony, gdy obie sekcje występują: „Niepewne / sprzeczne" przed „Brak danych w KB" (niżej) — dowody, które się kłócą, nie to samo co brak dowodów w ogóle. Strona bez tej sekcji nie jest „lepsza" — strona z niewykrytą sprzecznością w treści głównej jest gorsza; to mechanizm anty-propagacji (kompilator pisze „nie wiem" zamiast zgadywać i zamrażać zgadywankę jako fakt).
Polityka aktualizacji przy nowym, sprzecznym dowodzie: dopisz, nie
nadpisuj. Domyślnie nowy sprzeczny dowód trafia do „Niepewne/sprzeczne",
fakt w treści głównej nie jest nadpisywany, dopóki sprzeczność nie
zostanie rozstrzygnięta. Wyjątek: gdy nowy dowód jest tego samego typu i
wprost aktualizuje poprzedni (np. „nowy cennik od 1.09" jawnie
zastępujący poprzedni, bez sprzeczności) — to nie jest sprzeczność, to
aktualizacja: idzie do treści głównej z nową updated_at. Rozróżnienie
„aktualizacja" vs „sprzeczność" robi sesja kompilująca (CC/API), nie
reguła automatyczna.
Wersjonowanie dokumentów źródłowych
Ubezpieczenia i regulaminy w korpusie mają wielokrotne wersje z różnymi datami
„obowiązuje od". Strona encji nie kompiluje jednej płaskiej prawdy — jeśli
źródła mają rozbieżne daty obowiązywania, strona wymienia wersje osobno (np.
podsekcja per data) zamiast nadpisywać starszą nowszą bez adnotacji. To był
konkretny finding z pilota dedupa (docs/kb/eval/retrieval-pilot-2026-07-16.md,
docs/kb/modules/05-faza3-plan.md §3.2) — dokumenty bywają też duplikatami
binarnymi (excluded_reason='duplicate' w bazie), co jest czymś innym niż
kolejna wersja: duplikat pomijamy w kompilacji (baza już to wyklucza z retrievalu),
wersję z inną datą obowiązywania — nie.
Sekcja „Brak danych w KB" (rozszerzenie, faza 5 etap 1 rekoncyliacja, 2026-08-27)
„Zakaz dopowiadania" wyżej mówi, że pojedynczy fakt bez pokrycia w źródłach pisze się wprost jako „brak danych w KB" w miejscu użycia. To rozszerzenie formalizuje to jako osobną sekcję na końcu strony, odróżnioną od „Niepewne / sprzeczne":
- „Niepewne / sprzeczne" — dowody istnieją, ale się nie zgadzają (dwa chunki, dwie wartości, dwa przypisy).
- „Brak danych w KB" — zapytano retrievalem o coś istotnego dla tej encji, i żaden pobrany chunk/streszczenie tego nie potwierdza. Nie jest to błąd kompilacji — jest to jawne przyznanie granicy tego, co korpus dziś wie, zamiast milczącego pominięcia pytania.
Format — krótka lista na końcu strony, po „Niepewne / sprzeczne" (jeśli obie występują):
## Brak danych w KB
- Nazwisko trenera drużyny (OCR nieczytelny w `paperless:175`).
- Wynik końcowy/klasyfikacja drużyny w całym turnieju (KB ma tylko wyniki cząstkowe).
Praktyczna wartość: kolejna kompilacja/aktualizacja tej strony (albo lint) wie od
razu, czego szukać przy następnym retrievalu, zamiast rekonstruować to z pamięci
sesji albo przeczytać stronę i domyślać się, co zostało pominięte a co nigdy nie
było sprawdzone. Pierwszy przykład użycia (przed formalizacją tej reguły):
sprawy/fll-2025-26.md, sekcja „Brak danych w KB", kompilacja 2026-07-21.
Linkowanie między stronami
[[nazwa-pliku-bez-rozszerzenia]] — link do innej strony wiki po nazwie pliku
(bez katalogu, nazwy plików są unikalne w całym repo). Linkujemy tam, gdzie treść
się faktycznie styka (wspólny podmiot, wspólna sprawa, przywoływany dokument) —
nie tworzymy linków na wyrost do stron, które jeszcze nie istnieją, chyba że
świadomie oznaczamy brakujące pojęcie (patrz niżej), bo taki link psuje inwariant
lintu „brak stron-sierot i wiszących linków" dopóki strona docelowa nie powstanie.
Brakujące pojęcia (przyszłe strony)
Jeśli podczas kompilacji natrafiamy na encję wartą osobnej strony, ale poza
zakresem bieżącej kompilacji (np. inny ubezpieczyciel wspomniany punktowo, inna
sprawa), nie tworzymy linku [[...]] do niej (byłby wiszący). Zamiast tego
kandydatka trafia do listy „brakujące pojęcia" w najbliższym raporcie lintu
(_meta/lint-reports/), żeby nie zgubić się w wątku.
Zasady lintu
Okresowy lint (ręczny w tej fazie, _meta/lint-reports/YYYY-MM-DD.md) sprawdza:
- Strony-sieroty — strona bez żadnego linku przychodzącego z innej strony
(poza
INDEX.md, który z definicji linkuje do wszystkiego). - Wiszące linki —
[[cel]]bez odpowiadającego plikucel.mdw repo. - Brakujące pojęcia — encje wspomniane w treści (nie w linku) a nieopisane osobną stroną; kandydaci na przyszłe strony, nie błąd.
- Spot-check — dla losowej próbki przypisów
[^envelope_id#chunk_id]weryfikacja, że treść chunka w bazie faktycznie potwierdza przywołany fakt. - Sprzeczności międzystronicowe — ten sam fakt o tej samej encji opisany różnie na dwóch stronach (nie mylić z rozbieżnością międzywersyjną w obrębie jednej strony, która jest już jawnie flagowana w treści per wyżej).
Kompilacja: CC/API-only i inwariant 7 — izolacja retrievalu (decyzja f, audyt 08-26)
Kompilację i lint robi wyłącznie CC/zewnętrzne API (patrz akapit wstępny) — lokalny model za słaby na wielostronicowe operacje syntezy.
Inwariant 7: retrieval na potrzeby kompilacji strony wiki nigdy nie
czyta source='wiki' jako dowodu — zawsze wyklucza wiki
(exclude_sources=('wiki',) albo równoważny filtr SQL), czyta wyłącznie
warstwę dowodową (mail, paperless). Tylko retrieval na potrzeby /search
(warstwa użytkownika, po zbudowaniu syntezy odpowiedzi — poza zakresem tej
fazy) widzi wiki w kaskadzie. Mitygacja self-citation/citogenesis: bez tego
rozdziału kompilacja strony X mogłaby cytować inną stronę wiki (samą
skompilowaną z niepewnych przesłanek) jako „dowód", i błąd wzmacniałby się z
pozorem niezależnego potwierdzenia.
W praktyce (dopóki source='wiki' nie istnieje w bazie) retrieval
kompilacyjny i tak nie może dziś trafić na wiki — ale każde zapytanie
SQL/cascade_retrieve/hybrid_retrieve użyte przy kompilacji strony musi
jawnie nieść ten filtr od pierwszego dnia, nie dopisany post-factum, gdy wiki
już będzie źródłem w bazie.
Strony mogą linkować się nawzajem przez [[nazwa-strony]] (graf,
nawigacja) — to nie jest to samo co cytowanie jako dowód faktu. Przypisy
źródłowe ([^...]) zawsze wskazują envelope_id (warstwa dowodowa), nigdy
inną stronę wiki.
Integracja z retrievalem (poza zakresem tej fazy)
Docelowo strony wiki wchodzą do kb-postgres jako koperty source='wiki'
(id='wiki:<katalog>/<plik>'), embedowane tym samym pipeline'em co chunki
dokumentów — kaskada retrievalu rozszerza się wtedy o trzeci poziom: wiki →
streszczenie → chunk. Nie jest to realizowane w tej fazie (proof-of-concept
ręcznej kompilacji 3–5 stron) — patrz docs/kb/modules/05-faza3-plan.md §8.2
w homelab-codex-ws po szczegóły.