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
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.
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
- Counting unit (headline table): signatory-canton memberships, the chstat/BADAC convention — each agreement counts once per signatory canton (an agreement signed by 10 cantons counts 10, not 1). Signatory sets are estimated per agreement: cantons publishing the text in their collections ∪ cantons named in any language version's title ∪ cantons enumerated as contracting parties in the recitals (the text before Art. 1 — canton names occurring later are cross-references, not evidence of membership, so the scan stops there). Computed purely from the source data — no scaling; chstat's 2003 table is an external comparison reference only.
- Laws are (law, version) pairs. All year filtering uses the enactment date (original act), never the current consolidated version's date. A 1970 concordat amended in 2015 counts as 1970.
- Date provenance is ranked:
lexfind_family(LexFind'sfamily_active_since— the act's original date, from LexFind's frontend API, available for all 26 cantons) >lexwork_api(the portal'sdate_of_decision, authoritative but sometimes the canton's accession decision) >sibling:<CANTON>(a concordat is the same act in every member canton — dates propagate from cantons with authoritative data, only when all authoritative siblings agree) >text(parsed "vom / du / del D. Month YYYY" from the stored law text) >version_date_only. Higher provenance overwrites lower, never vice versa. - Repealed laws are included and flagged (
is_active: falsefrom the LexFind catalogs) — the collection is not in-force-only. - The accession caveat: LexWork's decision date is frequently each canton's accession decision rather than the concordat's original date — proven by sibling groups whose authoritative dates conflict across cantons. chstat counted 2003 membership, a question no public source answers directly today.
- "Unexplained" therefore contains: concordats no longer attached to LexFind's
public systematics catalogs (LexFind's own
global/statsreports more texts of law than the catalogs enumerate — the detached/delisted slice), plus accession-vs-membership date semantics.
5. Per-canton reconciliation
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)
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
- Reconciliation JSON (this page's data)
- The computed concordats table (one occurrence per signing canton per agreement; CSV & SDMX on the data page)
- Undated laws review page (JSON — every law excluded from year statistics, with its raw upstream date values)
- Concordats by domain (published-collections counting, with per-year breakdowns)
- Distinct agreements with signing cantons (signatories = published copies ∪ cantons named in a title ∪ cantons named as parties in the recitals, each tier reported per agreement)
- Cantons per concordat, 1848–2003 (reproduction of BADAC graph G1: size bands, memberships, evidence tiers)
- Per-instrument-type domain tables (same shape as concordats-by-domain, for every text category)
- Instrument-type review list (every "Other" law with its rule-based classification)
- Coverage audit (local files vs source catalogs, per canton × type)
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
| Integration | Endpoints (exact patterns) | Provides | Code |
|---|---|---|---|
| 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)
- 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. - enrich-categories — fill
category_type/global_categoryfrom the LexFind catalog; never overwrites —category_enricher.py. - Four date passes, provenance-ranked
(
lexfind_family4 >lexwork_api/fedlex3 >sibling2 >git_history/text/title1; higher rank overwrites lower, never vice versa) —date_enricher.py: (a) local text/git parsing, (b) LexWorkdate_of_decision+ versions, (c) sibling propagation between member cantons of the same concordat, (d) LexFindfamily_active_sincefor all 26 cantons. - Rule inference for gaps only, stored in separate
*_inferredfields with the rule recorded —domain_inference.py.
10.3 The concordats statistic, step by step
- Scan all law files' frontmatter; deduplicate languages by
(canton, systematic number) —
stats.py: _deduplicate. - Keep laws with instrument type id 2 ("Interkantonale
Vereinbarung" / "Accord intercantonal" / "Accordo intercantonale") —
effective_category_type. - Group sibling copies of the same agreement across cantons by
normalized title —
_concordat_agreement_groups. - 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. - 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. - 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:
python3 reproduce_concordats.py(full, ~2 min;--limit 20for a one-minute demo) — fetches the catalog, writesintercantonal_agreements.csv, and reports the G1 distribution from title evidence only: a strict lower bound, since open concordats name no parties in their titles.python3 reproduce_concordats.py --verify— no computation: fetches the published statistic and prints it against the BADAC G1 baseline.python3 reproduce_concordats.py --repo <clone of swiss-law>— recomputes the published numbers from the law corpus through the site's own code path (legalize_ch.stats, needspyyaml), then checks them against the published JSON. This is the mode that reproduces §3 exactly.
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.