Přeskočit na obsah

Pravidla brány

Co build doopravdy vynucuje: sémantika, referenční integrita, parita tabulky a JSON-LD expanze — vytažené z modulů, které ta pravidla vlastní.

30

pravidel celkem

5

shodí build (ERROR)

0

jen hlásí (WARNING)

Tahle stránka neopisuje pravidla z dokumentace. Čte je z modulů, které je vynucují — a co v kódu není, se tu neobjeví.

Pravidlo se stavem ERROR shodí build. WARNING se jen hlásí: je to nález k prohlédnutí, ne brána. Ten rozdíl je tu vidět schválně, protože stránka, která by obojí ukázala stejně, by slibovala víc, než se skutečně vynucuje.

S — Sémantika (redakční pravidla)

Co smí tvrzení a hrana slíbit o síle svého doložení. Odsud pochází stav CORROBORATED i to, kdy na něj nárok není.

Vlastník: scripts/data/validate-semantics.mjs — 11 pravidel

Pravidla S — Sémantika (redakční pravidla) 11

Pravidla S — Sémantika (redakční pravidla)
IDCo vynucujeZávažnost
S1claim status-single ⇒ ≥1 citovaný zdroj a všechny citované zdroje z JEDNÉ source family (ERROR). Nezávislost se počítá přes rodiny, ne přes ID/URL: dva zdroje téže rodiny (převzatá agenturní zpráva) jsou jedno doložení, takže status-single je pro ně správný; 2+ rodin evidenci podhodnocuje a patří status-corroborated (sémantika opravy 6b0bd4d, dříve validate-dossier.mjs)shodí build
S2claim status-corroborated ⇒ ≥2 zdroje z ≥2 různých source families; rodina = neprázdné sourceFamily, jinak outlet, jinak zdroj sám za sebe (ERROR — zrcadlí validate-dossier.mjs)shodí build
S3relation se statusem != contextual ⇒ ≥1 existující claim i ≥1 existující zdroj (tvarové minItems na polích vlastní relation.schema.json; tady se vlastní sémantika „hrana má skutečnou evidenci", tedy počítají se jen rozložitelné cíle)neuvedeno
S4relation status single ⇒ ≥1 zdroj z právě 1 source family (ERROR); status corroborated ⇒ ≥2 source families (WARNING, zrcadlí validate-graph.mjs, který to také jen hlásí). Dřív S4 vyžadovalo přesně jeden ZDROJ — počítalo tedy citace, ne nezávislost, a hraně doložené třemi převzetími téže agenturní zprávy nedovolilo přiznat, že jde o jedno doložení, aniž by zahodila dvě citace. Sjednoceno s S1 na úrovni tvrzení.shodí build
S5autorizace: každý dossier s dossierType=entity má neprázdné authorization.records a každý záznam existuje v data/authorizations.toml (transkripce append-only logu v AGENTS.md — parsuje se přímo, žádný druhý ručně udržovaný registr nevzniká; stejný princip jako validate-authorization.mjs)neuvedeno
S6žádná kontextová entita (publicationRole=context) nesmí být subjektem dossieru — nesmí mít subjectOf, dossierEnabled=true ani dossierStatus=authorized (zrcadlí validate-authorization.mjs)neuvedeno
S7subjektové uzly grafu (dossier.graph, fáze H — dřívější validate-graph.mjs): množina uzlů se subject=true se přesně rovná autorizovaným subjektům dossieru (dossier.subject, u agregátu sjednocení subjektů agregovaných dossierů)neuvedeno
S8souvislost grafu (dřívější validate-graph.mjs): každý uzel má cestu k subjektovému uzlu — BFS hloubka (scripts/data/lib/graph-depth.mjs) nesmí být nullneuvedeno
S9provenance refs entit se rozliší: každé CLM-##/SRC-## v provenance.claimRefs/sourceRefs sdílené entity musí existovat aspoň v jednom dossieru z jejího pole `dossiers` (composite-key sémantika dle entity.schema.json) — jinak jde o zamrzlý odkaz po smazání/sloučení zdroje nebo o chybný zápis při extrakcineuvedeno
S10týž vydavatel nikdy nezakládá nezávislé doložení: dva zdroje se shodným `outlet`em, shodnou registrovanou doménou `url` nebo shodnou SKUPINOU VYDAVATELŮ (`publisherGroup` v katalogu zdrojů) se počítají jako JEDEN nezávislý hlas BEZ OHLEDU na `sourceFamily` (ERROR u claims, WARNING u hran — zrcadlí severitu hostitelského pravidla S2/S4). Díra, kterou S10 zavírá: `familyOf` sahá po `outlet`u teprve tehdy, když je `sourceFamily` prázdná. Dva články TÉHOŽ vydavatele, z nichž jeden má rodinu vyplněnou a druhý ne, tak dostaly dva různé klíče (`family:ctk` vs `outlet:FORUM 24`) a S2 je považovala za dvě nezávislé redakce. Jedna redakce ale nepotvrzuje sama sebe: badge `CORROBORATED` znamená dva NEZÁVISLÉ vydavatele, ne dvě různé hodnoty jednoho pole. Druhá díra (T-083): jeden vydavatel může držet víc titulů na víc doménách — Česká justice, Ekonomický deník a Zdravotnický deník vydává Media Network s.r.o., Novinky.cz a Seznam Zprávy provozuje Seznam.cz. Outlet ani doména to nevidí; katalog zdrojů ano, a proto je jeho `publisherGroup` třetí osou identity vydavatele. Implementačně je S10 vlastnost společného primitivu `independentPair()`: nezávislé doložení je DVOJICE zdrojů, které se liší rodinou (S1/S2) A ZÁROVEŇ vydavatelem — outletem, registrovanou doménou i skupinou vydavatelů (S10). Primitiv používají S1, S2 i S4 — pravidlo tedy platí i pro grafové hrany. Párová (ne tranzitivní) formulace je záměrná: kdyby se zdroje slučovaly tranzitivně přes rodinu, vlastní reportáž Blesku by splynula s ČTK jen proto, že Blesk jinde ČTK přetiskuje — a pravdivá korroborace by zmizela.shodí build
S10bregistr a web, který ten registr přetiskuje, nejsou dvě nezávislá doložení: dvojice, kde OBA zdroje čerpají z téhož českého veřejného rejstříku (ARES, obchodní rejstřík, Hlídač státu, Podnikatel.cz, Kurzy.cz), se počítá jako JEDEN hlas — stejná severita jako u hostitelského pravidla (ERROR u claims, WARNING u hran, viz S10). Díra, kterou S10b zavírá: dvojice ARES + Podnikatel.cz projde rodinou, outletem i doménou, protože to opravdu JSOU dva různí provozovatelé na dvou různých doménách. Jenže agregátor svá rejstříková data z registru přebírá, takže mu nemůže odporovat: kdyby byl zápis chybný, přetiskl by tutéž chybu. Nezávislost znamená, že druhý zdroj mohl dojít k JINÉMU výsledku — testem není jiný provozovatel, ale jiný původ důkazu. Rozsah je úzký schválně. Rejstříky dvou různých států jsou na sobě nezávislé a slévat se nesmějí; redakce, která o rejstříku píše, sem nepatří, protože udělala vlastní práci a může se mýlit nezávisle. Citovat registr i agregátor společně je v pořádku a je to lepší provenience než jen agregátor — zakázané je počítat je jako dva hlasy. Implementačně je S10b, stejně jako S10, vlastnost primitivu v source-independence.mjs (`czechRegistryOrigin()` jako čtvrtý důvod kolize vedle rodiny, outletu a domény), takže platí pro S1, S2 i S4 naráz. Nalezeno živě 2026-08-05 na dossieru martin-pavlik: tři tvrzení a tři hrany nesly CORROBORATED přesně na téhle dvojici. Data opravena v 16c072ff.shodí build

R — Referenční integrita

Že každý odkaz mezi záznamy vede na existující cíl a že identita záznamu sedí s místem, kde leží.

Vlastník: scripts/data/validate-references.mjs — 8 pravidel

Pravidla R — Referenční integrita 8

Pravidla R — Referenční integrita
IDCo vynucujeZávažnost
R1každé @id je globálně unikátní (napříč záznamy i entitami)neuvedeno
R2identifier je unikátní v rámci dossier+recordTypeneuvedeno
R3soubor leží tam, kde jeho @id říká — @id, identifier, cesta souboru a pole dossier musí být navzájem konzistentní; žádné implicitní vazby jen podle názvu souboru, ale nesoulad cesty a @id je tvrdá chybaneuvedeno
R4každá reference záznam→záznam (claim→source, case→claims/sources, gap→claims, update→claims/gaps/sources, relation→claims/sources, quote blok→source) ukazuje na existující záznam VE STEJNÉM dossier namespace — @id nese slug dossieru, takže cross-dossier SRC-## kolize je mechanicky nemožná: cizí slug v referenci je chyba i tehdy, když cíl existujeneuvedeno
R5relation sourceEntity/targetEntity ukazují na existující sdílené entity; entity.dossiers slugy a entity.subjectOf odkazují na existující dossieryneuvedeno
R6každý claim mimo status-opinion má ≥1 EXISTUJÍCÍ zdroj (tvarové minItems na poli sources vlastní claim.schema.json; tady se vlastní existence cílů po rozkladu referencí)neuvedeno
R7kurátorovaná grafová vrstva (dossier.graph — fáze H, dřívější graph.toml, pravidla převzatá z validate-graph.mjs): unikátní uzly, uzel = existující globální entita s členstvím v dossieru, lokální claims/sources uzlů i clusterů existují v registrech dossieru, graph.edges je 1:1 permutace relations dossieru, endpointy každé relation jsou uzly grafu, žádný self-loop, žádná duplicitní (source,target,relationType) trojice, cluster reference konzistentní oběma směry, rodiny zdrojů odkazují existující zdrojeneuvedeno
R8vazba claim↔source je obousměrná: cituje-li tvrzení zdroj, musí ho tentýž zdroj uvádět ve svém poli claims, a naopak. R4 hlídá jen existenci cíle, ne to, že o vazbě ví i druhá strananeuvedeno

T — Parita registrové tabulky

Že přehledová tabulka na stránce dossieru a kanonické záznamy říkají totéž — dvě reprezentace, jeden zdroj pravdy.

Vlastník: scripts/data/validate-registry-table.mjs — 8 pravidel

Pravidla T — Parita registrové tabulky 8

Pravidla T — Parita registrové tabulky
IDCo vynucujeZávažnost
T1každá CLM řádka tabulky má <a id="clm-##"> kotvu se shodným číslem a odkaz na svou detailní stránku (@/dossiers/<slug>/ claims/clm-##.md) se shodným slugemneuvedeno
T2množina řádek tabulky == množina kanonických claim záznamů (1:1, žádný duplicitní CLM v tabulce)neuvedeno
T3řádka a záznam se shodují byte-verně: text == claim.text, status badge == claim.status, label == claim.statusLabel, SRC reference řádky == claim.sources (množinově)neuvedeno
T4status badge v tabulce je ze známého slovníku (překlep v ručně psané tabulce nesmí projít)neuvedeno
T5status-corroborated s ≥2 SRC musí vést na ≥2 RŮZNÉ URL — týž článek citovaný dvakrát je jeden zdroj, ne nezávislé potvrzení (rodinovou nezávislost vlastní S2; tohle je URL dedup)neuvedeno
T6interní odkazy těla na zdroje (@/…/sources/src-##.md) a mezery (@/…/gaps/gap-##.md) vedou na existující záznamy; text odkazu SRC-## se shoduje s cílemneuvedeno
T7zdroj: plnostránková doktrína — markdown tělo kanonického source záznamu má ≥150 znaků (redakční kontext, ne holý metadata stub)neuvedeno
T8(warning) CLM řádka bez SRC reference; context-only zdroj (claims = []) neodkázaný z těla dossieru; duplicitní kanonická URL dvou zdrojůneuvedeno

J — JSON-LD expanze

Že strojově čitelný export nese tutéž identitu a nepropašuje termy mimo deklarovaný kontext.

Vlastník: scripts/data/validate-jsonld.mjs — 3 pravidel

Pravidla J — JSON-LD expanze 3

Pravidla J — JSON-LD expanze
IDCo vynucujeZávažnost
J1expanze záznamu nepadáneuvedeno
J2expanze dává právě jeden root uzel a jeho @id se rovná @id záznamu (expanze nesmí identitu přepsat ani rozbít)neuvedeno
J3žádný uzel nenese termy mimo kontext — expanze nesmí tiše zahodit klíče. Mechanismus: (a) safe mode knihovny jsonld (chyba při jakékoli tiché ztrátě dat, i vnořené), (b) explicitní porovnání top-level klíčů záznamu proti termům kontextu, které neznámý klíč pojmenuje v hlášce. Jediná povolená výjimka je "$schema" — ukazatel na JSON Schema, deliberately ne-sémantický klíč, který se před expanzí odloží.neuvedeno

Jak tenhle seznam číst

Není to redakční předsevzetí ani plán. Je to výtah z modulů, které pravidla vynucují — pokud tu pravidlo je, běží při každém npm run build.

Závažnost „neuvedeno" znamená, že hlavička vlastníka severitu nezapsala, ne že pravidlo nic nedělá. Je to poctivější než dopsat závažnost, kterou nikdo nedeklaroval.

Odkaz na neexistující pravidlo je chyba buildu: kdyby dokumentace mluvila o pravidle, které žádný validátor nevlastní, shodí to npm run verify:rules-catalog.