Skip to content

OpenConceptLab/ocl_issues#2934 | The orange AI icon's tooltip names the code the AI recommends - #129

Merged
paynejd merged 2 commits into
mainfrom
OpenConceptLab/ocl_issues#2934-ai-tooltip-names-code
Nov 11, 2026
Merged

paynejd merged 2 commits into
mainfrom
OpenConceptLab/ocl_issues#2934-ai-tooltip-names-code

Conversation

@paynejd

@paynejd paynejd commented Nov 10, 2026 •

Copy link
Copy Markdown
Member

What changed and why

In the grid's Target Code cell, the AI icon is purple when the mapped code is the OCL AI Assistant's pick and orange otherwise. When the AI picked a different code and the mapped code isn't one of its alternates either, the orange icon's tooltip said only "AI Analysis", so a reviewer had to open the row to see what the AI recommends.

That tooltip now names the AI's pick: "The AI recommends BA00.Z".

  • getAIIndicatorTooltip (new, src/components/map-projects/viewBuilders.js) chooses the tooltip: "AI Recommended" when the mapped code is the AI's pick, "AI Alternate Candidate Suggestion" when it's one of the alternates, "The AI recommends {{code}}" when the AI picked another code, and "AI Analysis" when the analysis recommends no code at all.
  • MapProject.jsx: getRowAIIndicatorMeta also returns the AI's primaryCandidateId (already worked out there), and the Target Code cell's tooltip calls the helper instead of the inline ternary. The icon's color doesn't change.
  • New key map_project.ai_recommends_code in every catalog: en "The AI recommends {{code}}", es "La IA recomienda {{code}}", pt-BR "A IA recomenda {{code}}", zh "AI 推荐的是 {{code}}". The zh wording avoids reading as the existing "AI 推荐" badge.

How I tested it

Every run: step of .github/workflows/pr.yml, in order, on Node 22.23.2:

  • start-prod.sh secret-variable check: passes.
  • npm ci: passes.
  • ESLint: passes (exit 0). This worktree is nested inside another checkout of the repo, so a bare eslint src --ext .jsx,.js also loaded the outer copy's .eslintrc.json and stopped with "couldn't determine the plugin react uniquely". I ran it as eslint --no-eslintrc -c .eslintrc.json src --ext .jsx,.js, which loads only this repo's one config, as CI does. The PR check below runs the exact command.
  • npm run test:all: 658 unit tests and 11 integration tests pass (at 662ce17).

New tests in src/components/map-projects/__tests__/viewHelpers.test.js run getAIIndicatorTooltip through a real i18next instance loaded with each catalog, so they check the text a reviewer sees, not only the key. Run against main's viewBuilders.js and English catalog, the file fails (the helper doesn't exist there).

PR checks: Lint and test passed on 662ce17, running the exact ESLint command.

Browser check: I served the app with npm start on a free port and drove it with headless Chromium (Playwright, fresh context, 1440×900). Playwright answered every API and OCL AI Assistant call with stubs, so nothing left the machine. The stub is a saved three-row project whose AI analysis picks BA00.Z for a row mapped to BA00.0, picks 1A07.0 for a row mapped to its alternate 1A07.Y, and picks 1A02 for a row mapped to 1A02. Hovering each icon in the grid's Target Code cell gave:

Row Icon en es pt-BR zh
mapped code is neither pick nor alternate orange The AI recommends BA00.Z La IA recomienda BA00.Z A IA recomenda BA00.Z AI 推荐的是 BA00.Z
mapped code is an alternate orange AI Alternate Candidate Suggestion Sugerencia de candidato alternativo de IA Sugestão de Candidato Alternativo por IA AI 备选候选建议
mapped code is the AI's pick purple AI Recommended Recomendado por IA Recomendado por IA AI 推荐

No page errors. The ticket names no widths; the change is tooltip text only, in MUI's existing Tooltip, so I checked one desktop width.

