de.inf.lg / cfi: Replik + Duplik sequenced wrong (before Klageerwiderung + same date) #95

Open
opened 2026-05-25 13:15:09 +00:00 by mAi · 2 comments
Collaborator

m's report (2026-05-25 15:12)

Live timeline render of the de.inf.lg / cfi proceeding currently shows:

Klageerhebung                 Mo., 25.05.2026   ZPO §253
Anzeige Verteidigungsbereitschaft  Mo., 08.06.2026  ZPO §276(1)
  └─ "Innerhalb von 2 Wochen nach Zustellung der Klage … § 276(1) S. 1 ZPO"
Replik                        Mo., 22.06.2026   "Frist vom Gericht bestimmt"
Duplik                        Mo., 22.06.2026   "Frist vom Gericht bestimmt"

Three issues:

  1. Replik and Duplik render on the SAME date. They can't — Replik must come strictly before Duplik (claimant's reply then defendant's rejoinder).
  2. Both render BEFORE Klageerwiderung, which is missing from this slice but should anchor between Anzeige and Replik. Replik can never come before Klageerwiderung.
  3. "Frist vom Gericht bestimmt" is a court-set deadline placeholder — fine semantically — but the timeline still positions them off the Klageerhebung anchor rather than anchoring to the Klageerwiderung that should precede them.

m's correct sequence for de.inf.lg (ZPO Klage):

Klageerhebung  →  Anzeige Verteidigungsbereitschaft  →  Klageerwiderung  →  Replik  →  Duplik  →  …

Each strictly after the previous; Replik anchors off Klageerwiderung (court-set period), Duplik anchors off Replik (court-set period).

What to do

  1. Inspect the de.inf.lg / cfi rows in paliad.deadline_rules — what trigger_event_id, period_value, period_unit does each carry? Likely Replik + Duplik both point at Klageerhebung with the same court-set placeholder period.
  2. Identify Klageerwiderung rule — is it present in the catalog at all for de.inf.lg? If absent, ADD it as a rule (event_type='filing', anchored on Anzeige der Verteidigungsbereitschaft or directly on Klageerhebung per the court's ladenfrist).
  3. Fix Replik: trigger_event_id = Klageerwiderung's submission_code, period = court-set placeholder (e.g. NULL with a is_court_set: true flag if the schema has one, else NULL period with a label).
  4. Fix Duplik: trigger_event_id = Replik's submission_code, period = court-set placeholder.
  5. Verify rendering on a sample de.inf.lg project — confirm the order is Klageerhebung → Anzeige → Klageerwiderung → Replik → Duplik with distinct dates (or distinct "court-set" placeholders that the timeline visualises as later-than-Klageerwiderung).
  6. Cross-reference with curie's audit (m/paliad#94) — the researcher should also capture this as a "Wrong sequencing" finding for the audit's record.

Files most likely touched

  • A migration to fix the rows (likely 123 or 124 — ls internal/db/migrations/ | tail)
  • OR a one-shot script under scripts/fix-de-inf-lg-sequencing/main.go if the catalog is seeded from code rather than migrated
  • internal/services/projection_service.go if the rendering bug is in projection logic, not the data
  • frontend/src/client/views/verfahrensablauf-core.ts if the column placement misorders court-set events

Hard rules

  • Don't fix unrelated rules — scope is de.inf.lg / cfi only. Other jurisdictions stay untouched (curie's audit will cover them).
  • Cite the source in the migration comment: ZPO §§ 276–277 for Klageerwiderung, ZPO § 282 for Replik/Duplik discretion, court-set per § 273.
  • go build ./... && go test ./internal/... && cd frontend && bun run build clean.
  • Branch: mai/<worker>/de-inf-lg-replik-duplik-sequencing.

