Verification Report

Concordat data vs chstat.ch 2003 — methodology, reconciliation & data-quality provenance

1. Question under verification

How far can this collection's concordat data reproduce the reference table "Concordats par domaine" (chstat.ch, 2003), which was computed by the Institute of Federalism from the same underlying source (LexFind)? This page renders live from the published data — it updates with every regeneration.

Answer in short: not fully — and the statistic does not try to. The published concordats table is computed purely from the source data: one occurrence per signing canton per agreement, signatories estimated as the cantons publishing the text ∪ the cantons named in any language version's title ∪ the cantons enumerated as contracting parties in the recitals. No scaling, no external baseline (see below). chstat/BADAC's 2003 figure is kept as an external comparison reference; the difference is historical attrition — agreements repealed decades ago were delisted from today's collections. Filling in missing dates via the undated-laws review and importing corrections (legalize-ch import-dates) improves the statistic.

2. Reconciliation

loading…

Two evidence tiers recover memberships whose agreement text was delisted from today's collections: accession instruments — a canton's own Beitritt/adhésion decree or law referencing an intercantonal agreement the canton does not separately publish (matched inflection-tolerantly against its concordat titles) — and Intlex title evidence — cantons named in titles of the audited Intlex ≤2003 inventory (exports/concordats_2003/ in the law repository, see the reproduction script) with neither a published copy nor an accession instrument (German-titled collections only, so titles are comparable). Every counted and rejected instrument is listed in the membership-evidence audit trail.

3. Cantons per concordat — reproduction of BADAC graph G1

The 2003 reference answers two questions at once, and G1 states both in its caption: how many cantons each concordat associates, and how many canton signatures there are in total ("Total 1848–2003 = 733 concordats; 2564 cantons membres"). Its percentages are shares of the 2 564 memberships ("estimation BADAC (résultats pondérés : 2564 = 100 %)"), not shares of the 733 concordats — the prose reading ("44 % étaient des accords bilatéraux", "22 % regroupaient au moins 20 cantons") is arithmetically impossible against 733 concordats, since the ≥20-canton class alone would then exceed 3 200 memberships. Both units are reproduced below.

loading…

Where our distribution differs, and why. A concordat is by definition an agreement between cantons, so records for which only a single canton can be evidenced are counted as unresolved memberships, not as one-canton concordats — they are reported separately rather than dropped. The residual gap is structural and not improvable from LexFind: open concordats addressed to "Die unterzeichnenden Kantone" name no members anywhere in the text, so their composition is unrecoverable from the published record. BADAC read membership from the Institute of Federalism's concordat database, which records accessions; LexFind publishes no such lists. That is exactly why our 20–26 band stays thin while our 3–10 bands are heavy: an open concordat is observed through the cantons that happen to still publish it. Closing it would need an accession-register request to IDHEAP/BADAC or the Institute of Federalism.

Source: IDHEAP/BADAC, "Les concordats intercantonaux: clé de voûte du fédéralisme suisse", communiqué CP4 du 15.11.2004, graphique G1 (archived under exports/concordats_2003/baseline/CP4fr.pdf in the law repository) — built on the concordats database of the Institut du fédéralisme, Université de Fribourg. Our figures: size-distribution JSON.

4. Methodology

5. Per-canton reconciliation

loading…

Diagnosis: dating = we hold at least as many concordats as chstat counted, but dates place some outside 2003 (date semantics, improvable); delisting = we hold fewer than chstat counted (removed from the public record); reconciled = within ±5.

6. Comparison by domain (chstat 2003 vs ours)

loading…

chstat's six domains vs our concordats existing ≤2003 (same domain mapping: harmonized-taxonomy top levels {1,5}, {8}, {4}, {7}, {9}, {6}). "Other" holds civil/criminal-law concordats and those without a source domain — chstat's internal database classified everything, so our named-domain columns undercount by roughly the Other column's size.

7. Data-quality provenance

Enactment-date sources (concordats enacted ≤ 2003)

Instrument types

Legal domains (harmonized taxonomy)

8. Date methodology & changelog

The date basis is frozen: headline numbers change only when the underlying data changes, and every change is recorded here (changelog JSON).

9. Source data

10. Pipeline — which APIs, which integrations, which flows

