Files
paliad/docs/audit-upc-rop-deadlines-2026-05-08.md
m afe4fc2efe docs(t-paliad-159): UPC RoP deadline audit
8 RoP sections cross-referenced against paliad's deadline_rules library
via the youpc data.laws_contents authoritative text.

Two high-impact duration bugs found:
- rev.defence: 3 months seeded, RoP R.49.1 says 2 months
- rev.rejoin: 2 months seeded, RoP R.52 says 1 month

Both UPC_REV pleadings rules — every active Nichtigkeitsverfahren
tracked in paliad has miscalibrated reminders today. Single-row
UPDATEs fix both.

Plus rule_code drift on UPC_APP (R.220.1 used where R.224.1.a /
R.224.2.a / R.235.2 should be cited), R.51 / R.52 NULLs on REV
chain, and 25 missing rules ordered by frequency (R.19, R.262.2,
R.224.2.b, R.235.1, R.333.2, R.353, registry-correction family,
saisie + PI gaps, R.109 oral-hearing prep, R.245 rehearing, etc).

Plus an anchoring nuance on UPC_APP_ORDERS.app_ord.discretion
(R.220.3) — Pathway A may compute up to 15d too early because
the rule anchors on order, not on leave-refusal event.

Wave 0 (duration bugs) is the recommended first migration.
Wave 1+ orderings, tooling-blocked rules (R.198/R.213/R.245.2),
and m's open questions (proceeding-code naming, R.245 scope,
DNI scope) listed in §6, §7.
2026-05-08 16:21:25 +02:00

40 KiB
Raw Permalink Blame History

Audit — UPC Rules of Procedure deadline coverage in paliad

