diff --git a/docs/research-deadlines-completeness-2026-05-25.md b/docs/research-deadlines-completeness-2026-05-25.md new file mode 100644 index 0000000..caf46dc --- /dev/null +++ b/docs/research-deadlines-completeness-2026-05-25.md @@ -0,0 +1,956 @@ +# Bulletproof completeness audit — paliad.deadline_rules vs statutory sources + +**Author:** curie (researcher) +**Date:** 2026-05-25 +**Task:** t-paliad-263 (m/paliad#94) +**Mode:** read-only research, no DB writes +**Branch:** `mai/curie/researcher-bulletproof` + +Scope confirmed by head (paliad/head → paliad/curie, 2026-05-25 15:13): +**UPC Rules of Procedure + EPC + PatG / ZPO / GebrMG**, plus UPC Agreement / +Statute where they create time-limits. No HLC-internal checklists exist in +the current head's working tree. + +Companion / prior audits this report supersedes-and-extends: + +- `docs/audit-fristenrechner-completeness-2026-04-30.md` (curie, t-paliad-084) — youpc-vs-paliad gap analysis. +- `docs/audit-upc-rop-deadlines-2026-05-08.md` (curie, t-paliad-159) — first UPC RoP gap list (52 rules / 2 duration bugs). +- `docs/audit-fristen-logic-2026-05-13.md` (pauli, t-paliad-157) — schema audit; the codes used here (`upc.inf.cfi`, `de.inf.lg`, …) reflect the post-mig-096 rename. + +Migration baseline: migration ≤ `122_deadlines_custom_rule_text` (live as of 2026-05-25 14:00 UTC). + +--- + +## §0. TL;DR + +- **20 active fristenrechner proceeding_types** (live, `is_active=true`, + `lifecycle_state='published'`) carry **132 active rules**. One extra + `_archived_litigation` row holds 40 retired Pipeline-A rules from + mig 093 — not surfaced anywhere, kept only for FK validity. + +| Jurisdiction | Active types | Active rules | Statute-bound rules audited | +|---|---:|---:|---:| +| UPC (CFI + CoA) | 9 (incl. upc.ccr.cfi alias) | 67 | 67 | +| EPA | 3 | 23 | 23 | +| DPMA | 3 | 13 | 13 | +| DE (LG/OLG/BGH/BPatG) | 5 | 29 | 29 | +| **Total** | **20** | **132** | **132** | + +- **5 high-impact bugs still live** that the prior May 8 audit + surfaced (2) plus 3 new ones identified here. + - 🔴 **`upc.rev.cfi.defence` 3 months, RoP.49.1 says 2 months.** Flagged + May 8; still live. ★★★ — every UPC_REV defendant. + - 🔴 **`upc.rev.cfi.rejoin` 2 months, RoP.52 says 1 month.** Flagged + May 8; still live. ★★★ — every UPC_REV proceeding. + - 🟠 **`upc.apl.merits.response` 2 months, RoP.235.1 says 3 months.** + New finding (May 8 audit recorded the rule as "3 months / present-wrong + rule_code only" — actually live data shows 2 months, so the audit + sample mis-recorded the duration too). ★★★ — every UPC main-track + appeal respondent. + - 🟠 **`de.inf.lg.beruf_begr` chains parent = berufung (1mo) + 2mo = 3mo + from urteil. ZPO §520(2) anchors the 2-month Begründungsfrist on + service of urteil, not on filing of Berufung.** New finding. + ★★★ — every DE-first-instance appellant. + - 🟠 **`de.inf.lg.replik` + `.duplik` have `parent_id=NULL` so they fire + on the trigger date (Klageerhebung) — sequence-order says 30/40 but + the compute engine reads parent_id first.** Reported as live UI bug + by m via head (2026-05-25 13:13); confirmed by SQL. ★★★ — every + DE-LG-Verletzung timeline. + +- **5 rule-code / citation drift bugs still live** from the May 8 audit + (`upc.apl.merits.notice`, `.grounds`, `.response`, `upc.rev.cfi.reply`, + `.rejoin`) — durations may or may not be right, but the cited + `legal_source` / `rule_code` points at the wrong rule. Pure + cosmetic on `.notice`/`.grounds` (durations are right); load-bearing on + `.rev.cfi.reply` / `.rejoin` because the cited rule is what tells + the lawyer where to look the rule up. + +- **4 DPMA / DE citation bugs** new in this audit, all citing PatG / ZPO + sections that don't contain the cited deadline: + - `de.null.bpatg.erwidg` cites `DE.PatG.82.1`; the 2-month Erwiderung + is actually `§82(3)` (§82(1) is the 1-month Erklärungsfrist). + - `dpma.opp.dpma.erwiderung` cites `DE.PatG.59.3`; §59(3) is about + hearings, not a 4-month proprietor response. The 4-month figure is + DPMA-internal practice, not statutory — should be court-set. + - `dpma.appeal.bpatg.begruendung` cites `DE.PatG.75.1`; §75 is about + *aufschiebende Wirkung* — there is no Begründungsfrist in PatG §73-§80 + for the BPatG-Beschwerde. The 1-month figure is also non-statutory. + - `de.null.bgh.begruendung` cites `DE.PatG.111.1`; §111 is about the + grounds-of-appeal *content* (Verletzung des Bundesrechts), not the + Begründungsfrist. `de.null.bgh.erwiderung` cites `DE.PatG.111.3`; + §111(3) doesn't exist in the deadline sense. + +- **Wide UPC coverage gap inherited from May 8 audit, mostly un-closed:** + ~25 missing UPC RoP rules. Mig 095 (t-paliad-205) closed 4 of them + (R.19 Preliminary Objection on UPC_INF and UPC_REV, R.220.1(a) + merits-appeal spawn on both). The other ~21 (R.20.2, R.118.4, + R.197.3, R.198, R.207.6.a, R.207.9, R.213, R.109.1/.4/.5, R.118.5, + R.144, R.155, R.224.2(b), R.229.2, R.235.2, R.245.x, R.262.2, + R.321.3, R.333.2, R.353, plus the DNI family R.63-R.69) are + unchanged. + +- **EPC gaps:** EPA opposition + Beschwerde modelled at the + Article level only. Missing the entire Implementing Regulations + family that drives day-to-day deadlines — R.71(3) approval period + is half-modelled (the 4-month figure is there but the trigger + anchor is broken: parent_id=NULL), R.79(1) proprietor response + is modelled as a fixed 4-month period when it's actually + court-set, R.116 oral-proceedings cut-off is modelled as + duration-0/parent-NULL (works for some uses, not for others), + R.121 / R.135 Weiterbehandlung is missing entirely (concept + exists but no rule). + +- **DE/DPMA gaps:** the entire Wiedereinsetzung family (PatG §123) + is absent on the proceeding-tree side. `weiterbehandlung` and + `wiedereinsetzung` concept slugs exist in the cascade (Pathway B) + but no `paliad.deadline_rules` row computes them. Same for + `versaeumnisurteil-einspruch` (ZPO §339 — 2 weeks). + +- **15 ambiguities** that need m's judgement, not a coder's fix — + mostly around court-set vs statutory periods (e.g. richterliche + Fristen under ZPO §276(1) S.2, §283 Schriftsatznachreichung, + EPC R.79(1), §59(3) PatG) and around the "whichever is + longer / later" arithmetic primitives still missing + (R.198 / R.213 / R.245.2). + +- **Recommended fixes (§10) — total 41 items** prioritised in 4 + tiers. Tier 0 (5 hard duration bugs + 1 sequencing bug + 9 + citation/anchor bugs) should ship first. Tier 1 (12 rule-fill + gaps, ★★★ / ★★) next. Tier 2 + 3 are coverage breadth that + needs scoping by m (Wiedereinsetzung, R.198 working-day + arithmetic, full Implementing Regulations port). + +--- + +## §1. Methodology + +For each of the 20 active proceeding_types I: + +1. **Pulled the live rule set** via `mcp__supabase__execute_sql` against + the youpc Postgres on 2026-05-25 14:00–15:00 UTC. Schema = `paliad`. + Filter: `is_active = true AND lifecycle_state = 'published'`. +2. **Enumerated the statutory deadlines** in the relevant code for the + proceeding's scope. +3. **Cross-referenced each statutory deadline against the live rule + set** on (a) duration + unit, (b) anchor / parent, (c) party, + (d) `rule_code` / `legal_source` citation, (e) sequencing. +4. **Marked status**: `present-correct`, `present-wrong (duration)`, + `present-wrong (citation)`, `present-wrong (anchor)`, + `present-wrong (party)`, `partial`, `missing`, `n/a`. +5. **Frequency tag** for prioritisation: ★★★ every case, ★★ common, + ★ specialist. + +### 1.1 Sources + +All citations carry a date stamp and a URL. Where the text was checked +against more than one source, both are listed. + +| Source | URL | Verified on | Used for | +|---|---|---|---| +| UPC Rules of Procedure (consolidated 18.05.2023, in force 2023-06-01) | https://www.unifiedpatentcourt.org/sites/default/files/upc_documents/rop_application_-_consolidated_18_05_2023.pdf | 2026-05-25 | All UPC RoP citations | +| UPC RoP verbatim text via `data.laws_contents` (youpc Postgres, law_type=`UPCRoP`, language=en) | youpc Supabase | 2026-05-25 | Cross-check on R.019.1, R.020.2, R.029.b/.c, R.049.1, R.051, R.051.p1, R.052, R.052.p1, R.220.1.a, R.224.1, R.224.1.a/.b, R.224.2, R.224.2.a/.b, R.235.1, R.235.2, R.237, R.238.1, R.238.2 | +| European Patent Convention (EPC, 17th ed. 2020) — Articles | https://www.epo.org/en/legal/epc/2020/index.html (verbatim text per youpc `data.laws_contents`, law_type=`EPC`) | 2026-05-25 | EPC Articles 93, 99, 108, 112a, 116, 121, 123, 135 | +| EPC Implementing Regulations — Rules (in force 2026 consolidated) | https://www.epo.org/en/legal/epc/2020/r71.html (and equivalents) | 2026-05-25 | EPC R.70(1), R.71(3), R.79(1)/(2), R.116(1), R.135 | +| Patentgesetz (PatG) — gesetze-im-internet.de | https://www.gesetze-im-internet.de/patg/ | 2026-05-25 | §59, §73, §75, §82, §83, §99 ff., §100, §102, §110, §111 | +| Zivilprozessordnung (ZPO) — gesetze-im-internet.de | https://www.gesetze-im-internet.de/zpo/ | 2026-05-25 | §253, §276, §277, §283, §296a, §339, §517, §520, §521, §524, §544, §548, §551, §554 | +| Gebrauchsmustergesetz (GebrMG) — gesetze-im-internet.de | https://www.gesetze-im-internet.de/gebrmg/ | 2026-05-25 | §17 (Löschung), §18 (Verfahren) — referenced only to confirm out-of-scope: no GebrMG-rooted proceeding_type exists in paliad today | + +### 1.2 Conventions + +- A **rule** here means a row in `paliad.deadline_rules`. paliad's local + identifier is `submission_code` (post mig 098), e.g. + `upc.rev.cfi.defence`. +- A **statutory deadline** means an obligation derived directly from the + text of a procedural code, with a fixed period. +- "**Court-set**" / "richterliche Frist" means the statute authorises the + court / DPMA / EPO to set the period — there is no fixed statutory + duration. paliad models these with `is_court_set = true` + (post mig ~079) or, legacy-style, `duration_value = 0`. +- "**Anchoring**" refers to which event the period runs from. paliad + models this via `parent_id` (chain anchor) or `anchor_alt` (e.g. + `priority_date`); a NULL parent_id with non-zero duration means the + deadline runs from the user-supplied trigger date. + +### 1.3 Hard constraint: "no fabricated provisions" + +Where I'm not 100% sure of a citation (because the youpc law DB only +covers UPC + EPC, not PatG / ZPO, and my web-fetch coverage of +PatG / ZPO is partial), I flag the finding as **"needs lawyer review"** +in §9 rather than asserting a fix. Five PatG / ZPO findings carry that +tag. + +--- + +## §2. Current state inventory (per jurisdiction) + +### 2.1 UPC + +9 active types, 67 rules. `upc.ccr.cfi` is an alias proceeding that +holds zero rules — it points at `upc.inf.cfi` rules under the +`with_ccr` flag. + +| Code | Name | Rule count | Audited against | +|---|---|---:|---| +| `upc.inf.cfi` | Verletzungsverfahren | 15 | RoP 19, 23, 25, 29.a-e, 30, 32, 151, 220.1(a) | +| `upc.rev.cfi` | Nichtigkeitsverfahren | 17 | RoP 19, 32, 42, 43.3, 49.1, 49.2.a, 49.2.b, 51, 52, 56.1/3/4, 220.1(a) | +| `upc.pi.cfi` | Einstweilige Maßnahmen | 4 | RoP 205, 207, 211 | +| `upc.disc.cfi` | Bucheinsicht | 4 | RoP 141, 142.2, 142.3 | +| `upc.dmgs.cfi` | Schadensbemessung | 4 | RoP 131.2, 137.2, 139 | +| `upc.apl.merits` | Berufung | 8 | RoP 220.1, 224.1.a, 224.2.a, 235.1, 237, 238.1 | +| `upc.apl.order` | Berufung gegen Anordnungen | 5 | RoP 220.1(c), 220.2, 220.3, 237, 238.2 | +| `upc.apl.cost` | Berufung gegen Kostenentscheidung | 2 | RoP 221.1 | +| `upc.ccr.cfi` | Widerklage auf Nichtigkeit (alias) | 0 | — | + +### 2.2 EPA + +3 active types, 23 rules. + +| Code | Name | Rule count | Audited against | +|---|---|---:|---| +| `epa.grant.exa` | EP-Erteilung | 7 | EPC Art. 93, R.70(1), R.71(3) | +| `epa.opp.opd` | EPA Einspruch | 8 | EPC Art. 99(1), 108, 116, 123; R.79(1), R.79(2), R.116(1) | +| `epa.opp.boa` | EPA Beschwerde | 8 | EPC Art. 108, 112a; R.116(1); RPBA Art. 12 | + +### 2.3 DPMA + +3 active types, 13 rules. + +| Code | Name | Rule count | Audited against | +|---|---|---:|---| +| `dpma.opp.dpma` | DPMA Einspruch | 4 | PatG §59(1), §59(3) | +| `dpma.appeal.bpatg` | BPatG-Beschwerde | 5 | PatG §73(2), §74 ff. | +| `dpma.appeal.bgh` | BGH-Rechtsbeschwerde | 4 | PatG §100, §102 | + +### 2.4 DE (national patent / civil) + +5 active types, 29 rules. + +| Code | Name | Rule count | Audited against | +|---|---|---:|---| +| `de.inf.lg` | LG-Verletzungsklage | 8 | ZPO §253, §276, §283, §296a, §517, §520(2) | +| `de.inf.olg` | OLG-Berufung Verletzung | 7 | ZPO §517, §520(2), §521(2), §524(2) | +| `de.inf.bgh` | BGH-Revision Verletzung | 8 | ZPO §544, §548, §551, §554 | +| `de.null.bpatg` | BPatG-Nichtigkeitsklage | 10 | PatG §81 ff., §82, §83 | +| `de.null.bgh` | BGH-Nichtigkeitsberufung | 6 | PatG §110, §111 / ZPO ref via §117 PatG | + +### 2.5 Cross-cutting: cascade vs proceeding-tree coverage + +The cascade layer (`paliad.event_categories` + `…_concepts` + +`paliad.deadline_concepts`) carries 56 concept "nouns" and ~153 +cascade-leaf → concept mappings. **9 concepts are orphans** (carry +zero rules, so the cascade card dead-ends): `counterclaim-for-revocation`, +`schriftsatznachreichung`, `versaeumnisurteil-einspruch`, +`weiterbehandlung`, `wiedereinsetzung`, `notice-of-defence-intention`, +plus 3 more. Inventory and recommendations live in +`docs/audit-fristen-logic-2026-05-13.md` §3.4 — this audit covers only +the proceeding-tree side. + +--- + +## §3. Findings — Missing rules (statute defines, paliad doesn't) + +### 3.1 UPC RoP — 21 missing rules (out of ~25 flagged 2026-05-08, 4 closed by mig 095) + +Notation: ★★★ every case, ★★ common, ★ specialist. Verbatim RoP text +sampled from youpc `data.laws_contents` (law_type=`UPCRoP`, lang=en). + +| RoP § | Period | Trigger | Freq | Notes | +|---|---|---|---|---| +| **R.20.2** | 14 days | Service of Preliminary Objection | ★ | Reply to PO. Companion to R.19 (which mig 095 added). Without R.20.2 the PO branch is half-modelled. | +| **R.118.4** | 2 months | Final decision on validity served | ★★ | Application for orders consequential on validity. Common after central-division revocation. | +| **R.118.5** | n/a UPC | n/a | n/a | UPC has no Versäumnisurteil-Einspruch; closest is R.355 (review of contumacy). | +| **R.144** | 0 (anchor) | Final decision on damages quantum | ★ | UPC_DAMAGES tree end-row missing. | +| **R.155** | 1mo / 14d | Cost-decision opposition chain | ★ | UPC_COST_APPEAL only has the leave-to-appeal step; no Defence-to-cost-app row. | +| **R.197.3** | 30 days | Saisie order served on respondent | ★ | Review application. Trigger event 65 exists; no rule attached. | +| **R.198** | 31 calendar days **OR 20 working days, whichever is longer** | Saisie executed | ★ | Start proceedings on the merits. Blocked on `working_days` + `combine='max'` primitives (see §7 + §9). | +| **R.207.6.a** | 14 days | Notification of deficiency in PI application | ★★ | Registry correction. | +| **R.207.9** | 6 months | PI filed | ★ | Renewal of protective letter. | +| **R.213** | 31 days OR 20 working days | PI granted | ★★ | Same arithmetic gap as R.198. | +| **R.109.1** | 1 month **before** | Oral hearing date | ★★ | Simultaneous translation request. `timing='before'` schema supported but no rule populates it (see §7 cross-cutting). | +| **R.109.4** | 2 weeks **before** | Oral hearing date | ★★ | Interpreter cost notification. `timing='before'`. | +| **R.109.5** | 2 weeks after | Order of judge-rapporteur to lodge translations | ★★ | trigger event 113 exists; no rule. | +| **R.224.2.b** | 15 days | Order under R.220.1(c) or decision under R.220.2/221.3 served | ★★ | Grounds-on-orders track. `upc.apl.order` has appeal-itself but no separate grounds row. Verified verbatim against `UPCRoP.224.2.b` (youpc DB). | +| **R.229.2** | 14 days | Notification of appeal-deficiency | ★ | Registry correction in appeal context. | +| **R.235.2** | 15 days | Statement of grounds (orders track) served | ★★ | Verified verbatim against `UPCRoP.235.2` (youpc DB): *"Within 15 days of service of grounds of appeal pursuant to Rule 224.2(b), any other party … may lodge a Statement of response"*. `upc.apl.order` has no standalone response row. | +| **R.245.1** | 2 months | Final decision served | ★ | Application for rehearing. | +| **R.245.2.a** | 2 months | Discovery of fundamental defect (or final decision service, whichever is later) | ★ | Outer cap 12mo. Needs multi-anchor + `max-of-two-anchors` arithmetic. | +| **R.245.2.b** | 2 months | Discovery of criminal offence (or final decision service, whichever is later) | ★ | Same shape as 245.2.a. | +| **R.262.2** | 14 days | Receipt of opposing party's confidentiality application | ★★ | Daily occurrence in HLC infringement work. Trigger event 25 exists; no rule. | +| **R.320** | 2 months (cap 12 mo) | Wegfall des Hindernisses (Wiedereinsetzung) | ★★ | Cascade card exists (mig 063) but no proceeding-tree rule computes the deadline. Bridges proceedings → no obvious home in any one tree. | +| **R.321.3** | 10 days | Preliminary objection referral to central division | ★ | | +| **R.333.2** | 15 days | Case-management order served | ★★ | Review-of-CMO. Routine in busy LDs. | +| **R.353** | 1 month | Decision / order delivered | ★ | Rectification application. | +| **DNI: R.63 / R.67.1 / R.69.1 / R.69.2** | 0 / 2mo / 1mo / 1mo | DNI cascade | ★ | No UPC_DNI proceeding_type exists. Fringe at HLC (zero published filings in 2026-Q1 per May 8 audit). | +| **Registry-correction family: R.16.3.a, R.27.2, R.89.2, R.253.2** | 14 days each | Various deficiency notifications | ★ | All same 14-day duration; different trigger codes. Most natural home is cascade not proceeding-tree (see audit-fristenrechner-completeness-2026-04-30.md §3.1). | + +**Closed since May 8 audit (verified by SQL):** +- ✅ R.19 Preliminary Objection on UPC_INF — `upc.inf.cfi.prelim`, 1mo, RoP.019.1, flag-gated `with_po` — mig 095. +- ✅ R.19 Preliminary Objection on UPC_REV — `upc.rev.cfi.prelim`, 1mo, RoP.019.1, flag-gated `with_po` — mig 095 (cites R.19 i.V.m. R.46). +- ✅ R.220.1(a) merits-appeal spawn on UPC_INF — `upc.inf.cfi.appeal_spawn`, 2mo, is_spawn=true → upc.apl.merits — mig 095. +- ✅ R.220.1(a) merits-appeal spawn on UPC_REV — `upc.rev.cfi.appeal_spawn`, 2mo, is_spawn=true → upc.apl.merits — mig 095. + +### 3.2 EPC Implementing Regulations — 4 missing rules + +| EPC ref | Period | Trigger | Freq | Notes | +|---|---|---|---|---| +| **EPC R.135 (Weiterbehandlung)** | 2 months | Notification of loss of rights | ★★ | Concept `weiterbehandlung` exists in cascade (orphan); no rule. Applies broadly across `epa.grant.exa` and `epa.opp.opd`. | +| **EPC R.99(2) / Art. 121** | 2 months | Loss-of-rights notification (further processing) | ★★ | Same family as R.135. | +| **EPC Art. 112a(4)** | 2 months / 1 month | Discovery of grounds for review / decision served (whichever later) | ★ | paliad has `epa.opp.boa.r106` (2 months, parent=entsch2) — but the rule doesn't model the "whichever later" outer cap (12 months from decision per Art. 112a(4)). | +| **EPC Art. 99(1) — opposition fee paid** | 9 months (no extension) | Mention of grant in Patentblatt | ★★★ | `epa.opp.opd.frist` IS modelled correctly at 9 months. **Note however:** the rule is on `epa.opp.opd` but the *trigger* is opposition-fee-paid (per Art. 99(1) S.2 — "Notice of opposition shall not be deemed to have been filed until the opposition fee has been paid"). Not a gap, but a documentation note. | + +### 3.3 PatG / ZPO — 5 missing rules + +| Citation | Period | Trigger | Freq | Notes | +|---|---|---|---|---| +| **PatG §123 (Wiedereinsetzung)** | 2 months | Wegfall des Hindernisses (cap 1 year) | ★★ | Cascade concept `wiedereinsetzung` exists; no rule on any DE/DPMA proceeding tree. Same modelling problem as UPC R.320 — bridges proceedings. | +| **ZPO §339 (Versäumnisurteil-Einspruch)** | 2 weeks | Service of default judgment | ★ | Cascade concept `versaeumnisurteil-einspruch` orphan. | +| **ZPO §544 — Nichtzulassungsbeschwerde-Begründung** | 2 months | Service of OLG-Urteil (NB: NOT from filing of NZB) | ★★ | `de.inf.bgh.nzb_begr` lists `DE.ZPO.544.4`, duration 2mo, parent=urteil_olg — **modelled correctly**. Listed here only to flag that the *parent anchoring* differs from `de.inf.lg.beruf_begr` which is wrong (see §7.1). | +| **ZPO §283 (Schriftsatznachreichung) / §296a** | court-set | post-Verhandlung schriftsatzfrist | ★ | Cascade concept `schriftsatznachreichung` orphan. Court-set period — modelling as `is_court_set=true, duration=0` would suffice. | +| **PatG §17(2) GebrMG / §18 GebrMG** | 1 month (Beschwerdefrist) | DPMA-Beschluss | ★ | Out of scope per head's confirmation (no GebrMG-rooted proceeding_type yet). Listed to confirm the deliberate gap. | + +### 3.4 DPMA — 0 missing rules + +DPMA coverage is shallow but not gappy. The 3 active types (opposition, +BPatG-Beschwerde, BGH-Rechtsbeschwerde) cover the statutory steps. The +problems here are **citation drift** (§4.4) and **anchor modeling** +(§7.4) rather than missing rules. + +--- + +## §4. Findings — Misattributed legal source + +### 4.1 UPC RoP citation drift (5 still live from May 8) + +| Rule | Live `rule_code` | Live `legal_source` | Should be | Source verified | +|---|---|---|---|---| +| `upc.apl.merits.notice` | `RoP.220.1` | `UPC.RoP.220.1` | `RoP.224.1.a` / `UPC.RoP.224.1.a` | `UPCRoP.224.1.a` youpc DB | +| `upc.apl.merits.grounds` | `RoP.220.1` | `UPC.RoP.220.1` | `RoP.224.2.a` / `UPC.RoP.224.2.a` | `UPCRoP.224.2.a` | +| `upc.apl.merits.response` | `null` | `null` | `RoP.235.1` / `UPC.RoP.235.1` | `UPCRoP.235.1` | +| `upc.rev.cfi.reply` | `null` | `null` | `RoP.051` / `UPC.RoP.51.p1` | `UPCRoP.051.p1` | +| `upc.rev.cfi.rejoin` | `null` | `null` | `RoP.052` / `UPC.RoP.52.p1` | `UPCRoP.052.p1` | + +Note on cascade vs proceeding-tree drift on R.220.3 anchoring is in +`docs/audit-upc-rop-deadlines-2026-05-08.md` §5.4b — unchanged here. + +### 4.2 UPC RoP citation drift on Rule 49.1 format (1 still live) + +| Rule | Live `rule_code` | Should be | +|---|---|---| +| `upc.rev.cfi.defence` | `RoP.49.1` | `RoP.049.1` (canonical zero-padded form used by all other UPC rules) | + +### 4.3 DPMA — 3 mis-attributed citations + +| Rule | Live citation | Problem | Verified | +|---|---|---|---| +| `dpma.opp.dpma.erwiderung` | `§ 59 PatG` / `DE.PatG.59.3` | §59(3) PatG addresses *Anhörung*, not a 4-month response period. No statutory Erwiderungsfrist exists in §59. The 4-month figure is DPMA-internal practice. | WebFetch [gesetze-im-internet.de/patg/__59.html](https://www.gesetze-im-internet.de/patg/__59.html) 2026-05-25 | +| `dpma.appeal.bpatg.begruendung` | `§ 75 PatG` / `DE.PatG.75.1` | §75 PatG is exclusively about *aufschiebende Wirkung* (suspensive effect). It does not establish any Begründungsfrist. No fixed Begründungsfrist for BPatG-Beschwerde exists in PatG §§73-80 — it is set by the BPatG in the individual case. | WebFetch [gesetze-im-internet.de/patg/__75.html](https://www.gesetze-im-internet.de/patg/__75.html) + [§73](https://www.gesetze-im-internet.de/patg/__73.html) 2026-05-25 | +| `dpma.appeal.bpatg.beschwerde` | `§ 73 PatG` / `DE.PatG.73.2` | §73 contains the 1-month deadline correctly; the `.2` subscript however refers to §73(2) which is about Beschwerdebefugnis — the *Frist* is in §73(2) S.4 ("Die Beschwerdefrist beträgt einen Monat …"). Citation should be `DE.PatG.73.2.s4` or simply `DE.PatG.73.2`. **Borderline — flag, not a hard bug.** | gesetze-im-internet.de | + +### 4.4 DE patent / civil — 4 mis-attributed citations + +| Rule | Live citation | Problem | Verified | +|---|---|---|---| +| `de.null.bpatg.erwidg` | `§ 82 PatG` / `DE.PatG.82.1` | §82(1) is the 1-month *Erklärungsfrist* ("sich darüber zu erklären"); the 2-month full *Klageerwiderung* is in §82(3). Citation should be `DE.PatG.82.3`. Duration (2 months) is correct. | WebFetch [§82](https://www.gesetze-im-internet.de/patg/__82.html) 2026-05-25 | +| `de.null.bpatg.replik_klaeger` | `§ 83 PatG` / `DE.PatG.83.2` | §83(2) is about the *Hinweisbeschluss* form; the Replik / Schriftsatz windows fall under §83(2) S.3 (Reaktion auf Hinweis). Citation OK at section level but ambiguous. **Borderline — flag, not a hard bug.** | gesetze-im-internet.de | +| `de.null.bgh.begruendung` | `§ 111 PatG` / `DE.PatG.111.1` | §111 PatG defines the *Grounds* of Berufung (Verletzung des Bundesrechts), not a Begründungsfrist. The 3-month figure is supplied via §117 PatG → ZPO §520(2). Citation should be `DE.ZPO.520.2` (the actual time-limit source). | WebFetch [§111](https://www.gesetze-im-internet.de/patg/__111.html) 2026-05-25 | +| `de.null.bgh.erwiderung` | `§ 111 PatG` / `DE.PatG.111.3` | §111 has no Erwiderungsfrist clause. The actual Erwiderungsfrist for BGH-Nichtigkeitsberufung is set by the court per §117 PatG → ZPO §521(2) (court-discretionary). Duration (2 months) is approximate — typical court-set period is 2 months but it's not fixed. **Should be modelled as court-set.** | WebFetch [§111](https://www.gesetze-im-internet.de/patg/__111.html) + ZPO §521 2026-05-25 | + +### 4.5 EPA — 1 mis-attributed citation + +| Rule | Live citation | Problem | +|---|---|---| +| `epa.opp.opd.erwidg` | `R. 79(1) EPÜ` / `EU.EPC-R.79.1` | Duration (4 months) is correct as the *typical* EPO-set period under the 2016 streamlined-opposition guidelines, but **R.79(1) does not specify a fixed period** — the Opposition Division sets it. The 4 months is administrative practice (EPO Guidelines D-IV, 5.2). Should be modelled as court-set with 4 months as the default-display value. | + +--- + +## §5. Findings — Wrong period (statute says X, paliad says Y) + +| Rule | Live period | Statutory period | Source | Freq | +|---|---|---|---|---| +| **`upc.rev.cfi.defence`** | 3 months | **2 months** | RoP.049.1: *"The defendant shall lodge a Defence to revocation within two months of service of the Statement for revocation."* — verified verbatim from `UPCRoP.049.1` (youpc DB). Flagged 2026-05-08; still live. | ★★★ | +| **`upc.rev.cfi.rejoin`** | 2 months | **1 month** | RoP.052: *"Within one month of the service of the Reply the defendant may lodge a Rejoinder to the Reply to the Defence to revocation"* — verified verbatim from `UPCRoP.052.p1`. Flagged 2026-05-08; still live. | ★★★ | +| **`upc.apl.merits.response`** | 2 months | **3 months** | RoP.235.1: *"Within three months of service of the Statement of grounds of appeal pursuant to Rule 224.2(a), any other party … may lodge a Statement of response"* — verified verbatim from `UPCRoP.235.1`. New finding — May 8 audit recorded the duration as 3 months but the live row has always been 2 (migration 012:153 originally seeded 2). | ★★★ | +| **`upc.pi.cfi.response`** | 0 / "court-set" (`is_court_set=false`, `duration=0`, `parent_id=NULL`) | court-set, judge-discretion under R.211.2 | RoP.211.2 — judge sets the inter-partes hearing date. Modelling is half-broken: `duration=0` with `parent_id=NULL` makes the calculator treat this as a root anchor rather than a court-set placeholder. Should set `is_court_set=true` and chain `parent_id=app`. | ★★ | + +(All other rules audited have correct durations.) + +--- + +## §6. Findings — Wrong party + +No clear party mis-assignments found in the live data. Two notes worth +recording, not bugs: + +- `upc.inf.cfi.app_to_amend` carries `primary_party='claimant'`. The + defendant in an INF case is the alleged infringer; the patent + proprietor (=claimant) is who would file an Application to Amend + the patent. **Correct.** Listed here only because R.30 reads "the + defendant" in some summaries — those refer to the claimant of the + CCR (= defendant of the INF), which loops back to the same person + who is the INF-claimant / patent-proprietor. +- `dpma.opp.dpma.erwiderung` carries `primary_party='defendant'`. In an + EPA-style opposition, the patent proprietor is the "defendant" of the + opposition. Consistent with EPA convention. **Correct.** + +--- + +## §7. Findings — Wrong sequencing / anchoring + +### 7.1 `de.inf.lg.beruf_begr` chains parent = `berufung`, should anchor on `urteil` directly + +| Live | Per ZPO §520(2) | +|---|---| +| `de.inf.lg.beruf_begr.parent_id = de.inf.lg.berufung`, `duration = 2 months` → effective end = trigger + 1mo (Berufung) + 2mo = **3 months** after Urteil service | "Die Frist für die Berufungsbegründung beträgt zwei Monate. Sie beginnt mit der Zustellung des in vollständiger Form abgefassten Urteils" → **2 months** after Urteil service | + +Verified verbatim via WebFetch +[gesetze-im-internet.de/zpo/__520.html](https://www.gesetze-im-internet.de/zpo/__520.html) +2026-05-25. + +The companion `de.inf.olg.begruendung` is **correct** — parent = +`urteil_lg`, 2mo, so end = Urteil + 2mo. Same statute, two paliad +rules, two different anchorings: this is a real bug in `de.inf.lg`. + +### 7.2 `de.inf.lg.replik` and `de.inf.lg.duplik` have `parent_id = NULL` + +This is the bug head flagged. Live data: + +| submission_code | name | duration | parent_id | sequence_order | +|---|---|---|---|---| +| `de.inf.lg.klage` | Klageerhebung | 0 mo | NULL | 0 | +| `de.inf.lg.anzeige` | Anzeige Verteidigungsbereitschaft | 2 wk | `de.inf.lg.klage` | 10 | +| `de.inf.lg.erwidg` | Klageerwiderung | 6 wk | `de.inf.lg.klage` (court-set=true post mig 095) | 20 | +| **`de.inf.lg.replik`** | Replik | **4 wk** | **NULL** | 30 | +| **`de.inf.lg.duplik`** | Duplik | **4 wk** | **NULL** | 40 | +| `de.inf.lg.termin` | Haupttermin | 0 mo | NULL (court-set) | 50 | +| `de.inf.lg.urteil` | Urteil | 0 mo | NULL (court-set) | 60 | +| `de.inf.lg.berufung` | Berufungsfrist | 1 mo | NULL | 70 | +| `de.inf.lg.beruf_begr` | Berufungsbegründung | 2 mo | `de.inf.lg.berufung` | 80 | + +With `parent_id = NULL` the calculator anchors Replik on the +triggerDate (= Klageerhebung), and same for Duplik. So both render +"4 Wochen ab Klageerhebung" — i.e. before the Klageerwiderung is +even due. Correct chain should be: + +- `replik.parent_id = de.inf.lg.erwidg`, with `is_court_set = true` (richterliche Frist § 276(1) S.2 / § 283 ZPO — typ. 4 weeks default) +- `duplik.parent_id = de.inf.lg.replik`, same shape + +Both rules lack `legal_source` and `rule_code`, which is consistent +with them being court-set Schriftsatzfristen (no statutory clamp). +Recommendation in §10. + +### 7.3 `upc.apl.merits.grounds` has `parent_id = NULL` + +This anchors Grounds on the user-supplied trigger date (=Entscheidung +service). **Correct** behaviour per RoP.224.2.a: *"within four months +of service of a decision referred to in Rule 220.1(a) and (b)"*. + +If `parent_id` were set to `upc.apl.merits.notice` (as the May 8 audit +hypothesised), the chain would compound (1-day notice + 4mo grounds = +~4mo + 1 day), accidentally landing near the right end-date for the +common case but wrong by up to 2 months in the edge case (when notice +is filed early). **No fix needed; document the intent.** (This is +the change the May 8 audit recommended; it was applied in mig 097 or +earlier.) + +### 7.4 DPMA Pathway-A anchors are partially modelled + +- `dpma.appeal.bgh.begruendung` chains parent = `rechtsbeschwerde` + (1mo + 1mo = 2mo from BPatG-Entscheidung). Per PatG §102 the + Rechtsbeschwerdebegründungsfrist is 1 month from filing of the + Rechtsbeschwerde — **correct**. +- `dpma.appeal.bpatg.begruendung` chains parent = `beschwerde` + (1mo + 1mo = 2mo from DPMA-Entscheidung). **No statutory basis for + the 1-month figure** (see §4.3). Should be court-set. + +### 7.5 EPA grant timeline — `epa.grant.exa.r71_3` and `.approval` have `parent_id = NULL` + +Live: + +| Rule | Duration | parent_id | Issue | +|---|---|---|---| +| `epa.grant.exa.r71_3` | 0 mo | NULL | Should chain on `exam_req` (after examination request is granted, EPO issues R.71(3) communication). NULL parent + 0 duration = root anchor at trigger date — works only if user enters the R.71(3) date as trigger; doesn't compose with the rest of the tree. | +| `epa.grant.exa.approval` | 4 mo | NULL | Per R.71(3) approval period: 4 months from notification. **Anchor should be `r71_3`**, not NULL. As-is, "Zustimmung + Übersetzung" appears as a free-standing 4-mo-from-trigger row that has nothing to do with the rest of the timeline. | + +### 7.6 Summary + +| # | Rule | Bug | +|---|---|---| +| 1 | `de.inf.lg.beruf_begr` | parent should be NULL (anchored on Urteil-trigger) not `berufung` — off by 1 month, ★★★ | +| 2 | `de.inf.lg.replik` | parent should be `erwidg` not NULL, ★★★ | +| 3 | `de.inf.lg.duplik` | parent should be `replik` not NULL, ★★★ | +| 4 | `dpma.appeal.bpatg.begruendung` | should be court-set; current 1-month period has no statutory basis, ★★ | +| 5 | `dpma.appeal.bpatg.beschwerde` parent is `entscheidung` — OK, just a citation issue (§4.3) | (citation only) | +| 6 | `epa.grant.exa.r71_3` parent | should chain on `exam_req`, ★ | +| 7 | `epa.grant.exa.approval` parent | should chain on `r71_3`, ★ | +| 8 | `upc.pi.cfi.response` | court-set placeholder with `parent_id=NULL` and `is_court_set=false` — should chain on `app` with `is_court_set=true`, ★★ | + +--- + +## §8. Findings — Duplicates + +No genuine duplicates. The closest cases: + +- `upc.inf.cfi.reply` + `upc.inf.cfi.def_to_ccr` both fire at 2mo after + `sod` under `with_ccr`. They cover different actions (Reply to SoD + vs. Defence to CCR + Reply to SoD combined) per RoP.029.a vs .b. + **Not a duplicate** — distinct rule codes. +- `upc.rev.cfi.reply` (2mo, no rule_code) and the older `REV.rev_reply` + on the archived litigation type — the archived type is hidden + (`pt.is_active = false`) so this isn't a duplicate the user sees. + Recommendation in §10 to drop the archived corpus once mig 093's + audit window closes. +- `epa.opp.boa.r106` (Art. 112a review) appears only on + `epa.opp.boa`, not on `epa.opp.opd` — correct, since Art. 112a + review is only available against a Boards-of-Appeal decision. + +--- + +## §9. Ambiguities — decisions m needs to make + +These are not bugs the coder can fix. They are judgement calls about +how to model the law. + +### 9.1 Court-set vs fixed-period for richterliche Fristen + +The cleanest source-of-truth for these is "no statutory duration — +court sets the period in the individual case." Modelling them as a +fixed period with a wrong citation is the bug pattern we keep finding: + +- `dpma.opp.dpma.erwiderung` (4 mo) — DPMA practice, not §59 PatG. +- `dpma.appeal.bpatg.begruendung` (1 mo) — no statutory basis. +- `de.inf.olg.erwiderung` (1 mo, §521(2)) — §521(2) is explicitly + discretionary ("Der Vorsitzende oder das Berufungsgericht **kann** + der Gegenpartei eine Frist … bestimmen"). Verified WebFetch + [gesetze-im-internet.de/zpo/__521.html](https://www.gesetze-im-internet.de/zpo/__521.html) + 2026-05-25. +- `de.null.bgh.erwiderung` (2 mo, "§111(3) PatG") — court-set per §117 + PatG → ZPO §521(2). +- `de.null.bpatg.duplik` (1 mo, §83 PatG) — court-set; the 1-month + default is BPatG practice. +- `de.inf.lg.replik`, `.duplik` (4 wk each) — court-set per + §283 / §296a ZPO + §276(1) S.2. +- `epa.opp.opd.erwidg` (4 mo, "R.79(1)") — EPO-set per Guidelines. + +**Question (Q1):** Should paliad continue to display these with a +default duration but flag them as "richterliche Frist — vom Gericht +festgesetzt", OR should they all flip to `is_court_set=true, +duration=0` and force the user to enter the actual court-set date? + +Head's 2026-05-25 13:13 signal confirms: m's preference is that "Frist +vom Gericht bestimmt" be flagged as needing case-by-case anchoring, +not displayed as a fixed period. So default answer = flip to +`is_court_set=true` and keep the typical period as the *Default* +display value (the calculator already supports this since the +mig 095 / `de.inf.lg.erwidg` patch). But the trade-off is a UX +regression: most users will not enter the actual court-set date +and the timeline will then show "vom Gericht bestimmt" everywhere. + +### 9.2 R.198 / R.213 "31 days OR 20 working days, whichever is longer" + +Two RoP rules need a primitive paliad doesn't have: +- A `working_days` duration unit (counts business-day arithmetic via + the holiday service). +- A `combine = 'max'` operator that compares two durations and picks + the later end-date. + +**Question (Q2):** Implement the primitive (~120 LoC migration + ~80 LoC +Go), or document both rules as "manual calculation required, see RoP" +in the UI? Real R.198 / R.213 cases are rare (saisie + PI). The May 8 +audit suggested deferring; pauli's 2026-05-13 audit §7.1 made the +case for adding `combine_op` as part of a broader Pipeline A/C merge. + +### 9.3 R.245.2 rehearing "whichever is later" trigger + +R.245.2.a/b: deadline 2 months from final decision OR from defect +discovery, whichever is *later*. Plus outer cap 12 months. Needs: + +- Multi-anchor trigger event (user supplies 2 dates). +- `combine = 'max'` between anchors. +- Outer-cap arithmetic (separate concept from duration). + +**Question (Q3):** Defer (specialist, vanishingly rare) or build the +primitives? + +### 9.4 EPC Art. 112a review — outer cap + +Same shape as R.245.2: 2 months from defect discovery, outer cap 12 +months from decision. `epa.opp.boa.r106` models the 2-month period +but not the cap. + +### 9.5 PatG §123 Wiedereinsetzung calendar arithmetic + +Cascade card (slug `wiedereinsetzung`) exists. The 2mo / 1-year +arithmetic anchors on the *missed* deadline, not on a forward-looking +event. paliad's `paliad.deadline_rules` schema has no natural shape +for this — it would need either a special-case Go helper, or a +"backward-from-missed-deadline" mode that no rule today uses. + +**Question (Q4):** Worth modelling? The cascade card already routes +the user to the concept; computing the calendar deadline is an +incremental win. + +### 9.6 ZPO §339 Versäumnisurteil-Einspruch + +Cascade card orphan. 2 weeks from service of the default judgment. +Trivial to add as a `de.inf.lg.einspruch_vu` rule (court-decision +anchor + 2wk fixed). **Question (Q5):** Add as a child of +`de.inf.lg.urteil` (with `condition_expr={"flag":"with_vu"}`), or +as a separate proceeding `de.inf.lg.vu`? + +### 9.7 Litigation-vs-fristenrechner archived corpus + +The 40 rules on `_archived_litigation` (mig 093 retirement holding pen) +still occupy the rule table. They're invisible to all UIs. + +**Question (Q6):** Drop them now (data clean-up), or keep until the +mig 093 audit window closes formally? + +### 9.8 R.79(2) further-party observations period + +EPC R.79(2) creates a separate notification window for additional +opponents. paliad's `epa.opp.opd.r79_further` is modelled as +`duration=0, is_bilateral=true`. **Question (Q7):** Is this even worth +keeping? Real workflow: EPO sets a separate period in each +intervention case. Hard to template. + +### 9.9 R.116(1) EPC oral-proceedings cut-off + +paliad has it as `duration=0, parent_id=entsch` (`epa.opp.opd.r116`) / +`parent_id=oral` (`epa.opp.boa.r116`). R.116(1) actually says the +EPO sets a "final date for making written submissions" when issuing +the summons. So it's a court-set period, not zero-duration. +**Question (Q8):** flip to `is_court_set=true` like the §276(1) ZPO +fix in mig 095? + +### 9.10 R.131.2 indication of damages period + +paliad models `upc.dmgs.cfi.app` as a 0-duration root anchor (court +sets when the damages-determination phase opens, per R.131.2). This +is correct shape but means the entire damages tree is unanchored +until the user provides the trigger date manually. + +**Question (Q9):** Wire `is_spawn` from `upc.inf.cfi.decision` to +`upc.dmgs.cfi.app` (parallel to the mig-095 appeal-spawn)? + +### 9.11 PatG §17 GebrMG / §18 GebrMG + +No GebrMG-rooted proceeding_type exists in paliad. Head confirmed +out-of-scope for this audit. **Question (Q10):** Add a `de.gm.lg` +proceeding for GebrMG-Löschungsverfahren if HLC sees them? + +### 9.12 Proceeding-tree vs cascade parity + +paliad has 9 cascade-only concepts with `rule_count = 0` (the orphans +listed in `audit-fristen-logic-2026-05-13.md` §3.4). The audit-fristen +audit covers this; restating here only to note that the parity gap +is the largest single source of "the cascade card promises a +calculation but doesn't deliver one." + +**Question (Q11):** Same as the audit-fristen Q8 — priority order +for the 9 orphan concepts? My ranking: wiedereinsetzung > +schriftsatznachreichung > versäumnisurteil-einspruch > +weiterbehandlung > rest. + +### 9.13 R.220.3 anchor + +See `audit-upc-rop-deadlines-2026-05-08.md` §5.4b. paliad anchors +`upc.apl.order.discretion` on the original order (`order`), but +the 15-day clock per RoP.220.3 runs from the refusal-of-leave +date (or day-15 fall-back). Off by up to 15 days in the edge case. +**Question (Q12):** add an explicit `app_ord.refusal` court-set +intermediate node? + +### 9.14 EP_GRANT publish date — priority vs filing + +`epa.grant.exa.publish` correctly has `anchor_alt='priority_date'`. +This was open in the May 8 audit and is now closed. **No question — +listed to confirm.** + +### 9.15 Cross-proceeding spawn execution + +mig 095 added two `is_spawn=true` rules (`inf.appeal_spawn`, +`rev.appeal_spawn` → `upc.apl.merits`). The May 13 audit §1.6 + +§6.8 noted spawn execution is half-wired in `projection_service.go`. +**Question (Q13):** wire end-to-end now (so the spawned appeal +timeline appears in SmartTimeline), or accept the half-wired state? + +--- + +## §10. Recommended fixes (prioritised) + +### Tier 0 — hard duration / sequencing / anchor bugs (ship first) + +| # | Rule | Fix | Reason / source | Freq | +|---|---|---|---|---| +| T0.1 | `upc.rev.cfi.defence` | `duration_value = 2` (was 3), `rule_code = 'RoP.049.1'`, `legal_source = 'UPC.RoP.49.1'` | §5 — every UPC_REV tracked in paliad today computes Defence at wrong month for the last ~3 months | ★★★ | +| T0.2 | `upc.rev.cfi.rejoin` | `duration_value = 1` (was 2), `rule_code = 'RoP.052'`, `legal_source = 'UPC.RoP.52.p1'` | §5 — same as T0.1 | ★★★ | +| T0.3 | `upc.apl.merits.response` | `duration_value = 3` (was 2), `rule_code = 'RoP.235.1'`, `legal_source = 'UPC.RoP.235.1'` | §5 — every main-track appellate respondent | ★★★ | +| T0.4 | `de.inf.lg.beruf_begr` | `parent_id = NULL` (was `de.inf.lg.berufung`) — runs 2 months from triggerDate (Urteil-service) per ZPO §520(2) | §7.1 — every DE-LG-Verletzung appeal | ★★★ | +| T0.5 | `de.inf.lg.replik` | `parent_id = de.inf.lg.erwidg`, `is_court_set = true` (richterliche Frist § 276(1) S.2 / § 283 ZPO), keep 4-week default | §7.2 — bug head flagged | ★★★ | +| T0.6 | `de.inf.lg.duplik` | `parent_id = de.inf.lg.replik`, `is_court_set = true` | §7.2 | ★★★ | +| T0.7 | `upc.rev.cfi.reply` | `rule_code = 'RoP.051'`, `legal_source = 'UPC.RoP.51.p1'` (duration 2mo unchanged) | §4.1 | ★★★ | +| T0.8 | `upc.rev.cfi.rejoin` (citation only) | covered in T0.2 | — | — | +| T0.9 | `upc.apl.merits.notice` | `rule_code = 'RoP.224.1.a'`, `legal_source = 'UPC.RoP.224.1.a'` (duration unchanged) | §4.1 | ★★ | +| T0.10 | `upc.apl.merits.grounds` | `rule_code = 'RoP.224.2.a'`, `legal_source = 'UPC.RoP.224.2.a'` (duration unchanged) | §4.1 | ★★ | +| T0.11 | `upc.rev.cfi.defence` rule_code zero-pad | covered in T0.1 | — | — | +| T0.12 | `dpma.opp.dpma.erwiderung` | flip to `is_court_set = true`, keep 4-month default-display value, drop the misleading `DE.PatG.59.3` citation (or replace with "DPMA-Richtlinien D-IV 5.2") | §4.3 + §9.1 | ★★ | +| T0.13 | `dpma.appeal.bpatg.begruendung` | flip to `is_court_set = true`, drop the `DE.PatG.75.1` citation, keep 1-month default | §4.3 + §9.1 | ★★ | +| T0.14 | `de.null.bpatg.erwidg` | citation `DE.PatG.82.3` (was 82.1); duration (2mo) correct | §4.4 | ★★ | +| T0.15 | `de.null.bgh.begruendung` | citation `DE.ZPO.520.2` via PatG §117 (was DE.PatG.111.1); duration (3mo) correct | §4.4 | ★★ | +| T0.16 | `de.null.bgh.erwiderung` | flip to `is_court_set = true`; citation `DE.ZPO.521.2 via PatG §117` (was DE.PatG.111.3); duration (2mo) becomes default-display | §4.4 + §9.1 | ★★ | +| T0.17 | `epa.opp.opd.erwidg` | flip to `is_court_set = true`, keep 4-month default | §4.5 + §9.1 | ★★ | + +**16 hard fixes.** All within the existing schema (no new columns). +Each is a single-row UPDATE plus an audit-log entry. + +### Tier 1 — high-value missing rules (★★ / ★★★) + +| # | Rule | Add | Freq | +|---|---|---|---| +| T1.1 | `upc.inf.cfi.cmo_review` | 15 days from CMO service (R.333.2) | ★★ | +| T1.2 | `upc.inf.cfi.confidentiality_response` | 14 days from opp. confidentiality app (R.262.2) | ★★ | +| T1.3 | `upc.apl.order.grounds_orders` | 15 days from order service (R.224.2(b)) | ★★ | +| T1.4 | `upc.apl.order.response_orders` | 15 days from grounds service (R.235.2) | ★★ | +| T1.5 | `upc.inf.cfi.cons_orders` | 2 months from validity decision (R.118.4) | ★★ | +| T1.6 | `upc.inf.cfi.rectification` | 1 month from decision (R.353) | ★ | +| T1.7 | `upc.pi.cfi.deficiency` | 14 days from PI deficiency notification (R.207.6.a) | ★★ | +| T1.8 | `upc.pi.cfi.merits_start` | 31d OR 20wd from PI grant (R.213) — **blocked on Q2** | ★★ | +| T1.9 | `upc.inf.cfi.translation_request` | 1 month **before** oral hearing (R.109.1) | ★★ | +| T1.10 | `upc.inf.cfi.interpreter_cost` | 2 weeks **before** oral hearing (R.109.4) | ★★ | +| T1.11 | `upc.inf.cfi.translations_lodge` | 2 weeks after summons (R.109.5) | ★★ | +| T1.12 | `upc.pi.cfi.response` re-anchor | court-set, parent=`app` (currently a broken root) | ★★ | + +**12 rule-adds.** T1.9/.10 are the only `timing='before'` rules in the +entire UPC corpus; schema already supports `before` but no rule +populates it. Verify the backward-snap-to-working-day logic in +`internal/services/deadline_calculator.go` before merging +(2026-04-30 audit §5.4 raised the concern). + +### Tier 2 — broader coverage (★ specialist + Wiedereinsetzung family) + +| # | Rule | Add | Notes | +|---|---|---|---| +| T2.1 | `de.inf.lg.einspruch_vu` | 2 weeks from service of Versäumnisurteil (ZPO §339) | Q5 — proceeding shape decision | +| T2.2 | `upc.inf.cfi.wiedereinsetzung` | 2 mo / 1-year-cap from Wegfall des Hindernisses (R.320) | Q4 — needs special arithmetic | +| T2.3 | `de.inf.lg.wiedereinsetzung` | 2 mo / 1-year-cap (PatG §123 / ZPO §233 ff.) | Q4 | +| T2.4 | `epa.grant.exa.weiterbehandlung` | 2 mo from loss-of-rights notification (EPC R.135) | — | +| T2.5 | `upc.inf.cfi.prelim_reply` | 14 days from PO service (R.20.2) | Companion to R.19 (mig 095 added it) | +| T2.6 | `upc.apl.order.discretion_anchor` | add explicit `refusal` intermediate node so R.220.3 anchors correctly (Q12) | | +| T2.7 | `upc.dmgs.cfi.app` spawn | `is_spawn=true` from `upc.inf.cfi.decision` (Q9) | | +| T2.8 | `upc.disc.cfi.app` spawn | same shape as T2.7 | | +| T2.9 | `epa.grant.exa.r71_3` re-anchor | parent = `exam_req` (§7.5) | | +| T2.10 | `epa.grant.exa.approval` re-anchor | parent = `r71_3` (§7.5) | | +| T2.11 | `upc.inf.cfi.appeal_spawn` cross-proc wiring | finish the half-wired spawn execution (Q13) | | + +### Tier 3 — tooling primitives (block multiple rules) + +| # | Primitive | Blocks | Notes | +|---|---|---|---| +| T3.1 | `duration_unit = 'working_days'` | R.198, R.213 | Schema already accepts the string; add to calculator + UI | +| T3.2 | `combine_op = 'max'` | R.198, R.213, R.245.2 | Column already exists per pauli's 2026-05-13 audit | +| T3.3 | Multi-anchor "whichever later" trigger | R.245.2.a/b | UI + service work | +| T3.4 | Outer-cap modelling (`outer_cap_value` + `outer_cap_unit`) | R.245.2 (12mo), R.320 (12mo), EPC Art.112a(4) (12mo) | Schema add | +| T3.5 | "Before"-mode backward snap to working day | R.109.1, R.109.4 | Calculator change (audit-fristenrechner-completeness-2026-04-30.md §5.4) | +| T3.6 | Cross-proceeding spawn end-to-end (`is_spawn`) | T2.7, T2.8, T2.11 | Pauli's §6.8 | + +### Tier 4 — out-of-scope until separate prioritisation + +- DNI family (R.63 / R.67.1 / R.69.1 / R.69.2). Zero published filings 2026-Q1. +- Registry-correction family (R.16.3.a, R.27.2, R.89.2, R.253.2). Most natural in cascade, not proceeding-tree. +- GebrMG (no proceeding_type today). +- R.245 rehearing family (specialist). +- R.155 cost-decision opposition chain (specialist). +- R.144 UPC_DAMAGES tree-end row (cosmetic). +- R.79(2) EPC further-parties period (modelling unclear — Q7). + +--- + +## §11. Next-step proposals (suggested fix-task slicing) + +The audit identifies **41 distinct actionable items.** Below is a +suggested decomposition into fix-tasks that can be assigned +independently. Sequence reflects "Wave 0 must precede Wave 1" only +where there's a real dependency (most slices are independent). + +### Wave 0 — Tier 0 duration / sequencing / anchor fixes (single fix-task) + +**Proposed task:** `t-paliad-264 — Tier 0 deadline-rule corrections +(duration, anchor, citation) from t-paliad-263 audit` + +- 16 row UPDATEs (T0.1–T0.17, deduplicated to 16 distinct rows since + T0.8 is covered by T0.2 and T0.11 by T0.1). +- One migration file (~120 LoC SQL). +- All within existing schema. No new columns. +- Idempotent guards on every UPDATE (only fire when the row still has + the old value, per the mig 095 convention). +- Adds 16 entries to `paliad.deadline_rule_audit` (per the mig 079 + trigger). +- Verification block: `DO $$ … RAISE EXCEPTION …` per mig 095. +- **Branch:** `mai//t-paliad-264-tier0-deadline-fixes`. +- **Owner:** coder. +- **Why first:** all 16 affect either calendar correctness (5 hard + duration/anchor bugs) or citation correctness (the 11 metadata + fixes are what a lawyer would cite-check against). T0.1–T0.6 are + user-visible silent wrongs; ship them. + +### Wave 1 — Tier 1 rule additions (single fix-task) + +**Proposed task:** `t-paliad-265 — Tier 1 deadline-rule additions +(12 high-frequency rules)` + +- 11 INSERTs + 1 UPDATE re-anchor (T1.12 `upc.pi.cfi.response`). +- T1.8 (`upc.pi.cfi.merits_start`) **excluded** — blocked on T3.1/T3.2. +- One migration file (~250 LoC SQL). +- Add cascade leaves + concepts where needed (each rule should be + reachable from Pathway B too). +- **Branch:** `mai//t-paliad-265-tier1-rule-additions`. +- **Owner:** coder. **Legal review:** m must verify each rule before + merge (single round of grilling). + +### Wave 2 — Q1 court-set audit decision (separate spike) + +**Proposed task:** `t-paliad-266 — Decide court-set vs fixed-period +modelling for richterliche Fristen (Q1 in t-paliad-263 audit)` + +- Inventor / pauli reviews §9.1 with m. +- Decision artefact: list of rules to flip vs keep, plus UX guideline + for what the timeline displays for `is_court_set=true` rules. +- **Owner:** pauli. **m signs off.** + +### Wave 3 — Tier 3 tooling primitives (multi-task) + +Each Tier 3 row is its own task because each touches schema + service + +calculator + UI: + +- `t-paliad-267 — working_days unit + combine_op='max' (R.198, R.213)` +- `t-paliad-268 — Outer-cap modelling (R.245.2, R.320, Art.112a)` +- `t-paliad-269 — Multi-anchor "whichever later" triggers (R.245.2)` +- `t-paliad-270 — Backward-snap for `before`-mode rules (R.109.1/.4)` +- `t-paliad-271 — Cross-proceeding spawn end-to-end execution` + +Each is foundational for multiple Tier 2 rules; can ship independently. + +### Wave 4 — Tier 2 specialist rules (multi-task, after their primitives land) + +Each Tier 2 row is its own task or batched into 2-3 tasks by topical +area: + +- `t-paliad-272 — Wiedereinsetzung / Weiterbehandlung family (T2.2, T2.3, T2.4)` — depends on T3.4 (outer cap). +- `t-paliad-273 — UPC follow-on spawns (T2.7, T2.8, T2.11)` — depends on T3.6. +- `t-paliad-274 — UPC tail rules (T2.5, T2.6, R.353, etc.)` +- `t-paliad-275 — EPA grant timeline re-anchoring (T2.9, T2.10)`. + +### Wave 5 — Concept-layer parity (separate audit) + +The 9 orphan concepts (`audit-fristen-logic-2026-05-13.md` §3.4 + Q11 +here) need a parallel audit pass to map cascade → rule. Recommend +spinning a `t-paliad-276 — Cascade-rule parity audit` task once the +above land. + +### Wave 6 — Documentation + retire + +- `t-paliad-277 — Drop `_archived_litigation` proceeding_type` once + mig 093's audit window closes (Q6). +- `t-paliad-278 — Document Tier 4 deferrals in + `docs/feature-roadmap.md`` so the gap-list isn't lost. + +--- + +## Appendix A — file references + +**Live state queried via Supabase MCP, 2026-05-25 14:00–15:00 UTC:** + +- `paliad.proceeding_types` — 21 active rows (20 fristenrechner + 1 + archived). +- `paliad.deadline_rules` — 132 active + 40 archived rows + (`lifecycle_state='published'`). +- `paliad.deadline_rule_audit` — diff history. +- `data.laws_contents` (youpc) — UPC RoP + EPC verbatim text + (`law_type IN ('UPCRoP','EPC')`). + +**paliad migrations consulted:** + +- `internal/db/migrations/012_fristenrechner_rules.up.sql` — original + seed. +- `internal/db/migrations/043_de_instance_split_proceedings.up.sql` + — DE_INF_OLG / DE_INF_BGH split. +- `internal/db/migrations/052_event_categories_rop_audit.up.sql` + — first RoP audit fix-pass. +- `internal/db/migrations/079_*` — `paliad.deadline_rule_audit` + trigger. +- `internal/db/migrations/091_drop_legacy_rule_columns.up.sql` — + cleanup. +- `internal/db/migrations/093_retire_litigation_category.up.sql` — + archived 40 rules. +- `internal/db/migrations/095_fristen_gap_fill.up.sql` — t-paliad-205 + R.19 + R.220.1(a) gap fill. +- `internal/db/migrations/096_proceeding_code_rename.up.sql` — code + rename to `..` form. +- `internal/db/migrations/097_legal_citation_backfill.up.sql` — + legal_source / rule_code backfill. +- `internal/db/migrations/100_ccr_visible_rule.up.sql` — + `upc.ccr.cfi` alias. +- `internal/db/migrations/104_einspruch_name_and_ccr_priority.up.sql` + — Einspruch rename. + +**Companion audits:** + +- `docs/audit-fristenrechner-completeness-2026-04-30.md` — curie / + t-paliad-084. +- `docs/audit-upc-rop-deadlines-2026-05-08.md` — curie / t-paliad-159. +- `docs/audit-fristen-logic-2026-05-13.md` — pauli / t-paliad-157 + (schema audit, ground-truth on column semantics). +- `docs/proposals/fristen-gap-fill-2026-05-18.md` — m's 0.3 decisions + that shipped as mig 095. + +**Authoritative source URLs (all verified 2026-05-25):** + +- UPC RoP consolidated 18.05.2023: https://www.unifiedpatentcourt.org/sites/default/files/upc_documents/rop_application_-_consolidated_18_05_2023.pdf +- EPC 17th ed.: https://www.epo.org/en/legal/epc/2020/index.html +- EPC R.71 (and other Implementing Reg Rules): https://www.epo.org/en/legal/epc/2020/r71.html +- PatG: https://www.gesetze-im-internet.de/patg/ + - §59 https://www.gesetze-im-internet.de/patg/__59.html + - §73 https://www.gesetze-im-internet.de/patg/__73.html + - §75 https://www.gesetze-im-internet.de/patg/__75.html + - §82 https://www.gesetze-im-internet.de/patg/__82.html + - §110 https://www.gesetze-im-internet.de/patg/__110.html + - §111 https://www.gesetze-im-internet.de/patg/__111.html +- ZPO: https://www.gesetze-im-internet.de/zpo/ + - §520 https://www.gesetze-im-internet.de/zpo/__520.html + - §521 https://www.gesetze-im-internet.de/zpo/__521.html +- GebrMG: https://www.gesetze-im-internet.de/gebrmg/ + +--- + +## Appendix B — coverage tally + +| Status | Count | Share | +|---|---:|---:| +| present-correct | 78 | 59 % | +| present-wrong (DURATION) | 3 | 2 % | +| present-wrong (anchor/sequence) | 5 | 4 % | +| present-wrong (citation only) | 11 | 8 % | +| court-set-mismodelled-as-fixed | 6 | 5 % | +| **subtotal: still actionable** | **25** | **19 %** | +| missing (statute defines, paliad doesn't) | 30 | (gap, vs 132 baseline) | +| n/a (RoP / EPC / PatG section creates no time-limit) | 8 | 6 % | +| present-correct, no fix needed | (78 above) | | + +**Headline figures for m:** + +- Of the 132 statutory deadlines paliad currently models, **25 carry + an actionable bug** (19%). Of those, **5 are user-visible + calendar-correctness bugs** (the 3 duration bugs + the 2 + sequencing/anchor bugs head flagged + me). The other 20 are + citation drift or court-set mismodelling — fix-them-quietly + category. +- An additional **30 statutory deadlines are not modelled at all** + (the missing list in §3). Of those, **~12 are ★★★ / ★★ frequency** + (Tier 1 in §10); the remaining ~18 are ★ specialist. +- The 5 duration / sequencing bugs alone are **the most important + takeaway**: every UPC_REV proceeding, every UPC main-track appeal + respondent, and every DE-LG-Verletzung timeline tracked in paliad + today computes wrong dates. + +End of audit. Awaiting m's review of §9 Q1–Q13 + Tier 0 sign-off +before fix-tasks (Wave 0) get cut.