Everything below is implemented in the open swiss-law repository (paths refer to src/legalize_ch/). Documenting it here makes the statistic explainable end-to-end: if a number looks wrong, this section tells you which stage to inspect.

10.1 Data sources and their APIs

IntegrationEndpoints (exact patterns)ProvidesCode
LexFind catalog API lexfind.ch/api/fe/{lang}/entities · …/categories · …/entities/{id}/systematics (+ batched ?active_only=false&tols_for_systematics[]=…) · PDF lexfind.ch/tol/{id}/{lang} Per-canton catalogs: systematic number, title, instrument type (id 2 = intercantonal agreement), legal domain, active flag; PDF text fallback cantonal.py
LexFind frontend API lexfind.ch/api/frontend/v1/{lang}/texts-of-law/{id}/with-version-groups family_active_since — the act family's original date; our highest-ranked date source lexfind_frontend.py
LexWork portals (14 cantons) https://{host}/api/{lang}/texts_of_law/{number} (+/versions/{id}) — hosts like bgs.zg.ch, srl.lu.ch, belex.sites.be.ch, gr-lex.gr.ch… Structured XHTML text, date_of_decision, full version lists cantonal.py (LEXWORK_CANTONS)
Dedicated scrapers (ZH GE NE) zh.ch paginated JSON catalog + HTML · silgeneve.ch/legis TOC + HTML · rsn.ne.ch TOC + HTML Catalog + text where no API exists zurich_fetcher.py, cantonal_scrapers.py

Integration per canton: AG AR BE BL BS FR GL GR LU SG SO TG VS ZG = LexWork + LexFind · AI JU NW OW SH SZ TI UR VD = LexFind only (PDF→text) · ZH GE NE = dedicated scraper + LexFind for the catalog/backfill. HTTP client: 4 retries, exponential backoff on 429/5xx, ~0.1 s between requests, User-Agent legalize-ch/0.1.

10.2 Enrichment flow (fetch → dated, classified law files)

  1. bootstrap / backfill-lexfind — import every canton's full LexFind catalog (add-only; this is what brings in the concordats that LexWork collections lack) — lexfind_backfill.py.
  2. enrich-categories — fill category_type / global_category from the LexFind catalog; never overwrites — category_enricher.py.
  3. Four date passes, provenance-ranked (lexfind_family 4 > lexwork_api/fedlex 3 > sibling 2 > git_history/text/title 1; higher rank overwrites lower, never vice versa) — date_enricher.py: (a) local text/git parsing, (b) LexWork date_of_decision + versions, (c) sibling propagation between member cantons of the same concordat, (d) LexFind family_active_since for all 26 cantons.
  4. Rule inference for gaps only, stored in separate *_inferred fields with the rule recorded — domain_inference.py.

10.3 The concordats statistic, step by step

  1. Scan all law files' frontmatter; deduplicate languages by (canton, systematic number) — stats.py: _deduplicate.
  2. Keep laws with instrument type id 2 ("Interkantonale Vereinbarung" / "Accord intercantonal" / "Accordo intercantonale") — effective_category_type.
  3. Group sibling copies of the same agreement across cantons by normalized title — _concordat_agreement_groups.
  4. Signatories per agreement = cantons publishing the text in their collections ∪ cantons named in any language version's title (cantons_named_in_title, de/fr/it name variants). LexFind publishes no official member lists — this is the best available evidence.
  5. Year = earliest known evidence for the agreement (provenance-ranked; implausible sentinel dates < 1400 are treated as unknown and listed on the undated-laws page) — earliest_known_year.
  6. Count 1 occurrence per signing canton per agreement into the canton × domain × year table — generate_concordats_by_domain_signatories. No scaling, no external baseline.

10.4 Reproduce it yourself

A standard-library-only script queries the same LexFind APIs for the Intlex entity (LexFind's dedicated collection of intercantonal law, entity id 28) and outputs every intercantonal agreement with its year and the cantons named in its title. Every mode ends with the same G1 table as §3, so the script and this page report one statistic, not two:

reproduce_concordats.py

Heavyweight variant with full auditability (every request logged with URL/status/SHA-256, raw responses archived): see scripts/fetch_concordats_to_2003.py and its shipped run under exports/concordats_2003/ in the law repository.