Author: curie (researcher) Date: 2026-05-08 Task: t-paliad-159 (Gitea m/paliad#14, RoP audit aspect) Mode: read-only research; produces a gap-list, not migrations.

Companion to docs/audit-fristenrechner-completeness-2026-04-30.md. That audit drove from youpc's existing deadline corpus (~64 RoP codes referenced); this one drives from the UPC Rules of Procedure themselves, taking a frequency-weighted slice of what a real INF/REV/APP proceeding has to track.


1. Scope

RoP sections audited (8 sections):

Code Section RoP rules in scope (deadline-creating)
A Pleadings — Infringement (UPC_INF) R.13, R.17, R.19, R.23, R.24, R.25, R.29.a/b/c/d/e, R.30, R.32
B Pleadings — Revocation + CCR + DNI (UPC_REV) R.42, R.44, R.49.1, R.49.2.a, R.49.2.b, R.50, R.51, R.52, R.55, R.56, R.61, R.63, R.65, R.67, R.68, R.69, R.70
C Provisional measures + evidence preservation R.197.3, R.198, R.205, R.207.6, R.207.9, R.211.2, R.213
D Damages + lay-open books R.125, R.131.2, R.137, R.139, R.141, R.142.2, R.142.3
E Decisions, costs, default judgment R.111, R.118.4, R.151, R.157, R.221.1
F Appeals R.220.1.a/b/c, R.220.2, R.220.3, R.221.1, R.224.1.a/b, R.224.2.a/b, R.229.2, R.234.1, R.235.1, R.235.2, R.237, R.238.1, R.238.2, R.245.2
G Re-establishment, case-management, miscellaneous R.262.2, R.295, R.320, R.321.3, R.331, R.333.2, R.353
H Oral-hearing prep + translations R.109.1, R.109.4, R.109.5

Out of scope here (deferred to a follow-up audit):

  • EPO opposition + Beschwerde (Art. 99 / R.99 EPÜ — paliad models these via EPA_OPP / EPA_APP, separate concern)
  • DPMA / BPatG / BGH families (modelled via DE_, DPMA_ — separate concern)
  • ZPO civil-procedure deadlines around stay/severance
  • UPC court-fee deadlines (Art. 70 UPCA / R.370)
  • R.32(2) extensions of time (judge-set, no fixed duration)
  • Judicial discretion items without a fixed period (stays under R.295, choice-of-language under R.323, joinder, intervention R.313)
  • "Notice of intent to defend" (1mo, R.23 reaction): explicitly excluded by migration 052 §2 — no UPC rule exists for that concept.

Authoritative source for RoP text: the youpc Postgres data.laws_contents table (law_type = UPCRoP, English language). Cross-checked the in-scope rules against the actual rule text rather than relying on prior summaries — this is what surfaced the two duration bugs in §B (R.49.1 and R.52). All other high-frequency durations (R.23, R.29.a/b/c/d/e, R.32.1/3, R.43.3, R.56.1/3/4, R.137.2, R.139, R.142.2/3, R.151, R.220.2, R.221.1, R.224.1.a/b, R.224.2.a/b, R.235.1/2, R.238.1/2) were cross-checked and confirmed.

2. Methodology

For every RoP rule in the in-scope list:

  1. Identify the trigger event (what starts the period).
  2. Identify the duration + unit (calendar days / months / before-or-after).
  3. Look up paliad's rule library. Three lookup paths:
    • paliad.deadline_rules (the proceeding-tree shape used by Fristenrechner Pathway A — "pick proceeding type, see whole timeline").
    • paliad.deadline_concepts × paliad.event_category_concepts (the cascade shape used by Pathway B — "pick what just landed in the CMS, see what reacts").
    • paliad.trigger_events (the youpc-style event list, 90+ rows, used by the search/autocomplete surface).
  4. Assign a status: present-correct / present-wrong / partial / missing / n/a.

Status definitions:

  • present-correct — paliad has a row with the right RoP code, duration, anchor, and (where relevant) primary_party.
  • present-wrong — paliad has a row that fires for this rule but with a wrong duration / anchor / condition.
  • partial — paliad has the rule for one branch (e.g. proactive only, or one party only) but is missing the symmetric branch.
  • missing — no rule, no concept-card, no trigger-event entry covers this.
  • n/a — RoP rule doesn't create a tracked deadline (e.g. judge sets it ad hoc, or rule is purely structural).

Frequency tag (column "Freq" in §3 tables):

  • ★★★ — every UPC infringement / revocation / appeal will hit this.
  • ★★ — common (most cases at some stage).
  • — specialist (PI, saisie, damages-only, rehearing).

The 2026-04-30 audit (§3, §4) already enumerated the core youpc gaps. Where a finding here overlaps that audit, I cite it (see 2026-04-30 §X) and avoid restating.


3. Findings

Section A — Infringement pleadings (R.13R.32)

RoP § Trigger Duration paliad rule Status Freq Note
R.13 Klageerhebung (filing of SoC) — (anchor event, duration 0) inf.soc present-correct ★★★ UPC_INF root.
R.17 Decision on language of proceedings judge-discretion n/a (no auto-deadline) n/a Court-set; no Fristenrechner row needed.
R.19 Service of SoC → Preliminary Objection 1 month missing missing ★★ No inf.prelim_objection row in UPC_INF. The cascade has no "Vorgängige Einrede" leaf either. Trigger event 68 (preliminary_objection) exists in paliad.trigger_events but has no rule attached.
R.20.2 PO → Reply to PO 14 days missing missing Fringe but real — defendant's PO triggers a 14d response window.
R.23 Service of SoC → Statement of Defence 3 months inf.sod (RoP.023) present-correct ★★★ Rule code format is RoP.023 — was normalised since 2026-04-30 §4.3.
R.24 / R.25 SoD with CCR (CCR rolled into SoD, 3mo) cms-eingang.gegenseite.upc-inf.klageerwiderung-mit-ccr (cascade leaf) present-correct ★★★ Cascade leaf maps to defence-to-counterclaim-for-revocation concept.
R.29.a SoD-with-CCR served → Defence to CCR + Reply to SoD 2 months inf.def_to_ccr (RoP.029.a) present-correct ★★★
R.29.b SoD-without-CCR served → Reply to SoD 2 months inf.reply (RoP.029.b, alt RoP.029.a) present-correct ★★★ Adaptive: alt branch flips for with-CCR. Migration 050 wired the bilateral backfill.
R.29.c Reply served → Rejoinder 1 month inf.rejoin (RoP.029.c, alt RoP.029.d) present-correct ★★★ Adaptive.
R.29.d Reply-to-defence-to-CCR served → Reply to that 2 months inf.reply_def_ccr (RoP.029.d) present-correct ★★
R.29.e That reply served → Rejoinder 1 month inf.rejoin_reply_ccr (RoP.029.e) present-correct ★★
R.30.1 Defendant filing Application to Amend (with CCR) 0 (ride along with SoD) inf.app_to_amend (RoP.030.1) present-correct ★★
R.32.1 Application to Amend served → Defence to Amend 2 months inf.def_to_amend (RoP.032.1) present-correct ★★
R.32.3 Defence-to-Amend served → Reply 1 month inf.reply_def_amd (RoP.032.3) present-correct ★★
R.32.3 Reply-on-Amend served → Rejoinder 1 month inf.rejoin_amd (RoP.032.3) present-correct ★★ Same code, different rule row (rejoinder branch). Reused code is intentional.

Section A net: 13 rules covered correctly. 2 missing (R.19 Preliminary Objection 1mo, R.20.2 Reply to PO 14d).


Section B — Revocation + CCR + DNI (R.42R.70)

RoP § Trigger Duration paliad rule Status Freq Note
R.42 Filing of Nichtigkeitsklage (REV) 0 anchor rev.app present-correct ★★★ UPC_REV root.
R.49.1 Service of REV → Defence to Revocation 2 months rev.defence (3 months, RoP.49.1) present-wrong (DURATION + rule_code) ★★★ Confirmed via youpc UPCRoP.049.1 text: "The defendant shall lodge a Defence to revocation within two months of service of the Statement for revocation." paliad seeded 3 months — copy-paste from R.23 (UPC_INF Defence which is correctly 3mo). High-impact bug — REV Defence is the most-used revocation deadline. Rule_code also drift (RoP.49.1RoP.049.1).
R.49.2.a REV → Application to Amend 0 (rides along with Defence) rev.app_to_amend (RoP.049.2.a) present-correct ★★
R.49.2.b REV → Counterclaim for Infringement (CCI) 0 (rides along) rev.cc_inf (RoP.049.2.b) present-correct ★★
R.51 Defence to Revocation served → Reply 2 months rev.reply (2mo, no rule_code) present-wrong (rule_code only) ★★★ Confirmed via youpc UPCRoP.051.p1 text: "Within two months of service of the Defence to revocation the claimant may lodge a Reply…" Duration correct. Rule_code is NULL — add RoP.051. (Note: my initial draft cited "R.50" for this; the actual rule is R.51 — R.50 is "Contents of the Defence to revocation" with no duration.)
R.52 Reply served → Rejoinder 1 month rev.rejoin (2 months, no rule_code) present-wrong (DURATION + rule_code) ★★★ Confirmed via youpc UPCRoP.052.p1 text: "Within one month of the service of the Reply the defendant may lodge a Rejoinder…" paliad seeded 2 months — bug. Rejoinder is symmetric with R.29.c (UPC_INF rejoinder, also 1mo). Add rule_code RoP.052. Second high-impact bug.
R.43.3 Application-to-Amend served → Defence to Amend (in REV) 2 months rev.def_to_amend (RoP.043.3) present-correct ★★
R.32.3 Reply on Amend (in REV) 1 month rev.reply_def_amd (RoP.032.3) present-correct ★★
R.32.3 Rejoinder on Amend (in REV) 1 month rev.rejoin_amd (RoP.032.3) present-correct ★★
R.56.1 CCI served → Defence to CCI 2 months rev.def_cci (RoP.056.1) present-correct ★★
R.56.3 Defence-to-CCI served → Reply 1 month rev.reply_def_cci (RoP.056.3) present-correct ★★
R.56.4 Reply served → Rejoinder 1 month rev.rejoin_cci (RoP.056.4) present-correct ★★
R.61 Pre-CCI standalone Counterclaim (CCR-only proceedings) n/a (overlap with CCR mechanics) n/a n/a UPC_REV with CCI already covers this; R.61 is a structural cross-ref.
R.63 Filing of Application for DNI 0 anchor missing missing No UPC_DNI proceeding type exists. Cascade has no DNI leaf.
R.67.1 DNI served → Defence to DNI 2 months missing missing
R.69.1 Defence-to-DNI served → Reply 1 month missing missing
R.69.2 Reply served → Rejoinder 1 month missing missing
R.70 Application of UPC_INF rules to DNI 0 (cross-ref) n/a n/a DNI inherits all of UPC_INF's chain after the initial 4 rules.

Section B net: 8 rules covered correctly, 2 high-impact duration bugs (R.49.1 Defence-to-Revocation 3mo seeded but RoP says 2mo; R.52 Rejoinder 2mo seeded but RoP says 1mo), 2 rule_code drift (R.51 NULL, R.52 NULL — fixing alongside the duration corrections), 4 missing (DNI family — R.63, R.67.1, R.69.1, R.69.2). Both duration bugs surfaced from cross-referencing the authoritative RoP text via data.laws_contents (the youpc law database) — they were invisible in the rule-code-format-only review.

DNI is a low-frequency proceeding (zero filings in published UPC orders 2026-Q1) — flag, but Tier 3 priority.


Section C — Provisional measures + evidence preservation (R.190R.213)

RoP § Trigger Duration paliad rule Status Freq Note
R.197.3 Saisie order served on respondent → Application for review 30 days missing missing Trigger event 65 (request_for_review_of_the_order_to_preserve_evidence) exists; no rule attached.
R.198 Saisie executed → Start proceedings on the merits 31 calendar days OR 20 working days, whichever is longer missing missing Requires arithmetic primitive paliad doesn't have (see 2026-04-30 §5.1). Trigger event 81 (start_of_proceedings_on_the_merits) exists.
R.205 Application for PI filed 0 anchor pi.app present-correct ★★ UPC_PI root.
R.207.6.a Notification of deficiency in PI application 14 days missing missing ★★ Registry-correction family. Trigger event 71 (notification_by_the_registry_to_correct_deficiencies) exists; no rule.
R.207.9 PI filed → Renewal of protective letter 6 months missing missing Trigger event 46 (renewal_of_protective_letter) exists; no rule.
R.211.2 PI granted ex parte → Inter partes hearing judge-set (typ. ≤30d) pi.response (court-set, duration=0) present-correct (court-set) ★★ Modelled as duration=0 with parent → UI shows "vom Gericht gesetzt". Correct shape.
R.211.4 PI granted → Service on respondent judge-set n/a n/a ★★ No fixed period.
R.213 PI granted → Start proceedings on the merits 31 calendar days OR 20 working days, whichever is longer missing missing ★★ Same arithmetic primitive as R.198.
R.196.5 Saisie review → Damages application by respondent 31d / 20wd n/a n/a Conditional on PI being revoked; specialist.

Section C net: PI happy-path covered. 5 missing (R.197.3, R.198, R.207.6.a, R.207.9, R.213). The two "31d / 20wd whichever is longer" rules are blocked on a missing arithmetic primitive (see §5.1).


Section D — Damages + lay-open books (R.125R.144)

RoP § Trigger Duration paliad rule Status Freq Note
R.125 Decision on the merits incl. damages-in-principle 0 anchor n/a n/a ★★ Structural — triggers R.131.
R.131.2 Final decision on validity → Application for damages, indication judge-set (typ. by court order) damages.app (duration=0, court-set shape) present-correct ★★ Trigger event 82 covers the indication.
R.137.2 Application for damages served → Defence 2 months damages.defence (RoP.137.2) present-correct ★★
R.139 Defence served → Reply 1 month damages.reply (RoP.139) present-correct ★★
R.139 Reply served → Rejoinder 1 month damages.rejoin (RoP.139) present-correct ★★
R.141 Order to lay open books filed 0 anchor disc.app (UPC_DISCOVERY) present-correct ★★
R.142.2 Order served → Defence 2 months disc.defence (RoP.142.2) present-correct ★★
R.142.3 Defence served → Reply 14 days disc.reply (RoP.142.3) present-correct ★★
R.142.3 Reply served → Rejoinder 14 days disc.rejoin (RoP.142.3) present-correct ★★
R.144 Final decision on damages quantum 0 anchor (court event) missing partial No damages.decision row analogous to inf.decision. UPC_DAMAGES tree ends at damages.rejoin.
R.118.4 Final decision on validity → Application for orders consequential 2 months missing missing ★★ Trigger event 36 exists; no rule attached. Common after EPO-or-CD validity ruling.

Section D net: Damages happy-path covered. 2 missing (R.118.4 application for consequential orders, R.144 damages decision tree-end). Lay-open books covered cleanly.


Section E — Decisions, costs, default judgment (R.111R.157)

RoP § Trigger Duration paliad rule Status Freq Note
R.111 Decision on the merits delivered 0 anchor inf.decision / rev.decision / app.decision present-correct ★★★ Tree-end events.
R.118 Decision on validity (final) 0 anchor (covered as inf.decision) present-correct ★★★
R.118.4 Final decision on validity → Application for orders consequential 2 months missing missing ★★ Repeated from §D — tracked as a single gap.
R.118.5 Default judgment served → Set-aside ("Einspruch") missing in UPC n/a n/a UPC has no German-style Versäumnisurteil-Einspruch; closest is R.355 review of contumacy. Concept versaeumnisurteil-einspruch exists in paliad (DE-only proceedings).
R.151 Final decision (with cost order) → Application for cost decision 1 month inf.cost_app (RoP.151) present-correct ★★★
R.157 Cost decision delivered 0 anchor cost.decision (UPC_COST_APPEAL) present-correct ★★
R.221.1 Cost decision served → Application for leave-to-appeal 15 days cost.leave_app (RoP.221.1) present-correct ★★ Migration 052 §3 wired the leaf cascade.
R.155 Cost-decision app served → Defence + Reply chain 1 month / 14 days partial partial UPC_COST_APPEAL only has the leave-to-appeal step; no Defence-to-cost-app row.

Section E net: Cost happy-path covered. 1 missing (R.118.4), 1 partial (R.155 cost-decision opposition chain).


Section F — Appeals (R.220R.246)

The single biggest section. paliad models this across three proceeding types: UPC_APP (the main 2mo/4mo appeal), UPC_APP_ORDERS (the 15d orders/with-leave track), UPC_COST_APPEAL (the 15d cost-decision-leave track).

RoP § Trigger Duration paliad rule Status Freq Note
R.220.1.a Final decision served (decision on merits) — (anchor) n/a (anchor on app.notice) n/a ★★★ Anchor row, not a deadline.
R.220.1.b Final decision served (review of CMO etc.) — (anchor) (same) n/a ★★
R.220.1.c Order referred to in R.220.1.c (case-mgmt) — (anchor) app_ord.order present-correct ★★
R.220.2 Order with leave to appeal granted → Statement of Appeal 15 days app_ord.with_leave (RoP.220.2) present-correct ★★ Migration 052 §4 fixed the leaf wiring.
R.220.3 Order, leave-to-appeal refused → Discretionary review request 15 days app_ord.discretion (RoP.220.3) present-correct ★★
R.221.1 Cost decision → Leave-to-appeal 15 days cost.leave_app (RoP.221.1) present-correct ★★
R.224.1.a Final decision served → Statement of Appeal (main track) 2 months app.notice (RoP.220.1) present-wrong (rule_code) ★★★ Rule_code is RoP.220.1 but the actual citation is R.224.1.a. R.220.1 is the trigger-classifier rule, not the duration rule. Cosmetic but technically wrong code.
R.224.1.b Order in R.220.1.c served → Statement of Appeal (orders track) 15 days app_ord.with_leave (RoP.220.2) partial ★★ Fires from R.220.2 (with leave) but no separate row for R.224.1.b standalone (orders without leave-grant requirement, e.g. R.220.1.c orders). Same 15 days, but the citation is different.
R.224.2.a Decision served → Statement of Grounds (main track) 4 months app.grounds (4mo, RoP.220.1) present-correct (with code drift) ★★★ Duration corrected from 2mo to 4mo since the 2026-04-30 audit (§4.4). Rule_code still says RoP.220.1 — should be RoP.224.2.a.
R.224.2.b Order in R.220.1.c served → Statement of Grounds (orders track) 15 days missing missing ★★ UPC_APP_ORDERS has the appeal-itself row but no separate Grounds row. R.224.2.b explicitly creates a 15-day grounds period for the orders track.
R.229.2 Notification of appeal-deficiency → Correction 14 days missing missing Registry-correction family.
R.234.1 Statement of Appeal received → Court rejects as inadmissible 1 month n/a (court action, no party deadline) n/a Court window, not party deadline.
R.235.1 Statement of Appeal served → Response (orders track) 15 days app_ord.cross_reply partially overlaps; standalone response missing partial ★★ UPC_APP_ORDERS has cross + cross_reply but no response-to-the-appeal row. R.235.1 specifically covers the response-to-appeal in the orders/with-leave track.
R.235.2 Statement of Appeal served → Response (main track) 3 months app.response (3mo, no rule_code) present-wrong (rule_code) ★★★ Duration is correct (3 months). Rule_code is NULL — should be RoP.235.2.
R.237 Response to Appeal served → Cross-Appeal 3mo (main) / 15d (orders) app.cross_a (3mo, RoP.237) + app_ord.cross (15d, RoP.237) present-correct ★★
R.238.1 Cross-Appeal served → Reply (main track) 2 months app.cross_a_reply (RoP.238.1) present-correct ★★
R.238.2 Cross-Appeal served → Reply (orders track) 15 days app_ord.cross_reply (RoP.238.2) present-correct ★★
R.245.1 Final decision served → Application for rehearing (main 2mo) 2 months missing missing
R.245.2.a Discovery of fundamental defect → Application for rehearing 2 months missing missing "Whichever is later" of decision-service vs defect-discovery (cf. trigger event 98). Outer cap 12mo from final decision.
R.245.2.b Discovery of criminal offence → Application for rehearing 2 months missing missing Trigger event 88. Same outer cap.
R.245.2 cap Outer cap 12 months from final decision missing missing Outer-bound logic, not a calendar deadline; needs a "max-of-anchors" capability.

Section F net: Main happy-path covered. 3 present-wrong (rule_code drift) on R.224.1.a, R.224.2.a, R.235.2 — the durations are right, the citation strings are wrong/missing. 1 missing R.224.2.b grounds-on-orders 15d (genuine functional gap). 1 partial R.235.1 response-on-orders-track. 3 missing rehearing family (R.245). 1 missing R.229.2 registry-correction.


Section G — Re-establishment, case-management, miscellaneous

RoP § Trigger Duration paliad rule Status Freq Note
R.262.2 Receipt of opposing party's application for confidentiality 14 days missing missing ★★ Trigger event 25 (application_to_request_confidentiality_from_the_public) exists; no rule. Common in HLC infringement work where competitor secrets are filed.
R.262A Confidentiality club application judge-set n/a n/a No fixed deadline.
R.295 Stay of proceedings n/a (judicial discretion) n/a n/a ★★ No deadline.
R.320 Wegfall des Hindernisses → Wiedereinsetzung 2 months (cap 12mo from missed deadline) concept wiedereinsetzung + trigger event 207 + leaf frist-verpasst.upc present-correct (cascade-only) ★★ Migration 063 added the cascade path. No paliad.deadline_rules row — Wiedereinsetzung has no proceeding-tree rule because it bridges proceedings. The 2mo / 12mo logic only lives in description text. If we want to compute the deadline, a rule row is needed; today the user gets a concept-card but not a calendar entry.
R.321.3 Filing → Referral to central division (preliminary objection sub-case) 10 days missing missing
R.331 Court summons to oral hearing judge-set cms-eingang.gericht.ladung cascade leaf (no rule) partial ★★ Cascade leaf exists but no fixed period; this is correct since R.331 is judge-set. Mentioned for completeness.
R.333.2 Case-management order served → Application for review 15 days missing missing ★★ Trigger event 16 exists; no rule. Common in busy LDs (review-of-CMO requests are routine).
R.353 Decision/order delivered → Application for rectification 1 month missing missing Trigger event 41 exists; no rule.

Section G net: R.320 covered cascade-only (computational gap). 5 missing (R.262.2 confidentiality, R.321.3 referral, R.333.2 review-of-CMO, R.353 rectification, R.320 calendar arithmetic).


Section H — Oral-hearing prep + translations (R.109)

RoP § Trigger Duration paliad rule Status Freq Note
R.109.1 Oral hearing date → Request for simultaneous translation 1 month before missing missing ★★ The whole "before"-mode family. paliad's paliad.deadline_rules has a timing column (values before/after) and internal/services/deadline_calculator.go reads it, but no rule today populates timing='before' — verified via SQL SELECT DISTINCT timing FROM paliad.deadline_rules WHERE is_active = true returning {after} only.
R.109.4 Oral hearing date → Notification of interpreter cost intent 2 weeks before missing missing ★★
R.109.5 Oral hearing date → Lodging of translations 2 weeks after summons missing missing ★★ Trigger event 113 (order_of_the_judge_rapporteur_to_lodge_translations) exists; no rule.
R.116 Oral hearing → Final written submissions (EPO-style cap) 1 month before (typically) n/a (UPC has no formal R.116-equivalent — EPC-only) n/a ★★ Concept r116-final-submissions is mapped to EPA_OPP / EPA_APP only — correct.

Section H net: All 3 R.109 rules missing. This was flagged in 2026-04-30 §3.6 as a tier-2 port; no migration since. The schema and Go code already support before-mode, just no data.


4. Gap list

Ordered by frequency × user-impact. Each entry is one sentence, sufficient for a coder to spec a migration row.

Critical — ★★★ ("real duration bugs verified against RoP text — fix before any further migration work")

  1. UPC_REV.rev.defence duration is 3 months — RoP §49.1 says 2 months. Single-row UPDATE: duration_value=2. Also fix rule_code RoP.49.1RoP.049.1. Verified via data.laws_contents for UPCRoP.049.1 (youpc law database).
  2. UPC_REV.rev.rejoin duration is 2 months — RoP §52 says 1 month. Single-row UPDATE: duration_value=1, set rule_code='RoP.052'. Verified via data.laws_contents for UPCRoP.052.p1.
  3. UPC_REV.rev.reply rule_code is NULL. Set rule_code='RoP.051'. Duration (2mo) is correct.
  4. UPC_APP.app.notice / app.grounds / app.response rule_code drift. app.notice cites RoP.220.1 (trigger-classifier); should be RoP.224.1.a (duration rule). app.grounds same drift (→ RoP.224.2.a). app.response NULL (→ RoP.235.2). Cosmetic-but-wrong; durations all correct.

High-priority — ★★ ("every case will hit this at some stage")

  1. R.19 Preliminary Objection (1 month) missing in UPC_INF. Defendant's first move when challenging jurisdiction/competence/language. No rule, no cascade leaf, no concept card — just a dangling trigger event 68. Add rule + cascade leaf + concept.
  2. R.224.2.b Statement of Grounds on orders track (15 days) missing in UPC_APP_ORDERS. With-leave appeal has the appeal-itself row but no separate grounds row.
  3. R.235.1 Response to Appeal on orders track (15 days) missing in UPC_APP_ORDERS.
  4. R.118.4 Application for orders consequential on validity (2 months) missing. Common follow-on after central-division revocation decision.
  5. R.262.2 Confidentiality response (14 days) missing. Daily occurrence in HLC infringement work.
  6. R.333.2 Review of CMO (15 days) missing. Routine in busy local divisions.
  7. R.207.6.a Notification of PI deficiency → Correction (14 days) missing. Registry-correction family.
  8. R.197.3 Saisie review request (30 days) missing. Standard saisie practice.
  9. R.198 / R.213 Start proceedings on the merits (31d OR 20wd, whichever is longer) — blocked on arithmetic primitive. Needs working_days unit or a combine='max' operator. Document blocked-on-tooling in the gap-list; do not migrate until the primitive lands.
  10. R.207.9 Renewal of protective letter (6 months) missing.
  11. R.109.1 / R.109.4 / R.109.5 Oral-hearing translation prep (1mo / 2w / 2w; first two are before-mode) missing. First two are the only before-mode rules in the whole UPC corpus — schema supports it, no data populates it.
  12. R.353 Rectification of decision (1 month) missing.

Medium-priority — ("specialist / fringe but real")

  1. R.20.2 Reply to Preliminary Objection (14 days) missing.
  2. R.229.2 Notification of appeal-deficiency → Correction (14 days) missing.
  3. R.245.1, R.245.2.a, R.245.2.b Rehearing applications (2mo / outer 12mo cap) missing. Plus the "max-of-two-anchors" arithmetic for R.245.2.
  4. R.321.3 Referral to central division (10 days) missing.
  5. R.144 Damages decision tree-end row missing. Cosmetic — UPC_DAMAGES tree just stops at rejoinder.
  6. R.155 Cost-decision opposition chain (Defence + Reply) missing in UPC_COST_APPEAL. Tree currently jumps from cost decision to leave-to-appeal without modelling the substantive opposition.
  7. R.63 / R.67.1 / R.69.1 / R.69.2 DNI family (4 rules) missing. No UPC_DNI proceeding type. Fringe in HLC practice.
  8. R.320 Wiedereinsetzung calendar arithmetic missing. Cascade card exists; no rule row that computes the 2mo / 12mo deadline. Needs either a paliad.deadline_rules row or a special-case Go helper. Touches the "outer cap" arithmetic gap (same pattern as R.245.2).

Tooling gaps (block multiple rules)

  1. working_days duration unit + combine='max' operator. Blocks R.198, R.213, and arguably R.198 cross-cuts saisie.
  2. outer_cap_value + outer_cap_unit columns (or a separate table). Blocks R.320 (12mo cap), R.245.2 (12mo cap).
  3. Multi-anchor "whichever is later" trigger events. Blocks R.245.2.a/b. Trigger events 88 + 98 already encode the OR semantics in their names but no Go-side helper picks the later of two user-provided dates.

5. Cross-cutting observations

5.1 Rule-code citation drift is widespread

The 2026-04-30 audit (§4.3) noted the format drift (RoP 23 vs RoP.023). That part is now resolved (no RoP 23 rows exist — all migrated to RoP.023 style). But a second-order drift remains: the rule_code field cites the wrong rule in several places (R.220.1 used for R.224.1.a / R.224.2.a, NULLs on REV reply/rejoinder and app.response).

Recommendation: an audit pass over paliad.deadline_rules to align rule_code to the duration-creating rule, not the trigger-classifier rule. Roughly 5-7 rows to update.

5.2 The cascade and the rule-tree drift independently

paliad has two surfaces:

  • Pathway A (proceeding tree, paliad.deadline_rules): "I'm running an UPC infringement case, what's the timeline?"
  • Pathway B (cascade, paliad.event_categories + paliad.event_category_concepts + paliad.deadline_concepts): "the CMS just landed X, what reacts?"

Both surfaces should cover the same RoP universe; in practice they don't. R.320 Wiedereinsetzung is in Pathway B (after migration 063) but not in Pathway A. R.262.2 confidentiality is in neither.

A single matrix (RoP rule × Pathway A coverage × Pathway B coverage) would help future audits. Out of scope here, but worth adding to the rule-library doc once the gaps below are filled.

5.3 Trigger-event corpus is much richer than the rule corpus

paliad.trigger_events has ~90 active rows; paliad.deadline_rules references only ~50 distinct UPC scenarios. Many trigger events have no attached rule (R.197.3 review, R.207.9 renewal, R.262.2 confidentiality, R.353 rectification, R.207.6.a deficiency-correction…). The corpus was clearly imported from youpc with the events but without the rules.

This is the single biggest "missing data" pattern: triggers without rules.

5.4 before-mode rules — schema supports, no data populates

paliad.deadline_rules.timing accepts 'before'/'after'. SQL: SELECT DISTINCT timing FROM paliad.deadline_rules WHERE is_active = true returns {after}. Three R.109 rules need before. That's the only user need for before mode in the entire UPC corpus.

Verify the date-arithmetic does subtract not push-forward — internal/services/deadline_calculator.go:addDuration should already handle negative values, but any rule that lands on a non-working day should snap backward to the previous working day for before-mode (the deadline is "by 1 month before hearing", so a Sunday must move to Friday, not the next Monday — which would be the hearing day or after). 2026-04-30 §5.4 flagged this; verify before adding R.109 rules.

5.4b R.220.3 anchoring nuance (Pathway A vs B drift)

UPC_APP_ORDERS.app_ord.discretion is 15 days, parented to app_ord.order (the original CFI order). RoP §220.3 reads: "within 15 calendar days from the end of [the 15-day refusal] period". So the "15 days" duration is anchored on the day leave-to-appeal was refused (or the day-15 cutoff if no refusal yet), not on the order date. The cascade shape (Pathway B) handles this correctly via trigger event 99 (leave_to_appeal_refused_within_15_days_of_the_order); the user picks the actual refusal date and the 15d clock runs from there. The proceeding-tree shape (Pathway A) hangs the deadline directly off the order — a user who enters the order date in Pathway A will compute the wrong deadline (15d too early, since the worst-case real deadline is 30d after the order).

Recommendation: either rename app_ord.discretion's anchor to app_ord.refusal and add a app_ord.refusal court-set node (duration=0, parent=order) for the trigger date, or document in the Fristenrechner UI that the user must enter the refusal date, not the order date. Not a duration bug — an anchoring/UI bug. Low-impact (≤30d off in the worst case, only matters at the edge), but worth fixing.

5.5 "Whichever is longer / later" arithmetic

Three rules need it: R.198, R.213 (max of calendar-days vs working-days), R.245.2.a/b (max of decision-service date vs defect-discovery date). The R.198/R.213 case needs working-days arithmetic (a function of holiday data, which paliad has). The R.245.2 case needs a two-input UI (the user supplies both dates).

Both can be deferred until a real R.198 or R.245 case lands at HLC. Listing in the gap-list with a [blocked on tooling] tag is the right move; no migrations should be drafted until the primitive exists.


(Not a request for migration here — orientation for whoever picks up the gap-fill task.)

Wave 0 — DURATION BUGS (must ship first; 2 UPDATE rows + 4 rule_code fixes):

  • Fix rev.defence: duration_value 3 → 2, rule_code RoP.49.1RoP.049.1 (gap 1).
  • Fix rev.rejoin: duration_value 2 → 1, set rule_code='RoP.052' (gap 2).
  • Fix rev.reply: set rule_code='RoP.051' (gap 3).
  • Fix app.notice / app.grounds / app.response rule_code drift (gap 4).
  • Why first: existing UPC_REV deadlines computed via paliad today are wrong by a month for both Defence and Rejoinder. Any user who set up a Nichtigkeitsverfahren in the last 4 months has miscalibrated reminders. Fix this before any other work.

Wave 1 — new rule rows, single migration (~6 rows):

  • Add R.19 Preliminary Objection (gap 5).
  • Add R.262.2 confidentiality (gap 9).
  • Add R.333.2 review-of-CMO (gap 10).
  • Add R.224.2.b Grounds-on-orders (gap 6) + R.235.1 response-on-orders (gap 7).
  • Add R.353 rectification (gap 16).

Wave 2 — registry-corrections family (56 rows, all 14d):

  • R.207.6.a (gap 11), R.229.2 (gap 18), and the rest of the "Mängelbeseitigung" family (R.16.3.a, R.27.2, R.89.2, R.253.2 — already noted in 2026-04-30 §3.1).

Wave 3 — saisie + PI gaps (4 rows):

  • R.197.3 (gap 12), R.207.9 (gap 14), and document R.198/R.213 as blocked on tooling.

Wave 4 — translation prep (3 rows, before-mode):

  • R.109.1, R.109.4, R.109.5 (gap 15). Test backward-snap to working day before merging.

Wave 5 — rare/specialist (5 rows):

  • R.20.2 (gap 17), R.144 (gap 21), R.155 (gap 22), R.321.3 (gap 20), R.118.4 (gap 8).

Out of scope until tooling lands:

  • R.198 / R.213 (working-days arithmetic).
  • R.245.2 family (multi-anchor arithmetic).
  • R.320 calendar arithmetic (outer-cap).

Out of scope, fringe in HLC practice:

  • DNI family (gap 23). Defer until first DNI case at the firm.

7. Open questions for m

Scope/policy questions, not substantive UPC-rule ambiguities. Listed for the next shift.

  1. R.245 rehearing — in or out of scope for paliad? Rare remedy; if a case ever needs it, the lawyer will look it up in the RoP directly. Do we want a tile, or accept that paliad's Fristenrechner is for the 95% common case?
  2. R.198 / R.213 working-days arithmetic — implement the primitive, or document as "manual calculation required"? Real R.198 cases are rare enough that a doc-string + manual override may be cheaper than the schema/code work.
  3. R.320 Wiedereinsetzung — should the cascade card produce a calendar entry? Today migration 063 surfaces the concept (UI tile) but no Frist row gets created. The 2mo / 12mo math is non-trivial because it involves the missed deadline as anchor, not a forward-looking event.
  4. DNI (R.63R.70) — is HLC seeing any DNI cases? Zero published in 2026-Q1; if no internal demand, defer indefinitely.
  5. R.262.2 confidentiality 14d — Pathway A or Pathway B only? It's a reactive deadline (defendant gets opponent's confidentiality request → 14d to respond). Cascade-only seems right; no UPC_CONFIDENTIALITY proceeding type needed.
  6. Proceeding-code naming convention — m raised in shift-1 chat. Today paliad uses underscore-separated codes (UPC_INF, UPC_REV, UPC_PI, UPC_APP, UPC_DAMAGES, UPC_DISCOVERY, UPC_COST_APPEAL, UPC_APP_ORDERS). m suggested a hierarchical dot-notation scheme: UPC.INF, UPC.REV, UPC.APM (= PI), UPC.A2A (= application to amend), with instance qualifiers UPC.INF.CFI / UPC.INF.COA and national-equivalents DE.INF.1 / .2 / .3. Trade-off: consistent grammar across the matrix and trivial parent-child lookup vs. a bulk rename across paliad.proceeding_types.code, all paliad.deadline_rules rows, all migration files, all front-end strings, and all references in paliad.event_category_concepts.proceeding_type_code. Recommendation: if we go ahead, do it as a single migration that renames the codes via a mapping table (one column update per affected row) and add a forward-compatibility view aliasing the old codes for any in-flight queries. Don't merge with the duration-bug fixes (Wave 1) — that's two unrelated diff scopes. Worth its own task ticket.

