Commit Graph

135 Commits

Author SHA1 Message Date
mAi
6e8e2e7653 Merge: t-paliad-213 — mendel test-strategy design doc 2026-05-19 10:11:26 +02:00
mAi
de20356cec docs(export): inventor design for scoped Excel data export (org / project-subtree / personal)
t-paliad-214. Covers scope definitions, format choices (xlsx + JSON + CSV
in one zip, deterministic, schema_version 1), authorization model
(global_admin / project-team-with-associate-floor / authenticated-self),
trigger model (sync personal+project, async org), storage on
PALIAD_EXPORT_DIR with 7-day retention, PII/GDPR posture, 3-slice plan,
and 9 open questions for m. No code touches — design only.
2026-05-19 10:10:59 +02:00
mAi
8414aa4c14 docs(test-strategy): inventor design for production-grade test pyramid
t-paliad-213 — six-layer pyramid (migration dry-run, Go/frontend unit,
frontend DOM, service live-DB, handler integration, Playwright E2E),
audit of current coverage (323 test funcs, 24 untested services, 53
untested handlers, 4/90 frontend modules), eight-slice tracer-bullet
roll-out, six open questions for m.

Read-only design phase per CLAUDE.md inventor gate — no test files,
make targets or CI configs touched. Awaiting m go/no-go on §5 slice
plan + §6 open questions before any coder shift.
2026-05-19 10:10:23 +02:00
mAi
e1b91a9481 docs(caldav): design for multi-calendar binding model (t-paliad-212)
Inventor design for letting users connect Paliad's CalDAV sync to N
external calendars per user, with scope filters (master / personal /
per-project / per-client / per-litigation / per-patent / per-case)
rather than today's single-target push. Splits credentials (per user,
unchanged) from bindings (new join table). Adds a per-target join for
push state so the same Appointment can live in multiple calendars at
once. Includes per-provider limit research (iCloud 100, Google ~100,
Fastmail no cap, Nextcloud 30 default), a 4-slice rollout plan, and 6
open questions for m. READ-ONLY design — no schema or code changes.
2026-05-19 10:06:58 +02:00
mAi
391be09b1e docs(t-paliad-208): legal-citation backfill proposal for 130 deadline_rules
Researcher draft for Workstream A — per-rule proposals for rule_code +
legal_source on the 130 active+published deadline_rules with rule_code IS
NULL. Grouped by proceeding (53 PT rows) and orphan-bucket (77 rows with
proceeding_type_id IS NULL).

~75 HIGH/MED proposals, ~47 FLAG entries pending m's call (court-set
event-markers, combined-pleading rows, ambiguous orphans, RoP
sub-paragraph spot-checks). Profiles the field convention from the 83
already-populated rows. READ-ONLY phase: no DB writes, no migration yet
— mig 097 follows once m signs off.

Side-fix candidate: normalize the one outlier RoP.49.1 -> RoP.049.1 on
rev.defence as part of mig 097.
2026-05-18 14:56:42 +02:00
mAi
e857829ac2 docs(t-paliad-206): proceeding-code taxonomy spec — lowercase dot-separated
Captures m's 2026-05-18 ratification of the new fristenrechner
proceeding-code convention `<jurisdiction>.<X>.<Y>` and the 5
sub-decisions: ccr.cfi is an illustrative peer that routes back to
inf.cfi with with_ccr; damages-appeal stays bundled into
upc.apl.merits; NZB at BGH is a flag, not a separate proceeding;
DPMA appeals stay generic with source differentiation at rule level.

This document is the source of truth for mig 096 (lands next) and the
post-mig proceeding_mapping.go.
2026-05-18 12:13:02 +02:00
mAi
0123d11c6e docs(t-paliad-203): capture m's decisions on the 12 FLAGs (2026-05-18)
m + paliadin walked the open questions; new §0.3 records the calls so
the proposal doc reflects the final shape before m ingests via
/admin/rules. Net stays at 4 new rules (2 PO + 2 always-fire merits-
appeal spawns). de_inf.erwidg flips to court-set per ZPO §276(1) S.2.
No ccr-defendant PO, no ccr.appeal duplication, no R.263 deadline.
2026-05-18 11:26:32 +02:00
mAi
35aa5e63c0 docs(t-paliad-203): Fristenrechner gap-fill proposals — 4 new rules + 3 polish PATCHes
Drafts the 4 coverage questions the mig 093 commit body left open for
legal review (t-paliad-200 closeout):

  1. Preliminary Objection (RoP 19) on UPC_INF + UPC_REV — 2 new rules,
     party=defendant, 1 month from SoC/SfR served, flag-gated with_po.
  2. Cross-proceeding APP spawn (RoP 220.1(a)) from UPC_INF + UPC_REV
     into the UPC merits-appeal proceeding — 2 spawn rules, party=both,
     2 months from R.118 decision, flag-gated with_appeal. Third
     Pipeline-A relic (ccr.appeal) recommended not seeded — CCR appeal
     is structurally absorbed into inf.appeal_spawn because one R.118
     decision = one appeal window in the unified UPC_INF (CCR-as-flag)
     model.
  3. ccr.amend / rev.amend — claim "safe to drop" verified for patent
     amendment (fully covered by inf.app_to_amend / rev.app_to_amend
     chains under with_ccr+with_amend / with_amend flags). R.263 case-
     amendment is court-discretionary; recommended NOT modelled.
  4. zpo.* family — klage / vertanz / berufung redundancy verified
     (de_inf.klage, de_inf.anzeige, de_inf.berufung / de_inf_olg.berufung
     cover them). klageerw exposes a discrepancy on de_inf.erwidg
     (6-week heuristic vs ZPO §276.1 S.2 court-set 2-week floor) — flagged
     as a PATCH on the existing row, not a new rule. Task brief's mention
     of "Vertagungsantrag" is a misread of zpo.vertanz (= Verteidigungs-
     anzeige, not Vertagungsantrag); §227 itself recommended NOT modelled.

Net: 4 new rules drafted in Track B, 3 optional PATCHes in Track A, 12
FLAGs surfaced for m's decision before /admin/rules ingest. Appeal target
referenced by ROLE (not code) pending t-paliad-204 proceeding-code
rename — m picks final spawn_proceeding_type_id at ingest.

Per-rule template matches docs/proposals/orphan-concepts-2026-05-15.md.
Read-only research; no DB writes, no migration files. The spawn_proceeding_type_id
column is unused in live data today — these spawn rules will be the
first real consumer.
2026-05-18 11:18:23 +02:00
mAi
d027b0874c docs(t-paliad-196): orphan-concept seed proposals (Fristen Phase 3 Slice 12, draft)
5 live orphans (not 9 — discrepancy flagged), 7 linkage-only UPDATEs and
12 net-new rule drafts. Sources cited; 12 FLAGs for m's review before
/admin/rules ingest.
2026-05-15 17:47:30 +02:00
mAi
119b06dcff design(t-paliad-181): Fristen Phase 2 — unified rule model + 12-slice plan
Phase 2 design pass operationalising all 7 m-locked + 8 head-default
picks from audit §9.

Headline architecture:
- ONE unified deadline_rules table (evolved, not replaced) absorbing
  Pipeline A + Pipeline C. Adds trigger_event_id, spawn_proceeding_type_id,
  combine_op, condition_expr (jsonb AND/OR/NOT), priority (4-way enum),
  is_court_set (real column, drops heuristic), lifecycle_state +
  draft_of + published_at (rule-editor draft → published lifecycle).
  Drops condition_flag, condition_rule_id, is_mandatory, is_optional.
  Net +5 columns, 32 → 37.
- paliad.deadline_rule_audit table + DB trigger + RLS for admin-only
  rule editing (Q5C). Mandatory reason field. Migration-export
  endpoint keeps rules in version control after-the-fact.
