# 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/<coder>/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/<coder>/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 `<jurisdiction>.<proceeding>.<instance>` 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.
