Commit Graph

3 Commits

Author SHA1 Message Date
cesnimda fba858e8eb fix(cv): force language alias precedence over host culture data
The CI backend test job failed on HumanLanguageCatalogTests:
  nynorsk -> expected "Norwegian", actual "Norwegian Nynorsk"

This was a real bug, correctly caught by the runner -- not runner
instability. Reproduced on Ubuntu 20.04 / libicu66 (the CI runner's ICU)
with .NET 9 installed via dotnet-install.sh exactly as CI does.

Root cause: BuildLanguageLookup's explicit normalization aliases
(nynorsk/bokmål/norsk -> Norwegian) were added with map.TryAdd, which
loses to any key the culture enumeration already inserted. On libicu66
the "nn" culture's NativeName is the bare word "nynorsk", so enumeration
claimed key "nynorsk" -> "Norwegian Nynorsk" first and the explicit alias
silently lost. On libicu70+ (Debian/Ubuntu 22.04+, my earlier local
runs) the native name is "norsk nynorsk", so the key was free and the
alias won -- which is why it passed locally and only failed on the
runner's older ICU. Same host-ICU dependence class as 9681618.

Fix: add an Override helper (map[key] = value) and apply it to the
alias block so these mappings win regardless of insertion order. Also
collapse the full "Norwegian Nynorsk"/"Norwegian Bokmål" phrases to
"Norwegian" for consistency. Correct by construction for any ICU version.

Verified:
- reproduced the exact failure on libicu66 with the old code (probe)
- fix logic yields nynorsk/bokmål -> Norwegian on that same libicu66
- real net9 test DLL: 420/420 on focal libicu66 (CI mirror, dotnet
  9.0.316 via dotnet-install.sh), and 420/420 on libicu72 (Debian) and
  libicu74 (Ubuntu 24.04), plus locally
No test weakened, skipped, or relaxed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 23:08:37 +02:00
cesnimda 96816186cb fix(cv): preserve human languages during structured CV normalization
HumanLanguageCatalog built its lookup table solely from
CultureInfo.GetCultures, so which languages counted as human languages
depended on the host's ICU data rather than on the CV. Measured: 806
cultures on a normal Windows or Linux machine, exactly 1 under
globalization-invariant mode, and an English-only subset on a container
with trimmed ICU data.

Consequences by environment, all silent:
- full ICU: correct
- trimmed ICU: canonical names present in the reduced data survive and
  the rest are dropped, so a CV keeps English and loses Norwegian
- invariant: every language is dropped and a CV import loses its
  Languages section entirely, with no error

The tests were right and are unchanged. Seed the catalog explicitly with
the languages a CV realistically lists, before the culture enumeration,
which still runs and still adds breadth. Nothing in the seed collides
with a technical skill -- Go, Java, Swift, Rust and Basic are
deliberately absent, and Basic is also a proficiency level.

Verified 420 tests pass in four environments: Windows and Linux, each
with full ICU and with DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1. Before
this change the invariant runs failed 5 tests. No test was modified,
skipped or relaxed.

Added HumanLanguageCatalogTests to pin the seeded catalog, confirmed
non-vacuous by removing the seed and watching 15 tests fail.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 19:19:17 +02:00
cesnimda 44000f96f2 Improve CV parsing and profile editor flow 2026-03-29 14:29:18 +02:00