- paliad.projects.instance_level column (first/appeal/cassation)
  enables DE_INF → DE_INF_OLG → DE_INF_BGH ladder without proceeding_type
  re-pick.
- Cross-proceeding spawn wired via spawn_proceeding_type_id FK +
  global rule index in the calculator + cycle guard.
- POST /api/tools/event-trigger preserves Pipeline C contract on
  unified backend.

Migration path (Steps A-I, ~17 migrations 078-094):
- Step A additive schema → Step B backfill → Step C Pipeline C
  data-move → Step D calculator unification (service refactor) →
  Step E destructive drops (gated) → Step F project soft-merge
  (Q2) → Step G spawn → Step H instance-level → Step I rule_id
  backfill on legacy deadlines.
- Read-only trigger on paliad.event_deadlines during the cutover
  window prevents drift.
- Backup snapshots before destructive drops.

12 prioritized slices (§10) for Phase 3:
- Slices 1-4 sequential: schema, backfill, Pipeline C migration,
  calculator unification.
- Slices 5-8 parallel: project soft-merge, event-trigger endpoint,
  spawn wiring, instance level.
- Slices 9-10 cleanup: destructive drops, rule_id fuzzy-match
  backfill.
- Slices 11a + 11b: rule-editor backend + frontend (HEAVIEST,
  lands last on stable schema).
- Slice 12: orphan concept seed (wiedereinsetzung first), through
  the editor as its real-world workout.

§9 risk surface: destructive migrations, audit-log compliance gap
during cutover (mitigated by SET LOCAL audit_reason in migration
tooling), cross-corpus drift window (mitigated by read-only
trigger), condition_expr jsonb perf (trivial at 172-row scale),
migration-export manual step.

§12 has 12 open questions for HEAD (not m) — sub-decisions head
resolves at slice-start: migration window, draft lifecycle for
v1, audit retention, preview implementation, export format, slice
ordering, cycle-guard strictness, picker placement, testing scope,
ambiguity-tail handling, seed-vs-editor ordering, telemetry.

§0 drift since 2026-05-13 audit: 1 fristenrechner code deactivated
(20→19 active); mig 075-077 are SmartTimeline, NOT Fristen-logic;
new concept (56→57); new event_types (40→45). All audit findings
hold.

NOT self-merged. Head gates Phase 3 transition (no m-gate).
NOT cronus per memory directive 2026-05-06.
2026-05-15 00:10:07 +02:00
mAi
b455df265e audit(t-paliad-157): Fristen logic — rules, triggers, conditionals
Phase 1 audit (AUDIT ONLY, no implementation). 799 lines, mai/pauli/fristen-logic-audit.

Headline findings:

- THREE parallel deadline-generation systems coexist with overlapping
  intent:
  - Pipeline A (proceeding-driven) — paliad.deadline_rules (172 rows),
    FristenrechnerService.Calculate, drives /tools/fristenrechner +
    SmartTimeline.
  - Pipeline B (single-rule subset of A) — Pathway B cascade click.
  - Pipeline C (event-driven, youpc legacy) — paliad.trigger_events
    (110) + paliad.event_deadlines (77), EventDeadlineService.Calculate,
    drives "Was kommt nach…" tab. Disjoint corpus from A.

- Rule corpus is RICHER than the brief implied: 32 columns, 172 rules
  across 27 proceeding_types (132 fristenrechner + 40 litigation). The
  dual-corpus is a latent footgun: paliad.projects.proceeding_type_id
  accepts both categories with no CHECK constraint, so a project's
  SmartTimeline depends on which code lands first.

- Data model already encodes most of m's mental model:
  multi-deadline triggers via parent_id chains (deepest live: 3
  levels in UPC_INF), conditional via condition_flag (AND-only),
  flag-swap via alt_duration_value / alt_rule_code, court-set via
  heuristic + 4-bucket classification, holiday adjustment via
  HolidayService+CourtService.

- Real gaps (§6, 13 of them):
  - Pipeline A/C redundancy (different capabilities, disjoint data).
  - Litigation vs fristenrechner corpus drift (no contract).
  - is_mandatory + is_optional overlap.
  - deadline_concept_event_types is config layer, NOT trigger model.
  - No real event-driven trigger endpoint.
  - AND-only condition_flag (no OR/NOT/compound).
  - Cross-proceeding spawn half-wired.
  - 9 orphan concepts with rule_count=0 (incl wiedereinsetzung,
    schriftsatznachreichung, weiterbehandlung).
  - condition_rule_id dead column.
  - Instance dimension (LG/OLG/BGH) not on paliad.projects.
  - 1/26 deadlines linked to rule_id (anchor-from-actuals barely
    used).
  - Court-set is heuristic, not first-class column.
  - Pipeline A lacks before / working_days / combine_op.

- The big m's-question: "all in the Rules so we should be able to
  manage" is FALSE today. Rules edits = SQL migrations only. §8
  proposes a 3-step ladder: status-quo / read-only admin / full
  editor with audit log.

- §7 has concrete extension proposal for each §6 gap (migration size
  costed).

- §9 has 15 open questions for m to call before Phase 2 starts.

- Live data sparse: 11/11 projects NULL proceeding_type_id, 1/26
  deadlines with rule_id — demand-side mostly empty even though
  supply-side (rules) is rich.

NOT cronus per memory directive 2026-05-06. NOT self-merged. Awaiting
m's go/no-go.
2026-05-13 21:33:38 +02:00
mAi
7c4bc39115 design(t-paliad-166): Determinator B1 row-by-row cascade
- §0 premises verified live: 4-layer Pathway B mess (radio + 2 chip-strips
  + breadcrumb-cascade), 91/103 leaves carry forum tag, 16 leaves carry
  party tag, 11/11 live projects have NULL proceeding_type_id (graceful
  degrade), 4 distinct condition_flag value-sets on UPC_INF + UPC_REV
  only, project.court is free-text not FK, verfahrensablauf-core.ts
  carries zero cascade leakage post-t-paliad-179 Slice 1.
- §1 three intertwined pillars: project-driven narrowing / visual
  hierarchy overhaul / row-by-row persistent cascade.
- §2-3 single .fristen-row primitive (active / answered / prefilled /
  hidden) replaces radio + chip-strips + breadcrumb-cards.
- §4 data mapping: forum derivation already shipped; new
  litigation_code x jurisdiction -> fristenrechner_code helper
  (shared with t-paliad-178 Slice 2).
- §5 per-row pre-fill / hide / skipped-but-shown matrix across UPC /
  DE / EPA / DPMA / ad-hoc / zero-context flows with two compact
  ASCII diagrams.
