One convention for preliminary or to-be-amended information — brackets, everywhere, rather than silent omission #162

Open
opened 2026-07-30 14:56:43 +00:00 by mAi · 5 comments
Collaborator

m, 2026-07-30, asked whether a generated draft title should show a missing opponent the way the filename already shows a missing docket:

"Rare edge case, not really important — docket number may be uncertain, but parties should usually be sure. Maybe we find a common way to show preliminary info / info that needs to be amended? maybe with [ ... ] or similar?"

So the specific case is low priority. The general one is the issue.

The problem

Today each surface handles an unfilled value its own way, and one of them is silent:

Surface Missing value renders as
Submission filename (TBD) — visible
Draft title omitted — the name looks complete
Letterhead / variable bag reported as an unresolved selection (m/paliad#139 Slice B)
Formalities export explicit refusal record with a reason (schema 4, mig 211)

Four mechanisms, four spellings, and only the draft title makes an incomplete thing look finished.

What m is asking for

One convention for "this value is preliminary or needs amending", applied consistently wherever generated text can carry an unfilled or provisional value. His suggestion is bracket notation — [ … ] or similar.

Scope to establish before designing

  • Where does provisional information actually occur? Docket numbers before assignment, parties before service, dates before scheduling, court before filing. Enumerate rather than assume — the answer decides whether this is a rendering convention or a data concept.
  • Is "preliminary" the same as "missing"? A docket that does not exist yet is different from an opponent nobody recorded. The formalities family already distinguishes unsourced from not_applicable for exactly this reason, and that distinction turned out to matter. This may need the same split.
  • Does it ever reach a filing? If a bracketed placeholder can end up in a document served on a court, the convention must be one a lawyer recognises as not yet final at a glance — that is a house-style question and touches mAi/patentstyle.

Explicitly out of scope

The draft-title case that prompted it. m ruled it a rare edge case; fix it when the convention exists, not before.


Filed by paliad/head from m's answer of 2026-07-30. Related: the filename generator's (TBD) handling is the one surface that already does something reasonable and is worth reading first.

m, 2026-07-30, asked whether a generated draft title should show a missing opponent the way the filename already shows a missing docket: > "Rare edge case, not really important — docket number may be uncertain, but parties should usually be sure. **Maybe we find a common way to show preliminary info / info that needs to be amended? maybe with [ ... ] or similar?**" So the specific case is low priority. The general one is the issue. ## The problem Today each surface handles an unfilled value its own way, and one of them is silent: | Surface | Missing value renders as | |---|---| | Submission filename | `(TBD)` — visible | | Draft title | **omitted** — the name looks complete | | Letterhead / variable bag | reported as an unresolved selection (m/paliad#139 Slice B) | | Formalities export | explicit refusal record with a reason (schema 4, mig 211) | Four mechanisms, four spellings, and only the draft title makes an incomplete thing look finished. ## What m is asking for One convention for *"this value is preliminary or needs amending"*, applied consistently wherever generated text can carry an unfilled or provisional value. His suggestion is bracket notation — `[ … ]` or similar. ## Scope to establish before designing - **Where does provisional information actually occur?** Docket numbers before assignment, parties before service, dates before scheduling, court before filing. Enumerate rather than assume — the answer decides whether this is a rendering convention or a data concept. - **Is "preliminary" the same as "missing"?** A docket that does not exist yet is different from an opponent nobody recorded. The formalities family already distinguishes `unsourced` from `not_applicable` for exactly this reason, and that distinction turned out to matter. This may need the same split. - **Does it ever reach a filing?** If a bracketed placeholder can end up in a document served on a court, the convention must be one a lawyer recognises as *not yet final* at a glance — that is a house-style question and touches `mAi/patentstyle`. ## Explicitly out of scope The draft-title case that prompted it. m ruled it a rare edge case; fix it when the convention exists, not before. --- *Filed by paliad/head from m's answer of 2026-07-30. Related: the filename generator's `(TBD)` handling is the one surface that already does something reasonable and is worth reading first.*
mAi self-assigned this 2026-07-30 14:56:43 +00:00
Author
Collaborator

Scope established + design filed

docs/design-preliminary-value-convention-2026-07-30.md

Commit: https://mgit.msbls.de/m/paliad/commit/6d7c1fe (branch mai/ares/issue-162-one-convention)

The issue lists four surfaces. There are nine, and the two it does not list are the two that decide the design.

The two missing surfaces

Brackets are already the house convention, and they already reach filed documents. Three surfaces use [ … ] in the body of a Word file today:

  • [KEIN WERT: project.case_number] — the .docx substitution marker (pkg/docforge/placeholder.go:26)
  • [Hier folgt der Schriftsatztext …] — the fallback skeleton (pkg/docforge/docx/fallback_skeleton.go:212)
  • [title / identifier], [Insert original text here]patentstyle's own .dotm elements, vendored at frontend/scripts/patentsstyle-wiki/src/05-special-elements.de.md:87,96,100

So m's suggested notation is not a new proposal. It is the convention the firm already uses; three paliad surfaces follow it and four do not.

One surface already models "preliminary" as data, not text. The Fristenrechner's assumed date: a user-declared hypothetical taints every deadline computed from it (pkg/litigationplanner/engine.go:223), the taint propagates transitively, the UI renders <date> (angenommen) plus a premise line, and the promote path refuses to carry assumed deadlines into the real Fristenliste. That is the reference implementation.

The three scope questions, answered from measurement

Where does provisional information occur? Six values: docket, party, deadline date, court, evidence identifier, submission body. All one class — a value the firm will know later. And no data concept exists behind any of them: models.Party has no served/provisional flag, project.case_number is a nullable string with no status column. So this is a rendering convention, not a schema change. Building a per-field provisional flag across projects, parties, deadlines and courts to serve one cosmetic difference would be the wrong trade.

Is "preliminary" the same as "missing"? No — and paliad has independently answered this twice, in two vocabularies. Mig 211 splits not_applicable (CLOSED) from unsourced (permanent until the world changes). The Fristenrechner splits isConditional ("no date could be computed at all") from isAssumed ("the arithmetic is real; the PREMISE is hypothetical"). Both are the same question: will anyone ever look again?

That gives a closed set of four states, three of which already have a name in the tree:

State Meaning Already named as
pending The value will exist; the world has not produced it yet (new — the one m is asking for)
assumed A value the user invented as a premise isAssumed / angenommen
unsourced Someone should have recorded this and did not RefusalUnsourced
not_applicable The thing genuinely has no such property RefusalNotApplicable

Does it ever reach a filing? Yes — measured. ExportWithMarker defaults missing to DefaultMissingMarker, so every export path that passes nil produces a .docx carrying [KEIN WERT: project.case_number] in the body. No export path counts the remaining markers, warns, or refuses. The download succeeds and the file looks finished.

Three things are wrong with that text as filed text: it names a code path (project.case_number) rather than the thing the lawyer must supply; it asserts absence ("KEIN WERT") where the true statement is not yet; and its wording was inventor default D4 in the 2026-05-19 submission-generator design — a reasonable engineering default, never a house-style decision, never seen by a lawyer.

The convention proposed

Square brackets everywhere a human reads the output, never silence. Four rules:

  1. Bracket, do not omit — closes the draft title, the only surface that lies by omission.
  2. The bracket says what is needed, in the document's language[Aktenzeichen — noch nicht vergeben], not [KEIN WERT: project.case_number]. The human label already exists for every variable in nomen.VarDef.Label/LabelEN; the marker just does not use it.
  3. The bracket carries the state where the state is recorded — and not_applicable renders nothing, which is why the four states cannot collapse into "show a bracket".
  4. Filenames keep (TBD)[ and ] are glob metacharacters. This is not a special case: nomen.RenderTarget exists precisely so one composition renders differently per output policy.

No new mechanism is needed. Both seams already exist and are already per-consumer: nomen.MissingKind (whose KindLiteral comment says it is kept distinct "so future policy can diverge" — this is that divergence) and docforge.MissingPlaceholderFn.

One guard belongs with this work

No export counts its remaining markers. Once markers are the deliberate convention rather than a fallback, an export carrying one should say so — in the shape of UnresolvedSelections, which already made exactly this trade: do not fail the build, but stop being unaware. Without it the convention makes gaps prettier without making them harder to miss, and a nicer-looking gap in a filed document is worse than an ugly one.

Open — needs m (§8 of the design)

The marker text goes into a document that can be served on a court. That is house style, and it touches mAi/patentstyle, whose .dotm brackets slots bare ([title / identifier]) with no state suffix.

  • (A) Match patentstyle[Aktenzeichen]. One convention across both tools; loses m's own preliminary-vs-needs-amending distinction.
  • (B) State suffix[Aktenzeichen — folgt] vs [Gegner — nicht erfasst]. Carries the distinction; two bracket dialects unless patentstyle adopts it too.

Recommendation: (B), and take it to patentstyle as a shared convention. A bare [Aktenzeichen] cannot tell a reviewing partner whether the docket is coming or was forgotten, and those warrant different actions.

Not proposed

No schema change. No change to the assumed-date, block-refusal or formalities-refusal surfaces — this work adopts their vocabulary rather than replacing it. No change to the preview "Beispiel" mode. No renaming of unsourced / not_applicable (those names are patentstyle's, carried verbatim by mig 211).

The draft-title case m ruled out of scope is, once the vocabulary lands, the one change that needs no decision from anyone and touches nothing filed — the natural first slice, exactly as m ruled.


No status label set: this repo carries only deferred and done, and neither is honest here. Nothing shipped — the convention is proposed and awaits the §8 decision.

## Scope established + design filed `docs/design-preliminary-value-convention-2026-07-30.md` Commit: https://mgit.msbls.de/m/paliad/commit/6d7c1fe (branch `mai/ares/issue-162-one-convention`) The issue lists four surfaces. There are **nine**, and the two it does not list are the two that decide the design. ### The two missing surfaces **Brackets are already the house convention, and they already reach filed documents.** Three surfaces use `[ … ]` in the body of a Word file today: - `[KEIN WERT: project.case_number]` — the `.docx` substitution marker (`pkg/docforge/placeholder.go:26`) - `[Hier folgt der Schriftsatztext …]` — the fallback skeleton (`pkg/docforge/docx/fallback_skeleton.go:212`) - `[title / identifier]`, `[Insert original text here]` — **patentstyle's own `.dotm` elements**, vendored at `frontend/scripts/patentsstyle-wiki/src/05-special-elements.de.md:87,96,100` So m's suggested notation is not a new proposal. It is the convention the firm already uses; three paliad surfaces follow it and four do not. **One surface already models "preliminary" as data, not text.** The Fristenrechner's assumed date: a user-declared hypothetical taints every deadline computed from it (`pkg/litigationplanner/engine.go:223`), the taint propagates transitively, the UI renders `<date> (angenommen)` plus a premise line, and the promote path **refuses to carry assumed deadlines into the real Fristenliste**. That is the reference implementation. ### The three scope questions, answered from measurement **Where does provisional information occur?** Six values: docket, party, deadline date, court, evidence identifier, submission body. All one class — a value the firm will know later. And **no data concept exists behind any of them**: `models.Party` has no served/provisional flag, `project.case_number` is a nullable string with no status column. So this is a rendering convention, not a schema change. Building a per-field provisional flag across projects, parties, deadlines and courts to serve one cosmetic difference would be the wrong trade. **Is "preliminary" the same as "missing"?** No — and paliad has independently answered this twice, in two vocabularies. Mig 211 splits `not_applicable` (CLOSED) from `unsourced` (permanent until the world changes). The Fristenrechner splits `isConditional` ("no date could be computed at all") from `isAssumed` ("the arithmetic is real; the PREMISE is hypothetical"). Both are the same question: **will anyone ever look again?** That gives a closed set of four states, three of which already have a name in the tree: | State | Meaning | Already named as | |---|---|---| | `pending` | The value will exist; the world has not produced it yet | *(new — the one m is asking for)* | | `assumed` | A value the user invented as a premise | `isAssumed` / `angenommen` | | `unsourced` | Someone should have recorded this and did not | `RefusalUnsourced` | | `not_applicable` | The thing genuinely has no such property | `RefusalNotApplicable` | **Does it ever reach a filing?** **Yes — measured.** `ExportWithMarker` defaults `missing` to `DefaultMissingMarker`, so every export path that passes `nil` produces a `.docx` carrying `[KEIN WERT: project.case_number]` in the body. **No export path counts the remaining markers, warns, or refuses.** The download succeeds and the file looks finished. Three things are wrong with that text as filed text: it names a code path (`project.case_number`) rather than the thing the lawyer must supply; it asserts absence ("KEIN WERT") where the true statement is *not yet*; and its wording was inventor default **D4** in the 2026-05-19 submission-generator design — a reasonable engineering default, never a house-style decision, never seen by a lawyer. ### The convention proposed Square brackets everywhere a human reads the output, never silence. Four rules: 1. **Bracket, do not omit** — closes the draft title, the only surface that lies by omission. 2. **The bracket says what is needed, in the document's language** — `[Aktenzeichen — noch nicht vergeben]`, not `[KEIN WERT: project.case_number]`. The human label already exists for every variable in `nomen.VarDef.Label`/`LabelEN`; the marker just does not use it. 3. **The bracket carries the state where the state is recorded** — and `not_applicable` renders *nothing*, which is why the four states cannot collapse into "show a bracket". 4. **Filenames keep `(TBD)`** — `[` and `]` are glob metacharacters. This is not a special case: `nomen.RenderTarget` exists precisely so one composition renders differently per output policy. **No new mechanism is needed.** Both seams already exist and are already per-consumer: `nomen.MissingKind` (whose `KindLiteral` comment says it is kept distinct "so future policy can diverge" — this is that divergence) and `docforge.MissingPlaceholderFn`. ### One guard belongs with this work No export counts its remaining markers. Once markers are the deliberate convention rather than a fallback, an export carrying one should say so — in the shape of `UnresolvedSelections`, which already made exactly this trade: do not fail the build, but stop being unaware. Without it the convention makes gaps *prettier* without making them *harder to miss*, and a nicer-looking gap in a filed document is worse than an ugly one. ### Open — needs m (§8 of the design) The marker text goes into a document that can be served on a court. That is house style, and it touches `mAi/patentstyle`, whose `.dotm` brackets slots bare (`[title / identifier]`) with no state suffix. - **(A) Match patentstyle** — `[Aktenzeichen]`. One convention across both tools; loses m's own preliminary-vs-needs-amending distinction. - **(B) State suffix** — `[Aktenzeichen — folgt]` vs `[Gegner — nicht erfasst]`. Carries the distinction; two bracket dialects unless patentstyle adopts it too. **Recommendation: (B), and take it to patentstyle as a shared convention.** A bare `[Aktenzeichen]` cannot tell a reviewing partner whether the docket is *coming* or was *forgotten*, and those warrant different actions. ### Not proposed No schema change. No change to the assumed-date, block-refusal or formalities-refusal surfaces — this work adopts their vocabulary rather than replacing it. No change to the preview "Beispiel" mode. No renaming of `unsourced` / `not_applicable` (those names are patentstyle's, carried verbatim by mig 211). The draft-title case m ruled out of scope is, once the vocabulary lands, the one change that needs no decision from anyone and touches nothing filed — the natural first slice, exactly as m ruled. --- *No status label set: this repo carries only `deferred` and `done`, and neither is honest here. Nothing shipped — the convention is proposed and awaits the §8 decision.*
Author
Collaborator

m's ruling built: bare brackets, draft title shipped

Commit: https://mgit.msbls.de/m/paliad/commit/eb58bc5 (branch mai/ares/issue-162-one-convention)

Decision (m, 2026-07-30): [Aktenzeichen], [Gegner] — the variable's human label in square brackets, no state suffix. This is patentstyle's existing .dotm form, so one convention holds across both repositories from this commit and the cross-repository proposal is out of scope — there is nothing to propose.

What shipped

The draft title, first, as it needed no decision and touches nothing filed.

A project-bound draft now names all three of client, forum and opponent. An unresolved one renders as its bracketed label instead of vanishing:

Case Before Now
No opponent recorded 2026-05-31 Bayer AG ./. UPC 2026-05-31 Bayer AG ./. UPC ./. [Gegner]
No forum 2026-05-31 Bayer AG ./. Acme Generics 2026-05-31 Bayer AG ./. [Forum] ./. Acme Generics
Nothing filled 2026-05-31 2026-05-31 [Mandant] ./. [Forum] ./. [Gegner]
EN draft, nothing filled 2026-05-31 2026-05-31 [Client] ./. [Forum] ./. [Opponent]

A project-less draft is unchanged. Its trio is inapplicable, not unfilled, and bracketing it would invent three questions nobody asked — the one place where silence is still correct.

Three implementation notes worth knowing:

  • projectBound is an explicit parameter, not a project != nil check. A nil pointer on the project path means a project row that failed to load, and that draft's opponent is still a gap to mark. Only the caller knows which naming path it is on.
  • The marker is derived from the artifact catalog at render time, not stored in the composition. Storing it would freeze one language into a per-user override — the Az. folgt leak the filename placeholder already suffered.
  • overlayMissingRules splits a composition by owner. The stored override supplies the shape (variables, order, separators, wraps — exactly what Composition.Template() round-trips); the system supplies the missing-value rules, re-derived every render. That is what lets the wording change later without migrating a single stored override, and it closes the same latent freeze on the filename artifact (no output change there today).

Go suite green (./internal/... ./pkg/... ./cmd/...), 411 frontend tests green, gofmt clean, branch not behind main.

The cost, recorded as a limit (§5.1 of the design)

A bare bracket cannot distinguish "the docket is coming" from "nobody recorded the opponent". [Aktenzeichen] on a draft awaiting registry assignment and [Gegner] on a proceeding whose opposing party was never entered are the same mark, and they warrant different actions — the first is waiting, the second is work.

Weighed and declined: one convention shared with patentstyle from day one was judged worth more. Recorded in the design so the next person to feel the gap finds the question already asked, rather than re-deriving it. If it is ever reopened, the thing to change is R3 alone — the render path takes its missing-value rules from code on every render, so no stored composition needs migrating.

TestAutoSubmissionTitleMarkerForm pins the bare form against the shapes it must not drift into (the [KEIN WERT: key] form, a variable key, a colon, a state suffix, the filename's parentheses), so the declined distinction cannot creep back one well-meaning change at a time.

Does the distinction belong in the DATA instead? (§8) — measured answer: no

The formalities family kept unsourced separate from not_applicable in the data while both go downstream together, and that split mattered. The shape does not transfer here, and the reason is provenance rather than display.

A refusal record is the record of a human judgment. Someone read the RoP, concluded R. 52 is the wrong answer for Rejoinder, and wrote a prose reason — mig 211 is explicit that the reason "carries the argument" and exists to stop the next person fixing the refusal onto a filing. It is worth storing because it is not derivable.

There is no equivalent judgment for a docket that has not been issued. Nobody looks at an empty project.case_number and concludes anything; it is empty because the registry has not acted. Storing pending vs unsourced would need someone to declare it per empty field — and they will not, because filling the value in is strictly less work than annotating why it is empty. A state field nobody has an incentive to write sits at its default forever, and a default-valued field that looks authoritative is worse than no field.

The states also add nothing a query cannot answer today: "which drafts have no docket" is case_number IS NULL.

Rule carried forward: store a state only where a human declared it. Never derive one, and never provide a field hoping someone will.

Two places where it is already in the data, for free — named in §8.1 because they are where the distinction would live if ever wanted, and each already holds more than "empty":

  • The authored blank. submission_drafts.variables[key] = "" means the lawyer deliberately left this gap visible; an absent key means nobody touched it. That is an authored judgment, it is persisted, and today both render the same marker — the formalities shape exactly, arrived at without anyone designing it.
  • The unresolved selection. A draft storing a selected_court_id or selected_lawyers id matching nothing records that somebody chose a referent which has since vanished. That is unsourced in the strict sense, already reported by UnresolvedSelections, already distinguishable from "never selected".

Neither is proposed for change.

Next

The two surfaces that touch filed text: the .docx marker ([KEIN WERT: project.case_number] → the catalog label) and the letterhead/party selection (render a marker where a selection dropped, not only report it). Plus the export guard — no export path counts its remaining markers today, and a nicer-looking gap in a filed document is worse than an ugly one.

The filename stays (TBD) deliberately: parentheses are settled by R4, but the TBD token is m's own prior ruling (t-paliad-composer-docket-tbd-label) and changing it needs its own decision.


Still no status label: this repo carries only deferred and done, and the issue is partly shipped with two surfaces open.

## m's ruling built: bare brackets, draft title shipped Commit: https://mgit.msbls.de/m/paliad/commit/eb58bc5 (branch `mai/ares/issue-162-one-convention`) **Decision (m, 2026-07-30):** `[Aktenzeichen]`, `[Gegner]` — the variable's human label in square brackets, no state suffix. This is patentstyle's existing `.dotm` form, so one convention holds across both repositories from this commit and **the cross-repository proposal is out of scope** — there is nothing to propose. ### What shipped The draft title, first, as it needed no decision and touches nothing filed. A **project-bound** draft now names all three of client, forum and opponent. An unresolved one renders as its bracketed label instead of vanishing: | Case | Before | Now | |---|---|---| | No opponent recorded | `2026-05-31 Bayer AG ./. UPC` | `2026-05-31 Bayer AG ./. UPC ./. [Gegner]` | | No forum | `2026-05-31 Bayer AG ./. Acme Generics` | `2026-05-31 Bayer AG ./. [Forum] ./. Acme Generics` | | Nothing filled | `2026-05-31` | `2026-05-31 [Mandant] ./. [Forum] ./. [Gegner]` | | EN draft, nothing filled | `2026-05-31` | `2026-05-31 [Client] ./. [Forum] ./. [Opponent]` | A **project-less** draft is unchanged. Its trio is *inapplicable*, not unfilled, and bracketing it would invent three questions nobody asked — the one place where silence is still correct. Three implementation notes worth knowing: - **`projectBound` is an explicit parameter, not a `project != nil` check.** A nil pointer on the project path means a project row that failed to load, and that draft's opponent is still a gap to mark. Only the caller knows which naming path it is on. - **The marker is derived from the artifact catalog at render time, not stored in the composition.** Storing it would freeze one language into a per-user override — the `Az. folgt` leak the filename placeholder already suffered. - **`overlayMissingRules` splits a composition by owner.** The stored override supplies the *shape* (variables, order, separators, wraps — exactly what `Composition.Template()` round-trips); the system supplies the *missing-value rules*, re-derived every render. That is what lets the wording change later without migrating a single stored override, and it closes the same latent freeze on the filename artifact (no output change there today). Go suite green (`./internal/... ./pkg/... ./cmd/...`), 411 frontend tests green, gofmt clean, branch not behind main. ### The cost, recorded as a limit (§5.1 of the design) A bare bracket cannot distinguish *"the docket is coming"* from *"nobody recorded the opponent"*. `[Aktenzeichen]` on a draft awaiting registry assignment and `[Gegner]` on a proceeding whose opposing party was never entered are the same mark, and they warrant different actions — the first is waiting, the second is work. Weighed and declined: one convention shared with patentstyle from day one was judged worth more. Recorded in the design so the next person to feel the gap finds the question already asked, rather than re-deriving it. If it is ever reopened, the thing to change is R3 alone — the render path takes its missing-value rules from code on every render, so no stored composition needs migrating. `TestAutoSubmissionTitleMarkerForm` pins the bare form against the shapes it must not drift into (the `[KEIN WERT: key]` form, a variable key, a colon, a state suffix, the filename's parentheses), so the declined distinction cannot creep back one well-meaning change at a time. ### Does the distinction belong in the DATA instead? (§8) — measured answer: no The formalities family kept `unsourced` separate from `not_applicable` in the data while both go downstream together, and that split mattered. **The shape does not transfer here, and the reason is provenance rather than display.** A refusal record is the record of **a human judgment**. Someone read the RoP, concluded R. 52 is the wrong answer for Rejoinder, and wrote a prose reason — mig 211 is explicit that the reason "carries the argument" and exists to stop the next person fixing the refusal onto a filing. It is worth storing because it is not derivable. There is no equivalent judgment for a docket that has not been issued. Nobody looks at an empty `project.case_number` and concludes anything; it is empty because the registry has not acted. Storing `pending` vs `unsourced` would need someone to declare it per empty field — and they will not, because **filling the value in is strictly less work than annotating why it is empty**. A state field nobody has an incentive to write sits at its default forever, and a default-valued field that looks authoritative is worse than no field. The states also add nothing a query cannot answer today: "which drafts have no docket" is `case_number IS NULL`. **Rule carried forward: store a state only where a human declared it. Never derive one, and never provide a field hoping someone will.** **Two places where it is already in the data, for free** — named in §8.1 because they are where the distinction would live if ever wanted, and each already holds more than "empty": - **The authored blank.** `submission_drafts.variables[key] = ""` means the lawyer deliberately left this gap visible; an absent key means nobody touched it. That is an authored judgment, it is persisted, and today both render the same marker — the formalities shape exactly, arrived at without anyone designing it. - **The unresolved selection.** A draft storing a `selected_court_id` or `selected_lawyers` id matching nothing records that somebody chose a referent which has since vanished. That is `unsourced` in the strict sense, already reported by `UnresolvedSelections`, already distinguishable from "never selected". Neither is proposed for change. ### Next The two surfaces that touch filed text: the `.docx` marker (`[KEIN WERT: project.case_number]` → the catalog label) and the letterhead/party selection (render a marker where a selection dropped, not only report it). Plus the export guard — no export path counts its remaining markers today, and a nicer-looking gap in a filed document is worse than an ugly one. The filename stays `(TBD)` deliberately: parentheses are settled by R4, but the `TBD` token is m's own prior ruling (t-paliad-composer-docket-tbd-label) and changing it needs its own decision. --- *Still no status label: this repo carries only `deferred` and `done`, and the issue is partly shipped with two surfaces open.*
Author
Collaborator

Slice 2: catalogue-label markers, letterhead gaps, export guard

Commit: https://mgit.msbls.de/m/paliad/commit/dc9bad4 (branch mai/ares/issue-162-one-convention, merged main first)

All three remaining items. Two of them reach filed text.

1. The .docx marker

[KEIN WERT: project.case_number] named a variable key — a dotted identifier in a Go map — inside a document a lawyer may hand to a court. It now renders the variable's human label in bare brackets: [Aktenzeichen (Gericht)], [Court case number].

The label source already existed and no marker used it. SubmissionVariableCatalogue() is the resolvers' own bilingual VariableKey catalogue — the same one paliad publishes to the sidebar and the authoring palette — so the marker and the form that fills it now name the same thing.

Indexed forms the resolvers deliberately cannot enumerate (lawyer.2.name, parties.claimant.1.name) normalise onto their alias entry: the second letterhead name is still a letterhead name. TestCatalogMissingMarkerCoversEveryCataloguedKey fails if any catalogued variable lacks a DE or EN label, which is what keeps the key-path fallback unreachable for anything paliad actually emits.

docforge.DefaultMissingMarker also changed — it now brackets the bare key rather than spelling [KEIN WERT: key]. The engine holds no catalogue so the key is genuinely all it has, but a second spelling is exactly what #162 exists to remove. Paliad never hits it: services.DefaultMissingMarker delegates to the catalogue marker, so all seven render paths get the label form without any call site remembering to ask.

2. Letterhead — one of the three sub-cases can be bracketed, and only one

I read submission_vars_letterhead.go and the UnresolvedSelections path first as you said. The surface reports three kinds of unresolved selection and they are not alike. This is the part worth reading, because "render the other two in brackets too" looks like the obvious next commit and is not implementable.

Lawyers — bracketed. A selected colleague whose user row is gone now keeps their position as a nil hole instead of being dropped. Compacting the slice renumbered every later colleague: {{lawyer.1.name}} became whoever was chosen third, and no downstream report can undo a name that landed under the wrong index. Their indexed keys stay unbound, so the ordinary missing-marker path fills them — no second mechanism. Only the comma-joined {{lawyers}} spells the marker out, because a name missing from the middle of a joined string cannot be an unbound key. Both produce [Briefkopf: Name]: one spelling, two paths.

When the first choice is the gone one, the unindexed {{lawyer.name}} alias stays unbound rather than promoting the second choice into the primary sender slot — a real name in a position nobody assigned it is worse than a marker.

Parties — no honest bracket exists. An unresolved party id matches no row on the project, so paliad holds a uuid and nothing else: no name, no role, and therefore no position in the caption. Claimants and defendants are separate groups, and a marker cannot be placed in a group when the group is precisely what is unknown.

Court — a substitution, not an omission. An unresolvable selected_court_id falls back to the project's court, so no key is unbound and the document names a real court. The defect is that it is not the one the lawyer chose — worse than a gap for that reason. A bracket is the wrong instrument: there is a value, and it is wrong. Replacing the fallback with a marker is a live option but changes filed text in a case where the project's court is often correct, so it is its own decision rather than a consequence of this one. Flagging rather than deciding it.

Both uncovered cases land in the audit row instead.

3. The export guard

ReportingMissingMarker wraps whatever marker a render path passes and records every key it is asked for. ExportWithMarker attaches the result to SubmissionVarsResult.MissingKeys, and the export handler writes the count, the keys, and any UnresolvedSelections.Describe() onto the submission.exported audit row.

The wrapper is the whole mechanism deliberately: MissingPlaceholderFn is already the seam every render path threads, so counting needs no change to the substitution engine and cannot miss a path the engine gains later.

The export still succeeds. Refusing a whole submission over one gap is worse than the gap — the trade UnresolvedSelections already made and justified. The guard makes gaps findable after the fact, not impossible. The remaining half is the editor warning before the download, which is a frontend slice and is not built here.

MissingKeys and Unresolved are separate fields on purpose and both are needed: Unresolved is a selection that pointed at something gone, MissingKeys is a slot the template asked for and the bag could not fill. Either occurs without the other — the court case is unresolved with no missing key; a template asking for {{project.patent_number}} on a project that has none is a missing key with nothing unresolved behind it.

patentstyle

No artifact of theirs changed and none needed to. The markers are produced by paliad's placeholder substitution over the template the .dotm supplies; no new placeholder had to appear inside a docPart. Nothing was vendored and no vendored file was touched (git diff --stat -- frontend/scripts/ is empty). Had a docPart change been needed it would have come to you rather than being hand-edited.

Verification

Go suite green across ./internal/... ./pkg/... ./cmd/..., 411 frontend tests green, gofmt clean, branch merged with main (7c16dbb) and re-tested after.

What is left on #162

  • The editor warning before an export (frontend slice) — the guard records, nothing yet tells the lawyer before they download.
  • The court fallback decision above, if it is wanted.
  • The filename's TBD token, which is your separate prior ruling and untouched.
## Slice 2: catalogue-label markers, letterhead gaps, export guard Commit: https://mgit.msbls.de/m/paliad/commit/dc9bad4 (branch `mai/ares/issue-162-one-convention`, merged main first) All three remaining items. Two of them reach filed text. ### 1. The `.docx` marker `[KEIN WERT: project.case_number]` named a variable key — a dotted identifier in a Go map — inside a document a lawyer may hand to a court. It now renders the variable's human label in bare brackets: **`[Aktenzeichen (Gericht)]`**, `[Court case number]`. The label source already existed and no marker used it. `SubmissionVariableCatalogue()` is the resolvers' own bilingual `VariableKey` catalogue — the same one paliad publishes to the sidebar and the authoring palette — so the marker and the form that fills it now name the same thing. Indexed forms the resolvers deliberately cannot enumerate (`lawyer.2.name`, `parties.claimant.1.name`) normalise onto their alias entry: the second letterhead name is still a letterhead name. `TestCatalogMissingMarkerCoversEveryCataloguedKey` fails if any catalogued variable lacks a DE or EN label, which is what keeps the key-path fallback unreachable for anything paliad actually emits. `docforge.DefaultMissingMarker` also changed — it now brackets the bare key rather than spelling `[KEIN WERT: key]`. The engine holds no catalogue so the key is genuinely all it has, but a second *spelling* is exactly what #162 exists to remove. Paliad never hits it: `services.DefaultMissingMarker` delegates to the catalogue marker, so all seven render paths get the label form without any call site remembering to ask. ### 2. Letterhead — one of the three sub-cases can be bracketed, and only one I read `submission_vars_letterhead.go` and the `UnresolvedSelections` path first as you said. The surface reports three kinds of unresolved selection and they are not alike. This is the part worth reading, because "render the other two in brackets too" looks like the obvious next commit and is not implementable. **Lawyers — bracketed.** A selected colleague whose user row is gone now keeps their **position** as a nil hole instead of being dropped. Compacting the slice renumbered every later colleague: `{{lawyer.1.name}}` became whoever was chosen third, and no downstream report can undo a name that landed under the wrong index. Their indexed keys stay *unbound*, so the ordinary missing-marker path fills them — no second mechanism. Only the comma-joined `{{lawyers}}` spells the marker out, because a name missing from the middle of a joined string cannot be an unbound key. Both produce `[Briefkopf: Name]`: one spelling, two paths. When the **first** choice is the gone one, the unindexed `{{lawyer.name}}` alias stays unbound rather than promoting the second choice into the primary sender slot — a real name in a position nobody assigned it is worse than a marker. **Parties — no honest bracket exists.** An unresolved party id matches no row on the project, so paliad holds a uuid and nothing else: no name, no role, and therefore no position in the caption. Claimants and defendants are separate groups, and a marker cannot be placed in a group when the group is precisely what is unknown. **Court — a substitution, not an omission.** An unresolvable `selected_court_id` falls back to the project's court, so no key is unbound and the document names a real court. The defect is that it is not the one the lawyer chose — worse than a gap for that reason. A bracket is the wrong instrument: there *is* a value, and it is wrong. Replacing the fallback with a marker is a live option but changes filed text in a case where the project's court is often correct, so it is its own decision rather than a consequence of this one. Flagging rather than deciding it. Both uncovered cases land in the audit row instead. ### 3. The export guard `ReportingMissingMarker` wraps whatever marker a render path passes and records every key it is asked for. `ExportWithMarker` attaches the result to `SubmissionVarsResult.MissingKeys`, and the export handler writes the count, the keys, and any `UnresolvedSelections.Describe()` onto the `submission.exported` audit row. The wrapper is the whole mechanism deliberately: `MissingPlaceholderFn` is already the seam every render path threads, so counting needs **no change to the substitution engine** and cannot miss a path the engine gains later. The export still succeeds. Refusing a whole submission over one gap is worse than the gap — the trade `UnresolvedSelections` already made and justified. The guard makes gaps findable after the fact, not impossible. **The remaining half is the editor warning before the download**, which is a frontend slice and is not built here. `MissingKeys` and `Unresolved` are separate fields on purpose and both are needed: `Unresolved` is a *selection* that pointed at something gone, `MissingKeys` is a *slot* the template asked for and the bag could not fill. Either occurs without the other — the court case is unresolved with no missing key; a template asking for `{{project.patent_number}}` on a project that has none is a missing key with nothing unresolved behind it. ### patentstyle **No artifact of theirs changed and none needed to.** The markers are produced by paliad's placeholder substitution over the template the `.dotm` supplies; no new placeholder had to appear inside a docPart. Nothing was vendored and no vendored file was touched (`git diff --stat -- frontend/scripts/` is empty). Had a docPart change been needed it would have come to you rather than being hand-edited. ### Verification Go suite green across `./internal/... ./pkg/... ./cmd/...`, 411 frontend tests green, gofmt clean, branch merged with main (7c16dbb) and re-tested after. ### What is left on #162 - The editor warning before an export (frontend slice) — the guard records, nothing yet tells the lawyer before they download. - The court fallback decision above, if it is wanted. - The filename's `TBD` token, which is your separate prior ruling and untouched.
Author
Collaborator

The three-way split, filed; and where #162 now stands

Commit: https://mgit.msbls.de/m/paliad/commit/17a5364 (branch mai/ares/issue-162-one-convention, merged main 14faecd first)

The split, as the axis rather than three observations (design §6.2)

Two questions decide the treatment, asked in order:

  1. Is there a place to put a mark? A mark needs a slot, and a slot needs a coordinate that survived the thing it pointed at.
  2. Is something already sitting in that place? If a plausible value has taken the slot, the defect is not a gap, and a gap marker describes it wrongly.
Case Place to mark? Something already there? Treatment
Lawyers yes — the chosen position no BRACKETABLE
Parties no — no role, no position no NOT MARKABLE
Court yes — the court slot yes, a real court SUBSTITUTION

Flattening them would produce a marker that lies in two of three cases: a party marker has to guess a role it does not have, and a court marker describes a wrong value as a missing one.

The court — #139 already answered it, on the input side

I read diesel's Slice B before proposing anything, and it is already there:

A court no longer in the catalogue stays visible in the dropdown, labelled unknown, rather than disappearing and reading as "project default" — the same silent absence in a different place.

submission-draft.ts renders Unbekanntes Gericht: <id>, and unresolvedText already states the render consequence in words before generating: "das gewählte Gericht steht nicht mehr im Verzeichnis — der Schriftsatz geht an das Gericht des Projekts".

So the substitution is disclosed twice before the document is generated, and since the export guard a third time on the audit row afterwards. The residue is narrow: what still says nothing is the document itself, which names the project's court in ordinary type. A reader holding only the .docx cannot tell an override was overridden, and an export made without opening the editor gets none of the three disclosures.

Three options for m, recorded in §6.5:

  • (a) Leave it. Three disclosures exist; the project's court is frequently the right one.
  • (b) Mark the court slot instead of falling back. Consistent with the convention and visibly unfinished, but discards a probably-correct value and changes filed text.
  • (c) Fallback court plus a bracketed note. Rejected — it puts an editorial remark into text that may be served on a court. That is a different and worse thing than an unfilled slot.

I have not chosen. Given that #139 already fixed the disclosure, (a) is defensible and the narrow question is only whether the document should carry what the editor already says.

The parties case — a data question (§6.4)

A rendering question would be answerable with a marker. This one is not, and the comparison shows why:

selected_lawyers selected_parties
Order meaningful? yes — prints top to bottom no
Grouping comes from the position itself the party row's role
Survives the row's deletion? the position does nothing does

The lawyer case is markable only because the order is the lawyer's own choice and outlives the user row. A party id leaves no residue at all — strip the row and it does not even say which side the party was on.

So the question is whether a party selection should record enough to survive the row it points at: at minimum the role, arguably a name snapshot at selection time. That is m/paliad#161's shape — a row missing a field, where the gap blocks several things rather than one cosmetic case — not #162's. Not built, not proposed.

A correction this task owed

My own previous commit falsified one of diesel's warning clauses. It told the lawyer that a colleague with no account "will not appear in the letterhead"; since dc9bad4 they do appear, as a marked gap in their chosen position. A lawyer who reads that and exports anyway expects a shorter letterhead, not a bracket inside one.

The test covering that clause asserted the count and the surface name but not the consequence, so it stayed green straight through the change. It now pins the consequence, and pins that the party and court clauses still describe absence and substitution respectively.

Where #162 stands

Nothing remains that does not need a decision from m.

Shipped and merged: the draft title (eb58bc5 / 7c16dbb), the catalogue-label .docx markers, letterhead position preservation, and the export guard (dc9bad4 / 14faecd). This commit adds the classification and the warning correction.

Open, all three needing m:

  1. The court substitution — options above; head is taking it to m.
  2. The parties data question — belongs with #161's shape, needs a decision that it is wanted at all.
  3. The filename's TBD token — m's own separate prior ruling, deliberately untouched.

One thing I had listed as remaining is not open after all: the editor warning before an export. #139 Slice B built it, and it covers all three unresolved kinds. What it cannot cover is MissingKeys, which only exists after a render — so a post-export signal would be a different surface answering a different question, and the audit row already answers it. I do not think it is worth building.

Verification

Go suite green, 413 frontend tests green (2 new), gofmt clean, merged with main and re-tested.

## The three-way split, filed; and where #162 now stands Commit: https://mgit.msbls.de/m/paliad/commit/17a5364 (branch `mai/ares/issue-162-one-convention`, merged main 14faecd first) ### The split, as the axis rather than three observations (design §6.2) Two questions decide the treatment, asked in order: 1. **Is there a place to put a mark?** A mark needs a slot, and a slot needs a coordinate that survived the thing it pointed at. 2. **Is something already sitting in that place?** If a plausible value has taken the slot, the defect is not a gap, and a gap marker describes it wrongly. | Case | Place to mark? | Something already there? | Treatment | |---|---|---|---| | **Lawyers** | yes — the chosen position | no | **BRACKETABLE** | | **Parties** | no — no role, no position | no | **NOT MARKABLE** | | **Court** | yes — the court slot | yes, a real court | **SUBSTITUTION** | Flattening them would produce a marker that lies in two of three cases: a party marker has to guess a role it does not have, and a court marker describes a wrong value as a missing one. ### The court — #139 already answered it, on the input side I read diesel's Slice B before proposing anything, and it is already there: > A court no longer in the catalogue stays visible in the dropdown, labelled unknown, rather than disappearing and reading as "project default" — the same silent absence in a different place. `submission-draft.ts` renders `Unbekanntes Gericht: <id>`, and `unresolvedText` already states the render consequence in words before generating: *"das gewählte Gericht steht nicht mehr im Verzeichnis — der Schriftsatz geht an das Gericht des Projekts"*. So the substitution is disclosed **twice before the document is generated**, and since the export guard a **third time on the audit row** afterwards. The residue is narrow: what still says nothing is the **document itself**, which names the project's court in ordinary type. A reader holding only the .docx cannot tell an override was overridden, and an export made without opening the editor gets none of the three disclosures. Three options for m, recorded in §6.5: - **(a) Leave it.** Three disclosures exist; the project's court is frequently the right one. - **(b) Mark the court slot instead of falling back.** Consistent with the convention and visibly unfinished, but discards a probably-correct value and changes filed text. - **(c) Fallback court plus a bracketed note.** **Rejected** — it puts an editorial remark into text that may be served on a court. That is a different and worse thing than an unfilled slot. I have not chosen. Given that #139 already fixed the disclosure, (a) is defensible and the narrow question is only whether the *document* should carry what the editor already says. ### The parties case — a data question (§6.4) A rendering question would be answerable with a marker. This one is not, and the comparison shows why: | | `selected_lawyers` | `selected_parties` | |---|---|---| | Order meaningful? | **yes** — prints top to bottom | no | | Grouping comes from | the position itself | the *party row's* `role` | | Survives the row's deletion? | the position does | nothing does | The lawyer case is markable **only because the order is the lawyer's own choice and outlives the user row**. A party id leaves no residue at all — strip the row and it does not even say which side the party was on. So the question is whether a party selection should record enough to survive the row it points at: at minimum the role, arguably a name snapshot at selection time. That is m/paliad#161's shape — a row missing a field, where the gap blocks several things rather than one cosmetic case — not #162's. **Not built, not proposed.** ### A correction this task owed My own previous commit falsified one of diesel's warning clauses. It told the lawyer that a colleague with no account **"will not appear in the letterhead"**; since dc9bad4 they *do* appear, as a marked gap in their chosen position. A lawyer who reads that and exports anyway expects a shorter letterhead, not a bracket inside one. The test covering that clause asserted the count and the surface name but not the consequence, so it stayed green straight through the change. It now pins the consequence, and pins that the party and court clauses still describe absence and substitution respectively. ### Where #162 stands **Nothing remains that does not need a decision from m.** Shipped and merged: the draft title (eb58bc5 / 7c16dbb), the catalogue-label `.docx` markers, letterhead position preservation, and the export guard (dc9bad4 / 14faecd). This commit adds the classification and the warning correction. Open, all three needing m: 1. **The court substitution** — options above; head is taking it to m. 2. **The parties data question** — belongs with #161's shape, needs a decision that it is wanted at all. 3. **The filename's `TBD` token** — m's own separate prior ruling, deliberately untouched. One thing I had listed as remaining is **not** open after all: the editor warning before an export. #139 Slice B built it, and it covers all three unresolved kinds. What it cannot cover is `MissingKeys`, which only exists *after* a render — so a post-export signal would be a different surface answering a different question, and the audit row already answers it. I do not think it is worth building. ### Verification Go suite green, 413 frontend tests green (2 new), gofmt clean, merged with main and re-tested.
Author
Collaborator

Court ruled, one decision-free slice found and shipped, #162 closes

Commit: https://mgit.msbls.de/m/paliad/commit/98b0039 (branch mai/ares/issue-162-one-convention, merged main 18acbef first)

Answering the question directly

Neither exactly. m's rulings closed all three decisions and unblocked nothing new — but there was one slice left that needed no decision, and it was drift my own commits created. It is shipped, and now the task closes.

The court ruling (§6.5)

Option (a) leave it, recorded. The residue m accepted is named in the doc so nobody files it as a bug later: an export made without ever opening the editor receives none of the three pre-generation disclosures, and the document names the project's court in ordinary type.

One guard added to the wording: the ruling does not generalise. It says this fallback is usually right, not that a plausible default may stand in silently wherever one is available. The next substitution to appear gets classified on §6.2's two questions on its own merits.

The decision-free slice: my own drift

Two things, same family as the warning corrected last commit.

Fifteen comments across eight files still described the render as producing [KEIN WERT: key]. Untrue since dc9bad4. A comment asserting behaviour the code no longer has is worse than no comment, because it reads as current. All rewritten to the form the code actually produces.

TestSampleMissingMarker never tested its own stated property. Its comment said a sample marker must never emit the gap-marker form — that is the whole point of "Beispiel" mode. Its assertion checked that the string was non-empty. So it stayed green through #162 changing the gap marker's form, and it would have stayed green if sample mode had started emitting gap markers outright. It now checks the property — no bracketed output — for both languages and for a known and an unknown key.

That is the second instance this week of a test measuring that a message exists rather than that it is true, and both were in code this task touched.

Final state — §9 of the design, so nothing gets reopened by accident

Added as a table in the doc because two of the eight items are closed by ruling rather than by code, and both read as unfinished work otherwise.

Case State Do not
Draft title Shipped[Mandant] / [Forum] / [Gegner] on project-bound drafts
.docx marker Shipped — catalogue label, replacing [KEIN WERT: key]
Letterhead lawyers Shipped — position preserved, gap renders [Briefkopf: Name]
Export guard Shipped — unbound keys on the audit row; export still succeeds Turn it into a refusal without m
Letterhead parties Out of scope by classification (§6.4) Do not build a party marker — it would have to guess a role
Court substitution Closed by m's ruling: leave it Do not reopen on the grounds that the document is silent — that residue was accepted
Filename (TBD) Unchanged, deliberately Do not align it to brackets as "consistency"
Marker wording Bare [Label], m's ruling Do not add a state suffix — pinned by a test

§9.1 states the two that read as unfinished and are not:

  • Parties — the absence of a marker is a finding, not a gap in the work. §6.4 measured that a party selection stores nothing outliving the row it points at: no name, no role, no caption position. The remaining question is whether a selection should record more, which is a schema question of m/paliad#161's shape. It does not belong to this issue and was not left undone in it.
  • Court — ruled, weighed against three existing disclosures. Reopening needs a new reason, not a re-reading of §6.5.

One thing found and not fixed (§9.2)

Two label catalogues serve the same job and neither knows about the other: nomen.VarDef.Label/LabelEN for the name artifacts, SubmissionVariableCatalogue() for the .docx placeholder bag. Both carry DE/EN labels; until this work neither had a marker consumer. They agree today only because both were wired to the same convention in the same week, and nothing enforces that they stay in agreement. Worth converging before a third appears — separate work, not proposed here.

Verification

Go suite green across ./internal/... ./pkg/... ./cmd/..., 413 frontend tests green, gofmt clean, merged with main and re-tested.

#162 is complete from this side. No status label set — this repo carries only deferred and done, and closing is m's.

## Court ruled, one decision-free slice found and shipped, #162 closes Commit: https://mgit.msbls.de/m/paliad/commit/98b0039 (branch `mai/ares/issue-162-one-convention`, merged main 18acbef first) ### Answering the question directly Neither exactly. m's rulings **closed** all three decisions and unblocked nothing new — but there was one slice left that needed no decision, and it was drift my own commits created. It is shipped, and now the task closes. ### The court ruling (§6.5) Option **(a) leave it**, recorded. The residue m accepted is named in the doc so nobody files it as a bug later: an export made without ever opening the editor receives none of the three pre-generation disclosures, and the document names the project's court in ordinary type. One guard added to the wording: **the ruling does not generalise.** It says *this* fallback is usually right, not that a plausible default may stand in silently wherever one is available. The next substitution to appear gets classified on §6.2's two questions on its own merits. ### The decision-free slice: my own drift Two things, same family as the warning corrected last commit. **Fifteen comments across eight files still described the render as producing `[KEIN WERT: key]`.** Untrue since dc9bad4. A comment asserting behaviour the code no longer has is worse than no comment, because it reads as current. All rewritten to the form the code actually produces. **`TestSampleMissingMarker` never tested its own stated property.** Its comment said a sample marker *must never emit the gap-marker form — that is the whole point of "Beispiel" mode*. Its assertion checked that the string was non-empty. So it stayed green through #162 changing the gap marker's form, and it would have stayed green if sample mode had started emitting gap markers outright. It now checks the property — no bracketed output — for both languages and for a known and an unknown key. That is the second instance this week of a test measuring *that a message exists* rather than *that it is true*, and both were in code this task touched. ### Final state — §9 of the design, so nothing gets reopened by accident Added as a table in the doc because **two of the eight items are closed by ruling rather than by code, and both read as unfinished work otherwise.** | Case | State | Do not | |---|---|---| | Draft title | **Shipped** — `[Mandant]` / `[Forum]` / `[Gegner]` on project-bound drafts | — | | `.docx` marker | **Shipped** — catalogue label, replacing `[KEIN WERT: key]` | — | | Letterhead lawyers | **Shipped** — position preserved, gap renders `[Briefkopf: Name]` | — | | Export guard | **Shipped** — unbound keys on the audit row; export still succeeds | Turn it into a refusal without m | | **Letterhead parties** | **Out of scope by classification (§6.4)** | **Do not build a party marker** — it would have to guess a role | | **Court substitution** | **Closed by m's ruling: leave it** | Do not reopen on the grounds that the document is silent — that residue was accepted | | Filename `(TBD)` | **Unchanged, deliberately** | Do not align it to brackets as "consistency" | | Marker wording | **Bare `[Label]`, m's ruling** | Do not add a state suffix — pinned by a test | §9.1 states the two that read as unfinished and are not: - **Parties** — the absence of a marker is a **finding**, not a gap in the work. §6.4 measured that a party selection stores nothing outliving the row it points at: no name, no role, no caption position. The remaining question is whether a selection should record more, which is a schema question of m/paliad#161's shape. It does not belong to this issue and was not left undone in it. - **Court** — ruled, weighed against three existing disclosures. Reopening needs a new reason, not a re-reading of §6.5. ### One thing found and not fixed (§9.2) Two label catalogues serve the same job and neither knows about the other: `nomen.VarDef.Label`/`LabelEN` for the name artifacts, `SubmissionVariableCatalogue()` for the `.docx` placeholder bag. Both carry DE/EN labels; until this work neither had a marker consumer. They agree today only because both were wired to the same convention in the same week, and **nothing enforces that they stay in agreement**. Worth converging before a third appears — separate work, not proposed here. ### Verification Go suite green across `./internal/... ./pkg/... ./cmd/...`, 413 frontend tests green, gofmt clean, merged with main and re-tested. **#162 is complete from this side.** No status label set — this repo carries only `deferred` and `done`, and closing is m's.
mAi added the
done
label 2026-07-30 16:06:28 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#162
No description provided.