135 Commits

Author SHA1 Message Date
mAi
c945cbd330 docs(prd): fix 3 schema inaccuracies in litigation-planner PRD
planck flagged via mai report feedback (id 12301) after the B5+B6
verification round caught them:

- §5.4 'INSERT into paliad.project_parties' → real table is paliad.parties
- §5.4 'status=open' → real CHECK constraint allows pending/completed/cancelled/waived
- §7.4 listed verfahrensablauf-detail-mode.ts as dead code, but builder
  imports filterByDetailMode from it; struck through with KEEP note.

Code shipped (B5+B6) used the correct values throughout; this aligns
the historical PRD with reality so a future reader doesn't repeat the
verification time planck spent.
2026-05-31 15:16:55 +02:00
mAi
091804923a docs(docforge): PRD — modular doc-generator engine (t-paliad-349)
Extract the submission generator into pkg/docforge: neutral document model
+ opaque carrier (lossless .docx), VariableResolver interface per namespace,
pluggable importer/exporter (.docx first), WYSIWYG authoring page, generic
editor UI package. 8-slice train, extract-in-place migration that protects
the b78a984 underscore fix, the placeholderRegex + data-var contracts, and
the building-block/section model.

Includes all 13 of m's decisions (5 prose-grill metaphor + 8 structured).
upc-kommentar deferred as a live consumer (it is Bun/SvelteKit/TS, zero Go);
abstractions sized for a later HTTP veneer.