Acceptance criteria

  • The orange tooltip names the AI's recommended code, e.g. "The AI recommends BA00.Z". Test: getAIIndicatorTooltip: orange names the AI's pick; the alternate, purple and no-pick cases keep their wording checks the English text exactly; every catalog names the recommended code checks es, pt-BR and zh include the code. Seen in the browser check above, in all four languages.
  • The alternate case keeps its own wording. The same test checks "AI Alternate Candidate Suggestion" for a mapped alternate even when the AI picked another code, and that the purple "AI Recommended" and the no-pick "AI Analysis" are unchanged. Seen in the browser check above.

Docs

No doc describes this tooltip (README, src/i18n/README.md and the __integration__ README don't mention it), so none needed updating. The helper carries a one-line comment saying what it's for.

Review

  • Codex pass 1 at 60437ef: clean.
  • Simplification review at 60437ef: three cuts (a redundant assertion, four English tests merged into one, a shorter comment), all applied in 662ce17.
  • Codex check of 60437ef..662ce17: clean.

Chose not to do

  • The wording follows the ticket's example ("The AI recommends …"). It names the code only, not the concept's name: the tooltip is on a cell that already shows the mapped concept, and the code is what the reviewer looks for in the candidates.
  • The icon's colors and when it shows are unchanged.

Noticed, not fixed

  • When the analysis recommends no code at all (no primary candidate) and the mapped code isn't an alternate, the orange tooltip still says "AI Analysis". Saying "The AI recommends no match" there would help a reviewer too, but it's a different case from this ticket's.
  • getRowAIIndicatorMeta compares the AI's pick with targetConcept.id || targetConcept.reference.code. If a concept's id ever differed from its reference code, a mapped concept that is the AI's pick would show orange with its own code in the tooltip. I didn't find a case where they differ; the comparison is unchanged here.

closes OpenConceptLab/ocl_issues#2934

Written by an Octoad session worker (worker-v0.18, recipe lean-loop, flow public>public, run openconceptlab-ocl-issues-2934-20261110-183800).

🤖 Generated with Claude Code

https://claude.ai/code/session_01AaZ4qTi7WutsgsbAJ48PTj

…names the code the AI recommends

In the grid's Target Code cell, the orange AI icon (the mapped code is
neither the OCL AI Assistant's pick nor one of its alternates) said only
"AI Analysis". It now says "The AI recommends <code>", naming the AI's
pick. The purple icon and the alternate case keep their wording, and a
row whose analysis recommends no code still says "AI Analysis".

The choice of wording moves into getAIIndicatorTooltip in viewBuilders.js
so it can be unit-tested; the new map_project.ai_recommends_code key is
in every catalog (en, es, pt-BR, zh).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AaZ4qTi7WutsgsbAJ48PTj
@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 Nov 10, 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.167.1, commit 60437ef)

Clean.

findings.json
{"reviewer":"codex-cli 0.167.1","perspective":"defects","mode":"full","commit":"60437eff7d83c57fa3b6e9d72724dd7f286d6aba","verdict":"clean","prior":[],"findings":[]}

@paynejd

paynejd commented Nov 10, 2026

Copy link
Copy Markdown
Member Author

Response to Codex pass 1

No findings to answer. Pass 1 leaves no P0 or P1 open, so the Codex loop stops here.

@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 60437ef)

3 items: 1 dup-test, 2 shrink.

  • S1 · dup-test · src/components/map-projects/tests/viewHelpers.test.js:312 · the assert.notEqual(tooltip, t('map_project.ai_analysis')) in the every-catalog loop, implied by the includes('BA00.Z') check before it → nothing replaces it (-1)
  • S2 · shrink · src/components/map-projects/tests/viewHelpers.test.js:275 · four English tests that each build an i18next instance and repeat the whole meta object → one table-style test keeping all four assertions (-23)
  • S3 · shrink · src/components/map-projects/viewBuilders.js:622 · the 6-line JSDoc on getAIIndicatorTooltip, which mostly restates the code and describes icon colors the function doesn't set → a one-line comment naming its purpose and the ticket (-5)
