UPC per-jurisdiction holidays — seed national + state-level holidays for every division country and link the UPC location page #150

Open
opened 2026-05-27 15:51:08 +00:00 by mAi · 2 comments
Collaborator

m's flag (2026-05-27 15:19)

https://www.unifiedpatentcourt.org/en/contact-us/location-information — Have we got this linked somewhere? We have each holiday in the respective jurisdiction there.

Live audit confirms the gap:

  • The URL is NOT linked in Linkhub, Gerichtsverzeichnis, or any user-facing surface. Only mentioned in docs/research-deadlines-completeness-2026-05-25.md and docs/improvement-audit.md.
  • paliad.holidays corpus is DE-only + UPC vacations — only 2 distinct (country, regime, state) shapes seeded:
    • 22 rows of country=DE, state=null, regime=null, holiday_type='public_holiday' (German national holidays)
    • 33 rows of country=null, state=null, regime='UPC', holiday_type='vacation' (Summer + Winter recess)
  • No French (Paris CD/LD), no Italian (Milan LD), no Dutch (The Hague LD), no Portuguese (Lisbon LD), no German state-level (Munich LD = Bayern; Düsseldorf LD = NRW; Hamburg LD = HH; Mannheim LD = BW).

Two-part scope

Add https://www.unifiedpatentcourt.org/en/contact-us/location-information to:

  • Linkhub (the public-facing curated links). Category: "UPC Referenz" or similar. DE label: "UPC – Gerichtsstandorte & Feiertage"; EN: "UPC – Court Locations & Holidays".
  • Gerichtsverzeichnis (if not redundant with Linkhub): per-court entries can cite this page in their "Mehr Infos" link.

10-minute task. Coder/fixer can land in one commit.

Part B — Seed per-jurisdiction holidays

For every UPC division country (and German state where the LD sits), seed national + relevant regional holidays in paliad.holidays for the working horizon (2026 + 2027, extendable).

B.1 Country list (UPC member states with a local/central division)

The official UPC list per the location page. Today's UPC member states with a division:

  • DE — Munich LD (Bayern), Düsseldorf LD (NRW), Hamburg LD (HH), Mannheim LD (BW)
  • FR — Paris CD + Paris LD
  • NL — The Hague LD
  • IT — Milan LD + Milan CD section
  • PT — Lisbon LD
  • SI — Ljubljana LD
  • FI — Helsinki LD
  • DK — Copenhagen LD
  • AT — Vienna LD
  • BE — Brussels LD (if applicable)
  • SE — Nordic-Baltic regional division (Stockholm)
  • LT, LV, EE — Nordic-Baltic
  • (Verify the live list against the UPC page at write time — membership changes)