Out of scope

  • Adding more rules to other jurisdictions (curie's audit, then separate fix-tasks).
  • Building a court-set-period UI affordance (separate feature).
  • Renaming ruleprocedural_event (deferred per #93).

Reporting

mai report completed with branch + SHAs + before/after rendering on a sample de.inf.lg project + which migration / script approach was used + cross-reference comment on curie's audit (#94).

## m's report (2026-05-25 15:12) Live timeline render of the de.inf.lg / cfi proceeding currently shows: ``` Klageerhebung Mo., 25.05.2026 ZPO §253 Anzeige Verteidigungsbereitschaft Mo., 08.06.2026 ZPO §276(1) └─ "Innerhalb von 2 Wochen nach Zustellung der Klage … § 276(1) S. 1 ZPO" Replik Mo., 22.06.2026 "Frist vom Gericht bestimmt" Duplik Mo., 22.06.2026 "Frist vom Gericht bestimmt" ``` Three issues: 1. **Replik and Duplik render on the SAME date.** They can't — Replik must come strictly before Duplik (claimant's reply then defendant's rejoinder). 2. **Both render BEFORE Klageerwiderung**, which is missing from this slice but should anchor between Anzeige and Replik. Replik can never come before Klageerwiderung. 3. **"Frist vom Gericht bestimmt"** is a court-set deadline placeholder — fine semantically — but the timeline still positions them off the Klageerhebung anchor rather than anchoring to the Klageerwiderung that should precede them. m's correct sequence for de.inf.lg (ZPO Klage): ``` Klageerhebung → Anzeige Verteidigungsbereitschaft → Klageerwiderung → Replik → Duplik → … ``` Each strictly after the previous; Replik anchors off Klageerwiderung (court-set period), Duplik anchors off Replik (court-set period). ## What to do 1. **Inspect** the de.inf.lg / cfi rows in `paliad.deadline_rules` — what `trigger_event_id`, `period_value`, `period_unit` does each carry? Likely Replik + Duplik both point at Klageerhebung with the same court-set placeholder period. 2. **Identify Klageerwiderung** rule — is it present in the catalog at all for de.inf.lg? If absent, ADD it as a rule (event_type='filing', anchored on Anzeige der Verteidigungsbereitschaft or directly on Klageerhebung per the court's ladenfrist). 3. **Fix Replik**: `trigger_event_id` = Klageerwiderung's submission_code, period = court-set placeholder (e.g. NULL with a `is_court_set: true` flag if the schema has one, else NULL period with a label). 4. **Fix Duplik**: `trigger_event_id` = Replik's submission_code, period = court-set placeholder. 5. **Verify rendering** on a sample de.inf.lg project — confirm the order is Klageerhebung → Anzeige → Klageerwiderung → Replik → Duplik with distinct dates (or distinct "court-set" placeholders that the timeline visualises as later-than-Klageerwiderung). 6. **Cross-reference with curie's audit (m/paliad#94)** — the researcher should also capture this as a "Wrong sequencing" finding for the audit's record. ## Files most likely touched - A migration to fix the rows (likely 123 or 124 — `ls internal/db/migrations/ | tail`) - OR a one-shot script under `scripts/fix-de-inf-lg-sequencing/main.go` if the catalog is seeded from code rather than migrated - `internal/services/projection_service.go` if the rendering bug is in projection logic, not the data - `frontend/src/client/views/verfahrensablauf-core.ts` if the column placement misorders court-set events ## Hard rules - **Don't fix unrelated rules** — scope is de.inf.lg / cfi only. Other jurisdictions stay untouched (curie's audit will cover them). - **Cite the source** in the migration comment: ZPO §§ 276–277 for Klageerwiderung, ZPO § 282 for Replik/Duplik discretion, court-set per § 273. - `go build ./... && go test ./internal/... && cd frontend && bun run build` clean. - Branch: `mai/<worker>/de-inf-lg-replik-duplik-sequencing`. ## Out of scope - Adding more rules to other jurisdictions (curie's audit, then separate fix-tasks). - Building a court-set-period UI affordance (separate feature). - Renaming `rule` → `procedural_event` (deferred per #93). ## Reporting `mai report completed` with branch + SHAs + before/after rendering on a sample de.inf.lg project + which migration / script approach was used + cross-reference comment on curie's audit (#94).
mAi self-assigned this 2026-05-25 13:15:09 +00:00
Author
Collaborator

Shipped on branch mai/brunel/fixer-de-inf-lg-cfi @ f45ad50.

Root cause: de.inf.lg.replik and de.inf.lg.duplik both had parent_id = NULL with duration_value = 4 weeks. The projection therefore anchored both off the proceeding's trigger date (Klageerhebung) and added 4 weeks → both rendered at the same calendar date AND before Klageerwiderung (Klage + 6w).

Fix — migration 123 (internal/db/migrations/123_de_inf_lg_replik_duplik_sequencing.up.sql):

  • replik.parent_iderwidg.id
  • duplik.parent_idreplik.id
  • both marked is_court_set = true, legal_source = 'DE.ZPO.273'
  • deadline_notes cite §§ 273, 282 ZPO (court's case-management power + parties' duty to file timely)
  • 4-week placeholder duration retained so timeline renders distinct chronological dates the lawyer can override via "Datum setzen"
  • Klageerwiderung untouched (already present as parent=klage, dur=6w, is_court_set=true)

Applied to live youpc DB via Supabase MCP. paliad.applied_migrations bumped to version 123 (122 rows).

Verified ordering for trigger 2026-05-25 Mon (the user-reported anchor):

Submission Date Source
Klageerhebung 2026-05-25 Mon § 253 ZPO
Anzeige Verteidigungsbereitschaft 2026-06-08 Mon § 276 Abs. 1 S. 1 ZPO
Klageerwiderung 2026-07-06 Mon § 276 Abs. 1 S. 2 ZPO
Replik 2026-08-03 Mon § 273 ZPO (gerichtl. Frist)
Duplik 2026-08-31 Mon § 273 ZPO (gerichtl. Frist)

Each row strictly later than the previous; Replik and Duplik no longer collide on the same date and no longer precede the Klageerwiderung.

Build hygiene: go build ./... clean; go test ./internal/... all packages pass; bun run build clean (2801 i18n keys, no scan warnings). No code changes — pure data migration.

Cross-reference posted on curie's audit #94 (#94#issuecomment-9603) including one residual observation: fristenrechner.Calculate does not propagate r.IsCourtSet → d.IsCourtSet for non-zero-duration rules, so the dashed court-set border doesn't render today for Klageerwiderung / Replik / Duplik. Filed as a §10 candidate; out of scope for #95.

Awaiting maria's merge gate. NOT self-merged.

Shipped on branch `mai/brunel/fixer-de-inf-lg-cfi` @ f45ad50. **Root cause**: `de.inf.lg.replik` and `de.inf.lg.duplik` both had `parent_id = NULL` with `duration_value = 4 weeks`. The projection therefore anchored both off the proceeding's trigger date (Klageerhebung) and added 4 weeks → both rendered at the same calendar date AND before Klageerwiderung (Klage + 6w). **Fix — migration 123** (`internal/db/migrations/123_de_inf_lg_replik_duplik_sequencing.up.sql`): - `replik.parent_id` → `erwidg.id` - `duplik.parent_id` → `replik.id` - both marked `is_court_set = true`, `legal_source = 'DE.ZPO.273'` - `deadline_notes` cite §§ 273, 282 ZPO (court's case-management power + parties' duty to file timely) - 4-week placeholder duration retained so timeline renders distinct chronological dates the lawyer can override via "Datum setzen" - Klageerwiderung untouched (already present as parent=klage, dur=6w, is_court_set=true) **Applied to live youpc DB** via Supabase MCP. `paliad.applied_migrations` bumped to version 123 (122 rows). **Verified ordering** for trigger 2026-05-25 Mon (the user-reported anchor): | Submission | Date | Source | |---|---|---| | Klageerhebung | 2026-05-25 Mon | § 253 ZPO | | Anzeige Verteidigungsbereitschaft | 2026-06-08 Mon | § 276 Abs. 1 S. 1 ZPO | | Klageerwiderung | 2026-07-06 Mon | § 276 Abs. 1 S. 2 ZPO | | Replik | 2026-08-03 Mon | § 273 ZPO (gerichtl. Frist) | | Duplik | 2026-08-31 Mon | § 273 ZPO (gerichtl. Frist) | Each row strictly later than the previous; Replik and Duplik no longer collide on the same date and no longer precede the Klageerwiderung. **Build hygiene**: `go build ./...` clean; `go test ./internal/...` all packages pass; `bun run build` clean (2801 i18n keys, no scan warnings). No code changes — pure data migration. **Cross-reference** posted on curie's audit #94 ([#94#issuecomment-9603](https://mgit.msbls.de/m/paliad/issues/94#issuecomment-9603)) including one residual observation: `fristenrechner.Calculate` does not propagate `r.IsCourtSet → d.IsCourtSet` for non-zero-duration rules, so the dashed court-set border doesn't render today for Klageerwiderung / Replik / Duplik. Filed as a §10 candidate; out of scope for #95. **Awaiting** maria's merge gate. NOT self-merged.
Author
Collaborator

Re-pushed branch mai/brunel/fixer-de-inf-lg-cfi @ 8c94dcc (force update after rebase onto main).

Slot collision resolved: paliadin caught a crash-loop on paliad.de because my earlier in-process testing wrote applied_migrations(version=123, name='de_inf_lg_replik_duplik_sequencing') while cronus's #77 123_backups merged in parallel. Migrator bailed on the name mismatch. Paliadin DELETEd my stale applied_migrations row; container recovered with cronus's 123 applied cleanly.

Changes:

  • migration file renamed 123_…124_de_inf_lg_replik_duplik_sequencing.{up,down}.sql
  • audit_reason payload updated to reference mig 124
  • each UPDATE paliad.deadline_rules now guarded by AND parent_id IS NULL (mig 095 convention) — re-apply against a DB that already carries the fix matches zero rows and no-ops

Idempotency dry-run against live DB:

SELECT COUNT(*) … WHERE submission_code='de.inf.lg.replik' AND parent_id IS NULL  → 0
SELECT COUNT(*) … WHERE submission_code='de.inf.lg.duplik' AND parent_id IS NULL  → 0

Both guards short-circuit. On next container boot the runner applies mig 124, the UPDATEs no-op cleanly, the runner inserts applied_migrations(version=124, name='de_inf_lg_replik_duplik_sequencing'). No duplicate audit-log rows.

Build hygiene: go build ./... clean; go test ./internal/db/... ./internal/services/... pass; bun run build clean (2824 i18n keys — picks up cronus's backup-mode keys from #77).

NOT self-merged. Awaiting maria's merge gate.

Re-pushed branch `mai/brunel/fixer-de-inf-lg-cfi` @ 8c94dcc (force update after rebase onto main). **Slot collision resolved**: paliadin caught a crash-loop on paliad.de because my earlier in-process testing wrote `applied_migrations(version=123, name='de_inf_lg_replik_duplik_sequencing')` while cronus's #77 `123_backups` merged in parallel. Migrator bailed on the name mismatch. Paliadin DELETEd my stale applied_migrations row; container recovered with cronus's 123 applied cleanly. **Changes**: - migration file renamed `123_…` → `124_de_inf_lg_replik_duplik_sequencing.{up,down}.sql` - audit_reason payload updated to reference `mig 124` - each `UPDATE paliad.deadline_rules` now guarded by `AND parent_id IS NULL` (mig 095 convention) — re-apply against a DB that already carries the fix matches zero rows and no-ops **Idempotency dry-run against live DB**: ``` SELECT COUNT(*) … WHERE submission_code='de.inf.lg.replik' AND parent_id IS NULL → 0 SELECT COUNT(*) … WHERE submission_code='de.inf.lg.duplik' AND parent_id IS NULL → 0 ``` Both guards short-circuit. On next container boot the runner applies mig 124, the UPDATEs no-op cleanly, the runner inserts `applied_migrations(version=124, name='de_inf_lg_replik_duplik_sequencing')`. No duplicate audit-log rows. **Build hygiene**: `go build ./...` clean; `go test ./internal/db/... ./internal/services/...` pass; `bun run build` clean (2824 i18n keys — picks up cronus's backup-mode keys from #77). NOT self-merged. Awaiting maria's merge gate.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#95
No description provided.