UPC per-jurisdiction holidays — seed national + state-level holidays for every division country and link the UPC location page #150
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
m's flag (2026-05-27 15:19)
Live audit confirms the gap:
docs/research-deadlines-completeness-2026-05-25.mdanddocs/improvement-audit.md.paliad.holidayscorpus is DE-only + UPC vacations — only 2 distinct (country, regime, state) shapes seeded:country=DE, state=null, regime=null, holiday_type='public_holiday'(German national holidays)country=null, state=null, regime='UPC', holiday_type='vacation'(Summer + Winter recess)Two-part scope
Part A — Link the UPC location page
Add
https://www.unifiedpatentcourt.org/en/contact-us/location-informationto: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.holidaysfor 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:
B.2 What to seed per country
B.3 Schema check
paliad.holidayscolumns: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:
HolidayService.IsNonWorkingDay(date, country, regime)get called with the correctcountryper project? Trace fromprojects.proceeding_type_id→proceeding_types.country(or court derivation) → calculator call site.projects.court_id→paliad.courts.country+ jurisdiction-specific state).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
paliad.holidaysseeded for FR, NL, IT, PT (Phase 1 — the biggest division countries) + German state-level holidays for Bayern, NRW, HH, BW.holidays.jsonregenerated.Cross-references
docs/research-deadlines-completeness-2026-05-25.md— prior research notesdocs/improvement-audit.md— earlier auditpaliad.courtsschema (id, code, country, regime, court_type, parent_id, sort_order) — already has the division taxonomyinternal/services/holidays.go— HolidayService implementationpkg/litigationplanner/embedded/upc/holidays.go— embedded calendar (used by youpc.org)Out of scope
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.
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:38and:117attribute 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:
Both answers are implementable;
paliad.holidays.statealready 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 fromCalculateEasterSunday(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.
Part B done — per-country generators, nationwide only
Branch
mai/knuth/m-paliad-150-part-b-m. Part A shipped ata83ec2d.holidays.jsonregeneratedIt 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.courtsrather than from the issuetext: 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.holidaysnow holds only what no formula produces: the 33 UPCvacation 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.TestGeneratedDECorpusMatchesDeletedRowssweeps all of 2026–2027 and assertsIsNonWorkingDayis unchanged. It compares behaviour, not sets — the rowsalso 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.Kindno longer has"vacation", in both calendars, andVacationName/VacationStart/VacationEnd,findVacationBlockand thefrontend types went with it. It was unreachable and would have been wrong if
it fired —
sawVacationwas tested beforesawWeekend. The 33 rows stay.t-paliad-upc-vacation-corpus-expirynow has no consumer and can close.Snapshot no longer expires either
SnapshotHolidayCalendargenerates public holidays too, so aholidays.jsontaken today still computes 2031. Verified by
TestSnapshotHolidayCalendar_GeneratesBeyondSnapshotRange.Verification
Full gate on a harness carrying prod's snapshot + mig 214:
ci-test-gate.shgreen (
go vetclean, full-racesuite, 0 known-failing tolerated), allseven migration gates executed rather than skipped — including
NoCollisionWithSiblingBranchesagainst every pushed branch —check-gofmtclean, 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
courtID → paliad.courts.countryalreadyworked;
TestEveryUPCCourtHasAHolidayGeneratorreads the table and turnsred if a division's country has no generator (18 courts, 12 countries)
Fête nationale; the same date does not move for the München LD
holidays.jsonregeneratedTwo things left open, neither introduced here
cmd/gen-upc-snapshotis broken for four of its five steps.meta.jsonhas 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.jsonin the snapshotstill carries 2 courts, so youpc.org cannot resolve a Paris LD case yet.
Not closing this — over to you.