- §6 Filter / Suche mode = escape-hatch icon-button (inventor's pick).
- §7-9 mobile breakpoints, three reset flavours, search affordance
  placement.
- §10 three slices: visual-only (Slice 1), narrowing depth +
  proceeding_mapping.go helper (Slice 2), mobile + search polish
  (Slice 3).
- §11 seven trade-offs flagged (row-stack height, aus-Akte noise,
  auto-walk magic, radio removal, NULL proceeding_type_id reality,
  mapping ambiguities, ändern descendant invalidation).
- §12 file-touch map for Slice 1 only.
- §13 fifteen open questions for m to call before coder shift.

NOT self-merged. Awaiting m's go/no-go.
2026-05-13 11:27:06 +02:00
mAi
8e9cde6d52 design(t-paliad-178): Tools surface cleanup — split Fristenrechner / Verfahrensablauf
Inventor pass for t-paliad-178. Two intents (deadline determination vs
abstract procedural shape browse) get two dedicated routes:

- /tools/fristenrechner — keeps deadline-determination, gains Step 0
  ("Abstrakt oder Akte?") above today's Step 1.
- /tools/verfahrensablauf — new dedicated abstract-browse surface with
  variant chips (with_ccr / with_cci / with_amend), consolidated-vs-lane
  view, and side-by-side compare.

§0 premise audit corrects three things the task brief got wrong:
  1. projects.court is free-text, not FK — no silent court_id auto-pick.
  2. projects.proceeding_type_id points at litigation-category rows, not
     fristenrechner-category — a mapping helper (litigation × jurisdiction
     → fristenrechner code) is required.
  3. condition_flag variants only exist on UPC_INF + UPC_REV; every other
     proceeding renders a single canonical timeline. Variant chips honour
     this — no dead chips on DE_INF / EPA_OPP / DPMA_*.

Sliced into 4 independent merges: Slice 1 (route + shell split) is the
structural foundation; Slices 2-4 layer Step 0 / variant chips / compare.

DESIGN ONLY — no implementation. Awaiting m's go/no-go before coder shift.
2026-05-12 14:10:20 +02:00
m
84020022a6 design(t-paliad-177): Project Timeline / Chart — visualisation layer above SmartTimeline
Inventor design pass for m/paliad#35. NO IMPLEMENTATION.

Pinned premises:
- SmartTimeline data substrate (projection_service.go, ResponseEnvelope)
  is shipped through Slice 4. Chart is a presentation-only layer.
- No chart libs / PDF libs / headless browser in repo. Bun + std-Go only.
- Custom Views shapes today are list/cards/calendar; "timeline" slot
  reserved by t-paliad-169 §8.6 but not registered.

Recommended:
- Two renderers coexist: existing DOM/CSS shape-timeline.ts (vertical
  embed, Verlauf tab, no changes) + new hand-rolled SVG shape-timeline-
  chart.ts (horizontal Gantt, /projects/{id}/chart standalone). Both
  consume the same TimelineEvent[] + LaneInfo[] substrate.
- Lane model = substrate's existing LaneInfo. No new lane axis. Chart
  adds only render-side state (layout, columns, density, palette, zoom).
- Five built-in palette presets via CSS-var swap (default / kind-coded
  / track-coded / high-contrast / print). No per-user picker in v1.
- Export pipeline:
  - Client-side: SVG (serialize → blob), PNG (drawImage), PDF
    (window.print() + @media print stylesheet).
  - Server-side: CSV (encoding/csv), JSON (alt content type on existing
    /timeline endpoint), iCal (extends caldav_ical.go formatter).
  - Reject chromedp / server-side PDF for v1 — Chromium runtime weight
    not justified by browser-print quality gap.
- Mobile: vertical-only on <640px (horizontal Gantt unreadable on phone).

Phasing (4 sequential slices):
1. Standalone /chart page + horizontal SVG renderer.
2. Export pipeline (SVG/PNG/PDF/CSV/JSON/iCal).
3. Density / palette / zoom controls.
4. Custom Views shape="timeline" registration (cross-project chart).

12 open questions for m's gate. Files implementer touches in Slice 1
listed (~700 LoC frontend, ~50 LoC backend, zero migrations).

Doc: docs/design-project-chart-2026-05-09.md (607 lines).
2026-05-09 18:44:27 +02:00
m
f8cc86cd02 docs(t-paliad-169): SmartTimeline design — Verlauf-tab redesign with past+future+off-script
Inventor design for replacing the project-page Verlauf with a SmartTimeline that
composes past actuals (deadlines, appointments, structural project_events),
present, future-projected (deadline_rules calculator at read time), and
off-script events into one project-scoped vertical timeline.

Key calls:
- virtual view, no new top-level table; single optional column
  paliad.project_events.timeline_kind so a subset of audit rows surface as
  timeline content
- counterclaim = sub-project (new paliad.projects.counterclaim_of FK), parent
  renders parallel tracks; default our_side flips on creation
- date-anchoring reuses fristenrechner CalcOptions.AnchorOverrides — actuals
  anchor downstream projections automatically
- new ProjectionService.For(projectID) thin adapter over FristenrechnerService
- 3 new FilterBar axes (timeline_kind, timeline_status, timeline_track) +
  reuse of time, personal_only, deadline_event_type
- per-level aggregation rule: each level removes one tier of detail and adds
  one tier of grouping (Case → Patent → Litigation → Client)
- 4-slice phasing: skeleton, projection+anchor, counterclaim sub-project,
  parent-node aggregation

12 open questions for m before slice 1 PR opens. Inventor parks per gate
protocol; coder shift only after m's go-ahead.
2026-05-08 23:14:30 +02:00
m
f4815a9f9a docs(t-paliad-167): Determinator coverage audit + smart-navigation framing
Builds on t-paliad-159's UPC RoP audit. Drives from paliad's own corpus
outward: every active rule, every firm-wide event_type, every cascade
leaf — and asks whether a Determinator user can actually reach the row.

Headline finding: 71/76 (93%) of true Fristenrechner deadlines are
reachable from the cascade. The 5 unreachable cluster into one fix:
EP_GRANT (4 rules) plus UPC_INF.inf.app_to_amend lack cascade entry.
Adding an `ich-moechte-einreichen.ep-erteilung` subtree lifts coverage
to 100%.

Per-jurisdiction inventory (UPC, DE, EPO, DPMA) plus a §2.6 cross-cutting
table for the procedural-order categories m flagged (Hinweisbeschluss,
Beweisbeschluss, Streitwertbeschluss, Versäumnisurteil, R.71(3),
Beanstandungsbescheid, etc.).

§4 frames the smart-navigation choice: recommends P2 (persistent escape
button with capture) + P1 (free-text search per cascade level), defers
P3 (flatten deeper levels) until telemetry justifies it. The captured
"Mein Ereignis ist nicht dabei" texts feed both the gap-fill roadmap
and P1's ranking corpus.

No code changes; one markdown doc, 394 lines.
2026-05-08 22:34:23 +02:00
m
1e23745792 docs(t-paliad-163): inventor design — universal filter + view-mode primitive
m/paliad#23. Recommends a single <FilterBar> client component on top of
the existing Custom Views substrate (t-paliad-144) — FilterSpec +
RenderSpec + ViewService + 5 code-resident SystemViews + ad-hoc
/api/views/run already cover every axis the issue lists.

Position: m's "halfway there without custom views" is exactly right.
Lift the substrate from /views/{slug} up to "the bar that every list-
shaped page reads from", with one schema bump (RenderSpec.list.row_action)
to keep entity-table row-click contracts intact.

Migrate one surface per PR: /inbox first (lowest blast radius, no filter
today), /events last (proof point, richest filter). /projects stays
bespoke per t-paliad-149 lock-in.

12 open questions (Q1-Q12) for m before lock-in. No hour estimates.

Verified premises: the issue body's `paliad.user_view_layouts` is a
typo — actual table is `paliad.user_views` (056). `/api/views/run` and
`/api/views/{slug}/run` confirmed live in internal/handlers/views.go.
2026-05-08 21:44:09 +02:00
m
142edca401 docs(paliadin): t-paliad-161 inventor design — inline modal + agent-suggested write path
Two intertwined Paliadin upgrades, scoped together because the chat
surface is where the write path is triggered and the write path is what
makes the chat non-trivial:

1. Inline slide-out modal reachable from every authenticated paliad
   page, with structured page-context payload (route_name +
   primary_entity + selection text) and per-route starter prompts.
2. Agent-suggested write path that drafts deadlines/appointments/notes
   into the existing pending_create lifecycle (t-paliad-160) with new
   provenance columns on approval_requests (requester_kind + agent_turn_id);
   approved-from-agent rows render alongside 👀 with a sparkle .

Hard call: keep the existing tmux relay for v1; recommend (but do not
commit) the Anthropic API cutover as a prerequisite for opening beyond
owner-only. Single Paliadin persona — no scope-bouncer pre-design.

Inventor parked. DESIGN READY FOR REVIEW. Awaiting m's go/no-go before
any coder shift.

Refs: m/paliad#20, t-paliad-146, t-paliad-160, t-paliad-138.
2026-05-08 19:35:39 +02:00
m
b23a08867b Merge: t-paliad-158 — deadline data model proceedings-as-DAG analysis (einstein, 947 lines, m co-drove the design via AskUserQuestion sequence; maps current paliad.deadlines + deadline_rules + event_categories shape against m's framing 'natural sequence of proceedings which belong to a court system' with conditional triggers; proposes target schema for proceedings + court_systems + event-types-as-DAG-nodes with conditional edges; migration sketch for additive overlay vs destructive cutover; honest tradeoff analysis) 2026-05-08 16:27:40 +02:00
m
7be8511833 docs(t-paliad-158): deadline data model — proceedings-as-DAG analysis
Consultant analysis of paliad's deadline data model per m's framing
(court system → proceeding → ordered event types → conditional
trigger edges). Maps current 5-table fragmentation, identifies gaps
G1–G7, locks 5 structural decisions via AskUserQuestion, proposes
target shape with mermaid example, sketches 4-phase additive→cutover
migration. Pure design — no code or schema changes in this branch.

Locked decisions (verbatim):
- Q1: Reuse courts.court_type as court-system identity
- Q2: Project IS proceeding instance (sub-projects when needed)
- Q3: Separate proceeding_event_edges table (multi-parent natural)
- Q4: Typed if_flags/unless_flags/requires_event_id columns
- Q5: Subsume deadline_concepts into event_types.concept_slug
2026-05-08 16:27:04 +02:00
m
afe4fc2efe docs(t-paliad-159): UPC RoP deadline audit
8 RoP sections cross-referenced against paliad's deadline_rules library
via the youpc data.laws_contents authoritative text.

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

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

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

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

Wave 0 (duration bugs) is the recommended first migration.
Wave 1+ orderings, tooling-blocked rules (R.198/R.213/R.245.2),
and m's open questions (proceeding-code naming, R.245 scope,
DNI scope) listed in §6, §7.
2026-05-08 16:21:25 +02:00
m
f820aa8316 Merge: t-paliad-154 — approval-policy authoring UI (migration 062 paliad.approval_policies unit-defaults + 'none' sentinel + tree-walking resolver + 88 unit-default seed rows + paliad.policy_audit_log; ApprovalService rewire with resolver delegation + scope-split CRUD + audit emission; HTTP handlers admin APIs + form-hint endpoint + audit-log union; /admin/approval-policies admin page + admin-index card + form-time hints on deadline/appointment new pages + inbox empty-state nudge for admins; 13 m-locked design decisions honoured verbatim per docs/design-approval-policy-ui-2026-05-07.md §2) 2026-05-08 02:33:25 +02:00
m
bb035558be design(t-paliad-154): approval-policy authoring UI
Inventor pass for m/paliad#13. Surfaces the dormant t-138 4-eye system
(zero policies in DB → silent bypass) by adding /admin/approval-policies
with project-picker → 8-cell matrix + partner-unit-defaults section.

12 design questions surfaced sequentially via AskUserQuestion (per dogma)
and locked in §2 of the doc:

1. Surface: /admin/approval-policies only (admin page card on /admin index)
2. Defaults concept: per-partner-unit defaults
3. Multi-unit conflict: most-restrictive wins
4. Tree inheritance: yes (ancestors contribute candidates)
5. Cross-source precedence: most-restrictive across project+ancestor+unit;
   project row overrides outright
6. Suppression sentinel: 'none' value in required_role enum
7. Soft-disable: no, delete-only
8. Audit emission: /admin/audit-log only, not project verlauf
9. Empty-state: admin-only nudge card on /inbox when zero pending+policies
10. Bulk-apply: per-project "Auf Unterprojekte anwenden" button
11. Seed defaults: yes — conservative associate baseline for all partner units
12. Mobile shape: stacked sections per entity_type
13. Form hint: yes, above Speichern button on deadline/appointment new+edit

Migration 062 adds partner_unit_id (XOR with project_id),
'none' to required_role enum, paliad.approval_policy_effective() resolver,
and seeds 8 rows × N partner_units. ApprovalService.LookupPolicy delegates
to the resolver while preserving its calling contract (existing submit/
decide chain unchanged). New admin endpoints for unit-defaults, matrix
view, bulk-apply, and form-time effective lookup. ~3500-4500 LoC, single
PR, 5 commits.

Inventor parked. NOT cronus per memory directive. Awaiting m go/no-go.
2026-05-07 23:51:38 +02:00
m
f952fb85c3 design(t-paliad-151) amend: port 22022 bypass + Phase A.0 results
Phase A.0 revealed Tailscale SSH on mRiver intercepts :22 from tailnet
peers and bypasses OpenSSH's authorized_keys entirely (banner
"SSH-2.0-Tailscale", auth method "none", command= restriction never
fires). The fix is port 22022 via a systemd ssh.socket drop-in:
Tailscale SSH only intercepts :22, so :22022 hits real OpenSSH where
the design's command=/from= shim restriction works as specified.