m/paliad#157
2026-05-29 14:33:26 +02:00
mAi
661d87273c docs(plans): PRD — Procedures Litigation Builder (m/paliad#153)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
PRD for the columnar litigation planner replacing today's 4-tab catalog
at /tools/procedures with a Litigation Builder backed by a new Scenario
DB. Captures 20 chip-picker decisions (5 batches via AskUserQuestion)
covering: unified-builder shape with 3 entry modes (cold-open /
event-triggered / Akte), separate paliad.scenarios table with
multi-proceeding constellations, auto-save + named-list, per-proceeding
flags + perspective + Detailgrad, 3-state event cards
(planned/filed/skipped), per-event-card optional horizon, vertical
stacked column-triplets with inline spawn children, universal search
(events + scenarios + Akten), 3-step promote-to-project wizard,
read-only team sharing, desktop v1 + mobile basic-read.

Includes data model deltas (4 new tables + 1 column on
paliad.projects), 6-slice migration plan from the current live U0-U4
catalog, and coder hand-off notes. Cross-proceeding peer triggers and
DE/EPA/DPMA full expansion deferred to v1.1.
2026-05-27 23:00:24 +02:00
mAi
c8f310c62c design(procedures-tracker): fold m's 7 picks — §11 decisions + §6.5 multi-tl anchor + §9 direct-replace migration (t-paliad-337)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
5 picks on-recommendation, 2 diverged:

Q3 (multi-proceeding anchor scope): m picked 'other timelines auto-collapse to header-only' over the recommended 'stay expanded'. Added §6.5 with the header-card render rule.

Q7 (migration cadence): m picked 'direct replace at T1, no flag' over the recommended flag-gated dev. §9 rewritten end-to-end: T1 ships the minimum-viable tracker visibly to users, replacing the catalog UI in the same PR. T2-T4 layer zoom + Akte + polish. T5 is cleanup-only.

The 5 on-rec picks: inline checkbox forks (Q1), sibling-collapse zoom (Q2), 6 curated defaults on cold open (Q4), latest-done-deadline Akte anchor (Q5), global Stichtag (Q6) — all locked as drafted in §1-§8.

Ready for review. Coder gate held; head decides T1 hire.
2026-05-27 21:13:35 +02:00
mAi
7554e86673 design(procedures-tracker): rewrite after m's reframe — single timeline-tree, inline forks, no view toggle (t-paliad-337)
m's grilling-round answers (2026-05-27 21:01):
1. One canonical view (full timeline/tree); zoom is an interaction on it, not a separate view.
2. Forks = everything: scenario flags + optionals + appeal-target + court-set picks.
3. Find = combined affordance: text + pills + result-timelines are one thing.
4. Aux proceedings inline as expandable child timelines.

Doc rewritten end-to-end. The first draft's three-view toggle + Konstellationen drawer + Querverweise drawer + split-pane/breadcrumb apparatus collapses into:
- Sticky find header (search + pill rows + Akte/date)
- N matched proceedings rendered as inline-forked timeline-trees
- Anchor pin + opt-in zoom mode (collapses siblings, breadcrumb back)
- Aux proceedings expand inline at the spawn point

7 open questions in 4+3 batches for AskUserQuestion. T1-T5 migration unchanged in spirit.
2026-05-27 21:05:41 +02:00
mAi
23b151c0f3 design(procedures-tracker): t-paliad-337 shift-1 — workflow-tracker layer for /tools/procedures (m/paliad#152)
m's reframe (2026-05-27 20:43): /tools/procedures should be a workflow
tracker, not a catalog browser. Pick any procedural event, see backward
(predecessors) + self (where I am) + forward (successors), with
scenario_flags as togglable predicates and alternative constellations
explorable.

This shift-1 doc covers:
- 4-tab UX redo (single-pane radio-revealed entry form to fix the
  pre-form-leak bug)
- Anchor visualisation (vertical waterfall with anchor at centre line)
- Three views — Anchor / Verfahren / Konstellationen — toggle preserves
  anchor + scenario state
- Forward walk (current constellation only by default, conditional
  reveal toggle, view-mode toggle reused from atlas P3)
- Backward walk (3 hops default, Akte mode overlays paliad.deadlines
  actuals onto template chain)
- Compound rules drawer (per-anchor Querverweise affordance — column
  shape owned by curie editorial workstream)
- Constellation viewer (inline per-flag preview drawer + full
  Constellation view for browse)
- Akte entry (anchor derives from latest completed deadline)
- Migration: T1-T5 flag-gated dev under ?tracker=1, then hard-cut

Coder gate held. 11 open questions for m staged for AskUserQuestion in
4+4+3 batches. Decisions append as §13 before the
TRACKER DESIGN READY FOR REVIEW signal.
2026-05-27 20:56:51 +02:00
mAi
0aaa523494 design: fold m's 12 decisions into unified procedural-events doc (m/paliad#151)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
- §11.5 m's decisions section (9 on-rec + 3 divergent)
- diverged: Q2 /tools/procedures (English), Q3 all-tabs+search-in-filter-strip, Q11 hard cut no dual ship
- §11.5.1 changes triggered by divergences (URL rename, all-tabs behaviour, U4 rewrite)
- URL refs throughout body updated to /tools/procedures
- U4 slice rewritten to 301 hard-cut per Q11
2026-05-27 19:54:50 +02:00
mAi
d49ff55c41 design: unified procedural-events tool (m/paliad#151 shift-1, draft)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
- audit of 6 surfaces with question→dimension matrix
- proposal: fold Fristenrechner + Verfahrensablauf into /tools/verfahren
- 4 entry paths converge on tree + linear output shapes
- mobile narrow-viewport rules + 3 worked personas
- 5-slice migration train (U0-U4), no DB migration
- 12 open questions in 3 batches for AskUserQuestion
2026-05-27 19:23:24 +02:00
mAi
490c8a8c8c design(deadline-system): fold m's selection + view-mode + R.109 additions (t-paliad-329)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
m's clarification at 14:40 reframed the original "rarity" framing: every
optional rule is a per-scenario selectable card; the Verfahrensablauf
gets a three-way detail-level filter (Nur Pflicht / Gewählt / Alle
Optionen). The CCR-dropdown pattern generalises to per-rule chips.

Three folded additions:

§2.4a — Selection state + detail-level filter. NO new column on
sequencing_rules (reverts the earlier is_edge_case strawman). Extends
projects.scenario_flags jsonb to carry both named flags (with_ccr etc.)
and per-rule entries (rule:<uuid>). Storage only carries deviations
from the priority default (recommended = default-selected,
optional = default-unselected). Whitelist accepts rule:<uuid> when the
UUID resolves to an active rule on the project's PT.

§3.3a — Verfahrensablauf view-mode toggle: three-way segmented control,
localStorage persistence, default "Gewählt". Mode B result view stays
single-purpose (no view-mode toggle there).

§4.2.1 — R.109 translation chain editorial worked example: R.109.1 stays
as optional anchor; R.109.4 reparents to R.109.1 with condition_expr
{flag: with_interpreter_denied} and primary_party=both (parties, not
court); R.109.5 reparents to R.109.1 with {flag: with_translation_granted}.
Introduces two new flags to scenario_flag_catalog.

§6 UI spec updated: two mocked tree states (Gewählt + Alle Optionen)
showing the dotted-border [Aufnehmen] chips, [Entfernen] on selected
optionals, greyed-with-hint on flag-gated conditionals, and the
subtree-hide-on-unselected-ancestor render logic.

§10.0a captures the additions; §10.1 notes they don't change the slice
train (P0 + P3 take the extended scope; no new mig).
2026-05-27 14:45:00 +02:00
mAi
b1c9e8dd97 design(deadline-system): Phase 2 revision — connection schema + 12 m's decisions (t-paliad-329)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Builds on athena's Phase 1 assessment (9aee9e4) + atlas's t-paliad-327
pre-ratified subset. m's Option B direction: "overall schema for all
procedural events and how they are connected" — connection graph as the
spine.

Connection schema (§1):
- Rules are nodes, parent_id is the canonical edge, spawn rules are the
  cross-PT edges, condition_expr filters the visible subgraph
- ASCII trees for the 3 largest PTs (upc.inf.cfi 25, upc.rev.cfi 17,
  upc.apl post-Q5-split 16); Mermaid graph for the 4 spawn cross-PT edges
- Per-PT health table covering all 23 active primaries (17 ruled + 6 empty)

m's 12 design decisions (3 batches of 4 via AskUserQuestion):

Tier 1 — model (all 4 on-recommendation):
- Q1: parent_id is canonical, deprecate trigger_event_id
- Q2: Reparent 73 legacy globals via editorial walk
- Q3: Derive trigger discoverability from data (EXISTS)
- Q4: projects.scenario_flags jsonb (confirms t-paliad-327 design)

Tier 2 — surface (1 divergent, 3 on-recommendation):
- Q5 DIVERGENT: Reverse the upc.apl unification — split back into 3 PTs
  (merits/cost/order). m: "I only wanted the approach to be unified in
  the 'determinator' — but they are actually different proceedings!"
  Mig P1 retargets 16 rules by event_code prefix.
- Q6: Show empty PTs with "Keine Regeln gepflegt" badge
- Q7: Fold Entry A into /tools/verfahrensablauf
- Q8: Drop /event-deadlines after 73-globals reparenting

Tier 3 — editorial (all on-recommendation):
- Q9: Lock condition_expr grammar {flag} | {op:and|or, args}
- Q10: parent-NULL filter on /admin/procedural-events
- Q11: Drop trigger_events table once route is gone
- Q12: ASCII per-PT + Mermaid spawn graph

6-slice migration train (§5): P0 scenario SSoT, P1 appeal re-split, S1/S1a
from t-paliad-327, P2 empty-PT badge, P3 Entry A, P4 editorial walk, P5
trigger_event_id deprecation. P5 gated on P4.

No code yet — coder gate held per inventor SKILL.
2026-05-27 14:32:02 +02:00
mAi
810b65463e docs(assessment): Phase 1 audit — deadline + procedural-events system (m/paliad#149)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
t-paliad-328. Read-only audit of every consumer of paliad.sequencing_rules
+ paliad.procedural_events + the legacy paliad.trigger_events, plus the
rules-corpus quality on the live database. No design — Phase 2 (inventor)
gates on this landing.

Highlights:
- 226 active+published rules / 222 events (1:1 since mig 136)
- parent_id chain vs trigger_event_id are functionally disjoint
  (2/226 overlap); 73 legacy globals own the trigger_event_id lane
- 11 risk items captured with file:line; B1 (cross-party follow-up
  filter) and B2 (picker accepts spawn-only + leaves) confirmed
  from code at fristenrechner_followups.go:358-367 and :241-287
- 4 spawn rules still point at the inactive upc.apl.merits (id=11);
  the active appeal type is id=160 (upc.apl.unified)
- 6 active proceeding_types are entirely unruled
- 3 scenario stores wired (project_event_choices, scenarios table,
  DOM state); all currently empty, so divergence is dormant
- 738 lines (under the 800 cap)

Recommendation §6 sequences Tier 1 model decisions ahead of Tier 2
surface decisions and Tier 3 editorial cleanup for the inventor.
2026-05-27 11:02:38 +02:00
mAi
3219bff4d4 design(taxonomy): proceeding_types kind discriminator + 11 m's decisions (t-paliad-324)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Live audit established that 28 of 46 active proceeding_types have zero
downstream pressure (0 rules, 0 projects, 0 spawn FKs, 0 concepts). Mig
plan is purely additive: ADD COLUMN kind text CHECK (...), four UPDATE
statements to tag phase/side_action/meta rows, deactivate them, and add
a BEFORE INSERT/UPDATE trigger on projects.proceeding_type_id to enforce
kind='proceeding'.

m's call on the 11 AskUserQuestion decisions:
- Model 1 (kind discriminator)
- Phases implicit via procedural_events.event_kind, EXCEPT upc.costs.cfi
  stays kind='proceeding' (standalone R.151 application)
- Side-actions: kind='side_action', rules anchor on parent primary
- Schutzschrift kind='proceeding' (own RoP filing)
- DE inf + DE null + DE-vs-upc.apl unification: all keep discrete
- upc.ccr.cfi: keep status quo per t-paliad-204 S1
- DB trigger on projects only (admin-only writes on sequencing_rules)
- Deactivate non-primary rows (23 active post-mig, all kind='proceeding')
- Parallel-land vs m/paliad#146 — knuth's S3 picks up the filter

Final categorisation: 23 proceeding / 4 phase / 10 side_action / 9 meta.

No code yet — coder gate held per inventor SKILL. Design only.

Closes the inventor pass on m/paliad#147.
2026-05-27 09:54:18 +02:00
mAi
528fe35540 design(fristen): fold m's 12 decisions into Fristenrechner overhaul doc
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
All 12 questions answered via AskUserQuestion. 10/12 = inventor recommendation.
2 diverged:

  Q3 (Filter-vs-qualifier UX): m picked section-split (Filter strip above,
      result/qualifier strip below) instead of '(Pflichtangabe)' tag.
      §3.1 Mode A layout rewritten with Filter strip header; §3.2 wizard
      rows now carry Filter/Qualifier badges next to the row number.

  Q7 (No-project mode): m picked 'Hide CTA entirely' instead of disabled-
      with-hint. §4.4 footer renders only when project != null; an inline
      'Tipp: Wähle oben eine Akte' nudge replaces the missing footer.

New §11 'm's decisions (2026-05-26)' anchors each pick with reasoning where
it diverges from the recommendation. §11.1 captures the two follow-on edits
to §3.1 and §4.4. Migration plan and backend contracts unchanged.

DESIGN READY FOR REVIEW pending head's coder gate.
2026-05-26 21:45:41 +02:00
mAi
9c2788ed8c design: Fristenrechner complete UX overhaul (t-paliad-322)
Inventor shift-1 design pass for m/paliad#146.

- Mode taxonomy (Direct-search A + Wizard B → shared result view)
- Filter-vs-qualifier table ratified (forum/event_kind/inbox as filters;
  proceeding_type/perspective as qualifiers)
- Wizard branching: R1 event_kind → R2 forum → R3 proceeding_type →
  R4 procedural_event → R5 perspective; rows prefill+collapse from project
- Result view: 4 priority groups (mandatory/recommended/optional/conditional)
  with SPAWNED folded into priority + cross-proceeding badge
- Project write-back via existing POST /api/projects/{id}/deadlines/bulk
  with confirm-and-edit-dates modal and audit_reason wording
- Backend deltas: extend /api/tools/fristenrechner/search to return
  procedural_events; new /api/tools/fristenrechner/follow-ups
- No schema changes — pure UX + handler shape
- 6-slice migration plan from current buildRowStack to overhaul under
  ?overhaul=1 flag, then flip + cleanup
- One worked example (LG Düsseldorf Hinweisbeschluss)
- 12 open questions for m (3 batches of 4 via AskUserQuestion)
2026-05-26 21:30:26 +02:00
mAi
0e1691f00e docs: ratify Q1-Q12 — submission generator v2 design final (m/paliad#141)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
All 12 §11 design questions ratified by m on 2026-05-26 via
AskUserQuestion (paliadin-authorised override per instruction msg #2391).

Picks matching inventor recommendations (9 of 12):
 Q1 separate submission_sections table
 Q3 Gitea-backed body + thin DB row
 Q4 contentEditable + Markdown + in-house serializer
 Q5 section anchors + in-house MD->OOXML walker
 Q7 split content_md_de + content_md_en from day 1
 Q8 Go map for per-submission_code section defaults
 Q9 4 visibility tiers (private/team/firm/global)
 Q11 collapsed preview pane by default
 Q12 moot (superseded by Q2 simplification)

Deviations from recommendation (3 of 12):
 Q2 SIMPLIFY further — m: "sounds overengineered". Building blocks
    become plain text paste sources. No building_block_id column on
    sections, no _versions table referenced from sections, no
    refresh-from-library affordance. Slice G dropped.
 Q6 Auto-upgrade all 11 existing drafts at mig-148 apply time (not
    opt-in per draft). v1 fallback render path stays compiled in.
 Q10 *_auto kind removed. Caption/letterhead/signature sections are
    regular prose rows seeded with bag-driven Markdown; lawyer can
    edit/hide. Untouched drafts export identically to v1.

Body sections updated inline (§4.3 schema, §4.4 BB tables, §6.3
seeding, §8.3+8.4 BB insert, slice plan A/C/G, §11 ratification notes,
§14 risks #8+11, §17+18 acceptance + gate). §11 retains the historical
recommendation matrix.

Status: ALL DESIGN QUESTIONS RATIFIED — design doc final, ready for
Slice A coder shift. Inventor parks per hard gate. Head decides hire.

t-paliad-312
2026-05-26 19:04:21 +02:00
mAi
635457474a docs: PRD/design — submission generator v2 ("Composer") (m/paliad#141)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Sectioned composition, swappable base templates, in-app prose editing,
building-blocks library. Deepens t-paliad-215 + t-paliad-238 without
replacing them — v1 contracts (submission_drafts shape, {{rule.X}}
aliases, audit shape) preserved.

7 slices A→G; Slice B is the smallest "Composer works" milestone.
Existing 11 v1 drafts continue via v1 path; opt-in upgrade per draft.

12 open design questions with recommended defaults + alternatives for m
to ratify via head escalation (no AskUserQuestion per task brief).

Flags two issue-body inaccuracies: no submission_drafts.audit_log column
(audit lives in system_audit_log + project_events); live row count is
11, not 7.

t-paliad-312
2026-05-26 18:37:52 +02:00
mAi
ce28ea972e feat(litigationplanner): embedded UPC snapshot + generator (Slice C, m/paliad#124 §19)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Lays the foundation for youpc.org's cross-repo integration: an
in-package UPC subset of paliad's deadline corpus, embedded as JSON,
that any consumer can use to run the litigationplanner engine without
DB access.

Generator (cmd/gen-upc-snapshot):
  - Reads paliad's live DB (DATABASE_URL), applies pending migrations
    to match schema HEAD, SELECTs the UPC subset
    (proceeding_types WHERE jurisdiction='UPC' AND is_active=true,
    deadline_rules WHERE lifecycle_state='published' AND is_active=true
    on those proceedings, referenced trigger_events, DE+UPC holidays,
    UPC courts).
  - Writes pretty-printed JSON to
    pkg/litigationplanner/embedded/upc/{proceeding_types, rules,
    trigger_events, holidays, courts, meta}.json.
  - Idempotent — same DB state → same output (modulo
    meta.generated_at + auto-versioned suffix).
  - Date-stamped versioning (YYYY-MM-DD-N) with same-day suffix bump.
  - Operator runbook in cmd/gen-upc-snapshot/README.md.

Embedded subpackage (pkg/litigationplanner/embedded/upc/):
  - embed.go    — //go:embed *.json + LoadMeta()
  - snapshot.go — SnapshotCatalog (full lp.Catalog impl: LoadProceeding
    / LoadProceedingByID / LoadRuleByID / LoadRuleByCode /
    LoadRulesByTriggerEvent / LoadTriggerEventsByIDs / LookupEvents);
    O(1) map lookups; LookupEvents linear over the < 100-row UPC corpus.
  - holidays.go — SnapshotHolidayCalendar implementing lp.HolidayCalendar
    (IsNonWorkingDay / Adjust* with structured AdjustmentReason).
  - courts.go   — SnapshotCourtRegistry implementing lp.CourtRegistry.
  - Compile-time assertions (_ lp.X = (*Snapshot*)(nil)) catch
    interface drift.

Wire-up for consumers:
  cat, _ := upc.NewCatalog()
  hc, _  := upc.NewHolidayCalendar()
  cr, _  := upc.NewCourtRegistry()
  timeline, _ := lp.Calculate(ctx, "upc.inf.cfi", "2026-05-26",
                              lp.CalcOptions{}, cat, hc, cr)

Tests (snapshot_test.go, all DB-free):
  - meta parses cleanly, non-zero counts
  - LoadProceeding(upc.inf.cfi) returns expected proc + rules
  - LoadProceeding(unknown) returns ErrUnknownProceedingType
  - LookupEvents(Jurisdiction:UPC, all-following) covers corpus
  - LookupEvents(party=defendant, next) scopes anchors correctly
  - engine end-to-end via lp.Calculate against the embedded snapshot
  - holiday calendar (weekends, DE closures, UPC vacation block)
  - court registry (empty courtID fallback, known + unknown court)

Placeholder data shipped (2 proceedings, 2 rules, 5 holidays, 2
courts) so tests run without a live DB. Operator regenerates against
prod via `make snapshot-upc` once migrations 134 (B1) and 135 (B3)
have landed on prod — see cmd/gen-upc-snapshot/README.md for the
runbook. The placeholder's meta.version is suffixed `-placeholder`
to make the regeneration delta obvious.

Makefile target:
  make snapshot-upc — wraps the generator + reruns the snapshot tests

Design (§19 of docs/design-litigation-planner-2026-05-26.md):
  - Embedding format: go:embed JSON (diff-friendly, no compile coupling)
  - Generator entry: cmd/gen-upc-snapshot/main.go (idiomatic Go cmd path)
  - Versioning: meta.json carries semver + generated_at + paliad_commit
  - Regeneration: manual via Make target or `go generate`; no CI cron in v1
  - Out of scope: snapshot signing, DE/EPA/DPMA snapshots, snapshot
    diff tooling

Acceptance:
  - go build clean, go test all green (incl. 6 new tests in
    pkg/litigationplanner/embedded/upc, all DB-free)
  - SnapshotCatalog passes the compile-time lp.Catalog assertion
  - Generator binary builds + runs (Idempotence verified by re-running
    against the same source data)
2026-05-26 15:11:07 +02:00
mAi
426b90bb88 Merge: t-paliad-292 — Slice B1: Berufung unification (one upc.apl + 5 appeal_target chips, mig 134 additive) (m/paliad#124 §18.1)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
2026-05-26 13:49:52 +02:00
mAi
07acf7b4a2 feat(litigationplanner): Berufung unification — one upc.apl + 5 appeal_target chips (Slice B1, m/paliad#124 §18.1)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Collapses the 3 UPC appeal proceeding_types (upc.apl.merits 7 rules,
upc.apl.cost 2, upc.apl.order 7 = 16 total across 3 codes) into ONE
unified upc.apl proceeding type + a per-rule applies_to_target[]
discriminator. The verfahrensablauf picker now shows one "Berufung"
tile; after picking it, the user selects which decision the appeal is
directed AT via a 5-chip group (Endentscheidung / Kostenentscheidung /
Anordnung / Schadensbemessung / Bucheinsicht) and the engine filters
rules whose applies_to_target contains the picked slug.

m's 2026-05-26 decision: Schadensbemessung-as-appeal is a NEW first-
class target with its OWN rule set (no shared inheritance from
merits). The 5 enum values are all defined + addressable; for now
schadensbemessung and bucheinsicht return empty timelines until rules
are seeded in a follow-up slice (likely via /admin/rules or pairing
with t-paliad-193 orphan-concept-seed).

Migration 134 (additive only):
  - ADD proceeding_types.appeal_target text (CHECK on 5 slugs OR NULL)
  - ADD deadline_rules.applies_to_target text[] (CHECK each element
    in the 5 slugs)
  - INSERT the unified upc.apl row (inherits sort/color from
    upc.apl.merits)
  - Audit-first RAISE NOTICE pass listing every row about to be
    touched + a post-migration sanity check
  - Reassign rule rows: merits → applies_to_target={endentscheidung},
    cost → {kostenentscheidung}, order → {anordnung}
  - Archive (is_active=false, NOT DELETE) the 3 old proceeding_types
    so historical FKs stay intact
  - Down migration restores is_active=true on the 3 old types, points
    rules back by their applies_to_target stamp, drops the unified
    row, drops both columns. Safe.

Package additions (pkg/litigationplanner):
  - AppealTarget* constants + AppealTargets[] ordered list +
    IsValidAppealTarget(s) predicate (silent no-op on unknown slugs
    so a stale frontend chip doesn't break the render)
  - ProceedingType.AppealTarget *string field (top-level marker;
    NULL on non-appeal proceedings)
  - Rule.AppliesToTarget pq.StringArray field (per-row applies-to set)
  - CalcOptions.AppealTarget string (engine filter — when set,
    keeps only rules whose AppliesToTarget contains the slug)

Engine filter runs after ApplyRuleOverrides but before the rule walk
so the existing condition_expr / spawn / appellant-context machinery
operates on the filtered subset transparently.

paliad-side wiring:
  - deadline_rule_service.go: ruleColumns + proceedingTypeColumns
    extended to scan the new columns
  - handlers/fristenrechner.go: AppealTarget JSON field on the
    request payload, threaded into CalcOptions

Frontend (verfahrensablauf surface only):
  - Single "Berufung" tile replaces the 3 separate Berufung tiles
  - New 5-chip appeal-target row, shown only when upc.apl is picked
  - URL state ?target=<slug>; default endentscheidung when none set
  - APPELLANT_AXIS_PROCEEDINGS updated: upc.apl.* (3 entries) →
    upc.apl (1 entry)
  - i18n keys (DE + EN) for the new tile + the 5 chip labels +
    the "Worauf richtet sich die Berufung?" / "Appeal against:" prompt
  - calculateDeadlines threads appealTarget through to the API

Acceptance:
  - go build clean, go test all green (existing test suite — no new
    tests on the engine filter as a follow-up; the migration's
    sanity-check DO block guards the rule-reassignment count)
  - Live audit before drafting confirmed: 3 active UPC appeal
    proceeding_types, 16 rules total, primary_party already conforms
    to 4-value vocab on all proceeding-bound rules
2026-05-26 13:49:03 +02:00
mAi
c4c0a82abb docs(procedural-events): B.0 live-DB re-validation findings + design doc bug fix (t-paliad-273 / m/paliad#93)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Slice B.0 — read-only re-validation of cronus's procedural-events design
against the live youpc Supabase paliad schema, 24 h after the design was
authored.

* Adds docs/design-procedural-events-b0-findings-2026-05-26.md with the
  drift table, per-check confirmations, and a tightened B.1 brief.
* Annotates the cronus design doc's status header to point at the B.0
  findings file so future readers see both together.
* Fixes the self-contradictory sentence in §1 that referenced
  `deadline_rule_id` on both sides of a "not" — the live column is
  `paliad.deadlines.rule_id`, renamed directly to
  `paliad.deadlines.procedural_event_id` under Slice B (no intermediate
  step). Matching fix patched into the m/paliad#93 issue body via
  Gitea API (curl --netrc-file ~/.netrc-mai PATCH).

Key drift surfaced (vs design 2026-05-25):
- deadline_rules rows 254 → 231
- distinct submission_codes 158 → 153 (10 _archived_litigation.* codes
  gone — Q5 multi-row collapse premise is now MOOT)
- distinct legal_sources 70 → 87 (+17)
- concept-linked rules 125 → 129
- paliad.deadlines rows 1 → 5
- submission_drafts rows 4 → 7
- live mig head 123 → 133; next available = 134 (not 124)

No migration SQL written. No writes to paliad.deadline_rules. Researcher
stays parked pending m's B.1 greenlight.

Note: this commit also cherry-picks the original inventor design doc
(5bb6df6) onto the B.0 branch, because the design was never merged to
main and the doc bug fix needed somewhere to land.
2026-05-26 13:44:30 +02:00
mAi
5ab14f8b37 docs: t-paliad-262 — procedural-events data-model design (inventor)
Slice A (cosmetic rename) + Slice B (structural rework) for the
deadline_rules → procedural_events / sequencing_rules / legal_sources
split. Recommendation (R)=C (cosmetic now, structural follow-up).
Umbrella-term lock: procedural event / Verfahrensschritt.

Read-only design phase. No code or schema changes here. m/paliad#93.
2026-05-26 13:38:08 +02:00
mAi
acf5743fa3 docs(litigation-planner): Slice B design — Berufung unification + multi-axis catalog query + primary_party CHECK (m/paliad#124)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Adds §18 to the design doc folding in m's three 2026-05-26 decisions:

§18.1 Berufung unification — collapse 3 active UPC appeal proceeding_types
(upc.apl.merits / upc.apl.cost / upc.apl.order, 16 rules total) into ONE
upc.apl + appeal_target discriminator. 5 targets: Endentscheidung,
Kostenentscheidung, Anordnung, Schadensbemessung, Bucheinsicht. Adds
proceeding_types.appeal_target + deadline_rules.applies_to_target[]
columns; archives the 3 old codes; CalcOptions gains AppealTarget filter.
Migration 134 with pre-migration audit pass. Q to m on whether
Schadensbemessung-as-appeal shares the merits rule set (R) or has its own.

§18.2 Multi-axis catalog query API — new Catalog.LookupEvents method
taking optional {jurisdiction, proceeding_type_id, party,
event_category_id, appeal_target} axes + EventLookupDepth control
("next" / "all-following"). No schema delta — reuses existing parent_id
+ sequence_order graph. Returns EventMatch with priority + depth metadata.

§18.3 primary_party enum tightening — CHECK constraint on
deadline_rules.primary_party against canonical four-value vocab
(claimant/defendant/court/both, plus NULL for orphan concept seeds).
Live audit confirmed all 26+26+38+63 proceeding-bound rows already
conform; the 78 NULL rows are all proceeding_type_id IS NULL orphans
(cross-cutting concepts) and stay NULL. Migration 135 with audit-first
RAISE NOTICE pass. Package exposes PrimaryParties[] + IsValidPrimaryParty().

§18.4 revises §10 slice plan: B1 (Berufung), B2 (catalog query), B3
(enum tightening). Independent + parallel-friendly.

Branch: mai/cronus/inventor-litigation-slice-b (off main d1d0cf9).
NOT reusing the merged Slice A branch.
2026-05-26 13:37:26 +02:00
mAi
6e585951ee docs(litigation-planner): fold m's AskUserQuestion picks — new paliad.scenarios table + jsonb spec, no user-authored rules (t-paliad-292)
m's 2026-05-26 decisions:
- Q1 composition: primary+spawned (v1) with multi-proceeding peer compose as v2 goal — jsonb spec architected for N entries from day 1
- Q2 scope: per-project + abstract (project_id NULL = abstract saved templates)
- Q3 dates: per-anchor overrides over one base date (matches today's compute)
- Q4 storage: new paliad.scenarios table with jsonb spec (NOT project_event_choices column extension)
- "users should not add their own rules" — original Slice E (user-authored rules) DROPPED, replaced with abstract scenarios surface on /tools/verfahrensablauf

§5 rewritten with new schema (paliad.scenarios + active_scenario_id FK), jsonb spec shape (proceedings[] array, version-tagged), validate-on-load discipline, multi-peer v2 path. §6 struck-through with original body preserved as historical context. §10 slice plan revised: Slice E = abstract scenarios surface, not user-authored rules. §0.5 added with decision matrix; §13 marked resolved.

Package shape (§2 §3) unchanged — library was decoupled from persistence/UI choices by design.
2026-05-26 12:55:52 +02:00
mAi
8240717b5a docs(litigation-planner): pkg/litigationplanner design for paliad + youpc.org reuse (t-paliad-292)
Inventor design for m/paliad#124. Atomic extract of FristenrechnerService /
DeadlineCalculator / proceeding_mapping / SubTrackRoutings / legal-source
helpers into pkg/litigationplanner with Catalog / HolidayCalendar /
CourtRegistry interfaces. youpc.org reuse via embedded UPC snapshot
(catalog.json + holidays.json + courts.json) shipped inside the package.

6 slices: A extract, B catalog interface, C embedded snapshot + generator,
D scenarios persistence (project_event_choices.scenario_name), E
user-authored rules (deadline_rules.project_id), F youpc-side PR.

Q1 + Q2 (material) escalated to head per inventor protocol — NOT
AskUserQuestion. Q3-Q5 locked. Decision picks (R) noted; doc holds together
under any answer to the open Qs because pkg shape is decoupled from
persistence choices.
2026-05-26 12:55:52 +02:00
mAi
cc13a5b857 chore(admin): remove /admin/rules/export page + export-migrations API (t-paliad-297)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Workflow shifted to hand-written numbered migrations; the audit-row SQL
export tool no longer has any consumers. Pure deletion — /admin/rules
and /admin/rules/{id}/edit stay; only the export-to-SQL flow goes.

Deleted:
- frontend/src/admin-rules-export.tsx
- frontend/src/client/admin-rules-export.ts

Removed:
- routes GET /admin/rules/export and GET /admin/api/rules/export-migrations
- handleAdminExportRuleMigrations + handleAdminRulesExportPage
- RuleEditorService.ExportMigrationsSince + ExportResult + sqlEscape helper
- build.ts entries (import, client bundle, dist HTML write)
- Sidebar "Regel-Migrations" nav item + "Migrations exportieren" button on /admin/rules
- all admin.rules.export.* + nav.admin.rules_export + admin.rules.list.export i18n keys (DE+EN)
- .admin-rules-export-* CSS rules (dead after page deletion)

Doc references in design-fristen-phase2-2026-05-15.md and
design-paliad-data-export-2026-05-19.md updated to mark the endpoint as
removed (acceptance #2 requires grep to return zero hits).
2026-05-26 11:50:14 +02:00
mAi
c901293c9c feat(cicd): Slice A — pre-deploy gate + role-split migration smoke
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Adds .gitea/workflows/test.yaml that gates every push on `go build`,
`bun run build`, `go vet`, the migration coordination check, and the
role-split end-to-end migration smoke. On push to main + green, calls
Dokploy's compose.deploy API and polls /health/ready until 200.

t-paliad-282 / m/paliad#114. Design: docs/design-cicd-pre-deploy-gate-2026-05-25.md
(inventor shift on mai/cronus/inventor-ci-cd-pre).

Catches all three of today's outage classes:

  brunel (~13:20) slot collision     -> TestMigrations_NoDuplicateSlot
  hermes (~16:05) dropped-col refs   -> TestBootSmoke
  mig 129 (~14:56) 42501 ownership   -> TestMigrations_EndToEndAsAppRole

Snapshot approach. internal/db/testdata/prod-snapshot.sql is a pg_dump
of youpc-supabase paliad schema + applied_migrations rows. CI restores
this into a fresh `supabase/postgres:15.8.1.060` (same image, same role
topology as prod) and runs ApplyMigrations as the `postgres` role
(which is NOT a superuser on supabase/postgres, matching prod). Existing
migrations are skipped (already in applied_migrations); only NEW migs
from the PR run end-to-end. This sidesteps the fresh-DB idempotence
debt in some historical migrations (mig 037 missing pg_trgm, mig 051
inner COMMIT) — those are tracked separately and don't block the gate.

Sub-changes:

- internal/handlers/handlers.go — new /health/ready endpoint distinct
  from /healthz. /healthz stays liveness (process alive, no DB); /ready
  is readiness (DB pool pings within 2 s). Returns 503 when svc or pool
  is nil (DB-less deploys are intentionally not-ready). svc.Pool added
  to handlers.Services, wired in cmd/server/main.go.

- internal/db/migrate_test.go — TestMigrations_NoDuplicateSlot (pure
  unit, catches brunel) and TestMigrations_EndToEndAsAppRole (snapshot-
  gated, catches the 42501 class).

- cmd/server/main_smoke_test.go — TestBootSmoke now also asserts
  /health/ready returns 503 with a nil svc. New TestHealthReady_Live
  asserts 200 against a live pool.

- internal/db/migrations/024_rename_department_columns.up.sql and
  027_rename_to_partner_units.up.sql — ALTER INDEX / ALTER POLICY
  exception handlers now catch undefined_object OR undefined_table OR
  duplicate_object. Old handler only caught undefined_object; Postgres
  raises undefined_table when source object never existed, and
  duplicate_object when destination already exists. The expanded
  handlers make these migrations truly idempotent across all plausible
  starting states.

- Makefile — verify-mig-app, test-frontend, refresh-snapshot targets.
  refresh-snapshot pg_dumps youpc-supabase prod (needs PALIAD_PROD_DATABASE_URL),
  strips pg16 \restrict commands for pg15 restore compat, and filters
  applied_migrations rows to this branch's max on-disk version.

- internal/db/testdata/README.md — explains the snapshot's purpose,
  refresh procedure, and how to verify locally.

- docs/cicd-runner-setup-2026-05-25.md — one-time admin steps for
  registering a Gitea Actions runner on mriver and wiring DOKPLOY_TOKEN
  as a repo secret. Documents soft-launch plan per m's Q11.4 (keep
  Dokploy's autoDeploy=true webhook alive for one week, disable after
  the workflow has gated 5 successful deploys).

Build clean. Full go test ./internal/... ./cmd/... green without
TEST_DATABASE_URL. With TEST_DATABASE_URL + TEST_APP_DATABASE_URL set
to a supabase/postgres scratch + snapshot restored:
TestMigrations_NoDuplicateSlot, TestMigrations_EndToEndAsAppRole,
TestBootSmoke, TestHealthReady_Live all pass. Live-DB service tests in
internal/services/* fail under supabase/postgres 15.8 with a 42P08
parameter-binding error (unrelated to Slice A — tracked as a follow-up).
2026-05-25 17:42:06 +02:00
mAi
169ace5d26 design(t-paliad-265): fold m's decisions into the design doc
Four open questions answered via AskUserQuestion (2026-05-25):

  Q1 State location       → persisted table          (matches (R))
  Q2 Affordance           → caret + popover          (matches (R))
  Q3 Appellant layer      → per-card overrides       (matches (R))
  Q4 Slice order          → bundle A + B             (over (R) of "A first")

Q4 captured with rationale: cohesive PR, single user-visible release,
no half-shipped state where the include-CCR popover would exist
without the engine wire-through. Coder still organises commits per
slice internally; one branch, one ship.
2026-05-25 16:27:30 +02:00
mAi
ac7bc27fb7 design(t-paliad-265): per-event-card optional choices on Verfahrensablauf
Draft inventor design for m/paliad#96 — per-card affordances driving
projection state: appellant per decision, include-CCR on Klageerwiderung,
skip optional events.

Persisted choices in new paliad.project_event_choices table; opt-in
declared via choices_offered jsonb on paliad.deadline_rules. Caret +
popover affordance; chip indicators on cards with non-default picks.
Two-slice plan: A=appellant+skip (engine-stable), B=include-CCR.

m's decisions section to be filled after the AskUserQuestion round.
2026-05-25 16:27:30 +02:00
mAi
247e9005db Merge: t-paliad-248 Slice A — symmetric date-range picker + filter-bar wiring (m/paliad#79)
# Conflicts:
#	frontend/src/client/filter-bar/axes.ts
2026-05-25 15:51:36 +02:00
mAi
0f2f3e3ea1 docs(date-range-picker): inventor design — symmetric past/future fan + ALL center
t-paliad-248 / m/paliad#79.

§0 TL;DR + §1 audit of every paliad date-range affordance today
(/agenda chip row, /admin/audit-log select, /projects/:id/chart
symmetric range, /views editor, filter-bar time axis with stubbed
Anpassen chip, projects-detail Verlauf horizonBounds).

§2 upckommentar slicer pattern — read DateRangeSlider.svelte +
date-range-slider-pure.ts end-to-end. Borrow worth: anchor rail with
click-to-snap left/right halves, granularity zoom, epoch-day pure
math. Defer the actual slicer to Slice D.

§3 component design — <DateRangePicker> emits TimeSpec, extends
TimeHorizon with past_14d / next_14d / past_all / next_all
(additive; no migration). Symmetric chip fan layout, lime accent
for active, target glyph ⌖ for ALLES center button.

§4 URL contract — canonical ?horizon=…&from=…&to=…, surface-level
alias adapters for back-compat with existing ?range=N parsers.

§5 slice plan — A: filter-bar time axis (lights up 4 surfaces) /
B: /agenda / C: /admin/audit-log + /projects/:id/chart (sibling
SymmetricRangePicker for chart) / D (optional): slicer port.

§6 visual decisions, §7 edge cases, §8 open questions w/ (R)
defaults. 3 material picks escalated separately via mai instruct
head: chart migration shape, popover-vs-modal, Slice A first call
site.

§9 implementer notes + acceptance criteria for Slice A. §10
escalation-message summary.
2026-05-25 15:34:03 +02:00
mAi
2683c5f9cf docs(inbox): t-paliad-249 — inbox overhaul inventor design (m/paliad#80)
LOCKED design with head decisions (Q1=A) folded in §12. Slice plan
A/B/C reuses existing FilterSpec + RunSpec engine; no new aggregation
service. Slice A adds inbox_seen_at cursor + project_event source on
InboxSystemView + RowActionInbox dispatch in shape-list; Slice B adds
shape toggle (list/cards/calendar) + member_role_changed narrowing;
Slice C upgrades the badge + per-item dismiss.
2026-05-25 15:33:36 +02:00
mAi
94a9e7e5fb docs: t-paliad-263 bulletproof deadline-rules completeness audit
Read-only audit of paliad.deadline_rules against UPC RoP + EPC +
PatG/ZPO/GebrMG statutory sources, with verbatim verification of
all citations against youpc data.laws_contents (UPC RoP + EPC) and
gesetze-im-internet.de (PatG/ZPO).

Headline findings:
- 5 hard user-visible bugs: 2 UPC_REV duration bugs (R.49.1 3mo->2mo,
  R.52 2mo->1mo), 1 UPC appeal-response duration bug (R.235.1 2mo->3mo),
  2 DE-LG-Verletzung sequencing bugs (beruf_begr anchor + replik/duplik
  parent_id NULL).
- 11 citation drift bugs (rule_code/legal_source point at wrong rule).
- 6 court-set-mismodelled-as-fixed (DPMA + DE + EPA richterliche Fristen
  carrying made-up statutory citations).
- ~30 statutory deadlines unmodelled (12 high-frequency in Tier 1).
- 13 ambiguity questions for m's judgement (court-set policy,
  working-days arithmetic, Wiedereinsetzung modelling).

Slices into Wave 0 (16 Tier-0 fixes) and Wave 1-6 (Tier 1-4 + spikes).
No DB writes; findings only.

Refs: m/paliad#94, t-paliad-263
2026-05-25 15:23:39 +02:00
mAi
f7374a67cd docs(submissions): t-paliad-238 design — dedicated Submissions/Schriftsätze page
Adds docs/design-submission-page-2026-05-22.md (~600 lines) — a
dedicated submission-draft page at /projects/{id}/submissions/{code}/draft
with sidebar variable editor + read-only HTML preview + .docx export.

Reuses (resurrects from git) the deleted Slice 1 backend that t-paliad-230
ripped out — SubmissionVarsService (3677c81 + 1765d5e), in-house
SubmissionRenderer (8ea3509), TemplateRegistry (3677c81). All four
compile against today's services with zero API drift.

New schema: paliad.submission_drafts keyed on
(project_id, submission_code, user_id, name) with RLS via can_see_project.

Three slices: A = schema + page + variables-only export against universal
.docx; B = per-submission_code templates with fallback-chain registry;
C = toggleable passages.

Four material picks escalated to head in §11 (template authoring effort,
paliad.documents row, server-vs-client preview, inter-user draft
visibility). All other open questions defaulted to inventor (R)
recommendations from task brief.

No code. Read-only design phase per inventor → coder gate.
2026-05-22 23:43:51 +02:00
mAi
1c8cdd3079 docs(checklists): t-paliad-225 inventor design — user-authored checklists (#61)
918-line design doc covering all three capabilities from m/paliad#61:
authoring, multi-axis sharing, admin-promotion to global.

Load-bearing premise correction: the issue body claims `paliad.checklists`
is an existing table that gets new columns. It is NOT — checklists today
are static Go data in `internal/checklists/templates.go`. Design
introduces `paliad.checklists` from scratch and keeps the static catalog
as a parallel source via a hybrid catalog read layer.

Schema (mig 112): `paliad.checklists` (owner + visibility enum), `paliad.checklist_shares`
(polymorphic recipient: user/office/partner_unit/project),
`paliad.can_see_checklist` predicate, `paliad.checklist_instances.template_snapshot`
column for instance integrity under template edits.

12 decisions ledgered, all defaulted to (R) per task brief (no AskUserQuestion).
Three slices (A foundation, B sharing+promotion, C gallery+backfill).
2026-05-20 15:24:06 +02:00
mAi
2320cb765d docs(design): t-paliad-224 — head accepted all 8 (R) defaults
Decisions section §12 filled in per head msg #2087. Status → ACCEPTED.
Coder shift proceeds on same branch per Q7(R): single PR.
2026-05-20 15:23:28 +02:00
mAi
668558380d docs(design): t-paliad-224 — align calendar views (m/paliad#55)
Audit + refactor plan: three calendar implementations live today —
/events tab, standalone /deadlines|appointments/calendar pages, and
Custom Views shape-calendar.ts. Canonicalise on shape-calendar.ts by
extracting a shared mount-calendar.ts module, fold /events into it,
retire the standalone pages as 301 redirects, delete ~180 lines of
duplicated CSS.

Net: ~700 LOC removed, ~100 added, zero schema/endpoint changes.

8 open questions for head in §11; AskUserQuestion is disabled for this
task per role brief, so head answers via mai instruct and decisions
land in §12.
2026-05-20 15:23:28 +02:00
mAi
ea0715a8c7 feat(projects): t-paliad-222 — Client Role + auto-derived project codes
Implements m/paliad#47 (Client Role rework) + m/paliad#50 (auto-derived
project codes from the ancestor tree) in one shift.

Migrations:
- mig 112_client_role_rework: widen paliad.projects.our_side CHECK to
  seven sub-roles (claimant / defendant / applicant / appellant /
  respondent / third_party / other); drop legacy 'court' / 'both'
  and backfill rows to NULL (no-op on prod, defensive on staging).
- mig 113_projects_opponent_code: add paliad.projects.opponent_code
  text on litigation rows (slug pattern [A-Z0-9-]{1,16}); used as
  the middle segment when assembling auto-derived project codes.

Backend:
- internal/services/project_code.go — new package-level helpers
  BuildProjectCode (single row) + PopulateProjectCodes (bulk, one
  CTE-based round-trip). Walks the existing paliad.projects.path
  ltree; custom paliad.projects.reference on the target wins.
- Wired into ProjectService.List, GetByID, ListAncestors, GetTree,
  LoadCounterclaimChildrenVisible, BuildTreeWithOptions — every
  service entry-point that returns []models.Project / *models.Project
  populates .Code before returning.
- Models: Project.OurSide doc widened; new Project.OpponentCode
  (db:"opponent_code") and Project.Code (db:"-", projection-only).
- CreateProjectInput / UpdateProjectInput accept OpponentCode;
  validateOpponentCode + nullableOpponentCode mirror our_side helpers.
- validateOurSide widens to the seven sub-roles; legacy 'court' /
  'both' rejected at the service layer with a clear error before
  the DB CHECK fires.
- derivedCounterclaimOurSide CCR flip widened: applicant ↔ respondent,
  appellant → respondent; third_party / other / NULL pass through.
- submission_vars: project.code added to the placeholder bag.
  ourSideDE / ourSideEN now use the gender-neutral "-Seite" /
  "-Partei" suffix shape (Klägerseite / Antragstellerseite / ...);
  better legal-prose default for a B2B patent practice, matches the
  form labels which already used this shape (cf. head's soft-note on
  Q4).

Frontend:
- ProjectFormFields: opponent_code on a new projekt-fields-litigation
  block (hidden by default, shown when type=litigation); our_side
  moved into projekt-fields-case and re-labelled "Client Role" /
  "Mandantenrolle" with three <optgroup>s + seven options.
- project-form.ts: showFieldsForType toggles the new litigation
  block; readPayload / prefillForm wire opponent_code; our_side
  is now only emitted for type=case.
- fristenrechner: ourSideToPerspective widened to the seven sub-roles
  (Active→claimant, Reactive→defendant, Other→null). ProjectOption
  type literal updated.
- i18n.ts: new projects.field.client_role.* and
  projects.field.opponent_code.* keys (DE+EN). Legacy
  projects.field.our_side.* keys stay one release for cached
  bundles + Verlauf event-history rendering of the new sub-roles.

Tests:
- TestProjectCodeSegment, TestAssembleProjectCode, TestPatentLast3,
  TestSanitizeClientShort, TestProceedingTail, TestValidateOpponentCode,
  TestValidateOurSideSubRoles pin the new pure helpers.
- TestOurSideTranslations widened to the seven sub-roles + new
  prose shape; 'court'/'both' arms now return "" (legacy rejected).
- TestDerivedCounterclaimOurSide widened to the new flip map.

Migration slot history (this branch was rebumped twice on 2026-05-20):
mig 110 was claimed by m/paliad#51 (project_type_other, euler);
mig 111 was claimed by m/paliad#48 (project_admin_and_select, gauss).
Final slots 112 / 113.

go build && go test ./internal/... && cd frontend && bun run build
all clean.
2026-05-20 14:55:55 +02:00
mAi
3fdc969902 wip(projects): bump migrations 110→111, 111→112 (euler claimed 110) 2026-05-20 14:55:55 +02:00
mAi
cc23e9e537 design(projects): t-paliad-222 — Client Role + auto-derived project codes
Design doc for paired m/paliad#47 (Client Role rework) + m/paliad#50
(auto-derived project codes from the ancestor tree). Two migrations
(110 widen our_side CHECK + backfill court/both → NULL; 111 add
opponent_code on litigations), one new BuildProjectCode helper that
walks the existing ltree path, plus form / submission-template /
Determinator wiring.

9 open design questions surfaced for the head; recommendations
default to the issue-body (R) picks unless a material concern is
flagged in §2.2 / §3.2.

Verified against live data (2026-05-20): all 12 projects have
our_side=NULL, so the backfill is a no-op on production today.
No 'opponent' field exists yet.
2026-05-20 14:55:55 +02:00
mAi
4472faf224 docs(t-paliad-207): close-out assessment — verdict (A) DONE
Read-only audit of the t-paliad-207 surface per paliadin's 2026-05-20
re-engage instruction. Six commits shipped under this task are now
merged. Two larger follow-ups (m/paliad#39 youpc-laws ingest + #41 DE
combined timeline) are filed with concrete scope. Remaining tail is
optional polish, best handled as discrete issues rather than a parked
inventor.
2026-05-20 10:46:48 +02:00
mAi
c01f3f2db8 docs(approvals): t-paliad-216 — fold m's decisions, rewrite §3 implementation
§0a captures m's locked picks across all 8 questions. Two divergences from
inventor recommendations reshape the model:

- Q4: hybrid — approver edits the proposed values (counter-payload) AND/OR
  leaves free-text in decision_note. Adds counter_payload jsonb column.
- Q6/Q7: the counter is treated as a NEW pending approval_request authored
  by the approver, not an "edit and resubmit" CTA on the requester side.
  Original requester sees the old row as changes_requested ("Abgelehnt mit
  Vorschlag") and the new row as pending — they can approve it themselves
  if eligible (they're no longer the requested_by). 4-Augen still holds.

§3 implementation sketch rewritten: SuggestChanges atomically closes the
old row, applyRevert's the entity, spawns a new pending row with
counter_payload as payload + previous_request_id linking back, re-applies
the counter via write-then-approve, emits both *_approval_changes_suggested
and *_approval_requested events. Migration 103 adds the CHECK value plus
counter_payload jsonb + previous_request_id FK + index. Slice plan trimmed
to backend / frontend-modal / Verlauf-integration.
2026-05-20 09:50:07 +02:00
mAi
2fa47278ce docs(approvals): t-paliad-216 — design doc for "Suggest changes" action
Inventor draft of the fourth approval action alongside approve / reject /
revoke. Open questions in §2 will be resolved via AskUserQuestion before
any coder work. Recommendations folded in inline.

Verified live state before designing: status enum already carries an
unused 'superseded' value; entity approval_status is approved/pending/legacy
only; decision_note exists as free text; the existing decide() kernel
handles approve / reject / revoke with a single switch.
2026-05-20 09:50:07 +02:00
mAi
265f240151 docs(submission-generator): t-paliad-215 inventor design
DESIGN READY FOR REVIEW — copernicus inventor pass on the submission
generator (t-paliad-215). 5 questions answered with m's picks captured
in §2; awaiting head's go/no-go on coder shift.

Locked decisions:
- Scope: template-render to .docx (no LLM in v1)
- Template registry: Gitea (mWorkRepo proxy, same pattern as
  HL Patents Style)
- Output: direct download, no server-side binary persistence
- Mapping: fallback chain (firm → base/code → base/family → skeleton)
- Slice 1: one template end-to-end on one project
  (de.inf.lg.erwidg / Klageerwiderung)

No code, no migrations, no schema additions. Read-only design phase
per inventor SKILL.md.
2026-05-19 13:20:59 +02:00
mAi
0b57ec5257 Merge: t-paliad-214 — archimedes Excel-export decisions addendum (9 Qs answered) 2026-05-19 12:37:08 +02:00
mAi
2007ad39bb docs(export): §12 addendum — m's decisions on the 9 §11 questions
t-paliad-214. m walked all 9 questions live; deviated on Q2 (project-scope
floor = any team member, not associate), Q3 (retention 90d, not 7d), Q5
(paliadin_turns hard-excluded from org scope, not opt-in). Other 6
matched inventor picks. Net slice-plan deltas captured in §12.
2026-05-19 12:36:49 +02:00
mAi
b7c4de9ac9 Merge: t-paliad-212 — leibniz CalDAV decisions addendum (6 Qs answered) 2026-05-19 10:43:37 +02:00
mAi
8e0e4c9dcc docs(caldav): fold m's decisions on the 6 open Qs into the design (t-paliad-212)
Addendum after §10 captures m's picks (2026-05-19, via AskUserQuestion):
§8.1 bidirectional default: YES; §8.2 personal_only: KEEP first-class;
§8.3 MKCALENDAR: Slice 2 with Google-degrade; §8.4 soft caps: NONE in
v1 (add later if telemetry warrants); §8.5 admin view: don't ship;
§8.6 approval-flow remote-edit gap: separate task under t-138.

Net effect: drops the 20-warn/80-block UI guards from §6 and the
`read_only` flag from §3; Slice 2 gains MKCALENDAR + binding-count
telemetry; §8.6 fix filed separately so multi-cal slices stay clean.
2026-05-19 10:43:20 +02:00
mAi
023f32d4f2 Merge: t-paliad-213 — mendel test-strategy decisions addendum (all 6 Qs answered, picks match inventor recs) 2026-05-19 10:31:03 +02:00
mAi
621fe35d79 docs(test-strategy): fold m's §10 decisions addendum
m's 2026-05-19 picks via AskUserQuestion interview:
- Q1 budget: 60–90s gate, 3–4min full (inventor's call — m deferred)
- Q2 CI: Gitea Actions, gate tier only
- Q3 test DB: YouPC for devs + ephemeral docker for CI
- Q4 coverage: critical-path only, no % gate
- Q5 floor: Slices 1+4+5 before new feature work
- Q6 ownership: head decides + rotate per profile

All six matched inventor's recommendation. Slice 1 (migration
dry-run + boot smoke) starts first; Slices 4+5 in parallel after.
2026-05-19 10:30:25 +02:00
mAi
139c4a6406 Merge: t-paliad-214 — archimedes Excel data-export design doc 2026-05-19 10:12:24 +02:00