findings.json
{"reviewer":"claude subagent","perspective":"simplify","mode":"full","commit":"60437eff7d83c57fa3b6e9d72724dd7f286d6aba","verdict":"findings","prior":[],"findings":[{"id":"S1","severity":null,"tag":"dup-test","file":"src/components/map-projects/__tests__/viewHelpers.test.js","line":312,"claim":"In the 'every catalog names the recommended code' loop, `assert.notEqual(tooltip, t('map_project.ai_analysis'), locale)` adds nothing. The line before it already asserts `tooltip.includes('BA00.Z')`, and no catalog's ai_analysis string contains 'BA00.Z', so whenever the first assertion passes the second one passes too.","scenario":null,"action":"Nothing replaces it. Keep the `assert.ok(tooltip.includes('BA00.Z'), ...)` line.","lines_delta":-1,"confidence":"high"},{"id":"S2","severity":null,"tag":"shrink","file":"src/components/map-projects/__tests__/viewHelpers.test.js","line":275,"claim":"The four English tests (lines 275-305) each build a fresh i18next instance with `await translator('en')` and repeat the whole `{isPrimaryMatch, isAlternateMatch, primaryCandidateId}` object. Only one field changes per case.","scenario":null,"action":"Merge them into one table-style test that keeps all four assertions, including the AC1 and AC2 wording: `test('getAIIndicatorTooltip: orange names the AI\\'s pick; the alternate, purple and no-pick cases keep their wording', async () => { const t = await translator('en'); const tooltip = meta => getAIIndicatorTooltip({isPrimaryMatch: false, isAlternateMatch: false, primaryCandidateId: 'BA00.Z', ...meta}, t); assert.equal(tooltip({}), 'The AI recommends BA00.Z'); assert.equal(tooltip({isAlternateMatch: true}), 'AI Alternate Candidate Suggestion'); assert.equal(tooltip({isPrimaryMatch: true}), 'AI Recommended'); assert.equal(tooltip({primaryCandidateId: null}), 'AI Analysis') })`. Written one statement per line, that is about 8 lines in place of 31.","lines_delta":-23,"confidence":"medium"},{"id":"S3","severity":null,"tag":"shrink","file":"src/components/map-projects/viewBuilders.js","line":622,"claim":"The 6-line JSDoc on getAIIndicatorTooltip mostly says what the code or the call site already shows. Its purple/orange explanation describes the icon color, which MapProject.jsx sets and this function never touches. The parts worth keeping are what the function is for and the ticket link.","scenario":null,"action":"Replace the block with one line: `// The AI icon's tooltip in the grid's Target Code cell; the orange one names the AI's pick (OpenConceptLab/ocl_issues#2934).`","lines_delta":-5,"confidence":"low"}]}

… comment

From the simplification review: the four English tooltip cases become
one table-style test with the same assertions, the every-catalog loop
drops an assertion its includes() check already implies, and the
helper's comment shrinks to one line.

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

paynejd commented Nov 10, 2026

Copy link
Copy Markdown
Member Author

Response to the simplification review

The full gate passes again after the cuts: secret-variable check, npm ci, ESLint, and npm run test:all (658 unit tests, 11 integration tests).

@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 60437ef..662ce17

(codex-cli 0.167.1, commit 662ce17)

Clean.

findings.json
{"reviewer":"codex-cli 0.167.1","perspective":"defects","mode":"final","commit":"662ce174c3f6da29e890150fe3c07a645f351cfc","verdict":"clean","prior":[],"findings":[]}

@paynejd
paynejd marked this pull request as ready for review November 10, 2026 23:49
@paynejd
paynejd merged commit 0940ebb into main Nov 11, 2026
2 checks passed
@paynejd
paynejd deleted the OpenConceptLab/ocl_issues#2934-ai-tooltip-names-code branch November 11, 2026 02:01
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: the orange AI icon's tooltip says only "AI Analysis" when the AI recommends another code

1 participant