Verfahrensablauf: rules anchored on uncertain triggers render concrete dates (R.109 backward-anchor without oral-hearing date, R.262(2) without Vertraulichkeitsantrag) #121

Open
opened 2026-05-26 07:27:04 +00:00 by mAi · 2 comments
Collaborator

m's report (2026-05-26 09:26)

Symptom A — backward-anchored rule with no anchor renders today-relative date

UPC Verletzungsverfahren · Ausgangsdatum: Mo., 25.05.2026

Antrag auf Simultanübersetzung optional Mo., 27.04.2026 UPC RoP R.109(1)
⚠ Verschoben wegen Wochenende: Sa., 25.04.2026 → Mo., 27.04.2026
Frist 1 Monat VOR der mündlichen Verhandlung (R.109.1).

This shows that the antrag auf simultanübersetzung depends on the oral hearing's date - and if it is not set, it can't use a different date like done here.

The rule has timing='before' (knuth's Wave 2 Slice A primitive, mig 128). When the oral hearing date is NOT set on the project, the projection appears to substitute the trigger date (Ausgangsdatum, 25.05.2026) and compute 1mo-backward from THAT — producing a meaningless 25.04.2026. Backward-anchored rules MUST have their anchor set OR they should render as "abhängig von …" / "unset" state.

Symptom B — conditional dependent rule renders fixed date as if triggered

Erwiderung auf Vertraulichkeitsantrag optional Mo., 08.06.2026 UPC RoP R.262(2)
Frist 14 Tage ab Zustellung des Vertraulichkeitsantrags der Gegenseite (R.262.2).

This should not have a defined date if the whole submission triggering this (Vertraulichkeitsantrag) is not certain.

This rule anchors on the opposing party's Vertraulichkeitsantrag — which is OPTIONAL on the opposing side. Without a recorded Vertraulichkeitsantrag, the projection should NOT render a concrete date; it should show as conditional ("falls Antrag eingeht: 14 Tage danach").

Root-cause class

Both are the same bug: the projection treats a missing/uncertain anchor as a triggerable anchor, computing a date from the nearest-fallback (project trigger date OR today). It should instead:

  1. Detect anchor uncertainty: rule's parent_id is set but the parent rule has no actual date set (no paliad.deadline_anchors row for this project AND not derivable from the rule chain).
  2. Render conditional: "abhängig von " with no concrete date AND no calendar-render OR rendered as a faded "pending"-state row.
  3. Same applies to timing='before' rules: if the anchor is itself uncertain, the backward-computed date is meaningless.

For optional-on-the-other-side rules (R.262(2)): if the project has not recorded the opposing side's filing, no concrete date.

What to do

  1. Identify the projection logic in internal/services/projection_service.go (and/or deadline_calculator.go) that handles missing/empty anchors.
  2. Add an explicit IsConditional bool (or AnchorState string"set"|"unset"|"optional-not-recorded") on the computed-deadline shape.
  3. Frontend: when IsConditional=true, render the row WITHOUT a date column entry — instead a chip "abhängig von <parent.name>" and a small dotted-border on the row to visually distinguish.
  4. Backward-anchored rules (timing='before'): if the forward anchor is unset, mark as conditional. If set, compute normally (no change).
  5. Update verfahrensablauf-core.test.ts with these cases.

Files most likely touched

  • internal/services/projection_service.go
  • internal/services/deadline_calculator.go
  • frontend/src/client/views/verfahrensablauf-core.ts
  • frontend/src/client/views/verfahrensablauf-core.test.ts
  • frontend/src/styles/global.css — conditional-row visual treatment
  • frontend/src/client/i18n.ts + frontend/src/i18n-keys.ts — "abhängig von …" key

Hard rules

  • Don't change the rule data; this is projection logic only.
  • Backward-compat: rules with anchors set keep computing the same date.
  • go build ./... && go test ./internal/... && cd frontend && bun run build clean.
  • Branch: mai/<worker>/conditional-rule-projection.

Out of scope

  • Adding a UI to record a Vertraulichkeitsantrag as actually-filed (that goes through the existing event-anchor flow).
  • Re-architecting the calculator for graph-style multi-anchor rules — Tier 3 Slice B territory.

Reporting

mai report completed with branch + SHAs + UX path: open a UPC inf project without oral-hearing date → confirm R.109(1) and R.109(4) render as conditional, no date; open same project, then add the opposing party's Vertraulichkeitsantrag as an actual filing → confirm R.262(2) NOW renders with concrete date.

## m's report (2026-05-26 09:26) ### Symptom A — backward-anchored rule with no anchor renders today-relative date > UPC Verletzungsverfahren · Ausgangsdatum: Mo., 25.05.2026 > > Antrag auf Simultanübersetzung optional Mo., 27.04.2026 UPC RoP R.109(1) > ⚠ Verschoben wegen Wochenende: Sa., 25.04.2026 → Mo., 27.04.2026 > Frist 1 Monat VOR der mündlichen Verhandlung (R.109.1). > > This shows that the antrag auf simultanübersetzung depends on the oral hearing's date - and if it is not set, it can't use a different date like done here. The rule has `timing='before'` (knuth's Wave 2 Slice A primitive, mig 128). When the oral hearing date is NOT set on the project, the projection appears to substitute the trigger date (Ausgangsdatum, 25.05.2026) and compute 1mo-backward from THAT — producing a meaningless 25.04.2026. Backward-anchored rules MUST have their anchor set OR they should render as **"abhängig von …"** / **"unset"** state. ### Symptom B — conditional dependent rule renders fixed date as if triggered > Erwiderung auf Vertraulichkeitsantrag optional Mo., 08.06.2026 UPC RoP R.262(2) > Frist 14 Tage ab Zustellung des Vertraulichkeitsantrags der Gegenseite (R.262.2). > > This should not have a defined date if the whole submission triggering this (Vertraulichkeitsantrag) is not certain. This rule anchors on the opposing party's Vertraulichkeitsantrag — which is OPTIONAL on the opposing side. Without a recorded Vertraulichkeitsantrag, the projection should NOT render a concrete date; it should show as **conditional** ("falls Antrag eingeht: 14 Tage danach"). ## Root-cause class Both are the same bug: **the projection treats a missing/uncertain anchor as a triggerable anchor**, computing a date from the nearest-fallback (project trigger date OR today). It should instead: 1. **Detect anchor uncertainty**: rule's `parent_id` is set but the parent rule has no actual date set (no `paliad.deadline_anchors` row for this project AND not derivable from the rule chain). 2. **Render conditional**: "abhängig von <parent>" with no concrete date AND no calendar-render OR rendered as a faded "pending"-state row. 3. Same applies to `timing='before'` rules: if the anchor is itself uncertain, the backward-computed date is meaningless. For optional-on-the-other-side rules (R.262(2)): if the project has not recorded the opposing side's filing, no concrete date. ## What to do 1. Identify the projection logic in `internal/services/projection_service.go` (and/or `deadline_calculator.go`) that handles missing/empty anchors. 2. Add an explicit `IsConditional bool` (or `AnchorState string` — `"set"|"unset"|"optional-not-recorded"`) on the computed-deadline shape. 3. Frontend: when `IsConditional=true`, render the row WITHOUT a date column entry — instead a chip "abhängig von <parent.name>" and a small dotted-border on the row to visually distinguish. 4. Backward-anchored rules (`timing='before'`): if the forward anchor is unset, mark as conditional. If set, compute normally (no change). 5. Update `verfahrensablauf-core.test.ts` with these cases. ## Files most likely touched - `internal/services/projection_service.go` - `internal/services/deadline_calculator.go` - `frontend/src/client/views/verfahrensablauf-core.ts` - `frontend/src/client/views/verfahrensablauf-core.test.ts` - `frontend/src/styles/global.css` — conditional-row visual treatment - `frontend/src/client/i18n.ts` + `frontend/src/i18n-keys.ts` — "abhängig von …" key ## Hard rules - Don't change the rule data; this is projection logic only. - Backward-compat: rules with anchors set keep computing the same date. - `go build ./... && go test ./internal/... && cd frontend && bun run build` clean. - Branch: `mai/<worker>/conditional-rule-projection`. ## Out of scope - Adding a UI to record a Vertraulichkeitsantrag as actually-filed (that goes through the existing event-anchor flow). - Re-architecting the calculator for graph-style multi-anchor rules — Tier 3 Slice B territory. ## Reporting `mai report completed` with branch + SHAs + UX path: open a UPC inf project without oral-hearing date → confirm R.109(1) and R.109(4) render as conditional, no date; open same project, then add the opposing party's Vertraulichkeitsantrag as an actual filing → confirm R.262(2) NOW renders with concrete date.
mAi self-assigned this 2026-05-26 07:27:04 +00:00
Author
Collaborator

Sweep verdict (2026-07-29): ALREADY DONE.

internal/services/projection_service.go:999-1006 handles both symptoms and names them in the code: "court-set ancestor without override, backward-anchor without forward date, or optional event not recorded" → Status = "conditional", and critically ev.Date = nil ("Conditional rows must not carry a date even if the calculator left one"). Shipped as t-paliad-289.

Symptom A (R.109 backward-anchor with no oral-hearing date) and Symptom B (R.262(2) with no Vertraulichkeitsantrag) both now render as conditional instead of a computed date.

But see #126 — the label on those conditional rows still names the wrong dependency. That half is still true.

Full sweep: docs/findings-issue-sweep-2026-07-29.md (commit 4c39886).

**Sweep verdict (2026-07-29): ALREADY DONE.** `internal/services/projection_service.go:999-1006` handles both symptoms and names them in the code: "court-set ancestor without override, **backward-anchor without forward date**, or **optional event not recorded**" → `Status = "conditional"`, and critically `ev.Date = nil` ("Conditional rows must not carry a date even if the calculator left one"). Shipped as t-paliad-289. Symptom A (R.109 backward-anchor with no oral-hearing date) and Symptom B (R.262(2) with no Vertraulichkeitsantrag) both now render as conditional instead of a computed date. **But see #126** — the *label* on those conditional rows still names the wrong dependency. That half is still true. Full sweep: `docs/findings-issue-sweep-2026-07-29.md` (commit 4c39886).
Author
Collaborator

Correction to my comment above (2026-07-29).

I wrote "But see #126 — the label on those conditional rows still names the wrong dependency. That half is still true." That is wrong. #126 is fixed; see the verdict I have just posted there.

The ALREADY DONE verdict on this issue stands unchanged — projection_service.go:999-1006 clears the date and renders conditional for both of m's symptoms. Only the pointer to #126 was wrong.

Corrected in docs/findings-issue-sweep-2026-07-29.md (commit 3b20c2c).

**Correction to my comment above (2026-07-29).** I wrote "But see #126 — the *label* on those conditional rows still names the wrong dependency. That half is still true." **That is wrong.** #126 is fixed; see the verdict I have just posted there. The ALREADY DONE verdict on this issue stands unchanged — `projection_service.go:999-1006` clears the date and renders conditional for both of m's symptoms. Only the pointer to #126 was wrong. Corrected in `docs/findings-issue-sweep-2026-07-29.md` (commit 3b20c2c).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#121
No description provided.