Updated:
- §3 locked decisions: row 5 added (port 22022, m's call 23:35)
- §4.5 new subsection: Tailscale SSH bypass via socket drop-in
  + records the "Address already in use" first-attempt failure as a
  "don't retry without cleaning sshd_config Port directives first"
  lesson
- §5.2/5.3: ssh-keyscan now uses -p 22022; known_hosts is host:port
  keyed for non-22 ports
- §6.1/6.2/6.3: SSHPort field on RemotePaliadinService config, -p
  flag in callShim, PALIADIN_REMOTE_PORT env (default 22022)
- §7 phasing: A.0 completion checked off step-by-step with concrete
  fingerprints; A.5/A.6/A.7 split out as m-driven
- §8 security: Tailscale-SSH-on-:22 risk explicitly tabled with
  port-22022 mitigation
- §10 deliverables: mRiver host-setup artifacts noted
- §12 new Phase A.0 completion summary with the three secrets m
  needs to register in Dokploy

Phase A.0 verified end-to-end:
- ssh -p 22022 paliad-prod-key m@mriver health → ok
- run-turn UUID base64msg → 3.4 s including a real Claude response
- from="100.99.98.201" correctly rejects connections from mRiver
  itself

mRiver host state in place (not in repo): authorized_keys with
restrictions, /home/m/.local/bin/paliadin-shim, ssh.socket drop-in.
Three secrets staged at ~/.paliad-staging/ on mRiver for m to copy
into Dokploy: paliad-prod-key (PALIADIN_SSH_PRIVATE_KEY),
known_hosts (PALIADIN_KNOWN_HOSTS), and the three plain env vars.

Refs m/paliad#12
2026-05-07 23:37:26 +02:00
m
befa41c00e design(t-paliad-151): Paliadin Tailscale SSH route to mRiver
Inventor design for routing Paliadin from paliad.de's Dokploy container
on mLake to mRiver via Tailscale + SSH, preserving m's Claude Code
subscription instead of paying Anthropic API tokens.

Three sub-designs covering m's four locked decisions (2026-05-07 22:35):
- network_mode: host on paliad (m overrode the sidecar recommendation;
  Phase A explicitly tests traefik compatibility under host mode)
- server-side paliadin-shim with one RPC per turn (run-turn / reset /
  health / bootstrap), authorized_keys command= restriction, from=mlake
- env-var routing trigger (PALIADIN_REMOTE_HOST) + Paliadin interface
  split: LocalPaliadinService keeps the laptop PoC, RemotePaliadinService
  shells out to ssh m@mriver paliadin-shim
- ed25519 keypair via Dokploy secret PALIADIN_SSH_PRIVATE_KEY, written
  to a chmod 600 tmpfile at startup; pinned host key via
  PALIADIN_KNOWN_HOSTS

Verified live before designing: mRiver tmux+claude present, mLake
Tailscale active and sees mRiver, paliad Dockerfile is alpine-minimal,
no authorized_keys on mRiver yet. No assumptions left from CLAUDE.md.

Includes: friendly error code mriver_unreachable extending t-paliad-150,
single-flight rate limit, security review (defence-in-depth via
command=/from= restrictions), three-phase rollout (manual proof →
Dockerfile bake → polish), file-level deliverables for the coder shift.

Inventor stops here — no code shipped. Awaiting m's go/no-go.

Refs m/paliad#12
2026-05-07 22:47:30 +02:00
m
438e73fd13 docs(t-paliad-149): renumber migrations 058→060 (PR 1) and 059→061 (PR 2)
058 = paliadin_poc (t-146), 059 = profession_vs_responsibility (t-148), both shipped on main 2026-05-07. Next available is 060.

Per maria's coder-shift instruction.
2026-05-07 22:15:22 +02:00
m
597d76e21c Merge remote-tracking branch 'origin/main' into mai/godel/inventor-projects-page 2026-05-07 22:14:28 +02:00
m
b9824dd86f docs(t-paliad-149): lock 4 surfaced questions per m's AskUserQuestion answers
m's locks (2026-05-07 22:08):
- Q1 default landing → last-viewed restore (sessionStorage; URL params override; first-visit fallback Tree+Alle+top-level)
- New-Q20 cards default content → rich (~9 facts: title+type+status+clientmatter+parent path+deadline counts+next 3+last 3+team)
- New-Q21 cards customisation → FULL drag-rearrange + named layouts (new paliad.user_card_layouts table, migration 059)
- Q13 search shape → both (in-place page filter on active view + global Cmd-K palette unchanged)

Implementation impact: PR 2 grows from ~700-900 LoC to ~1300-1700 LoC because
m chose (c) full drag-rearrange over (b) localStorage-only. New backend
service CardLayoutService + JSON validator + 5 endpoints; frontend gets
edit-mode chrome + HTML5 drag-and-drop + layout dropdown. Optional internal
PR 2a / PR 2b split if review feels heavy (read-only cards first, then
customisation).

PR 1 (tree + chips + pin + search) is unchanged at ~1100-1400 LoC.
Other 17 recommendations stay READY-FOR-REVIEW per the dogma.
2026-05-07 22:11:18 +02:00
m
397a9b1854 docs(t-paliad-149): inventor design — projects page redesign (tree-first + chips + pinning + cards)
Three view modes (Tree default | Cards | Flat), chip filter row, pinning,
search-as-tree-filter, mobile drill-in. Cards view (m's addition) has
configurable content + per-user prefs in localStorage v1.

Q15 decision (delegated to inventor): bespoke /projects, NOT Custom Views.
Custom Views is event-shaped; projects are scope, not events. Adding
SourceProject + ShapeTree to t-144's substrate would break shape ⊥ source
orthogonality. Reversible if a unifying abstraction emerges.

Two-PR phasing: PR 1 = tree + chips + pin + search (~1100-1400 LoC,
migration 058). PR 2 = Cards view + customisation modal + cards-preview
endpoint (~700-900 LoC, additive on PR 1).

4 surfaced questions for m via AskUserQuestion: default landing + view mode,
cards default content, cards customisation scope, search shape. Other 17
questions answered with recommendations + rationale per the dogma (make it
easy for m).

Awaiting m's go on §12 questions before locking. NO coder shift until lock.
2026-05-07 22:05:44 +02:00
m
efaa7787af Merge remote-tracking branch 'origin/main' into mai/kepler/inventor-profession-vs 2026-05-07 22:00:26 +02:00
m
d24f73358c design(t-paliad-146): re-scope to PoC track — m-only + monitoring
m's reframing 2026-05-07 20:56: Paliadin is "mostly for myself now
but can be expanded — monitoring use." Two-stage shape replaces the
single-PR production-v1:

- Phase 0 (PoC): tmux-Claude pattern lifted from goldi/mVoice
  (mVoice/server.py:250-380). Claude Code window in a long-lived
  tmux session, prompts via tmux send-keys -l, response via
  /tmp/paliadin/{turn_id}.txt tail-f → SSE relay. Single user (m),
  m's laptop only (PALIADIN_ENABLED=false on prod). ~600-900 LoC,
  ~1 day. Migration 057 (PoC variant) stores full prompt + response
  for monitoring — no redaction at this scope.
- Phase 1 (production v1): the original §2-§6 Anthropic API design,
  GATED on PoC success per §0.5.7 expansion criteria (≥3 turns/wd,
  ≥50% tool-use rate, 4 weeks).

§0.5 (new) inserted as the load-bearing PoC spec. §7 leads with the
two-stage frame. §8.5 questions split into PoC-relevant (Q-PoC-1..6)
and production-v1-deferred. youpc case-law lookup promoted to
Q-PoC-6: m himself does case-law research, so include it from day
one (cross-schema SELECT into data.judgments is technically trivial
since paliad and youpc share the same Postgres).

What we drop for PoC: Anthropic API client, BYO-AI, rate limit,
token caps, multi-user RLS edge cases, /admin cost dashboard,
compliance disclosure, most i18n keys.

What we keep: system prompt voice, citation discipline (best-effort),
visibility gate (Claude is required to use paliad.can_see_project()
in queries), /paliadin surface, SSE shape, audit table.

The two-stage shape protects against the t-145 pattern: ship cheap,
observe, decide. No 4500-LoC investment based on m's gut feel about
adoption.
2026-05-07 20:59:46 +02:00
m
dc7c807725 design(t-paliad-146): Paliadin — in-app AI buddy
Inventor design pass for the Paliadin: a Claude-backed conversational
assistant grounded in the user's own paliad data + paliad's static
reference (courts, glossary, deadline rules, Fristenrechner concept
tree). Long-lived in-process Go service that calls Anthropic's
Messages API directly with tool use; every tool is a thin shim over
an existing service (Dashboard / Project / Deadline / Appointment /
Court / Glossary / DeadlineRule). RLS / visibility inherited from
those services — Paliadin literally cannot see what the caller cannot.

Five coordinated sub-designs answer the issue's 20 open questions:
  A. LLM architecture + tool-use + prompts (§2)
  B. Data access + RLS + PII (§3)
  C. UX (§4)
  D. Token budget + cost + audit (§5)
  E. Phasing (§7)

Phase 1 v1: /paliadin full page + sidebar entry, SSE stream of
Anthropic, 7 read-only tools, session-only history, 30/hour user cap
+ 1000/hour global cap, audit row per turn (metadata only — no
transcript), 4k input + 2k output token caps, no avatar/mascot, no
proactive onboarding. Migration 057 introduces paliadin_turns +
paliadin_rate_limit. Single PR, ~3500-4500 LoC.

mlex / /lex-* reuse: shape (system-prompt voice, tool-catalog idea,
citation style) — NOT code. mLex is a workspace, not a Go/TS repo;
the /lex-* skills drive Claude against youpc's MCP and cannot be
embedded in a paliad service.

Premise verifications surfaced one CLAUDE.md doc-bug (the
ANTHROPIC_API_KEY "Reserved for Phase H — do not set" row needs to
flip in the implementation PR — Paliadin un-defers it).

12 open questions for m in §8.5 — Anthropic key choice (personal vs
HLC enterprise), default model (Sonnet vs Haiku), surface
(/paliadin page vs drawer), mascot phase, 2-PA sanity check before
locking scope, etc. Same adoption-risk concern that just parked
t-paliad-145 — Paliadin's edge over open-Claude-in-another-tab is
data grounding, which only works if v1 makes it visible (citation
chips + tool-call evidence + tagline).

STOP after design. Awaiting m go/no-go before coder shift.
2026-05-07 20:45:31 +02:00
m
1eb43ceb6b design(t-paliad-148): split project_teams.role into firm-level profession + project-level responsibility
Inventor design doc (kepler) for issue m/paliad#6. Splits the conflated
project_teams.role column into two axes:

- paliad.users.profession (firm-wide, drives t-138 approval ladder)
- paliad.project_teams.responsibility (per-project, lead/member/observer/external)

Approval ladder evaluated as tuple: profession_level if responsibility
opens the gate (lead/member), else 0. Policy grammar from t-138 stays
single-valued.

Verified live state: project_teams=3 rows (all 'lead'), partner_unit_members=20
rows (all default 'attorney'). Backfill is essentially trivial; risk is the
SQL rewiring (4 sites in approval_service.go, 2 in derivation_service.go,
2 in reminder_service.go) — all mechanical.

12 open questions from issue body answered with recommendations + rationale +
alternatives. Awaits m's go before any coder shift.

DESIGN READY FOR REVIEW.
2026-05-07 20:45:07 +02:00
m
dd4f563212 design(t-paliad-145): local chat for teams
Inventor design for in-app messaging surface inside paliad. Three
coordinated sub-designs (surface/visibility, real-time/content/
persistence, integration with existing surfaces) answering all 21
issue-body questions plus 11 inventor follow-ups.

Recommendations:
- Per-project chat + DMs in v1; per-deadline/termin/partner-unit defer
- Per-thread visibility = can_see_project (existing predicate, derivation-aware)
- SSE for real-time (single new long-lived endpoint)
- New: paliad.chat_threads, chat_messages, chat_reads, chat_thread_participants, chat_mentions
- New project_teams.chat_access flag, default OFF for local_counsel/expert
- Approval auto-post into project chat (one auto-event class only)
- Markdown subset, @mentions, entity-refs (#frist-, #projekt-, #termin-, #approval-)
- 5-min author edit window, soft-delete by author or admin
- In-app sidebar badge in v1; PWA push + email digest deferred Phase 2
- Both top-level /chat and per-project Chat tab
- NOT a 5th source in Custom Views (chat is conversation, not events)

Trade-off flagged: adoption risk against existing Slack/WhatsApp.
Recommend m sanity-check with PA colleagues before locking v1 scope.

Migration 057. Awaiting m go/no-go before coder shift.
2026-05-07 16:03:05 +02:00
m
956ff10e4d design(t-paliad-144): m signed off + Q4 correction (3 shapes, not 4)
m's lock-in 2026-05-07: agree with all recommendations on Q1-Q18 and §10
Q19-Q27, with one correction on Q4: "activity" is a content selection
(sources + filters), not a render shape. Folded into `list` shape with
density: "compact" + actor/time columns. Shape ⊥ source — any source can
render in any shape.

Render shapes for v1: list / cards / calendar (3, was 4).

PR split decision (delegated to inventor): A1 backend substrate + API
(no UI change, ~1800 LoC, smoke via curl) → main → A2 frontend Custom
Views UI (~1600 LoC, additive on A1) → main.

Status flipped DRAFT → LOCKED. Inventor → coder transition initiated.
2026-05-07 12:36:05 +02:00
m
5c263102e3 design(t-paliad-144): data display model — additive Custom Views + render-shape switcher
Inventor pass on m's data-display rethink (m/paliad#5). Three coordinated
sub-designs in one doc, scoped to m's locked direction (additive, subsume
unified inbox, sidebar Meine Sichten group, in-page render-shape switcher,
paliad-only).

Recommended substrate: 4-source ViewService (deadline + appointment +
project_event + approval_request) returning discriminated ViewRow.
Recommended filter grammar: structured JSON spec with server-side validator.
Recommended render shapes for v1: list / cards / calendar / activity (defer
kanban, connections-graph, distinct-timeline). Recommended persistence:
new paliad.user_views table (migration 056), RLS-bounded to caller, code-
resident system defaults (no is_system flag).

Phasing: Phase A ships substrate + Custom Views standalone (~3400 LoC,
no system page changes); Phase B refactors /agenda/events/inbox/dashboard
internals onto the substrate later. Coexists transparently with t-139
(hierarchy aggregation in flight on noether's other branch) and t-138
(approvals shipped).

27 questions answered (18 from issue body §1–§5 + 9 inventor follow-ups
in §10 for m's call before coder shift).
2026-05-06 17:25:44 +02:00
m
2d06cdf20e Merge: t-paliad-139 Phase 1 — /projects/{id} aggregation bug fix (use projectDescendantPredicate on 3 legacy narrow methods + frontend toggle + attribution chip) 2026-05-06 16:29:14 +02:00
m
2247c0707d docs(t-paliad-139): design lock — m signed off on all 19 §6 recommendations
m's go/no-go pass at 2026-05-06 15:58: "I agree with all your recommendations
- go." All 19 questions in §6 lock as the recommended answers verbatim.

§0 status flipped from READY-FOR-REVIEW to LOCKED. New "Locked m decisions
on §6" subsection captures the highlights inline so future readers don't
have to scan the whole table to know what's pinned.

§13 end-of-design line updated to reflect the lock.

Implementation phasing (§7) unchanged:
- Phase 1: bug fix on the 3 narrow service methods (no schema, ~400 LoC,
  ships standalone, closes the user-visible /projects/{id} "Keine Fristen"
  bug).
- Phase 2: migration 055 (partner_unit_members.unit_role,
  project_partner_units, extended can_see_project()) + DerivationService +
  frontend Team-tab subsections + /admin/partner-units unit_role tagging
  + project /settings/team Partner Units section. Independent of t-138.
- Phase 3: approval extension — canApprove + inbox SQL widening for
  derived_peer decision_kind. Gates on cronus's t-138 (currently on
  mai/cronus/inventor-dual-control @ b3401ec) landing on main.

Inventor parked. Awaiting head's coder-shift assignment.
2026-05-06 15:59:37 +02:00
m
6c41550945 docs(t-paliad-139): inventor design — hierarchy aggregation + effective team + PA derivation
Three coordinated sub-designs in one doc, scoped to m's locked constraints
(2026-05-06):

1. Surface-by-surface aggregation policy. Bug surface fix:
   /projects/{client_id} renders "Keine Fristen" because
   DeadlineService.ListForProject + AppointmentService.ListForProject +
   ProjectService.ListProjectEvents all WHERE project_id=$1 exact-match
   instead of walking paliad.projects.path descendants. The shipped t-124
   contract (projectDescendantPredicate, deadline_service.go:133 etc.)
   already aggregates correctly on the union endpoints — three legacy
   narrow paths just bypass it. Per-surface decision table for events /
   deadlines / termine / Verlauf / project tree counts / dashboard /
   CalDAV / email / search.

2. Effective-team semantics. Three structural gaps in the issue's
   premise (verified against schema):
   - No project↔unit junction (partner_unit involvement on a project).
   - No PA/lawyer distinction in partner_unit_members (no role column).
   - No lawyer↔PA pairing anywhere — Q11's "where is it stored" → nowhere.
   Proposes:
   - paliad.partner_unit_members.unit_role (lead|attorney|senior_pa|pa|paralegal),
     unit-scoped not firm-wide so 3-axis principle holds.
   - paliad.project_partner_units junction with derive_unit_roles[]
     (default {pa, senior_pa}) + derive_grants_authority bool.
   - Compute-on-read derivation via extended can_see_project() — no
     materialised state, no drift.
   - Display-effective vs visibility-effective team are different sets;
     rename ListEffectiveMembers to ListVisibilityEffectiveMembers + add
     ListSubtreeMembers.

3. Approval policy × hierarchy × derivation. Coordinates with t-138
   (cronus, mai/cronus/inventor-dual-control @ 7d1ddb9):
   - Q10: keep cronus's no-auto-inheritance, harden UX with a "Eltern-
     Politik (zur Information)" panel showing parent rules without
     applying.
   - Q12: derived members visibility-only by default; per-(project, unit)
     opt-in flag derive_grants_authority. When opted in, decision_kind
     extends with derived_peer for honest audit chronology.
   - canApprove + inbox SQL extension shape spec'd; coordinates with
     cronus's t-138 §3.4 / §7.4.

Locked m decisions surfaced in §0:
- Behaviour is surface-specific.
- Effective Team of a Client = direct ∪ descendants ∪ partner-unit-derived.
- PA derivation = unit-on-project trigger.
- Derivation honesty: annotated everywhere.
- paliad-only scope.

19 design questions with proposed answers in §6 for m to lock. Migration
055 specced (§5). Implementation phased into 3 PRs (§7) — Phase 1 bug fix
ships standalone if m wants quick win.

Inventor parked. Awaiting m go/no-go before coder shift.
2026-05-06 15:38:41 +02:00
m
7d1ddb9b84 docs(t-paliad-138): inventor design — dual-control approvals (4-eye)
Locked design for 4-Augen-Prüfung on Fristen + Termine. m-confirmed
decisions on all 11 open questions:

- Qualification gate reuses paliad.project_teams.role per-project
  (no new firm-wide axis). Adds new value `senior_pa` to the enum.
- Strict ladder: lead > of_counsel > associate > senior_pa > pa.
  Default required_role = associate. Per-project override allows pa-
  approves-pa or senior_pa-tier escalation.
- Per-(project, entity_type, lifecycle_event) policy grammar — up to
  8 settable rows per project in paliad.approval_policies.
- Edit-trigger allowlist = date-bearing fields only (Frist due_date /
  original_due_date / warning_date; Termin start_at / end_at).
- Write-then-approve: row mutates immediately, approval_status flips
  between approved/pending/legacy. Delete is the one stage-then-write
  exception (hard-delete on approve, restore on reject).
- Refuse + global_admin override on single-qualified-approver deadlock.
- Pending state visualised everywhere — list views, agenda, dashboard
  traffic-light, project detail, CalDAV-synced calendars (`[PENDING] `
  title prefix), email reminders.
- Bell + /inbox page with two tabs (zur Genehmigung / meine Anfragen).
- Operational paliad.approval_requests + audit lifecycle written to
  existing paliad.project_events (4 new event_types per entity).
- RLS = same can_see_project predicate; service layer enforces the
  approve/reject action gate. CHECK constraint blocks self-approval.
- Mark-legacy backfill: approval_status='legacy' on existing rows;
  next mutation flows through the gate.

Implementation phasing: single migration 054 + 8-commit PR plan
covering schema, service, wiring, policy authoring page, inbox,
pending pills, CalDAV/email integration, Verlauf rendering.

Inventor parked. Awaiting m go/no-go before any coder shift.
2026-05-06 14:58:01 +02:00
m
bf06499d9c docs(t-paliad-122): inventor design — courts entity + per-country holidays
Archives m's locked design call (2026-05-05 18:51) plus live-codebase
verification: paliad.holidays.country exists per-country; paliad.courts
does not (must create); proceeding_types.jurisdiction is regime not
country (do not remove); 41 hand-curated courts already in
internal/handlers/courts.go ready to seed; HolidayService.loadYear is
country-blind today (latent bug); germanFederalHolidays merge is
hardcoded (must become country-conditional). Task stays ON-HOLD until a
non-DE forum or EPO closure-day calendar comes into scope.
2026-05-05 23:51:47 +02:00
m
30ac337a78 docs(t-paliad-136): Fristenrechner v4 inventor design
v4 addresses three concerns from m on 2026-05-05 in priority order:

1. Card-click → compute deadline → add-to-project (v3 cards were dead-ends).
2. Filter narrowing bug — slug → concept_id allow-list dropped per-leaf
   proceeding_type_code, so picking "UPC infringement opposing party"
   leaked DE/EPA/DPMA pills. Confirmed via DB query: 25+ leaves overbroad.
3. RoP-rigorous tree audit: 6 confirmed seed errors (Hinweisbeschluss
   DE_INF mismap, notice-of-defence-intention UPC_INF mismap, three
   cost-appeal notice-of-appeal mismaps, request-for-discretionary-review
   needs UPC_APP_ORDERS narrowing), plus reply-to-cross-appeal coverage
   gap and bescheid-mit-frist orphan.

Plan splits into three independent phases (A: filter fix, no schema; B:
card-click flow + new calculate-rule endpoint; C: taxonomy migration 052
without RAISE EXCEPTION coverage gates per last night's outage lesson).

Inventor → coder gate held: no production code in this commit.
2026-05-05 12:11:36 +02:00
m
f40b652d01 Reapply "Merge: t-paliad-133 — Fristenrechner v3 (Pathway A/B fork + B1 decision tree + B2 forum filter + retire legacy tabs)"
This reverts commit 5bd17de732.
2026-05-05 11:18:38 +02:00
m
5bd17de732 Revert "Merge: t-paliad-133 — Fristenrechner v3 (Pathway A/B fork + B1 decision tree + B2 forum filter + retire legacy tabs)"
This reverts commit f7d72ff1d3, reversing
changes made to 1ea983f0c7.
2026-05-05 11:17:58 +02:00
m
7e363ac01d design(t-paliad-133): lock v3 design with m's answers (10:33)
m approved all 12 open questions in one batch. Locked spec:

1. Legacy tabs RETIRED in Phase E.
2. Decision-tree depth UNLIMITED (was: 4 max). Property of
   event_categories data, not hard-coded.
3. Clickable breadcrumb for navigation.
4. Partial-path bookmarks (?b1=...).
5. Multi-select forum filter, default 1 selected.
6. Path-matching cards at each step. Renamed "Pfad lockern" →
   "Schritt zurück".
7. Emojis only, no separate colour treatment.
8. Forum buckets simplified to 10: UPC CFI + UPC CoA + DE LG/OLG/
   BGH/BPatG + EPA Erteilung/Einspruchsabt./Beschwerdek. + DPMA.
   m collapsed UPC LD/CD into UPC CFI (rules identical).
9. B1↔B2 share filter state.
10. Single branch / sequential commits / one final merge.
11. Party perspective default Claimant/Proactive; localStorage
    remembers last-used. URL ?my_side= + ?appeal_filed_by=.
12. Bilateral rules tagged via new is_bilateral column on
    deadline_rules; mirroring only when flagged.

Maria's two scope additions folded in:
- Court-system granularity for forum filter (clarification).
- Party-perspective selector absorbing t-paliad-132.

Implementation now starting on this branch.
2026-05-05 10:37:44 +02:00
m
2ed476dc64 design(t-paliad-133): Fristenrechner v3 — Pathway A vs Pathway B fork
m's 2026-05-05 brief restructures the page surface that v2 (t-paliad-131)
shipped. The current Fristenrechner stacks three blurred entrypoints —
Phase D search bar, Verfahrensablauf tile grid, "Was kommt nach…" tab.
v3 forks the page so each mental model has its own entry:

- Pathway A — Verfahrensablauf informieren (Browse): existing wizard.
- Pathway B — Frist eintragen aufgrund Ereignis (Event → Deadline),
  subdivided into:
  - B1 Entscheidungsbaum: data-driven button cascade (CMS-Eingang →
    Vom Gericht → Hinweisbeschluss → cards), max 4 deep, back +
    breadcrumb + bookmark URLs.
  - B2 Filter / Suche: Phase D concept-card search PLUS new
    Gericht/System multi-select chip filter (Q8 reversal). All filters
    AND-narrow.

Adds two new tables (Phase A — purely additive):

- paliad.event_categories — recursive taxonomy tree, with step
  questions on non-leaf nodes.
- paliad.event_category_concepts — leaf → concept junction with
  optional proceeding_type_code narrowing.

Existing data layer (deadline_concepts, deadline_rules, trigger_events,
deadline_search matview) untouched. Phase D search handler gains
?event_category_slug= and ?forum= query params; forum-bucket map lives
in Go (UPC / DE LG / DE OLG / DE BGH / DE BPatG / EPA / DPMA).

Phasing: A (data) → B (landing fork) → C (B1 tree) → D (B2 forum
filter) → E (retire legacy tabs, gate-gated). Each phase independently
shippable.

Open questions for m at §10: retire legacy tabs, decision-tree depth,
back/breadcrumb, partial-path bookmarks, multi vs single-select forum,
all-vs-path-matching cards per step, austere icons, 7 forum buckets,
B1↔B2 state-sharing, PR phasing.

Inventor parked. Next: m's go/no-go before coder shift.

Cross-references docs/plans/unified-fristenrechner.md (v2, shipped) for
concept-layer / search-backend / coverage details v3 inherits unchanged.
2026-05-05 10:21:20 +02:00
m
20eaa9bba4 design(t-paliad-131): v2 — flip slug rule (EN for shared) + drop flag_param
m's revisions (23:36):

- Q1 corrected: EN slug for shared concepts too (klageerwiderung →
  statement-of-defence, replik → reply-to-defence, berufungsfrist →
  notice-of-appeal, einspruchsfrist → opposition, wiedereinsetzung →
  re-establishment-of-rights). DE slug only for German-law-only
  concepts (nichtzulassungsbeschwerde, versaeumnisurteil-einspruch,
  hinweisbeschluss-stellungnahme).

- Q4 simplified: drop the customizable-extension flag_param mechanism.
  Replace with a generalised "user can override any computed date,
  downstream re-anchors off it" capability. CalcOptions gains
  AnchorOverrides map[string]string; tree-walk consults it before the
  computed-date map. UI gives each row a click-to-edit date affordance
  (also unlocks court-set decision dates being entered post-hoc, which
  the existing IsCourtSet placeholder UX has been hinting at). PatG §82
  seed stays at 2 months static; user-set extensions handled by inline
  date override, not by a flag_param mechanism.

  Cleaner. No new DB column. Generalises beyond extensions to any case
  where the user knows the real date better than the calculator's
  projection.
2026-05-04 23:38:23 +02:00
m
94ebc1d043 design(t-paliad-131): v2 — m's answers to the 8 v2 open questions locked
- Q1 concept slug naming: mixed convention. EN slug for UPC/EPC-native
  concepts (application-to-amend, request-for-discretionary-review).
  DE slug for German-only concepts (nichtzulassungsbeschwerde,
  versaeumnisurteil-einspruch). DE slug for SHARED concepts that exist
  in both DE and UPC/EPC (klageerwiderung, replik, berufungsfrist,
  einspruchsfrist, wiedereinsetzung) because m works primarily in
  German and the slug is internal/maintenance-facing only.
- Q2 EU.EPÜ confirmed for EPÜ namespace.
- Q3 PatG §111(1) 1mo→3mo confirmed for Phase B3.
- Q4 PatG §82(1): shape (b) — 1mo base + with_extension flag with
  CUSTOMIZABLE extension duration (default 1mo). New flag_param
  mechanism on flag-conditioned rules: CalcOptions.Flags becomes
  map[string]int; rules with flag_param_code add caller's param to
  duration. UI shows number input next to checkbox. Generalises to
  PatG §75 etc. Phase A5 picks up the calculator extension; Phase B3
  hooks PatG §82.
- Q5 Full Appeal Chain: multiple date inputs per stage, no inter-stage
  gap guessing. Stage N's downstream deadlines render as IsCourtSet
  placeholders until user enters Stage N-1's terminal decision date.
- Q6/Q7/Q8 confirmed as drafted.

§5.2.2 PatG §82 row updated to reflect flag-based shape. §4.4 concept
slug examples expanded with the mixed-convention rule rendered
explicitly. §7 Phase A5 added for the flag_param calculator change.
2026-05-04 23:33:33 +02:00
m
79f09006fc design(t-paliad-131): v2 — incorporate m's go-direction (Unifier shape, concept cards, no tab subsumption)
Significant restructure after m's 10 answers (relayed via head 23:10):

- Augment, not replace — search bar at top + existing tile grid stays as
  browse fallback. Both existing tabs stay live. Phase E (subsumption)
  dropped.
- Unifier shape: new paliad.deadline_concepts layer above existing
  deadline_rules; deadline_rules gains concept_id FK + structured
  legal_source. condition_flag scalar→array (Q3) for AND-of-flags
  semantics on UPC_REV (with_amend ∥ with_cci).
- Search hits as ONE card per concept with proceeding pills inside (NOT
  a flat list of one-per-proceeding hits). Card body: pills [UPC R.23.1
  3mo] [LG §276.1 6w] [BPatG §82.1 1mo] [EPA R.79.1 4mo] etc.
- Structured legal_source codes: UPC.RoP.23.1, DE.ZPO.276.1,
  EU.EPÜ.108, DE.PatG.111.1 — parseable, filterable, indexed.
- "Vollständige Instanzenkette" checkbox synthesises LG→OLG→BGH (or
  BPatG→BGH) timeline as one tree at render-time; data stays per-
  instance.
- Forum filter dropped (Q8). Filters now: Verfahrensart / Partei /
  Rechtsquelle.
- Court-set placeholders ("Verhandlung", "Entscheidung",
  "Zwischenverfügung") surface as searchable triggers (Q10).
- Columns-view sequence preservation (Q9) flagged but punted to a
  separate follow-up task — t-paliad-129 column renderer must respect
  sequence_order even on undated court-set events.

8 remaining open questions for m (concept slug convention, EPÜ
namespace, PatG §82(1) modeling, Full Appeal Chain anchor handoff,
quick-pick chip seed, etc.).
2026-05-04 23:21:28 +02:00
m
355e718516 design(t-paliad-131): unified Fristenrechner — search-by-anything + complete coverage
Inventor design doc at docs/plans/unified-fristenrechner.md.

Covers:
- Single search bar UX over both deadline_rules (proceeding-tree) and
  trigger_events (event-driven) backends, federated via a materialised
  view with pg_trgm indexes.
- Faceted filters: forum, proceeding type, party, legal source.
- UPC counterclaim cross-flows missing today (R.29(a)/(d)/(e), R.30,
  R.32, R.43.3, R.49(2), R.51, R.52, R.55, R.56) — verbatim citations
  pulled from data.laws_contents (UPCRoP).
- German PatG/ZPO gap audit: missing OLG + BGH-Revision + BGH-NZB cycles,
  ZPO §339 Versäumnis, §521 Berufungserwiderung, PatG §111 (likely 1mo→3mo
  fix), DPMA Einspruch + Beschwerde. EPA gaps: R.116, R.79(2/3), R.106
  Überprüfung, Wiedereinsetzung × 3.
- Phased migration plan A–E, each independently shippable.
- 10 open questions for m's go/no-go before coder shift.

No code changes; awaiting m's review.
2026-05-04 23:11:16 +02:00