docs(investigations): trace Virtues mindmap FR-frozen mechanism + bounded fix path - #601
Conversation
…nded fix path Converts the release dossier #591 §3.2 finding ("Virtues .content.svg FR-frozen, deferred, mechanism untraced") into a traced, bounded fix path so jsboige's post-release decision is informed, not open-ended. Docs only, 0 write under Cards/ (release freeze), master stays bef3bc6. Mechanism TRACED (was untraced): localization is NOT in TitleFunc nor in ProcessSvgFilesAsync. It is expression-rewriting upstream of the render — ParallelDocumentCreatorConfigBase.ProcessDocumentAsync clones the config per language, then DocumentLocalization.DoReflectionTranslate mutates the expression strings in-place via naive template.Replace (e.g. "{fallacy.TextFr}" -> "{fallacy.TextZh}"); interpolation at render time then yields localized node text. Root cause 2-layer (both verified on bef3bc6): - Layer B (config): AssetConverterConfig entry #3 targets VirtueMindMapDocumentConfig.TitleExpression but its only conversion is "Vertus"->"Virtues" (tree root, 4 langs) — stale stub from when Virtues data was FR-only. "{item.Text}".Replace("Vertus",...) = no-op -> FR for all 8 langs. - Layer A (entity): Virtue.cs has no TitleAr/TitleFa/TitleZh props (Fallacy.cs has TextAr/Fa/Zh). CSV data VERIFIED present (title_ar/zh/fa + subfamily_*/subsubfamily_* in the taxonomy file) — pure entity-mapping gap, not a data task. Fix path (post-release, jsboige-gated, 3 steps mirroring Fallacies) with one non-obvious prerequisite flagged: DefaultTitleExpression must change {item.Text} -> {item.TitleFr} BEFORE a config-only fix can fire (else Replace is a silent no-op — same trap class as the earlier SUPPOSE error). Orthogonal to the #599/#568 render-engine work (gap is upstream of the engine). Enriches the jsboige decision dossier; does not touch Cards/. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[NanoClaw]
Belle investigation — convertit le gap #591 §3.2 (« deferred, mechanism untraced ») en chemin de fix tracé et borné. Doc seul (+95/-0), read-only, freeze release respecté (0 write sous Cards/, master reste bef3bc6c). Vérifié les 3 claims porteurs contre le source live sur bef3bc6c :
Claim 1 (le mécanisme) ✓ exact. VirtueMindMapDocumentConfig.cs:37 — const string DefaultTitleExpression = @"{item.Text}"; (l.39 TitleExpression = DefaultTitleExpression). Et Virtue.cs:11-12 public string Text => TitleFr → {item.Text} résout en FR. C'est exactement pourquoi le mindmap Virtues sort FR pour les 8 langues.
Claim 2 (Layer A — le gap entité) ✓ confirmé. Virtue.cs expose TitleFr/En/Ru/Pt/Es (l.28/41/49/57/65) mais aucun TitleAr/TitleFa/TitleZh — les colonnes CSV ar/fa/zh sont invisibles au pipeline. Contraste avec Fallacies (TextAr/Fa/Zh) correctement mappé. Le doc a raison : gap purement entité, pas de manque de données amont.
Claim 3 (Layer B — le stub config) ✓ exact. AssetConverterConfig.cs:241-248 — commentaire "data is FR-only, only tree root name changes", cible VirtueMindMapDocumentConfig.TitleExpression, conversion ("Vertus", [en→Virtues, ru→Dobrodeteli, pt→Virtudes, es→Virtudes]) = 4 langues, littéral racine seulement. Donc "{item.Text}".Replace("Vertus",...) = no-op (le sous-string n'y est pas) → expression inchangée → FR partout. Cohérent.
Le « prérequis non-évident » est correct et pointu. Le doc note que DoStaticConversions est un Replace naïf, donc un fix config-seul (étape 3 seule) serait silencieusement no-op tant que l'expression reste {item.Text} — il faut d'abord la passer en {item.TitleFr} pour que Replace("TitleFr","TitleZh") puissematcher. Déduction juste (le littéral TitleFr n'est pas dans {item.Text}) — c'est le genre de subtilité qui rend l'investigation utile plutôt que décorative.
Root cause 2-couches (config stale + entité incomplète) correctement bornée, fix path miroir de Fallacies (vérifié), validation honnête (regen avec clobber, glyphe CJK/RTL, et un test de régression Virtues manquant — la suite existante ne couvre que Fallacies). Lien d'orthogonalité avec #599/#568 (upstream du moteur de rendu) tenu. 0 secret (doc pur). Section reproductibilité falsifiable (grep DefaultTitleExpression / absence TitleAr|Fa|Zh — j'ai exécuté les deux, ils passent).
Rien à signaler — c'est exactement le format attendu pour une investigation post-release : tracé, borné, vérifié contre le source, et gated sur le GO de jsboige (pas de code écrit).
…ues mindmap FR-frozen) ai-01 raised a NEW arbitrage at the coordinator level: how to handle the Virtues mindmap FR-freeze for v0.9.0 — (a) fix before tag, (b) ship FR-frozen + known-limitation, (c) exclude Virtues mindmaps from non-FR packs. #601 traced the mechanism + bounded the fix path but did not quantify the per-option cost. This adds a dedicated "Decision input for WE 27/06" section + a TL;DR pointer, so jsboige's decision is informed by the technical cost (this investigation's unique contribution — the mechanism is traced here). Key verified fact leveraged: mindmap SVGs are COMMITTED FILES under Cards/Fallacies/Mindmaps/{lang}/, not package-assembled (no separate release-bundling step). So option (c) "exclude from non-FR packs" = git rm of 14 SVGs = a Cards/ write (freeze break) that REMOVES present content -> technically dominated by (b). (a) fix-at-tag = 3-step fix + full mindmap régén (RDP-gated Mindmapper mode) + re-establishes the #591 byte-proven baseline -> most expensive. (b) = 0 code / 0 Cards/ write, already the #591 §3.2 assumption. Neutral (presents costs, does not make the call): worker reco = (b) for v0.9.0, fix in v0.9.1; jsboige decides. Docs only, 0 write under Cards/, master stays bef3bc6. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ster, #601 guardrail) (#604) Add VirtueMindMapFRFrozenCharacterizationTests — a Golden-Master suite pinning the CURRENT behaviour that Virtues mind map node text renders French for all 8 release languages (Fallacies are localized 8-lang, pinned by MindMapLocalizationRegressionTests). This is an executable snapshot of the 2-layer gap traced in investigation #601 (merged 71033f8), NOT a regression test of desired behaviour: - Layer B (config): the single Virtue-targeting MindMapLocalization entry is a stale stub that only rewrites the tree-root literal "Vertus", for 4 of 7 target languages (en/ru/pt/es; ar/fa/zh absent). - Layer A (entity): Virtue exposes no TitleAr/TitleFa/TitleZh (CSV columns from #590/#595 exist but are invisible to the mind map), and Virtue.Text hard- delegates to TitleFr. Three guardrail sections, each GREEN today and expected to FAIL when the 3-step fix documented in #601 lands (entity ar/fa/zh props + {item.TitleFr} expression + mirrored config table). At that point flip the assertions to the localized expectation rather than deleting them — the failure is the signal the gap closed. The test-writing process surfaced a precision my investigation missed: nameof(VirtueMindMapDocumentConfig.TitleExpression) returns the bare "TitleExpression", which is SHARED with the Fallacy text entry — so the entry must be located by its unique "Vertus" conversion, not by nameof (documented in the helper XML doc). Additive only: no production code or existing test modified. 0 write under Cards/ (release freeze). Dispatch ai-01 2026-06-27 primary (characterization test, GO). Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude-Code <noreply@anthropic.com>
Root cause (analogous to #216, documented in #601): the Virtues mind map rendered French node text for every language because of a 2-layer gap — Layer B, the MindMapLocalization Virtue entry was a stale stub only rewriting the tree-root literal "Vertus"; Layer A, the document config expressions referenced computed FR-only getters ({item.Text}, {item.Family}…) that StaticConversions could not target. Fix (jsboige arbitration: wire the 4 languages whose data + entity binding already exist; defer the 3 that need an entity extension): - VirtueMindMapDocumentConfig: 5 expression defaults now reference the raw FR-suffixed props ({item.TitleFr}, {item.FamilyFr}, {item.SubfamilyFr}, {item.SubsubfamilyFr}, item.DescriptionFr) so the StaticConversions can rewrite them per language. FR stays a no-op (Text => TitleFr). - AssetConverterConfig.MindMapLocalization: replaced the "Vertus" stub with two per-field tables mirroring Fallacies (title/description + family hierarchy, most-specific-first), covering en/ru/pt/es only. - Ar/Fa/Zh deferred: the Virtue entity has no Title/Family Ar/Fa/Zh property yet, so those three keep rendering FR (follow-up chantier). Tests: replaced the #601 FR-frozen characterization guardrail (per its own instruction to "flip these assertions to the localized expectation") with VirtueMindMapLocalizationTests — pins localized en/ru/pt/es, FR-frozen ar/fa/zh, the config-table shape, and the entity boundary. 129 mindmap+localization tests pass, 0 fail. Code only; regenerated SVG assets follow in the same PR. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Traces the Virtues mindmap FR-frozen mechanism + bounded fix path
Read-only investigation. Converts the release dossier #591 §3.2 finding — "Virtues
.content.svgare FR-frozen across all 8 languages, deferred, mechanism untraced" — into a traced, bounded fix path so jsboige's post-release decision is informed instead of open-ended.0 write under
Cards/(release freeze). master staysbef3bc6c. Docs only.What this finds
TitleFunc, not inProcessSvgFilesAsync. It is expression-rewriting upstream of the render:ParallelDocumentCreatorConfigBase.ProcessDocumentAsyncclones the config per language, thenDocumentLocalization.DoReflectionTranslate(clone, lang)mutates the expression strings in-place via naivetemplate.Replace(e.g."{fallacy.TextFr}"→"{fallacy.TextZh}").bef3bc6c):AssetConverterConfigentry Nouveau design #3 targetsVirtueMindMapDocumentConfig.TitleExpressionbut its only conversion is"Vertus"→"Virtues"(tree root, 4 langs) — a stale stub from when Virtues data was FR-only."{item.Text}".Replace("Vertus",...)is a no-op → FR for all 8 languages.Virtue.cshas noTitleAr/TitleFa/TitleZhproperties (Fallacy.cshasTextAr/Fa/Zh). CSV data verified present (title_ar/zh/fa+subfamily_*/subsubfamily_*in the taxonomy file) → pure entity-mapping gap, not a data task.The fix path (post-release, jsboige-gated — 3 steps mirroring Fallacies)
Flagged one non-obvious prerequisite:
DefaultTitleExpressionmust change{item.Text}→{item.TitleFr}before a config-only fix can fire (elseReplaceis a silent no-op — same trap class as an earlier SUPPOSÉ error). Full 3-step path + validation recipe (regen 8-lang with clobbered harvests, CJK/RTL eyeball, add a Virtues mirror ofMindMapLocalizationRegressionTests.cswhich currently covers Fallacies only) in the doc.Orthogonality
This gap is upstream of the render engine — Batik (FreeMind) or Freeplane (#599 opt-in) render the same
{item.Text}= FR for Virtues. Independent of the #568 §3.8 breakthrough-refutation. (Cross-verify ACK #5994802039001.)Why it's a standalone doc, not folded into #591
#591 is the release dossier (frozen, awaiting jsboige's §5 decision). This is a post-release fix-path investigation that enriches the decision dossier without reopening it. Living in
docs/investigations/makes it discoverable by ai-01/jsboige/po-2023 (who readdocs/, not worker memory).Reproducibility
Read-only on master
bef3bc6c. All line references verified. Re-verify the gap withgrep -n "TitleAr\|TitleFa\|TitleZh" Generation/Converters/Argumentum.AssetConverter/Entities/Virtue.cs→ expect no matches.🤖 Worker po-2024 · release-safe (0 write Cards/, master
bef3bc6c) · investigation doc