Skip to content

OpenConceptLab/ocl_issues#2909 | A candidate leads with its name in the input language, and the matched name comes second - #102

Merged
snyaggarwal merged 6 commits into
mainfrom
OpenConceptLab/ocl_issues#2909-candidate-display-name
Oct 16, 2026
Merged

snyaggarwal merged 6 commits into
mainfrom
OpenConceptLab/ocl_issues#2909-candidate-display-name

Conversation

@paynejd

@paynejd paynejd commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Codex's last open finding, F3.1, was accepted here and moved to OpenConceptLab/ocl_issues#2916, fixed in oclmap#104 (based on this branch). Everything else is done and reviewed.
Merge it together with oclmap#104.

What changed and why

A candidate led with the name its match was made on, then an arrow and its display name. When that name was a translation, an English project showed candidates titled in another language: for "Pregnancy test" (input language English, LOINC 2.81), 89497-2 read "Anamnesi Punto nel tempo (episodio) Test prenatale → Mother's Prenatal tests".

Now a concept leads with its name in the project's input language, and the name that matched comes second, on the line below, with its locale:

LOINC:89497-2 Mother's Prenatal tests
Matched name (it-IT): Anamnesi Punto nel tempo (episodio) Test prenatale

  • conceptNames.js (new, pure, unit-tested) holds the two rules:
    • localizedDisplayName(concept, inputLocale): the concept's name in the input language, matched on the primary subtag (so pt takes a pt-BR name). If the display name is already in that language it stays. Otherwise the concept takes that language's preferred name, then its fully specified name, then its first. With no name in that language, or no input language, it falls back to display_name, which OCL computes from the repository's default locale.
    • getMatchedName(...): the name that matched (a name highlight means the display name matched, otherwise the best synonyms highlight, picked as before), with its locale from the concept's names. It returns null when that name is the one the concept leads with (compared ignoring case and spacing).
  • Concept.jsx leads with localizedDisplayName and shows the matched name on its own line, through a small MatchedName component, with the new string map_project.matched_name ("Matched name"). The old prefix and arrow are gone. Bridge rows name their concepts the same way.
  • Everywhere a candidate or target is named, the same two rules apply:
    • the grid's Target Code cell;
    • the row panel's candidate list, including the AI Analysis grouping that lists the OCL AI Assistant's primary and alternate candidates;
    • the row panel's Search tab;
    • the row panel's Target Code header (MappingDecisionResult). Its box has a fixed height, so the matched name keeps to one line there, with all of it on hover.
  • A reopened project restores each mapped target from its CSV, with only an id, a name and a URL. The grid now fills in the names and highlights the row's restored candidates hold for that concept (withCandidateNames, found by findTargetRowView in viewBuilders.js). findTargetRowView is the URL-then-id match the row panel header already used; both now share it.
  • The table views of the candidates and the Search tab name each concept the same way, with the matched name below. TableResults now lets an extra column with a base column's id replace it in place (withExtraColumns, in src/components/search/tableColumns.js), and both tables pass that name column. The rows themselves are unchanged, so Map and the concept panel keep the concept's own display_name, and that's what a mapping stores and the export writes.
  • Sorting candidates by display name sorts on the name shown. sortRowViews takes the input language.
  • The name-locale filter (the project's filters.locale) still hides a matched name in a language it excludes, everywhere above. It now compares primary subtags, so a filter of it admits an it-IT name. That's how the filter already treats the names sent to the OCL AI Assistant (filterAndTrimNames).

How I tested it

  • The steps of .github/workflows/pr.yml, run in order on Node 22.23.2:
    • Secret check: start-prod.sh writes no secret-shaped variable. Passed.
    • npm ci: passed.
    • eslint (./node_modules/eslint/bin/eslint.js src --ext .jsx,.js): no problems. I ran it with --no-eslintrc -c .eslintrc.json, which reads only this repo's config: the worktree sits inside another checkout, whose config ESLint would otherwise merge in.
    • npm run test:all: 499 unit tests and 6 integration tests pass, on 19f6eba.
  • PR checks: "Lint and test" passed on 19f6eba: https://github.com/OpenConceptLab/oclmap/actions/runs/38837904500
  • New tests, each failing without its change:
    • src/components/map-projects/__tests__/conceptNames.test.js: 14 tests. One is the ticket's case, LOINC 89497-2 with its it-IT name matched in an English project.
    • src/components/search/__tests__/tableColumns.test.js: 3 tests.
    • src/components/map-projects/__tests__/views.test.js: 4 more. One sorts by the shown name. The others cover findTargetRowView and withCandidateNames, using a target shaped as a reopened project restores it.
  • In a browser. I rendered Concept, MappingDecisionResult and a SearchResults table in headless Chromium, through a throwaway harness that isn't committed, with Concept from main beside this branch's. The ticket names no widths: the page was 1600px wide, with the candidate lists at 520px, the grid cell at 360px and the header at 640px.
    • main: reproduces the ticket: "Anamnesi Punto nel tempo (episodio) Test prenatale → Mother's Prenatal tests".
    • This branch, English project: "LOINC:89497-2 Mother's Prenatal tests", with "Matched name (it-IT): Anamnesi Punto nel tempo (episodio) Test prenatale" below it, in the candidate list, the grid cell, the header and the table. Matched words are still bold. A candidate that matched on its display name shows no second line.
    • Spanish project: the candidates, the grid cell, the header and the table lead with the Spanish name. Where the English display name matched, it shows second as "Matched name (en)". In the header that line stays on one line, and the score chip stays in view.
    • Reopened project: a target restored as its CSV saves it leads with its Spanish name once withCandidateNames fills it from the row's candidates.
    • Name-locale filter of es: the it-IT and en matched names are hidden.
    • Spanish UI: the label reads "Nombre coincidente (it-IT)".
    • Console: no new errors. One validateDOMNesting warning comes from MappingDecisionResult's existing markup.

Acceptance criteria

  • A candidate leads with the target's display name in the project's input language, falling back to the repository's default locale. Covered by the localizedDisplayName tests (input language, primary subtag, preferred, then fully specified, then first name, fallback to display_name) and the browser check above.
  • The matched name shows second, with its locale, and only when it differs from the display name. Covered by the getMatchedName tests (the ticket's case, the same name, a display-name match, the filter, an unknown locale) and the browser check.
  • Same in the grid, the row panel and the AI card, except one case, which moved to Mapper: a reopened project forgets the names of a target mapped from the Search tab ocl_issues#2916:
    • Grid: the Target Code cell follows both rules, in the session and after the project is reopened.
    • Row panel: the candidates, Search tab, tables and Target Code header follow both rules.
    • AI card: the OCL AI Assistant's card names its picks by code. The candidates it picks are listed under it, through Concept.
    • The one case: after a project is reopened, a target that was mapped from the Search tab, rather than from the row's candidates, has no candidate to take its names and highlights from. Its grid cell leads with the repository's name until its row is opened, which fetches the concept, and never gets its matched name back. That's Codex's F3.1, fixed in oclmap#104.

Review

Codex ran three passes:

Then 0bbdb05 merged main (one import-line conflict in MapProject.jsx, resolved as the union). The simplification review ran on 0bbdb05 and proposed six cuts, all applied in 19f6eba. Codex's check of d03da8c..19f6eba was clean.

Docs

  • The Input Language helper text said the setting only chooses which name locales go to the OCL AI Assistant. It now says candidates lead with their name in that language too. That's in en, es, pt-BR and zh, and in ConfigurationForm's English default.
  • The comments in Concept.jsx, MappingDecisionResult.jsx and viewBuilders.js are updated. No README or docs page describes how candidates are named.

Translations

New key map_project.matched_name in all four catalogs: en "Matched name", es "Nombre coincidente", pt-BR "Nome correspondente", zh "匹配名称". A native speaker may want to check the es, pt-BR and zh wording, and the helper text changes.

Not done, and why

Noticed, not fixed

  • The CSV export keeps display_name: the mapped concept's name (__map_concept_name__) and the candidate columns. The ticket doesn't cover exports.
  • The concept details dialog and the bridge-contributor tooltip keep display_name too. Neither is a candidate title.

closes OpenConceptLab/ocl_issues#2909

🤖 Generated with Claude Code

https://claude.ai/code/session_01NSAveBj6W6LKJLYTWJ9rwi

Written by an Octoad session worker (worker-v0.11, recipe lean-loop, flow public>public, run openconceptlab-ocl-issues-2909-20261014-125457).

paynejd and others added 2 commits October 14, 2026 13:12
…he input language, and the matched name comes second

A candidate led with the name its match was made on, then an arrow and its
display name, so a match on a translation put a name in another language
first. For "Pregnancy test" in an English project, LOINC 89497-2 read
"Anamnesi Punto nel tempo (episodio) Test prenatale -> Mother's Prenatal
tests".

- conceptNames.js picks the names. localizedDisplayName is the concept's
  name in the project's input language (its preferred name, then its fully
  specified name, then its first), or else display_name, which OCL computes
  from the repository's default locale. getMatchedName is the name that
  matched, with its locale, or null when it is the name the candidate
  leads with.
- Concept.jsx leads with that name and shows "Matched name (<locale>): ..."
  on the line below it. The grid's Target Code cell, the row panel's
  candidates (with its AI Analysis grouping) and Search tab, and the row
  panel's Target Code header get the project's input language.
- The candidates' table view names each row the same way.
- The name-locale filter compares primary subtags, so "it" admits an it-IT
  name, as it already does for the names sent to the OCL AI Assistant.
- New string map_project.matched_name in en, es, pt-BR and zh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NSAveBj6W6LKJLYTWJ9rwi
…candidates lead with their name in it

The helper text said the input language only chose which name locales go to
the OCL AI Assistant. It now also sets the name each candidate leads with,
so the text says so, in en, es, pt-BR and zh, and in ConfigurationForm's
English default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NSAveBj6W6LKJLYTWJ9rwi
@paynejd paynejd added origin/ai-generated Issue or PR created by an AI agent origin/session-worker Opened by the Octoad session worker; a run record backs it labels Oct 14, 2026

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review, pass 1 (codex-cli 0.162.1, commit 797f81a)

3 P1.

F1.1 · P1 · src/components/map-projects/MapProject.jsx:1136 · The grid and selected-target summary omit the required matched name and locale. (Select the ticket's candidate with its Italian synonym highlight. Its candidate card shows the secondary matched name, but the grid explicitly suppresses it through noMatchedName. MappingDecisionResult also renders only the localized title and properties. Acceptance criteria 2–3 therefore remain unmet.)
F1.2 · P1 · src/components/map-projects/Search.jsx:212 · Search results revert to the repository language when switched to table view. (In a Spanish project, a result with display_name 'Blood glucose' and preferred Spanish name 'Glucosa en sangre' shows the Spanish title as a card. Switching to table view shows 'Blood glucose': TableResults bypasses this Concept renderer and reads the unchanged response.data display_name.)
F1.3 · P1 · src/components/map-projects/Candidates.jsx:190 · Sorting by display name no longer sorts the names users see. (In a Spanish project, choose display-name sorting for candidates 'Blood glucose' → 'Glucosa en sangre' and 'Diabetes mellitus'. sortRowViews still compares conceptDefinition.display_name before localization, so the visible ascending list is 'Glucosa en sangre', then 'Diabetes mellitus'.)

findings.json
{
  "reviewer": "codex-cli 0.162.1",
  "perspective": "defects",
  "mode": "full",
  "commit": "797f81a8fbbe9d39c3b2c477ebbd4d6c45fa600b",
  "verdict": "findings",
  "prior": [],
  "findings": [
    {
      "id": "F1.1",
      "severity": "P1",
      "tag": null,
      "file": "src/components/map-projects/MapProject.jsx",
      "line": 1136,
      "claim": "The grid and selected-target summary omit the required matched name and locale.",
      "scenario": "Select the ticket's candidate with its Italian synonym highlight. Its candidate card shows the secondary matched name, but the grid explicitly suppresses it through noMatchedName. MappingDecisionResult also renders only the localized title and properties. Acceptance criteria 2–3 therefore remain unmet.",
      "action": "Render the distinct matched name and locale in the grid and selected-target summary using the shared helper and retained search highlights.",
      "lines_delta": null,
      "confidence": "high"
    },
    {
      "id": "F1.2",
      "severity": "P1",
      "tag": null,
      "file": "src/components/map-projects/Search.jsx",
      "line": 212,
      "claim": "Search results revert to the repository language when switched to table view.",
      "scenario": "In a Spanish project, a result with display_name 'Blood glucose' and preferred Spanish name 'Glucosa en sangre' shows the Spanish title as a card. Switching to table view shows 'Blood glucose': TableResults bypasses this Concept renderer and reads the unchanged response.data display_name.",
      "action": "Apply localized display-name rendering to the search table as well, preserving the original concept for mapping actions.",
      "lines_delta": null,
      "confidence": "high"
    },
    {
      "id": "F1.3",
      "severity": "P1",
      "tag": null,
      "file": "src/components/map-projects/Candidates.jsx",
      "line": 190,
      "claim": "Sorting by display name no longer sorts the names users see.",
      "scenario": "In a Spanish project, choose display-name sorting for candidates 'Blood glucose' → 'Glucosa en sangre' and 'Diabetes mellitus'. sortRowViews still compares conceptDefinition.display_name before localization, so the visible ascending list is 'Glucosa en sangre', then 'Diabetes mellitus'.",
      "action": "Use localizedDisplayName with the project's input locale as the display-name sort key, including nested bridge candidates, and add a regression test.",
      "lines_delta": null,
      "confidence": "high"
    }
  ]
}

…r and both tables name a concept as its candidate card does

Codex review, pass 1:

- F1.1: the grid's Target Code cell and the row panel's Target Code header
  now show the matched name, with its locale, under the name the target
  leads with, from the mapped concept's search highlights, as a candidate
  card does. The header's box has a fixed height, so there the line keeps
  to one line, with the whole of it on hover. The name-locale filter
  reaches both. Concept's noMatchedName prop, now unused, is gone.
- F1.2: the Search tab's table view, like the candidates' one, names each
  concept in the input language. TableResults lets an extra column with a
  base column's id replace it in place (withExtraColumns, unit-tested), and
  both tables pass a name column that renders localizedDisplayName. The rows
  stay as they were, so Map and the concept panel keep the concept's own
  display_name. The candidates' rows no longer rename display_name.
- F1.3: sorting candidates by display name sorts on the name shown in the
  input language (sortRowViews takes inputLocale), including bridge
  children. Tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NSAveBj6W6LKJLYTWJ9rwi
@paynejd

paynejd commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

Response to Codex pass 1

F1.1 fixed in 071ef7a
F1.2 fixed in 071ef7a
F1.3 fixed in 071ef7a

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review, pass 2 (codex-cli 0.162.1, commit 071ef7a)

2 P1.

F2.1 · P1 · src/components/map-projects/MapProject.jsx:1136 · Reopening a saved project loses localized titles and matched names in the grid. (Save and reopen a Spanish project mapping 'Blood glucose', whose preferred Spanish name is 'Glucosa en sangre'. setProjectFromData reconstructs mapSelected from CSV without names or highlights. getConcept searches URL-shaped cache keys, but saved candidate definitions use opaque concept keys. The grid therefore receives the incomplete CSV stub and displays 'Blood glucose' without the matched name, even though both are available in the restored candidate state. The fresh-selection fix for F1.1 does not cover this path.)
F2.2 · P1 · src/components/map-projects/Concept.jsx:73 · Switching candidates or search results to table view still hides the distinct matched name and locale. (For the ticket's English candidate with an Italian synonym highlight, card mode shows the matched Italian name and its locale. Switching to table mode renders only the localized display name because localizedNameColumn never renders MatchedName. Acceptance criteria 2–3 remain unmet in these row-panel views.)

findings.json
{
  "reviewer": "codex-cli 0.162.1",
  "perspective": "defects",
  "mode": "verify",
  "commit": "071ef7a4afac23eb9a6379b405d2949dd839a3f2",
  "verdict": "findings",
  "prior": [
    {
      "id": "F1.1",
      "status": "unresolved"
    },
    {
      "id": "F1.2",
      "status": "resolved"
    },
    {
      "id": "F1.3",
      "status": "resolved"
    }
  ],
  "findings": [
    {
      "id": "F2.1",
      "severity": "P1",
      "tag": null,
      "file": "src/components/map-projects/MapProject.jsx",
      "line": 1136,
      "claim": "Reopening a saved project loses localized titles and matched names in the grid.",
      "scenario": "Save and reopen a Spanish project mapping 'Blood glucose', whose preferred Spanish name is 'Glucosa en sangre'. setProjectFromData reconstructs mapSelected from CSV without names or highlights. getConcept searches URL-shaped cache keys, but saved candidate definitions use opaque concept keys. The grid therefore receives the incomplete CSV stub and displays 'Blood glucose' without the matched name, even though both are available in the restored candidate state. The fresh-selection fix for F1.1 does not cover this path.",
      "action": "Resolve grid targets against the restored concept definitions and merge their row-specific candidate highlights before rendering. Add a save/reload regression test.",
      "lines_delta": null,
      "confidence": "high"
    },
    {
      "id": "F2.2",
      "severity": "P1",
      "tag": null,
      "file": "src/components/map-projects/Concept.jsx",
      "line": 73,
      "claim": "Switching candidates or search results to table view still hides the distinct matched name and locale.",
      "scenario": "For the ticket's English candidate with an Italian synonym highlight, card mode shows the matched Italian name and its locale. Switching to table mode renders only the localized display name because localizedNameColumn never renders MatchedName. Acceptance criteria 2–3 remain unmet in these row-panel views.",
      "action": "Render the distinct matched name and locale below the table title using getMatchedName and MatchedName, and pass through the name-locale filter.",
      "lines_delta": null,
      "confidence": "high"
    }
  ]
}

…d both tables, show the matched name too

Codex review, pass 2:

- F2.1 (and F1.1, which it reopened): a project reopened from its saved
  file restores each mapped target from the CSV, with no names or
  highlights, so its grid cell named it in the repository's language and
  showed no matched name. withCandidateNames gives the target the names and
  highlights its row's candidates hold for it, found by findTargetRowView:
  the URL-then-id match the row panel header already used, now shared.
  Both are unit-tested with a target as a reopened project restores it.
- F2.2: the table views' name column shows the matched name, with its
  locale, under the name, as a candidate card does, and the name-locale
  filter reaches it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NSAveBj6W6LKJLYTWJ9rwi
@paynejd

paynejd commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

Response to Codex pass 2

F1.1 fixed in d03da8c (it stayed open for the reopened-project path, F2.1; 071ef7a covered a target mapped in the session)
F2.1 fixed in d03da8c
F2.2 fixed in d03da8c

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review, pass 3 (codex-cli 0.162.1, commit d03da8c)

1 P1.

F3.1 · P1 · src/components/map-projects/viewBuilders.js:442 · Targets mapped from Search still lose localized names and match evidence after reopening. (In a Spanish project, map a Search result absent from the row's algorithm candidates, then save and reopen. Before saving, 'Hemoglobin' displays as 'Hemoglobina' with the English matched name underneath. Reload reconstructs mapSelected from CSV without names or highlights; it does not restore the full concept submitted in matches. This helper finds no candidate and returns the stub, so the grid shows 'Hemoglobin' without the matched name.)

findings.json
{
  "reviewer": "codex-cli 0.162.1",
  "perspective": "defects",
  "mode": "verify",
  "commit": "d03da8cdc3b494af978c08dd8b3ef18327a4fec7",
  "verdict": "findings",
  "prior": [
    {
      "id": "F1.1",
      "status": "resolved"
    },
    {
      "id": "F1.2",
      "status": "resolved"
    },
    {
      "id": "F1.3",
      "status": "resolved"
    },
    {
      "id": "F2.1",
      "status": "resolved"
    },
    {
      "id": "F2.2",
      "status": "resolved"
    }
  ],
  "findings": [
    {
      "id": "F3.1",
      "severity": "P1",
      "tag": null,
      "file": "src/components/map-projects/viewBuilders.js",
      "line": 442,
      "claim": "Targets mapped from Search still lose localized names and match evidence after reopening.",
      "scenario": "In a Spanish project, map a Search result absent from the row's algorithm candidates, then save and reopen. Before saving, 'Hemoglobin' displays as 'Hemoglobina' with the English matched name underneath. Reload reconstructs mapSelected from CSV without names or highlights; it does not restore the full concept submitted in matches. This helper finds no candidate and returns the stub, so the grid shows 'Hemoglobin' without the matched name.",
      "action": "Restore names and row-specific highlights for Search-only selections, independently of algorithm candidates, and add a save/reopen regression test for this path.",
      "lines_delta": null,
      "confidence": "high"
    }
  ]
}

@paynejd

paynejd commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

Response to Codex pass 3

F3.1 open: fixing it needs a decision this ticket doesn't make, so it's the question in the "Needs you" comment below.

@paynejd

paynejd commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

Needs you

Decision: should a reopened project bring back the input-language name and the matched name of a target that was mapped from the Search tab, and if so, how? There are two ways, both beyond this ticket:

  • Save more: store each mapped target's names and match highlights with the project. That changes the saved format.
  • Fetch on open: fetch the names of those targets when the project opens. That's one request per Search-mapped row, and the matched name still can't come back, because the search highlights aren't saved.

Or leave it to a follow-up ticket.

This is Codex's F3.1 (P1), still open after the last of the three passes. Here's what happens now:

  • Reopening restores only the CSV's id, name and URL for each mapped target. A target mapped from a row's candidates gets its names and highlights back from the restored candidates (F2.1, fixed in d03da8c).
  • A target mapped from Search isn't among the candidates. Its grid cell names it in the repository's default language, with no matched name, as on main.
  • Opening its row already fetches the concept, names included. From then on the cell leads with the input-language name. Only the matched name stays missing.

State of the rest:

  • Every other Codex finding (F1.1–F1.3, F2.1, F2.2) is resolved.
  • "Lint and test" passes on d03da8c.
  • The simplification review didn't run: the work order ends a run that will need a person without it.

@paynejd

paynejd commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

Decision on F3.1

F3.1 accepted for this PR, and moved to OpenConceptLab/ocl_issues#2916. A target mapped from the Search tab keeps today's behavior here: its cell leads with the repository's name after a reopen, until its row is opened.

The fix doesn't need a new saved format. Every save already sends each mapped target's full concept, with its names and search highlight, in the project's matches, and opening a project returns it. oclmap never reads it back. ocl_issues#2916 restores a target's names and highlight from that entry on reopen, which also stops the next save from overwriting it with the stripped target. That fix goes in its own PR, based on this branch.

Next on this PR: the simplification review it skipped.

…y-name branch

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplification review (commit 0bbdb05)

6 items, about -12 lines.

  • S1 · delete · src/components/map-projects/Concept.jsx:477 · Bridge children get matchedName={matchedName} (the parent's matched name), but Item renders MatchedName only when !bridgeConceptDefinition, and every bridge child is passed bridgeConceptDefinition={conceptDefinition}. The prop is never read. This is the old synonymPrefix pass-through under a new name. → Nothing replaces it. Remove the prop from the bridge-children ConceptItem. (-1)
  • S2 · delete · src/components/map-projects/viewBuilders.js:422 · The pass-2 helpers guard against cases their callers rule out. findTargetRowView's if(!target) return undefined and (views || []): MapProject calls it only under targetConcept ? ... : false with an array, and withCandidateNames calls it only from the grid inside if(targetConcept?.id) with buildQualityRowViews' array. withCandidateNames' rowState ? ... : undefined is also redundant, because buildQualityRowViews already returns [] for a missing rowState (viewBuilders.js:237). → Make findTargetRowView views.find(...) with no target guard. Write const view = findTargetRowView(buildQualityRowViews(rowState, conceptCache), target) in withCandidateNames. Drop the findTargetRowView(views, null) assertion (views.test.js:715). The rest of that test and the withCandidateNames tests, which pin the F2.1 fix, stay, and the undefined-rowState assertion still passes. (-2)
  • S3 · yagni · src/components/map-projects/conceptNames.js:23 · toLocaleList has one caller and accepts an array that no caller passes. Every locales/filterLocales comes from filters.locale || '', which ConfigurationForm always builds with values.join(','). The array branch and its test assertion cover unused flexibility. → Inline it in getMatchedName as const allowed = (filterLocales || '').split(',').map(locale => primarySubtag(locale.trim())).filter(Boolean). Optionally use the existing uniqByPrimarySubtag from normalizers.js if trimming isn't wanted. Drop the filterLocales: ['it'] assertion (conceptNames.test.js:164). (-3)
  • S4 · shrink · src/components/map-projects/conceptNames.js:16 · plainText has one caller, and its (html || '') guard can't fire: getMatchedName has already returned null when fragment is falsy. → Inline it as const text = fragment.replace(/<\/?em>/g, '') and delete the helper. (-1)
  • S5 · dup-test · src/components/search/tests/tableColumns.test.js:19 · 'appends extra columns after the base ones' is covered by the next test, whose id-order assertion ['id', 'name', 'datatype', 'mappings'] already checks that a non-matching extra column (mappings) is appended after the base columns. → Nothing replaces it. Delete the first test. The replace-in-place test, which pins the F1.2 fix, stays. (-4)
  • S6 · dup-test · src/components/map-projects/tests/conceptNames.test.js:87 · In the ticket-case getMatchedName test, assert.equal(displayName, "Mother's Prenatal tests") repeats the assertion localizedDisplayName(PRENATAL_TESTS, 'en') already makes in 'keeps the display name when it is already in the input language'. → Nothing replaces it. Delete the assertion and keep the getMatchedName deepEqual. (-1)
findings.json
{
  "reviewer": "claude subagent",
  "perspective": "simplify",
  "mode": "full",
  "commit": "0bbdb050d280e83288ffe49f619910ce1b7fa386",
  "verdict": "findings",
  "prior": [],
  "findings": [
    {
      "id": "S1",
      "severity": null,
      "tag": "delete",
      "file": "src/components/map-projects/Concept.jsx",
      "line": 477,
      "claim": "Bridge children get `matchedName={matchedName}` (the parent's matched name), but Item renders MatchedName only when `!bridgeConceptDefinition`, and every bridge child is passed `bridgeConceptDefinition={conceptDefinition}`. The prop is never read. This is the old synonymPrefix pass-through under a new name.",
      "scenario": null,
      "action": "Nothing replaces it. Remove the prop from the bridge-children ConceptItem.",
      "lines_delta": -1,
      "confidence": "high"
    },
    {
      "id": "S2",
      "severity": null,
      "tag": "delete",
      "file": "src/components/map-projects/viewBuilders.js",
      "line": 422,
      "claim": "The pass-2 helpers guard against cases their callers rule out. findTargetRowView's `if(!target) return undefined` and `(views || [])`: MapProject calls it only under `targetConcept ? ... : false` with an array, and withCandidateNames calls it only from the grid inside `if(targetConcept?.id)` with buildQualityRowViews' array. withCandidateNames' `rowState ? ... : undefined` is also redundant, because buildQualityRowViews already returns [] for a missing rowState (viewBuilders.js:237).",
      "scenario": null,
      "action": "Make findTargetRowView `views.find(...)` with no target guard. Write `const view = findTargetRowView(buildQualityRowViews(rowState, conceptCache), target)` in withCandidateNames. Drop the `findTargetRowView(views, null)` assertion (views.test.js:715). The rest of that test and the withCandidateNames tests, which pin the F2.1 fix, stay, and the undefined-rowState assertion still passes.",
      "lines_delta": -2,
      "confidence": "high"
    },
    {
      "id": "S3",
      "severity": null,
      "tag": "yagni",
      "file": "src/components/map-projects/conceptNames.js",
      "line": 23,
      "claim": "toLocaleList has one caller and accepts an array that no caller passes. Every `locales`/`filterLocales` comes from `filters.locale || ''`, which ConfigurationForm always builds with `values.join(',')`. The array branch and its test assertion cover unused flexibility.",
      "scenario": null,
      "action": "Inline it in getMatchedName as `const allowed = (filterLocales || '').split(',').map(locale => primarySubtag(locale.trim())).filter(Boolean)`. Optionally use the existing `uniqByPrimarySubtag` from normalizers.js if trimming isn't wanted. Drop the `filterLocales: ['it']` assertion (conceptNames.test.js:164).",
      "lines_delta": -3,
      "confidence": "medium"
    },
    {
      "id": "S4",
      "severity": null,
      "tag": "shrink",
      "file": "src/components/map-projects/conceptNames.js",
      "line": 16,
      "claim": "plainText has one caller, and its `(html || '')` guard can't fire: getMatchedName has already returned null when `fragment` is falsy.",
      "scenario": null,
      "action": "Inline it as `const text = fragment.replace(/<\\/?em>/g, '')` and delete the helper.",
      "lines_delta": -1,
      "confidence": "high"
    },
    {
      "id": "S5",
      "severity": null,
      "tag": "dup-test",
      "file": "src/components/search/__tests__/tableColumns.test.js",
      "line": 19,
      "claim": "'appends extra columns after the base ones' is covered by the next test, whose id-order assertion `['id', 'name', 'datatype', 'mappings']` already checks that a non-matching extra column (`mappings`) is appended after the base columns.",
      "scenario": null,
      "action": "Nothing replaces it. Delete the first test. The replace-in-place test, which pins the F1.2 fix, stays.",
      "lines_delta": -4,
      "confidence": "high"
    },
    {
      "id": "S6",
      "severity": null,
      "tag": "dup-test",
      "file": "src/components/map-projects/__tests__/conceptNames.test.js",
      "line": 87,
      "claim": "In the ticket-case getMatchedName test, `assert.equal(displayName, \"Mother's Prenatal tests\")` repeats the assertion `localizedDisplayName(PRENATAL_TESTS, 'en')` already makes in 'keeps the display name when it is already in the input language'.",
      "scenario": null,
      "action": "Nothing replaces it. Delete the assertion and keep the getMatchedName deepEqual.",
      "lines_delta": -1,
      "confidence": "medium"
    }
  ]
}

…ound unused or repeated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@paynejd

paynejd commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

Response to the simplification review

S1 applied in 19f6eba
S2 applied in 19f6eba
S3 applied in 19f6eba
S4 applied in 19f6eba
S5 applied in 19f6eba
S6 applied in 19f6eba

Lint and npm run test:all pass on 19f6eba (499 unit, 6 integration). 0bbdb05 merged main into this branch first: one import-line conflict in MapProject.jsx, resolved as the union of both sides.

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex check of commits d03da8c..19f6eba (codex-cli 0.163.0, commit 19f6eba)

Clean. It checked the merge of main (0bbdb05) and the simplification cuts (19f6eba).

findings.json
{
  "reviewer": "codex-cli 0.163.0",
  "perspective": "defects",
  "mode": "cuts",
  "commit": "19f6eba865e75fd43323252b0efcc85a26d4fe7d",
  "verdict": "clean",
  "prior": [],
  "findings": []
}

@snyaggarwal
snyaggarwal merged commit c28025b into main Oct 16, 2026
2 checks passed
@snyaggarwal
snyaggarwal deleted the OpenConceptLab/ocl_issues#2909-candidate-display-name branch October 16, 2026 03:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

origin/ai-generated Issue or PR created by an AI agent origin/session-worker Opened by the Octoad session worker; a run record backs it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mapper: a candidate can lead with a translated name instead of one in the input language

2 participants