B.2 What to seed per country

  • National public holidays (fixed dates: Jan 1, May 1, Christmas, …; movable: Easter-based; per country's official calendar)
  • The German LDs ALSO need their state's regional holidays (Bayern: Hl. Drei Könige, Allerheiligen, Mariä Himmelfahrt; NRW: Fronleichnam, Allerheiligen; Hamburg: Reformationstag; BW: Hl. Drei Könige, Fronleichnam, Allerheiligen)
  • Horizon: 2026 + 2027 minimum (rolls forward; 2028+ in a follow-up regen run)

B.3 Schema check

paliad.holidays columns: id, date, name, country, state, holiday_type, regime. Today already supports per-country + per-state holidays — just not seeded. Schema work needed only if the calculator doesn't already route per-court-country lookups correctly.

Verify:

  1. Does HolidayService.IsNonWorkingDay(date, country, regime) get called with the correct country per project? Trace from projects.proceeding_type_idproceeding_types.country (or court derivation) → calculator call site.
  2. Where does the calculator decide "this UPC INF case sits at Munich LD, therefore observe Bayern + DE + UPC holidays"? If that derivation doesn't exist yet, that's the gap — likely a small services-layer addition (read projects.court_idpaliad.courts.country + jurisdiction-specific state).
  3. The embedded snapshot at pkg/litigationplanner/embedded/upc/ also needs per-country shipping for youpc.org. Today the snapshot only ships DE + UPC; widen the generator (cmd/gen-upc-snapshot/main.go:211) to include all UPC member countries.

Acceptance

  • Linkhub entry added (DE + EN labels).
  • Gerichtsverzeichnis entries link to the UPC location URL where useful (decide which courts).
  • Live paliad.holidays seeded for FR, NL, IT, PT (Phase 1 — the biggest division countries) + German state-level holidays for Bayern, NRW, HH, BW.
  • (Phase 2, can be a follow-up) Remaining UPC member states.
  • Calculator routing audited: a German-LD project gets Bayern + DE + UPC holidays; a French project gets FR + UPC; etc.
  • Embedded snapshot generator extended to include all UPC member countries; holidays.json regenerated.
  • Worked example: deadline calc on Paris LD case crossing 2027-07-14 (Fête nationale) → date rolls.

Cross-references

  • docs/research-deadlines-completeness-2026-05-25.md — prior research notes
  • docs/improvement-audit.md — earlier audit
  • paliad.courts schema (id, code, country, regime, court_type, parent_id, sort_order) — already has the division taxonomy
  • internal/services/holidays.go — HolidayService implementation
  • pkg/litigationplanner/embedded/upc/holidays.go — embedded calendar (used by youpc.org)

Out of scope

  • UPC Court of Appeal Luxembourg holidays (those are LU national + UPC regime — minor seed if needed)
  • Non-UPC jurisdictions beyond DE (EPO Munich for EPO procedure, DPMA Munich) — those already work for the existing DE + UPC corpus; only state-level granularity might improve
  • Holiday data for 2028+ (start with 2026 + 2027; refresh annually)
  • Outlook/Calendar sync of these holidays (long-term goal)
## m's flag (2026-05-27 15:19) > https://www.unifiedpatentcourt.org/en/contact-us/location-information — Have we got this linked somewhere? We have each holiday in the respective jurisdiction there. Live audit confirms the gap: - The URL is **NOT linked** in Linkhub, Gerichtsverzeichnis, or any user-facing surface. Only mentioned in `docs/research-deadlines-completeness-2026-05-25.md` and `docs/improvement-audit.md`. - `paliad.holidays` corpus is **DE-only + UPC vacations** — only 2 distinct (country, regime, state) shapes seeded: - 22 rows of `country=DE, state=null, regime=null, holiday_type='public_holiday'` (German national holidays) - 33 rows of `country=null, state=null, regime='UPC', holiday_type='vacation'` (Summer + Winter recess) - No French (Paris CD/LD), no Italian (Milan LD), no Dutch (The Hague LD), no Portuguese (Lisbon LD), no German *state-level* (Munich LD = Bayern; Düsseldorf LD = NRW; Hamburg LD = HH; Mannheim LD = BW). ## Two-part scope ### Part A — Link the UPC location page Add `https://www.unifiedpatentcourt.org/en/contact-us/location-information` to: - **Linkhub** (the public-facing curated links). Category: "UPC Referenz" or similar. DE label: "UPC – Gerichtsstandorte & Feiertage"; EN: "UPC – Court Locations & Holidays". - **Gerichtsverzeichnis** (if not redundant with Linkhub): per-court entries can cite this page in their "Mehr Infos" link. 10-minute task. Coder/fixer can land in one commit. ### Part B — Seed per-jurisdiction holidays For every UPC division country (and German state where the LD sits), seed national + relevant regional holidays in `paliad.holidays` for the working horizon (2026 + 2027, extendable). #### B.1 Country list (UPC member states with a local/central division) The official UPC list per the location page. Today's UPC member states with a division: - **DE** — Munich LD (Bayern), Düsseldorf LD (NRW), Hamburg LD (HH), Mannheim LD (BW) - **FR** — Paris CD + Paris LD - **NL** — The Hague LD - **IT** — Milan LD + Milan CD section - **PT** — Lisbon LD - **SI** — Ljubljana LD - **FI** — Helsinki LD - **DK** — Copenhagen LD - **AT** — Vienna LD - **BE** — Brussels LD (if applicable) - **SE** — Nordic-Baltic regional division (Stockholm) - **LT, LV, EE** — Nordic-Baltic - (Verify the live list against the UPC page at write time — membership changes) #### B.2 What to seed per country - National public holidays (fixed dates: Jan 1, May 1, Christmas, …; movable: Easter-based; per country's official calendar) - The German LDs ALSO need their state's regional holidays (Bayern: Hl. Drei Könige, Allerheiligen, Mariä Himmelfahrt; NRW: Fronleichnam, Allerheiligen; Hamburg: Reformationstag; BW: Hl. Drei Könige, Fronleichnam, Allerheiligen) - Horizon: 2026 + 2027 minimum (rolls forward; 2028+ in a follow-up regen run) #### B.3 Schema check `paliad.holidays` columns: `id, date, name, country, state, holiday_type, regime`. Today already supports per-country + per-state holidays — just not seeded. **Schema work needed only if the calculator doesn't already route per-court-country lookups correctly.** Verify: 1. Does `HolidayService.IsNonWorkingDay(date, country, regime)` get called with the correct `country` per project? Trace from `projects.proceeding_type_id` → `proceeding_types.country` (or court derivation) → calculator call site. 2. Where does the calculator decide "this UPC INF case sits at Munich LD, therefore observe Bayern + DE + UPC holidays"? If that derivation doesn't exist yet, that's the gap — likely a small services-layer addition (read `projects.court_id` → `paliad.courts.country` + jurisdiction-specific state). 3. The embedded snapshot at `pkg/litigationplanner/embedded/upc/` also needs per-country shipping for youpc.org. Today the snapshot only ships DE + UPC; widen the generator (`cmd/gen-upc-snapshot/main.go:211`) to include all UPC member countries. ## Acceptance - [ ] Linkhub entry added (DE + EN labels). - [ ] Gerichtsverzeichnis entries link to the UPC location URL where useful (decide which courts). - [ ] Live `paliad.holidays` seeded for FR, NL, IT, PT (Phase 1 — the biggest division countries) + German state-level holidays for Bayern, NRW, HH, BW. - [ ] (Phase 2, can be a follow-up) Remaining UPC member states. - [ ] Calculator routing audited: a German-LD project gets Bayern + DE + UPC holidays; a French project gets FR + UPC; etc. - [ ] Embedded snapshot generator extended to include all UPC member countries; `holidays.json` regenerated. - [ ] Worked example: deadline calc on Paris LD case crossing 2027-07-14 (Fête nationale) → date rolls. ## Cross-references - `docs/research-deadlines-completeness-2026-05-25.md` — prior research notes - `docs/improvement-audit.md` — earlier audit - `paliad.courts` schema (id, code, country, regime, court_type, parent_id, sort_order) — already has the division taxonomy - `internal/services/holidays.go` — HolidayService implementation - `pkg/litigationplanner/embedded/upc/holidays.go` — embedded calendar (used by youpc.org) ## Out of scope - UPC Court of Appeal Luxembourg holidays (those are LU national + UPC regime — minor seed if needed) - Non-UPC jurisdictions beyond DE (EPO Munich for EPO procedure, DPMA Munich) — those already work for the existing DE + UPC corpus; only state-level granularity might improve - Holiday data for 2028+ (start with 2026 + 2027; refresh annually) - Outlook/Calendar sync of these holidays (long-term goal)
mAi self-assigned this 2026-05-27 15:51:08 +00:00
Author
Collaborator

Failure mode established, Part A done, Part B blocked on one question that is yours

Branch mai/darwin/issue-150-holidays. Full write-up: docs/findings-holiday-corpus-de-only-2026-07-29.md (98a6445).

The failure mode, measured

A missing holiday is never consulted — the date silently does not move. Not a wrong shift, so the fix is data, not logic.

Court's state Date (2026) non-working? deadline lands on holiday
FR 14 Jul (Tue) false 14 Jul Fête nationale
FR 11 Nov (Wed) false 11 Nov Armistice
IT 2 Jun (Tue) false 2 Jun Festa della Repubblica
NL 27 Apr (Mon) false 27 Apr Koningsdag
PT 10 Jun (Wed) false 10 Jun Dia de Portugal
DE 6 Jan (Tue) false 6 Jan Heilige Drei Könige (BY/BW)
DE 25 Dec (Fri) true 28 Dec control — works

Two dates I probed first would have misled a spot-check: FR 15 Aug and IT 25 Apr did move — because both are a Saturday in 2026. The weekend rule moved them, not the holiday.

The governing rule is R. 301(1), and we cite the wrong one

deadline_calculator.go:38 and :117 attribute the extension to R. 300(b) — that is the years rule. The extension is R. 301(1); the day definitions are R. 300(f)/(g). All three say "official holiday of the Contracting Member State in which the division … is located", which confirms the per-country model paliad already has is correct.

The question for you, and it is why Part B is not built

That phrase does not resolve for states with no single national list.

Germany — public holidays are Land competence, and the four German divisions sit in four Länder. München (Bayern) would observe Heilige Drei Könige, Fronleichnam, Mariä Himmelfahrt and Allerheiligen under one reading and none of them under the other.

Italy makes it sharperSant'Ambrogio, 7 December, is a City-of-Milan holiday, and both the Milan LD and the Milan section of the central division sit in Milan. 7 Dec 2026 is a Monday.

Two questions:

  1. Does a division observe the regional holidays in force at its seat, or only its Member State's nationwide ones?
  2. If regional — does that extend to municipal ones like Sant'Ambrogio, or stop at the regional/Land level?

Both answers are implementable; paliad.holidays.state already exists and is NULL on every row. Seeding national-only data before the answer would make Paris and Lisbon right, leave Munich and Milan wrong, and make the corpus look complete — the harder state to notice.

Next January: a generator, not a seed

paliad already answers this for Germany. germanFederalHolidays(year) computes the set from CalculateEasterSunday(year), so DE never expires and the 22 DB rows are redundant with it. A seeded FR/IT/NL/PT corpus for 2026 would be silently wrong on 1 January. Part B should add per-country generator functions carrying each country's holiday statute as its citation — re-derivable by construction, which is what "not typed in from a web page" asks for.

One exception: UPC judicial vacations are set by an AC decision per year, follow no formula, currently run out at 2027-01-06, and nothing advances them. No correctness risk for deadlines (R. 300(h) — periods are not suspended during vacations, and we already exclude them), but they will simply stop existing with nothing saying so. No owner and no reminder today.

Part A — done

The location-information page you pointed at was linked nowhere user-facing. Added to the Link Hub under UPC: 2b65212.


Not closing — that is yours.

## Failure mode established, Part A done, Part B blocked on one question that is yours Branch `mai/darwin/issue-150-holidays`. Full write-up: [`docs/findings-holiday-corpus-de-only-2026-07-29.md`](https://mgit.msbls.de/m/paliad/src/branch/mai/darwin/issue-150-holidays/docs/findings-holiday-corpus-de-only-2026-07-29.md) ([98a6445](https://mgit.msbls.de/m/paliad/commit/98a6445)). ### The failure mode, measured **A missing holiday is never consulted — the date silently does not move.** Not a wrong shift, so the fix is data, not logic. | Court's state | Date (2026) | non-working? | deadline lands on | holiday | |---|---|---|---|---| | FR | 14 Jul (Tue) | **false** | 14 Jul | Fête nationale | | FR | 11 Nov (Wed) | **false** | 11 Nov | Armistice | | IT | 2 Jun (Tue) | **false** | 2 Jun | Festa della Repubblica | | NL | 27 Apr (Mon) | **false** | 27 Apr | Koningsdag | | PT | 10 Jun (Wed) | **false** | 10 Jun | Dia de Portugal | | DE | 6 Jan (Tue) | **false** | 6 Jan | Heilige Drei Könige (BY/BW) | | DE | 25 Dec (Fri) | true | 28 Dec | control — works | Two dates I probed first would have misled a spot-check: FR 15 Aug and IT 25 Apr **did** move — because both are a **Saturday** in 2026. The weekend rule moved them, not the holiday. ### The governing rule is R. 301(1), and we cite the wrong one `deadline_calculator.go:38` and `:117` attribute the extension to **R. 300(b)** — that is the *years* rule. The extension is **R. 301(1)**; the day definitions are R. 300(f)/(g). All three say *"official holiday of the Contracting Member State in which the division … is located"*, which confirms the per-country model paliad already has is correct. ### The question for you, and it is why Part B is not built That phrase does not resolve for states with no single national list. **Germany** — public holidays are *Land* competence, and the four German divisions sit in four Länder. München (Bayern) would observe Heilige Drei Könige, Fronleichnam, Mariä Himmelfahrt and Allerheiligen under one reading and none of them under the other. **Italy makes it sharper** — **Sant'Ambrogio, 7 December, is a City-of-Milan holiday**, and both the Milan LD and the Milan section of the central division sit in Milan. 7 Dec 2026 is a **Monday**. Two questions: 1. Does a division observe the **regional** holidays in force at its seat, or only its Member State's **nationwide** ones? 2. If regional — does that extend to **municipal** ones like Sant'Ambrogio, or stop at the regional/Land level? Both answers are implementable; `paliad.holidays.state` already exists and is NULL on every row. Seeding national-only data before the answer would make Paris and Lisbon right, leave Munich and Milan wrong, and make the corpus *look* complete — the harder state to notice. ### Next January: a generator, not a seed paliad already answers this for Germany. `germanFederalHolidays(year)` **computes** the set from `CalculateEasterSunday(year)`, so DE never expires and the 22 DB rows are redundant with it. A seeded FR/IT/NL/PT corpus for 2026 would be silently wrong on 1 January. Part B should add per-country generator functions carrying each country's holiday **statute** as its citation — re-derivable by construction, which is what "not typed in from a web page" asks for. One exception: **UPC judicial vacations** are set by an AC decision per year, follow no formula, currently run out at **2027-01-06**, and nothing advances them. No correctness risk for deadlines (R. 300(h) — periods are not suspended during vacations, and we already exclude them), but they will simply stop existing with nothing saying so. No owner and no reminder today. ### Part A — done The location-information page you pointed at was linked nowhere user-facing. Added to the Link Hub under UPC: [2b65212](https://mgit.msbls.de/m/paliad/commit/2b65212). --- *Not closing — that is yours.*
Author
Collaborator

Part B done — per-country generators, nationwide only

Branch mai/knuth/m-paliad-150-part-b-m. Part A shipped at a83ec2d.

Commit What
9b07241 mig 214 — delete the 22 DE public_holiday rows
debec66 the generators + both calendars + vacation-branch removal
d774265 statute reference doc, holidays.json regenerated
a2c82bc Paris LD worked example + courts-table coverage guard

It is a generator, not a seed

litigationplanner.NationalHolidays(country, year) — one function per country,
each citing its own statute, movable feasts derived from Easter. Nothing
expires on 1 January.

Twelve countries, taken from paliad.courts rather than from the issue
text:
AT BE DE DK FI FR IT LU NL PT SE SI. That is more than the four the
task named. LU is in because R. 301(1) names the Court of Appeal alongside the
divisions, and the marginal cost of a country is one function. Leaving seven
out would have left the same silent failure in place for them.

Nordic-Baltic resolves to SE only — the division sits in Stockholm, so
R. 301(1) points at Sweden. LT/LV/EE are members but no deadline resolves to
their calendars.

Sources

DE Feiertagsgesetze der Länder + Einigungsvertrag Art. 2 Abs. 2 · FR Code du
travail L. 3133-1 · IT L. 260/1949 art. 2 as amended · NL Algemene termijnenwet
art. 3 · PT Código do Trabalho art. 234.º · AT ARG § 7 Abs. 2 · BE AR 18 avril
1974 art. 1 · LU Code du travail L. 232-2 · DK Danske Lov 2-4-5 + forordning
1770 · FI Kirkkolaki 652/2023 1:6 · SE Lag (1989:253) 1–2 §§ · SI ZPDPD.

Full table, plus the three dated statute changes and every deliberate omission:
docs/reference-national-holiday-generators-2026-07-30.md.

Cross-checked against EMA/240605/2025 (EU member-state holidays recorded in
CTIS, 2026). DE/FR/IT/AT/LU/NL match exactly. The rest diverge because CTIS
records working closures, so it mixes statutory and customary days — it
carries midsommarafton for SE and juhannusaatto for FI, and omits several
statutory Slovenian days. The statutes govern; CTIS was a control, not a source.

One statute change that recall would have missed

L. 8 ottobre 2025 n. 151 makes 4 October (San Francesco d'Assisi) an Italian
national holiday with civil effect from 1 January 2026.
It is generated from
2026 and absent before. 4 October 2026 is a Sunday, so the first year it moves
a date is 2027.

Scope rulings, both encoded

Nationwide only, per your 2026-07-30 answer. Not observed: Sant'Ambrogio
(7 Dec, comune of Milan), Heilige Drei Könige (6 Jan, Bayern), Santo António
(13 June, comune of Lisboa), Alsace-Moselle's two.

A second axis needed deciding and I decided it rather than block: statutory
only
. Days everyone takes off that rest on collective agreement are excluded
— DK grundlovsdag / juleaftensdag / nytårsaftensdag, FI juhannusaatto /
jouluaatto, SE midsommarafton / julafton / nyårsafton, PT Carnaval, AT
Karfreitag. Each generator names its own exclusions in a comment. The Danish
legislature draws the same line: statutes meaning to cover grundlovsdag have
to name it in addition to "helligdage". Say the word if you want the other
reading — it is a one-line change per country.

The 22 DE rows

Deleted (mig 214). They duplicated the generator, and two copies of one fact
drift. paliad.holidays now holds only what no formula produces: the 33 UPC
vacation rows. A DB row still wins over the generator for the same
(country, date), so a one-off closure can be seeded without touching Go.

TestGeneratedDECorpusMatchesDeletedRows sweeps all of 2026–2027 and asserts
IsNonWorkingDay is unchanged. It compares behaviour, not sets — the rows
also carried Ostersonntag and Pfingstsonntag, which are Brandenburg holidays
and always Sundays, so their absence moves nothing. A set comparison would
have flagged that and been wrong about what it meant.

Vacation branch: gone (option B)

AdjustmentReason.Kind no longer has "vacation", in both calendars, and
VacationName/VacationStart/VacationEnd, findVacationBlock and the
frontend types went with it. It was unreachable and would have been wrong if
it fired — sawVacation was tested before sawWeekend. The 33 rows stay.
t-paliad-upc-vacation-corpus-expiry now has no consumer and can close.

Snapshot no longer expires either

SnapshotHolidayCalendar generates public holidays too, so a holidays.json
taken today still computes 2031. Verified by
TestSnapshotHolidayCalendar_GeneratesBeyondSnapshotRange.

Verification

Full gate on a harness carrying prod's snapshot + mig 214: ci-test-gate.sh
green (go vet clean, full -race suite, 0 known-failing tolerated), all
seven migration gates executed rather than skipped — including
NoCollisionWithSiblingBranches against every pushed branch — check-gofmt
clean, 411 frontend tests pass. Prod's applied set is at 212; 214 is not
burnt. Nothing was applied to prod.

Every date asserted in the tests is a weekday. FR 15 August and IT 25 April
both moved before this work because both are Saturdays in 2026, and a
spot-check landing on those two would have concluded the corpus was fine.
The tests assert on AdjustmentReason.Kind, not on the moved date.

The 2024–2044 sweep found two real collisions a single-year table would have
missed: Journée de l'Europe and Ascension on the same day in Luxembourg 2024,
and 25 April with Easter Sunday in Portugal 2038. The court closes once, so
the names merge into one entry.

Acceptance

  • Live corpus for FR, NL, IT, PT — and AT, BE, DK, FI, LU, SE, SI
  • Calculator routing audited — courtID → paliad.courts.country already
    worked; TestEveryUPCCourtHasAHolidayGenerator reads the table and turns
    red if a division's country has no generator (18 courts, 12 countries)
  • Worked example: Paris LD, Wednesday 2027-07-14 → 2027-07-15, reason names
    Fête nationale; the same date does not move for the München LD
  • Embedded snapshot widened to every UPC country; holidays.json regenerated
  • German state-level holidays — deliberately not done, ruled out
  • Phase 2 remaining member states — no longer applicable, all twelve are in

Two things left open, neither introduced here

  1. cmd/gen-upc-snapshot is broken for four of its five steps. meta.json
    has recorded since 2026-05-27 that rules / proceeding types / trigger events
    / courts are placeholders, because mig 140 dropped paliad.deadline_rules.
    Only the holiday step is live; I regenerated that one from the harness. The
    other four want their own task. It also means courts.json in the snapshot
    still carries 2 courts, so youpc.org cannot resolve a Paris LD case yet.
  2. The statutory-vs-customary axis above, if you want the other reading.

Not closing this — over to you.

## Part B done — per-country generators, nationwide only Branch `mai/knuth/m-paliad-150-part-b-m`. Part A shipped at a83ec2d. | Commit | What | |---|---| | [9b07241](https://mgit.msbls.de/m/paliad/commit/9b07241) | mig 214 — delete the 22 DE public_holiday rows | | [debec66](https://mgit.msbls.de/m/paliad/commit/debec66) | the generators + both calendars + vacation-branch removal | | [d774265](https://mgit.msbls.de/m/paliad/commit/d774265) | statute reference doc, `holidays.json` regenerated | | [a2c82bc](https://mgit.msbls.de/m/paliad/commit/a2c82bc) | Paris LD worked example + courts-table coverage guard | ### It is a generator, not a seed `litigationplanner.NationalHolidays(country, year)` — one function per country, each citing its own statute, movable feasts derived from Easter. Nothing expires on 1 January. **Twelve countries, taken from `paliad.courts` rather than from the issue text:** AT BE DE DK FI FR IT LU NL PT SE SI. That is more than the four the task named. LU is in because R. 301(1) names the Court of Appeal alongside the divisions, and the marginal cost of a country is one function. Leaving seven out would have left the same silent failure in place for them. Nordic-Baltic resolves to **SE** only — the division sits in Stockholm, so R. 301(1) points at Sweden. LT/LV/EE are members but no deadline resolves to their calendars. ### Sources DE Feiertagsgesetze der Länder + Einigungsvertrag Art. 2 Abs. 2 · FR Code du travail L. 3133-1 · IT L. 260/1949 art. 2 as amended · NL Algemene termijnenwet art. 3 · PT Código do Trabalho art. 234.º · AT ARG § 7 Abs. 2 · BE AR 18 avril 1974 art. 1 · LU Code du travail L. 232-2 · DK Danske Lov 2-4-5 + forordning 1770 · FI Kirkkolaki 652/2023 1:6 · SE Lag (1989:253) 1–2 §§ · SI ZPDPD. Full table, plus the three dated statute changes and every deliberate omission: `docs/reference-national-holiday-generators-2026-07-30.md`. Cross-checked against EMA/240605/2025 (EU member-state holidays recorded in CTIS, 2026). DE/FR/IT/AT/LU/NL match exactly. The rest diverge because CTIS records *working closures*, so it mixes statutory and customary days — it carries midsommarafton for SE and juhannusaatto for FI, and omits several statutory Slovenian days. The statutes govern; CTIS was a control, not a source. ### One statute change that recall would have missed **L. 8 ottobre 2025 n. 151 makes 4 October (San Francesco d'Assisi) an Italian national holiday with civil effect from 1 January 2026.** It is generated from 2026 and absent before. 4 October 2026 is a Sunday, so the first year it moves a date is 2027. ### Scope rulings, both encoded Nationwide only, per your 2026-07-30 answer. **Not** observed: Sant'Ambrogio (7 Dec, comune of Milan), Heilige Drei Könige (6 Jan, Bayern), Santo António (13 June, comune of Lisboa), Alsace-Moselle's two. A second axis needed deciding and I decided it rather than block: **statutory only**. Days everyone takes off that rest on collective agreement are excluded — DK grundlovsdag / juleaftensdag / nytårsaftensdag, FI juhannusaatto / jouluaatto, SE midsommarafton / julafton / nyårsafton, PT Carnaval, AT Karfreitag. Each generator names its own exclusions in a comment. The Danish legislature draws the same line: statutes meaning to cover grundlovsdag have to name it *in addition to* "helligdage". Say the word if you want the other reading — it is a one-line change per country. ### The 22 DE rows Deleted (mig 214). They duplicated the generator, and two copies of one fact drift. `paliad.holidays` now holds only what no formula produces: the 33 UPC vacation rows. A DB row still wins over the generator for the same `(country, date)`, so a one-off closure can be seeded without touching Go. `TestGeneratedDECorpusMatchesDeletedRows` sweeps all of 2026–2027 and asserts `IsNonWorkingDay` is unchanged. It compares **behaviour, not sets** — the rows also carried Ostersonntag and Pfingstsonntag, which are Brandenburg holidays and always Sundays, so their absence moves nothing. A set comparison would have flagged that and been wrong about what it meant. ### Vacation branch: gone (option B) `AdjustmentReason.Kind` no longer has `"vacation"`, in **both** calendars, and `VacationName`/`VacationStart`/`VacationEnd`, `findVacationBlock` and the frontend types went with it. It was unreachable and would have been wrong if it fired — `sawVacation` was tested before `sawWeekend`. The 33 rows stay. `t-paliad-upc-vacation-corpus-expiry` now has no consumer and can close. ### Snapshot no longer expires either `SnapshotHolidayCalendar` generates public holidays too, so a `holidays.json` taken today still computes 2031. Verified by `TestSnapshotHolidayCalendar_GeneratesBeyondSnapshotRange`. ### Verification Full gate on a harness carrying prod's snapshot + mig 214: `ci-test-gate.sh` green (`go vet` clean, full `-race` suite, 0 known-failing tolerated), all seven migration gates **executed** rather than skipped — including `NoCollisionWithSiblingBranches` against every pushed branch — `check-gofmt` clean, 411 frontend tests pass. Prod's applied set is at **212**; 214 is not burnt. Nothing was applied to prod. **Every date asserted in the tests is a weekday.** FR 15 August and IT 25 April both moved *before* this work because both are Saturdays in 2026, and a spot-check landing on those two would have concluded the corpus was fine. The tests assert on `AdjustmentReason.Kind`, not on the moved date. The 2024–2044 sweep found two real collisions a single-year table would have missed: Journée de l'Europe and Ascension on the same day in Luxembourg 2024, and 25 April with Easter Sunday in Portugal 2038. The court closes once, so the names merge into one entry. ### Acceptance - [x] Live corpus for FR, NL, IT, PT — and AT, BE, DK, FI, LU, SE, SI - [x] Calculator routing audited — `courtID → paliad.courts.country` already worked; `TestEveryUPCCourtHasAHolidayGenerator` reads the table and turns red if a division's country has no generator (18 courts, 12 countries) - [x] Worked example: Paris LD, Wednesday 2027-07-14 → 2027-07-15, reason names Fête nationale; the same date does not move for the München LD - [x] Embedded snapshot widened to every UPC country; `holidays.json` regenerated - [ ] German **state-level** holidays — deliberately not done, ruled out - [ ] Phase 2 remaining member states — no longer applicable, all twelve are in ### Two things left open, neither introduced here 1. **`cmd/gen-upc-snapshot` is broken for four of its five steps.** `meta.json` has recorded since 2026-05-27 that rules / proceeding types / trigger events / courts are placeholders, because mig 140 dropped `paliad.deadline_rules`. Only the holiday step is live; I regenerated that one from the harness. The other four want their own task. It also means `courts.json` in the snapshot still carries 2 courts, so youpc.org cannot resolve a Paris LD case yet. 2. **The statutory-vs-customary axis** above, if you want the other reading. Not closing this — over to you.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#150
No description provided.