Conversation
A MultiUnicode/MultiString custom field whose WsSelector is singular (kwsAnal, kwsVern, or unset) stores one fixed alternative. The Custom Fields dialog cannot create that combination, but LIFT import and older projects can. The composer marked every multi-alternative custom field IsMultiStringRow, so such a field's label and in-string menus gained the mnuDataTree-MultiStringSlice group (the Writing Systems submenu and Show All), which the plain StringSlice legacy builds for these fields never shows. MakeCustomFieldNode now picks the string editor for singular selectors, matching the slice choice in MakeAutoCustomSlice, so the row composes as a single-ws string row and the multistring menu group stays off. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1109 +/- ##
=======================================
Coverage 38.34% 38.34%
=======================================
Files 1507 1507
Lines 350586 350591 +5
Branches 40294 40295 +1
=======================================
+ Hits 134432 134444 +12
+ Misses 186927 186920 -7
Partials 29227 29227
🚀 New features to boost your workflow:
|
thejambi
approved these changes
Aug 26, 2026
thejambi
left a comment
Contributor
There was a problem hiding this comment.
@thejambi made 1 comment.
Reviewable status: 0 of 2 files reviewed, all discussions resolved.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Quick Summary
In the Avalonia detail view, a custom text field stored as
MultiUnicode/MultiString with a singular writing-system selector
(
kwsAnal,kwsVern, or unset) now composes as a plain single-ws stringrow, matching the legacy
StringSlice. Before this, its label andin-string menus carried the
mnuDataTree-MultiStringSlicegroup — aWriting Systems submenu and Show All — that legacy never shows for these
rows. (LT-22691 follow-up.)
The first question this diff raises: how does that field shape exist at
all, when the Custom Fields dialog forces singular-ws text fields to type
String? LIFT import takes both the type and the WsSelector verbatim from
the file header, and older projects can carry the combination natively —
legacy
MakeAutoCustomSlicehas an explicit arm for it. So the reviewquestion is the fix site, not reachability.
Where to look:
DetailComposer.MakeCustomFieldNode— the fix mirrors legacy's slicechoice (singular selector →
stringeditor). Layout-authoredmultistringparts are untouched by design: legacy always builds aMultiStringSlice for those regardless of ws spec, so plurality only
discriminates on the custom-field path.
Compose_CustomMultiStringWithSingularWsSelector_ComposesAPlainStringRow— fabricates the MultiString+kwsAnal trigger in the shared custom-field
fixture and asserts both directions (singular composes plain, plural
"Tone Pattern" stays multistring).
Deliberately not here:
multistring arm; legacy throws "unhandled ws code" on it. Pre-existing
degenerate case, out of scope.
Verification:
build.ps1 -CommentHygienegreen; targetedtest.ps1composer sweep in xWorksTests 93/93 including the new test; manual
before/after in FLEx against a LIFT-imported MultiUnicode+kwsAnal custom
field.
CI-ready checklist
.github/commit-guidelines.md.build.ps1 -CommentHygiene; targetedtest.ps1).Docs/workflows/ai-pr-workflow.mdand ranpr-preflightor the equivalent branch-readiness review before requesting review.Src/**folders touched, correspondingAGENTS.mdfiles are updated or explicitly confirmed still accurate (no nestedAGENTS.mdunderSrc/xWorks;Src/AGENTS.mdunaffected).Reading this a year from now — start here
This PR fixes one menu-parity defect found while auditing the LT-22691
field-menu work: the Avalonia composer's custom-field path classified
every multi-alternative custom field as a multistring row, while legacy
distinguishes singular from plural selectors. The reasoning below is the
full record; no working documents were created for this change.
Decisions, and why
Fix the editor choice, not the menu flag. Two candidate fix sites
existed: (1) the
IsMultiStringRowassignment in the composer's textwalk could have gained a ws-plurality check, or (2)
MakeCustomFieldNodecould choose the editor the way legacy
SliceFactory.MakeAutoCustomSlicechooses the slice. Option 2 was taken because legacy's real discriminator
is the slice type, which is determined by the path: layout-authored
multistringparts always become MultiStringSlices regardless of theirws=spec (a plurality check would have broken parity for a hypotheticalsingular-ws layout part), and only the auto-custom path builds a
StringSlice for singular selectors. Choosing the editor at node synthesis
makes the existing
IsMultiStringRowderivation correct in both pathswith no second condition.
The
fieldWs == 0arm. Legacy treats an unset selector as singular(
case 0: // a desperate defaultbuilds a StringSlice on the defaultanalysis ws), so the composer does the same rather than leaving the
degenerate input to drift into the multistring arm.
Row values are unaffected by the editor switch. Text-row values
resolve from the LCM property type plus the ws spec, and both editor
strings classify to
DetailEditorCategory.Text; a singular selectoralready resolved to a one-entry ws list. The editor string's only other
production consumer is the
IsMultiStringRowassignment — verified bysweeping for
"multistring"/EditorKindMap.MultiStringEditoracrossSrc/**/*.cs(two production sites, both inDetailComposer).Evidence and repro
Reachability of the trigger.
AddCustomFieldDlgcreatesCellarPropertyType.Stringfor singular-ws text fields and flips thetype when the ws choice changes, so the dialog cannot mint the trigger.
LIFT import can:
FindOrCreateCustomFieldparsesType=andWsSelector=verbatim from the header'sqaa-x-specform, so a headerdeclaring
Type=kcptMultiUnicode; WsSelector=kwsAnalcreates the exactcombination. Manual repro used such a file imported into a Sena 3 copy.
(Caution for future repro: opening the Custom Fields dialog and pressing
OK normalizes the type/ws mismatch and destroys the repro field.)
Manual before/after. Before the fix, the imported field's menus
showed the Writing Systems submenu / Show All in the Avalonia view;
legacy showed the plain StringSlice menus. After the fix, the Avalonia
row composes as a single analysis-ws string row with no multistring menu
group.
Automated.
test.ps1 -CommentHygiene -TestProject xWorksTests -TestFilter "FullyQualifiedName~Composer": 93/93 passed, including thenew decisive test and the pre-existing plural custom-field assertions.
Preflight review details
Code Review Summary
Branch: LT-22691f
Base: main (merge base 17cdfba)
Date: 2026-08-25
Review model: Claude Fable 5 (Claude Code)
Files changed: 2
Overview
Custom fields of type MultiUnicode/MultiString whose WsSelector is
singular (kwsAnal, kwsVern, or unset) were composed with the
multistringeditor, so the Avalonia detail view marked themIsMultiStringRowand their menus gained the mnuDataTree-MultiStringSlicegroup that legacy never shows for these rows. The composer now picks the
stringeditor for singular selectors, mirroring the legacy slice choicein
SliceFactory.MakeAutoCustomSlice.Contract/API Changes
None.
MakeCustomFieldNodeis private; no public surface, serializedformat, or project file changed.
Findings
Critical - Must address before merge
None.
Important - Should address before merge
None.
Minor - Consider
A custom field whose stored ws selector is a REAL writing-system(pre-existing degenerate case; the composer being moreid still takes the
multistringarm, where legacy throws "unhandled wscode".
lenient than a legacy crash is acceptable and out of scope)
Required Validation / Evidence
./build.ps1 -CommentHygiene— green../test.ps1composer sweep — 93/93 passed.LIFT-imported MultiUnicode+kwsAnal custom field.
Interview Notes
single-WS custom text fields.
confirmed the fix in the same scenario after the build.
before the commit. No unresolved items.
Suggested Review Focus
plurality check is the preferred shape.
expectations for old-project data.
🤖 Generated with Claude Code
This change is