Merge: t-paliad-363 generation-quality diagnosis (picker filter, layout, Rubrum styling+fill)
This commit is contained in:
357
docs/design-generation-quality-2026-06-01.md
Normal file
357
docs/design-generation-quality-2026-06-01.md
Normal file
@@ -0,0 +1,357 @@
|
||||
# Generation-quality diagnosis — docforge loop (2026-06-01)
|
||||
|
||||
**Task:** t-paliad-363 · researcher (kepler) · READ-ONLY diagnosis + sliced fix-plan
|
||||
**Trigger:** m exercised the docforge loop live 2026-06-01 ~15:33 (global `/submissions/new`
|
||||
picker → start draft "Ohne Projekt" → generate) and surfaced 3 real problems.
|
||||
**Scope:** investigate + plan only. No code/data/template edits this shift.
|
||||
|
||||
Three problems, increasing depth:
|
||||
|
||||
1. **P1** — the global picker lists court/trigger acts, not just party submissions.
|
||||
2. **P2** — the grouped picker table looks layout-broken (proceeding name "in the row flow").
|
||||
3. **P3** — a generated project-less draft is both **unstyled** (no HL Patents Style) and
|
||||
**unfilled** (every caption/party value `[KEIN WERT: …]`). This is the docforge core.
|
||||
|
||||
---
|
||||
|
||||
## P1 — picker lists court acts, not just party submissions
|
||||
|
||||
### What m saw
|
||||
"Service of OLG Judgment" (`de.inf.bgh.urteil_olg`, *Zustellung OLG-Urteil*) appears in the
|
||||
draftable-submission picker. That is a **court/trigger act** (the service of the lower-court
|
||||
judgment that *starts* the appeal clock), not a party submission anyone drafts.
|
||||
|
||||
### Root cause
|
||||
The catalog query (`loadSubmissionCatalog`, `internal/handlers/submissions.go:177-211`) filters:
|
||||
|
||||
```sql
|
||||
WHERE dr.is_active = true AND dr.lifecycle_state = 'published'
|
||||
AND dr.event_type = 'filing'
|
||||
AND dr.submission_code IS NOT NULL AND dr.submission_code <> ''
|
||||
```
|
||||
|
||||
The model **already has a correct court-act tier**: 16 rows with `event_type='decision'` and
|
||||
`primary_party='court'` (e.g. `de.inf.olg.urteil_olg` "OLG-Urteil", `upc.inf.cfi.decision`
|
||||
"Entscheidung"). Those are correctly excluded by `event_type='filing'`.
|
||||
|
||||
But **8 anchor/trigger rows are mislabeled** `event_type='filing'` with `primary_party='both'`.
|
||||
They are the "Zustellung …" (service of judgment) / "Veröffentlichung der Erteilung"
|
||||
(publication-of-grant) events that **start** a proceeding's deadline chain. They are used
|
||||
**structurally as `parent_id` anchors** — e.g. `de.inf.bgh.urteil_olg` is the parent of
|
||||
Revisionsfrist, Revisionsbegründung, NZB, Mündliche Verhandlung BGH, BGH-Urteil. They are not
|
||||
draftable by a party.
|
||||
|
||||
### Affected rows (the 8 to re-kind)
|
||||
|
||||
| submission_code | proceeding | name | event_type (is) | primary_party (is) | anchors (children) |
|
||||
|---|---|---|---|---|---|
|
||||
| `de.inf.bgh.urteil_olg` | de.inf.bgh | Zustellung OLG-Urteil | filing | both | Revisionsfrist, Revisionsbegr., NZB, NZB-Begr., Termin, BGH-Urteil |
|
||||
| `de.inf.olg.urteil_lg` | de.inf.olg | Zustellung LG-Urteil | filing | both | Berufungsschrift, Berufungsbegr., Termin, OLG-Urteil |
|
||||
| `de.null.bgh.urteil_bpatg` | de.null.bgh | Zustellung BPatG-Urteil | filing | both | Berufungsschrift, Berufungsbegr., Termin, BGH-Urteil |
|
||||
| `dpma.appeal.bgh.entsch_bpatg` | dpma.appeal.bgh | Zustellung BPatG-Entscheidung | filing | both | Rechtsbeschwerde, BGH-Entscheidung |
|
||||
| `dpma.appeal.bpatg.entscheidung` | dpma.appeal.bpatg | Zustellung DPMA-Entscheidung | filing | both | Beschwerde, Termin, BPatG-Entscheidung |
|
||||
| `epa.opp.boa.entsch` | epa.opp.boa | Zustellung der Beschwerdeentscheidung | filing | both | Beschwerdeeinlegung, Beschwerdebegr. |
|
||||
| `dpma.opp.dpma.publish` | dpma.opp.dpma | Veröffentlichung der Erteilung | filing | both | Einspruchsfrist, DPMA-Entscheidung |
|
||||
| `epa.opp.opd.grant` | epa.opp.opd | Veröffentlichung der Erteilung | filing | both | Einspruchsfrist |
|
||||
|
||||
(Verified read-only via Supabase MCP against `paliad.deadline_rules_unified`, 2026-06-01.)
|
||||
|
||||
### The clean-filter question — and why a pure picker-filter does NOT work
|
||||
The task hypothesised "exclude `primary_party='court'`". **That does not catch these 8** — they
|
||||
carry `primary_party='both'`, not `'court'`. And `'both'` cannot be excluded wholesale: many real
|
||||
party submissions are `'both'` (Berufungsbegründung, Anschlussberufung, every UPC appeal brief).
|
||||
There is **no existing column value that isolates the 8** from genuine party submissions — the only
|
||||
thing wrong with them is the mislabel itself. So a stronger picker WHERE-clause cannot cleanly fix
|
||||
this without first fixing the data.
|
||||
|
||||
### → FORK (i): data-fix vs filter — RECOMMENDATION: **data correction**
|
||||
|
||||
**Recommended — data correction (re-kind the 8 anchor rows):**
|
||||
Set on each of the 8 rows: `event_type = 'decision'` and `primary_party = 'court'`, matching the
|
||||
16 sibling court-act rows the model already has. Then the *existing* picker filter
|
||||
(`event_type='filing'`) excludes them automatically — **no handler change**.
|
||||
- **Safe for anchoring:** the deadline chain links via `parent_id` (uuid FK), *not* via
|
||||
`event_type`/`primary_party`. Re-kinding does not touch the FK, so Revisionsfrist &co. still
|
||||
anchor correctly.
|
||||
- **`submission_code` retained:** the 16 sibling `decision` rows keep their submission_codes too
|
||||
(they're used as stable anchor identifiers), so retaining them here is consistent — no need to
|
||||
strip.
|
||||
- **Caveat to confirm before applying:** verify nothing computes a *deadline trigger* off
|
||||
`event_type='filing'` for these specific rows (a quick grep of the deadline engine for
|
||||
`event_type` filters). The `parent_id` graph is the structural link, so this is expected-safe,
|
||||
but the coder should confirm.
|
||||
|
||||
**Defensive hardening (do in addition, not instead):** add `AND dr.primary_party IS DISTINCT FROM
|
||||
'court'` to `loadSubmissionCatalog`'s WHERE clause. After the data fix the 8 rows are `'court'`, so
|
||||
this is belt-and-braces: any future mis-kinded court act can't leak into the picker even if its
|
||||
`event_type` is wrong.
|
||||
|
||||
**Why not "stronger filter only":** there is no filter on current columns that removes the 8
|
||||
without also removing legitimate `'both'` party submissions. A filter alone cannot fix mislabeled
|
||||
data — it would have to encode a brittle name-pattern blocklist ("Zustellung%/Veröffentlichung%"),
|
||||
which is the kind of tech debt the project bars.
|
||||
|
||||
---
|
||||
|
||||
## P2 — grouped picker table layout
|
||||
|
||||
### What m saw
|
||||
The full proceeding name ("Revision / Non-admission Appeal BGH (Infringement) de.inf.bgh") appears
|
||||
"in the row flow" so the columns (Schriftsatz | Partei | Rechtsgrundlage | Entwurf starten) look
|
||||
broken.
|
||||
|
||||
### Root cause — it is NOT structural; it is **visual weight**
|
||||
The grouped rows are hydrated by `frontend/src/client/submissions-new.ts`. The group header is
|
||||
**already a correct full-width colspan row** (committed `a911a2d`, 2026-05-23 — i.e. m saw this
|
||||
exact code):
|
||||
|
||||
```ts
|
||||
// client/submissions-new.ts:167-174
|
||||
const colspan = 4;
|
||||
html.push(`<tr class="entity-table-group-header"><th colspan="${colspan}" scope="colgroup">
|
||||
<span class="entity-table-group-header__name">${esc(group.name)}</span>
|
||||
<span class="entity-table-group-header__code">${esc(code)}</span></th></tr>`);
|
||||
```
|
||||
|
||||
CSS for it exists at `frontend/src/styles/global.css:6066-6109`. So structurally the name spans all
|
||||
4 columns — it is not crammed into column 1.
|
||||
|
||||
**The actual defect is contrast.** The group-header band paints
|
||||
`background: var(--color-bg-subtle)` (`global.css:6074`) = **`#f7f3f0`** — and the table `thead`
|
||||
column-label row uses the **same** `--color-bg-subtle` (`global.css:7979`), over a near-cream page
|
||||
background, with faint `--color-border: #e1dcd6` top/bottom rules. Result: the proceeding-name band
|
||||
is barely distinguishable from the column-header band directly above it and from the page. The eye
|
||||
reads it as un-delimited floating text sitting between the column labels and the data — "the name is
|
||||
in the row flow and the columns look broken." The long EN proceeding names amplify it.
|
||||
|
||||
(Could not confirm against the live render — `/submissions/new` is auth-gated and redirects to
|
||||
`/login`. Diagnosis is from source + the CSS variable values, which are conclusive about contrast.)
|
||||
|
||||
### → Fix (quick — pure CSS, no fork)
|
||||
Give `.entity-table-group-header th` a distinctly stronger treatment so each proceeding group reads
|
||||
as its own band, clearly separated from the column header:
|
||||
- a heavier/darker background than the `thead` (e.g. a deeper tint, or the midnight/lime accent the
|
||||
`--own` modifier already uses at `6089-6093`), **and/or**
|
||||
- a heavier top border / a small accent rule, plus a touch more vertical padding.
|
||||
|
||||
Anchor: `frontend/src/styles/global.css:6066-6109`. No TS change needed — the markup is already
|
||||
correct. The sibling project-scoped tab (`client/submissions.ts:137-141`) shares the same classes,
|
||||
so the CSS fix improves both at once.
|
||||
|
||||
(If the coder finds the live deploy *doesn't* show the colspan header at all, the secondary
|
||||
hypothesis is a stale `/assets/submissions-new.js` bundle — verify the deployed bundle includes the
|
||||
`a911a2d` grouping code. Source on `main` is correct as of this diagnosis.)
|
||||
|
||||
---
|
||||
|
||||
## P3 — generated Rubrum is UNSTYLED + UNFILLED (the docforge core)
|
||||
|
||||
m generated a draft from the global picker ("Ohne Projekt") and got: letterhead filled
|
||||
(`Schriftsatz von HLC / Matthias Siebels, duesseldorf`) but **every** caption/party/project value =
|
||||
`[KEIN WERT: …]` and the Rubrum is **plain text with no HL Patents Style formatting**. Two distinct
|
||||
layers, diagnosed separately.
|
||||
|
||||
### P3(a) — UNSTYLED — confirmed: it's `BuildFallbackSkeleton` output
|
||||
|
||||
**The path m hit.** `resolveSubmissionTemplate` (`internal/handlers/submission_drafts.go:1359-1408`)
|
||||
is a 7-tier fallback chain. For any code without a dedicated per-code template (only
|
||||
`de.inf.lg.erwidg` has one), and with the firm/universal skeletons rejected by the merge-safe guard
|
||||
(see below), generation lands on **tier 6 — `docx.BuildFallbackSkeleton(lang)`**
|
||||
(`pkg/docforge/docx/fallback_skeleton.go`).
|
||||
|
||||
**What that emits.** A minimal in-process .docx whose `styles.xml`
|
||||
(`fallback_skeleton.go:121-138`) defines only three generic styles:
|
||||
`Heading1` (bold 14pt), `Heading2` (bold 12pt), `Normal` (nothing). The Rubrum is built from those
|
||||
(`buildFallbackDocumentXML`, lines 215-269) — `fbHeading2` / `fbPlain` / `fbBold`. **No HL Patents
|
||||
Style typography, no named Rubrum styles, no firm font/numbering.** m's "plain text" is exactly
|
||||
this. Confirmed.
|
||||
|
||||
**Why the styled base isn't used (the merge-safe guard).** Tiers 3/4/5 fetch the firm/universal
|
||||
skeletons from mWorkRepo but are **guarded by `docx.HasMergePlaceholders`** (lines 1378/1384/1388).
|
||||
I fetched the firm-skeleton
|
||||
(`HL/mWorkRepo:6 - material/Templates/Word/Paliad/HLC/_firm-skeleton.docx`, 157 KB) and unzipped it:
|
||||
|
||||
- **`styles.xml` carries the FULL HL Patents Style catalogue** — including the exact named styles a
|
||||
Rubrum needs:
|
||||
- `HLpat-Table-Recitals-Party`, `HLpat-Table-Recitals-PartyDetails`,
|
||||
`HLpat-Table-Recitals-PartyRoles`, `HLpat-Table-Recitals-Sequencers` — the party-block (Rubrum)
|
||||
styles (e.g. `Recitals-Party` = `basedOn Body1`, bold, numbered list `numId 4`).
|
||||
- `HLpat-Heading-H1..H5`, `HLpat-Body-B0/B1`, `HLpat-Header-Section/Subsection`,
|
||||
`HLpat-Signature`, `SignatureBlock`, `HLpat-Requests-Intro`, `HLpat-Citation`, …
|
||||
- full letterhead: `header1/header2` + `footer1/footer2` + `media/image1.jpeg` (logo) +
|
||||
`media/image2.jpg`, theme1.xml, fontTable.xml.
|
||||
- **But its `document.xml` body is ANCHORS-ONLY** — ten `{{#section:KEY}}…{{/section:KEY}}` pairs
|
||||
(`letterhead`, `caption`, `introduction`, `requests`, `facts`, `legal_argument`, `evidence`,
|
||||
`exhibits`, `closing`, `signature`) and **zero `{{key}}` merge placeholders**.
|
||||
|
||||
So `HasMergePlaceholders` correctly rejects it for the **merge** path (feeding it to `merge.go`
|
||||
would print literal `{{#section:…}}` junk — the t-paliad-358 A-S1 regression). The styled base is a
|
||||
**Composer base**, consumed by `pkg/docforge/docx/compose.go` (exists, 22 KB), which splices section
|
||||
content into those anchors. **The merge path and the Composer path are different engines, and
|
||||
one-click /generate + project-less export run the merge path.**
|
||||
|
||||
**The styled HL base therefore already carries every named paragraph style the Rubrum needs.** The
|
||||
gap is purely that generation runs the merge path (→ bare in-process skeleton) rather than a styled
|
||||
base.
|
||||
|
||||
#### → FORK (ii): styling approach — three framed options
|
||||
|
||||
- **Option A — drive generation off the Composer path (the "real docforge").**
|
||||
Route one-click /generate and the project-less draft-export through `compose.go` with the
|
||||
firm-skeleton base + the section seeds (`submission_bases.section_spec`, migs 146/150; the caption
|
||||
seed already exists per t-paliad-358). Output is fully HL-styled (Rubrum in `HLpat-Table-Recitals-*`,
|
||||
headings in `HLpat-Heading-*`, signature in `HLpat-Signature`, logo letterhead) **and** carries
|
||||
seeded section bodies. *Cost:* the biggest change — generation currently never calls the Composer
|
||||
for these entry points; needs routing + the project-less bag wired into the Composer.
|
||||
*This is the long-term correct path.*
|
||||
|
||||
- **Option B — author a merge-safe styled firm-skeleton (tracer-bullet, RECOMMENDED first).**
|
||||
Start from the firm-skeleton's full part-set (its `styles.xml`, theme, fonts, headers/footers,
|
||||
logo media) and replace **only** its anchors-only `document.xml` body with a **merge-safe Rubrum
|
||||
body** that uses the HLpat style IDs (`HLpat-Table-Recitals-Party` for party lines,
|
||||
`HLpat-Heading-H2` for section heads, `HLpat-Signature` for the signature block) and the same
|
||||
`{{key}}` / `{{caption.*}}` placeholders the current fallback already uses. Publish it as a
|
||||
merge-safe `_firm-skeleton.docx` (or a new slug). The resolver's **tier 4 already prefers a
|
||||
merge-safe firm-skeleton automatically** — its own comment says: *"should a merge-safe
|
||||
firm-skeleton (with letterhead) be restored later it is preferred again automatically"*
|
||||
(`submission_drafts.go:1352-1354`). So this needs **no handler change** — drop in the file and the
|
||||
guard picks it. Output: HL-styled Rubrum + letterhead via the existing merge path.
|
||||
*Cost:* author one .docx body (the styles/letterhead already exist in the base); smallest blast
|
||||
radius; reuses the entire existing merge pipeline and the `caption.*` keys.
|
||||
|
||||
- **Option C — graft real styles into `BuildFallbackSkeleton`.**
|
||||
Embed the firm `styles.xml` + theme + letterhead into the in-process builder and map its
|
||||
paragraphs to HLpat styles. Keeps a code-only last-resort that is also styled. *Cost:* duplicates
|
||||
the base's 89 KB styles.xml into Go and must track it on every firm-template change — more
|
||||
maintenance than B for the same visual result. Only worth it if we want even the never-reached
|
||||
last-ditch tier styled.
|
||||
|
||||
**Recommendation:** **B first** (tracer bullet — slots into the existing tier-4 hook, styled Rubrum
|
||||
this iteration), **A as the strategic target** (full Composer-driven generation with seeded
|
||||
sections). C is not recommended.
|
||||
|
||||
### P3(b) — UNFILLED (`[KEIN WERT]`) — confirmed cause + a pinned resolver-wiring gap
|
||||
|
||||
**Confirmed cause: no project context.** The draft was started "Ohne Projekt" → `project_id` NULL.
|
||||
In `SubmissionVarsService.Build` (`internal/services/submission_vars.go:125-216`), the project-less
|
||||
branch is **lines 171-178**:
|
||||
|
||||
```go
|
||||
if in.ProjectID == nil {
|
||||
// Project-less draft (t-paliad-243): no project / parties / deadline state to resolve.
|
||||
out.Placeholders = docforge.NewResolverSet(resolvers...).BuildBag()
|
||||
return out, nil
|
||||
}
|
||||
```
|
||||
|
||||
`resolvers` at that point is **only** `firmResolver, todayResolver, userResolver,
|
||||
proceduralEventResolver` (lines 158-163). It does **not** include `projectResolver`,
|
||||
**`captionResolver`**, `partiesResolver`, or `deadlineResolver` (those are appended only on the
|
||||
project branch, lines 203-208). So `caption.*`, `project.*`, `parties.*` are never populated →
|
||||
every one renders `[KEIN WERT: …]`. firm/user/today DID fill (letterhead correct) — consistent with
|
||||
m's screenshot.
|
||||
|
||||
**The resolver-wiring gap (pinned).** This is the important finding the task asked for. Even with
|
||||
no project, the draft has a `submission_code`, and:
|
||||
|
||||
- the `rule` is **already loaded** on this path (`loadPublishedRule`, line 138 — *before* the
|
||||
`ProjectID == nil` check), and
|
||||
- `DeadlineRule.ProceedingTypeID *int` is populated (`internal/models/…:114`; `proceeding_type_id`
|
||||
is in `ruleColumns`, `deadline_rule_service.go:42`), and
|
||||
- `resolveCaption(p, pt)` is a **pure function that tolerates a nil project**
|
||||
(`submission_vars.go:453-533`): it guards `if pt != nil` (464) and `if p != nil` (506). With `pt`
|
||||
set and `p == nil` it resolves **heading / subject / claimant_designation / defendant_designation
|
||||
/ versus** from the proceeding alone (jurisdiction + dotted-code "nature" segment + the mig-137
|
||||
role-label overrides). Only the *appeal/cassation* designation upgrade needs
|
||||
`project.instance_level`, which simply falls back to the civil default when absent.
|
||||
|
||||
**So `caption.heading_de` is empty on the project-less path purely because the branch never loads
|
||||
the ProceedingType from `rule.ProceedingTypeID` and never runs `captionResolver` — not because the
|
||||
data is missing.** The submission_code *does* tie the draft to a proceeding; the wiring just doesn't
|
||||
use it. This is a genuine gap, independently fixable from the product decision below.
|
||||
|
||||
Minimal fix shape (for the coder, if m chooses to fill-what-we-can): in the `ProjectID == nil`
|
||||
branch, `pt, _ := s.loadProceedingType(ctx, rule.ProceedingTypeID)` (the helper already tolerates a
|
||||
nil id, lines 275-291) and append `captionResolver{project: nil, pt: pt, lang}` (+ optionally a
|
||||
proceeding-only `projectResolver` for `project.proceeding.name`). That fills the caption wording and
|
||||
the proceeding line; party names / case number / court stay blank.
|
||||
|
||||
#### → FORK (iii): require-Akte vs fill-what-we-can
|
||||
|
||||
- **Option 1 — require an Akte/project to draft.** A draftable submission must be bound to a
|
||||
project (drop or disable "Ohne Projekt", or block generation until linked). Rubrum is *fully*
|
||||
filled (project + parties + caption all present). Simplest correctness, but removes the
|
||||
quick project-less drafting affordance t-paliad-243 deliberately added.
|
||||
- **Option 2 — fill-what-we-can on a project-less draft (RECOMMENDED, pairs with the wiring fix).**
|
||||
Keep "Ohne Projekt" but resolve `caption.*` (heading / designations / versus / subject) and the
|
||||
proceeding line from the submission_code's proceeding, leaving only party names / case number /
|
||||
court blank for the lawyer. The Rubrum then renders with correct procedural wording instead of
|
||||
five `[KEIN WERT]`s; the genuinely project-specific blanks remain honest gaps. This is the
|
||||
resolver-wiring fix above; it does not require the require-Akte product change.
|
||||
|
||||
**Recommendation:** **Option 2** — it's the smaller change, preserves the t-paliad-243 affordance,
|
||||
and turns a wall of `[KEIN WERT]` into a real (if partial) Rubrum. m may *additionally* prefer
|
||||
"start from Akte" as the *primary* CTA for a fully-filled document, but that's a UX nudge, not a
|
||||
hard gate.
|
||||
|
||||
---
|
||||
|
||||
## Sliced fix-plan (tracer-bullet first)
|
||||
|
||||
Ordered cheap → meaty. Each slice is independently shippable.
|
||||
|
||||
1. **P1 data-fix (quick, data-only).** Re-kind the 8 anchor rows
|
||||
(`event_type='decision'`, `primary_party='court'`) in `paliad.deadline_rules_unified`. No code.
|
||||
Confirm the deadline engine doesn't trigger off `event_type='filing'` for them first (expected
|
||||
safe — anchoring is `parent_id`). *Optionally* add the `primary_party IS DISTINCT FROM 'court'`
|
||||
guard to `loadSubmissionCatalog` as belt-and-braces.
|
||||
2. **P2 layout (quick, CSS-only).** Strengthen `.entity-table-group-header th`
|
||||
(`global.css:6066-6077`) so each proceeding band is visually distinct from the column header.
|
||||
Verify the deployed `submissions-new.js` bundle is current.
|
||||
3. **P3(b) fill-what-we-can (small, Go).** Wire `captionResolver` (and a proceeding-only
|
||||
`projectResolver`) into the project-less branch of `SubmissionVarsService.Build` using
|
||||
`rule.ProceedingTypeID`. Turns the Rubrum wording from `[KEIN WERT]` into resolved procedural
|
||||
labels; party/case/court stay blank. (Decide FORK iii first — this *is* Option 2.)
|
||||
4. **P3(a) styling — tracer bullet (Option B, medium).** Author a merge-safe styled firm-skeleton
|
||||
(firm-skeleton part-set + a `{{key}}`/`{{caption.*}}` Rubrum body in `HLpat-Table-Recitals-*` /
|
||||
`HLpat-Heading-*` / `HLpat-Signature`). Drops into the existing tier-4 hook — no handler change.
|
||||
Combined with slice 3, the project-less draft now renders an HL-styled, partially-filled Rubrum.
|
||||
5. **P3(a) styling — strategic (Option A, meaty, later).** Route generation through the Composer
|
||||
(`compose.go`) off the firm-skeleton base with section seeds, for fully-styled documents with
|
||||
seeded section bodies. Larger change; do after slices 1-4 validate.
|
||||
|
||||
---
|
||||
|
||||
## The three forks for m
|
||||
|
||||
- **(i) P1 — data-fix vs filter:** → **data correction** (re-kind the 8 anchor rows to
|
||||
`decision`/`court`; existing filter then excludes them). A picker-filter alone *cannot* isolate
|
||||
them (`primary_party='both'`, shared with real submissions). Optional `primary_party<>'court'`
|
||||
guard as hardening.
|
||||
- **(ii) P3 styling — Composer vs merge-safe styled skeleton vs grafted fallback:** → **Option B**
|
||||
(merge-safe styled firm-skeleton) as the tracer bullet; **Option A** (Composer-driven) as the
|
||||
strategic target. The styled base already carries all HL Patents Style + Rubrum styles — the work
|
||||
is a styled body, not new styles.
|
||||
- **(iii) P3 fill — require-Akte vs fill-what-we-can:** → **Option 2** (fill caption.* from the
|
||||
submission_code's proceeding on project-less drafts; leave party/case/court blank). Pairs with the
|
||||
pinned resolver-wiring fix.
|
||||
|
||||
---
|
||||
|
||||
## Appendix — evidence index
|
||||
|
||||
- Picker filter: `internal/handlers/submissions.go:177-211`.
|
||||
- P1 affected rows + the 16-row correct `decision`/`court` tier + `parent_id` anchoring:
|
||||
Supabase MCP read-only on `paliad.deadline_rules_unified` (2026-06-01).
|
||||
- P2 group header: `frontend/src/client/submissions-new.ts:167-174` (commit `a911a2d`, 2026-05-23);
|
||||
CSS `frontend/src/styles/global.css:6066-6109`; `--color-bg-subtle:#f7f3f0` (`:28`), same as
|
||||
`thead` (`:7979`); auth-gated render not directly observed.
|
||||
- P3(a) unstyled fallback: `pkg/docforge/docx/fallback_skeleton.go:53-89,121-138,215-269`;
|
||||
resolver chain + merge-safe guard `internal/handlers/submission_drafts.go:1359-1408` (esp.
|
||||
1352-1354, 1378/1384/1388/1395).
|
||||
- P3(a) styled base: `HL/mWorkRepo:6 - material/Templates/Word/Paliad/HLC/_firm-skeleton.docx`
|
||||
(fetched + unzipped: full HLpat styles incl. `HLpat-Table-Recitals-*`; anchors-only body);
|
||||
Composer `pkg/docforge/docx/compose.go`; registry `internal/handlers/files.go:94-101`.
|
||||
- P3(b) project-less gap: `internal/services/submission_vars.go:125-216` (branch 171-178),
|
||||
`resolveCaption` 453-533, `loadProceedingType` 275-291, `rule` load 138; `DeadlineRule.
|
||||
ProceedingTypeID` (`internal/models/…:114`, `ruleColumns` `deadline_rule_service.go:42`).
|
||||
Reference in New Issue
Block a user