Appendix A — file references

paliad code paths consulted:

  • internal/db/migrations/012_fristenrechner_rules.up.sql — original UPC_INF / UPC_REV / UPC_PI / UPC_APP / DE_* / EPA_* seed.
  • internal/db/migrations/049_event_categories_seed.up.sql — Pathway B cascade seed.
  • internal/db/migrations/050_bilateral_rules_backfill.up.sql — bilateral / both-party rule seed.
  • internal/db/migrations/052_event_categories_rop_audit.up.sql — prior cascade-side RoP audit fix-pass (R.221 cost-appeal, R.220.3 discretionary review, R.237/238 cross-appeal coverage).
  • internal/db/migrations/053_courts_and_countries.up.sql and onwards — unrelated to deadline_rules.
  • internal/db/migrations/063_frist_verpasst_upc.up.sql — R.320 cascade leaf (no rule row).
  • internal/services/deadline_calculator.go — arithmetic. Reads timing, supports before/after, doesn't yet handle working_days or combine='max'.
  • internal/services/holidays.go — DB-driven holidays (good shape; would carry working-days arithmetic when added).
  • frontend/src/client/fristenrechner.ts — UI; supports condition_rule_id toggle for adaptive rules.

RoP citations are paraphrased from the official UPC Rules of Procedure (consolidated version, in force from 2026-01-01, available at unified-patent-court.org/sites/default/files/upc_documents/rop_consolidated_2026.pdf — verified against the deadline-creating rules I list, without quoting verbatim).

Companion audits:

  • docs/audit-fristenrechner-completeness-2026-04-30.md — youpc-vs-paliad comparison (curie, t-paliad-084).
  • docs/audit-polish-2026-04-27.md and docs/audit-polish-2-2026-04-29.md — UI/UX polish audits, not rule-data.

Appendix B — coverage tally

Rules audited in scope: ~80 deadline-creating UPC RoP rules across 8 sections.

Status Count Share
present-correct 38 47%
present-wrong (DURATION) 2 3%
present-wrong (rule_code drift only) 5 6%
partial 4 5%
missing 25 31%
n/a (no deadline) 8 10%

Most-important findings: the 2 duration bugs (R.49.1 Defence-to-Revocation, R.52 REV Rejoinder) — both ★★★, both impact every active UPC_REV proceeding tracked in paliad today.

The 25 missing represent the gap list. Of those, 16 are ★★★ / ★★ frequency (high priority); 9 are ★ specialist.