Skip to content

Mapper: one recommendation rule — the OCL AI Assistant decides when it has run, the score orders the rest #2908

Description

@paynejd

Part of OpenConceptLab/ocl_online#464 (critical user journey 1). This is the Mapper's first recommendation rule that combines the OCL AI Assistant and the reranker. It is the simplest form of #2333, and it doesn't change the reranker. The reranker refactor and a broader reasoning layer stay in #2593.

Why. The reranker scores names only. The OCL AI Assistant reads every field. In a 5-row LOINC 2.81 test on 2026-10-13, AutoMatch with AI:

  • proposed Hemoglobin (Blood) as 110885-1, an order-only code, at Recommended 99.42%. The AI picked 718-7.
  • left Potassium (Serum) Unmapped. The AI's pick, 2823-3, sat under Low Ranked at 44.74%.

The panel can already order candidates by the AI (Group → AI Analysis, #2529), but that isn't the default view, and the grid and AutoMatch ignore the AI.

The rule

If the OCL AI Assistant has analysed the row's current candidates, it decides what is proposed, and the score orders everything else. If it hasn't, the score decides, as today.

Order of candidates:

  1. The AI's pick
  2. Its alternates, by score
  3. Everything else, by score, in today's buckets (Recommended, Available, Low Ranked, Unranked)

What AutoMatch proposes:

AI analysis AutoMatch proposes Grid's "OCL AI Assistant" column
None, failed, or out of date Top score, if Recommended (today's rule) Empty, running, failed, or out of date
RECOMMEND The AI's pick, in any score bucket Agrees, or Different pick
CONDITIONAL The AI's pick Agrees or Different pick, marked conditional
REJECT Nothing; the row stays Unmapped No match
INSUFFICIENT Nothing; the row stays Unmapped Not enough to decide
  • "Agrees" means the AI's pick is the Address performance issues with collections #1 candidate by score.
  • "Out of date" means the candidates changed after the analysis ran. This is the same candidate-pool check AutoMatch already uses to decide whether to re-run the AI.
  • Confidence (HIGH, MEDIUM, LOW) is shown but doesn't change the proposal.
  • If the AI's pick isn't a target-repo candidate, the score rule applies and the case is logged.
  • The AI's REJECT or INSUFFICIENT stands even when the score says Recommended. The score reads names only. A missed proposal costs the user one click. A wrong proposal can be bulk-approved.

Acceptance criteria

Rule

  • One function in viewBuilders.js returns the candidate order, the proposal and the agreement state. It has a unit test for each row of the table, and it replaces the AI Analysis grouping logic in Candidates.jsx.

Panel

  • The Match Quality view starts with an "OCL AI Assistant's pick" section and an "Alternates" section. Today's score buckets follow, holding the remaining candidates. Every card keeps its score chip.
  • Whenever the row has an analysis, a summary line shows the AI's verdict in plain words, its pick and the top score, and says whether they differ. "Read analysis" opens the AI's full explanation.
  • The Group → AI Analysis option is removed.
  • Without an analysis, the panel is unchanged. The Algorithm grouping and the ID and name sorts show badges only, as today.

AutoMatch

  • A row's proposal follows the rule, using any current analysis.
  • When the run's AI step returns for a row, the row is decided again: proposed with the pick, or left Unmapped on REJECT or INSUFFICIENT. A row the user changed after the run proposed it is left alone.
  • The log records who chose (chosen_by: ai_assistant | score). A REJECT or INSUFFICIENT outcome records the AI's verdict.
  • An analysis the user runs on one row reorders the panel and updates the grid. It doesn't change the row's mapping.
  • Without an analysis, AutoMatch is unchanged.

Grid

  • Target Code shows an AI icon with the tooltip "OCL AI Assistant's pick" when the target is the AI's pick. The orange icon is removed.
  • A new "OCL AI Assistant" column shows the agreement state.
    • Its tooltip names the other side, e.g. "Top score: 110885-1, Recommended 99.42%", or where the AI's pick ranks by score.
    • The column sorts and filters.
    • The AI's running and failed indicators move into it.
  • Next to the Match Quality bucket filters, an "OCL AI Assistant disagrees (n)" filter shows the rows marked Different pick, No match or Not enough to decide.
  • Match Quality stays score-only.

Copy and checks

  • Badge tooltips read "OCL AI Assistant's pick" and "OCL AI Assistant alternate". New strings are added in en, es, zh and pt-BR.
  • Before merging, replay the function over projects that have AI analyses, starting with the 2026-10-13 LOINC 2.81 test. Post the counts here:
    • rows where the AI and the score agree
    • rows where the AI picked a different candidate
    • rows with REJECT or INSUFFICIENT where the top score was Recommended
  • Document the rule in the Mapper pipeline docs.

Components: viewBuilders.js, Candidates.jsx, Score.jsx, MapProject.jsx (setAutoMatched, the AutoMatch path in fetchRecommendation, the grid columns, the bucket filters), and the locale files.

Activity

  1. added this to the P2 · Mapper: Beta milestone on Oct 13, 2026
  2. ocl-automation commented on Oct 13, 2026

    @ocl-automation
    Collaborator

    Automated Triage — 2026-10-13

    Dimension Score
    Complexity 3
    Scope 3
    Clarity 4
    Dependency 2
    Risk 2

    Decision: decision/ai-ready
    Type: type/feature
    Signals: signal/low-risk, signal/well-specified

    This is a display-only change across three named frontend components (AICandidatesAnalysis.jsx, Candidates.jsx, MapProject.jsx), with a checklist of acceptance criteria and concrete examples (Hemoglobin and Potassium). Dependency is low because it explicitly leaves AutoMatch selection unchanged, so the open #2333 and #2593 do not block it. Risk is low since it is UI-only and easy to revert, though the one-click Proposed mapping touches user data in the project.


    Generated by ticket-triage pipeline v3. Model: anthropic/claude-sonnet-5.5 (openrouter).

  3. added theissue type on Oct 16, 2026
  4. changed the title [-]Mapper: show the OCL AI Assistant's pick in the grid and first in the row's candidates[/-] [+]Mapper: one recommendation rule — the OCL AI Assistant decides when it has run, the score orders the rest[/+] on Oct 16, 2026
  5. paynejd commented on Oct 16, 2026

    @paynejd
    MemberAuthor

    Replay of the rule (getRowRecommendation, OpenConceptLab/oclmap@2e3b945)

    I replayed the rule read-only over every active saved project with OCL AI Assistant analyses: 53 projects, 3,216 analysed rows, using each row's latest analysis. The rule acts only on an analysis of the row's current candidates, checked with the candidate-pool fingerprint Auto Match uses. Analyses have stored that fingerprint only recently, so 98 rows in 6 projects qualify. The replay rebuilt each fingerprint from the saved candidates, and it matched the stored one on all 98.

    The three counts, on the rows the rule acts on

    2026-10-13 LOINC 2.81 test (5 rows) All current analyses (98 rows, 6 projects)
    The AI and the score agree 1 37
    The AI picked a different candidate 4 17
    REJECT or INSUFFICIENT where the top score was Recommended 0 0

    The other 44 of the 98 are 43 REJECT or INSUFFICIENT rows whose top score was below Recommended, and 1 CONDITIONAL with no primary candidate, which falls back to the score rule.

    The different picks by score bucket: in the test, 2 Available and 2 Low Ranked; overall, 4 Recommended (not the top one), 3 Available and 10 Low Ranked.

    What AutoMatch would propose, compared with today:

    Test All current
    Newly proposed (Unmapped today) 3 18
    A different concept 1 6
    Proposal withdrawn (REJECT or INSUFFICIENT over Recommended) 0 0
    Unchanged 1 30
    Nothing either way 0 44

    Wider picture: every analysis treated as current. Older analyses predate the fingerprint, so the rule never acts on them as saved; Auto Match runs the AI again for them. Treating them as current shows what the rule does at a larger scale, though on older prompts and models: 1,656 rows in 35 projects.

    Rows
    The AI and the score agree 670
    The AI picked a different candidate 570
    REJECT or INSUFFICIENT where the top score was Recommended 177 (72 REJECT, 105 INSUFFICIENT)

    The rest are 235 REJECT or INSUFFICIENT rows under a top score below Recommended, and 4 picks that aren't candidates. Compared with today, AutoMatch would newly propose 707 rows, propose a different concept on 269, and withdraw 177 proposals.

    Left out: 47 rows with no saved candidates, and of the rest, 409 analyses with no verdict (the earliest raw responses and empty entries) and 1,104 in the first structured shape, which names candidates by concept_id only.

  6. snyaggarwal commented on Oct 19, 2026

    @snyaggarwal
    Contributor

    @paynejd I can see some work OpenConceptLab/oclmap@2e3b945 on this is done on branch:OpenConceptLab/ocl_issues%232908-ai-first-rule -- is it ready for PR?

  7. paynejd commented on Oct 20, 2026

    @paynejd
    MemberAuthor

    Evidence from a production run, 2026-10-20 (Mapper 1.0.31-beta, template match-recommend-normalized-icd11 v1.0, Claude Haiku 4.5): 20 IMO terms from the ICD-11 evaluation set, CIEL bridge plus three ICD-11 algorithms, scored against the evaluation's expert answers (strict match).

    Matches the expert
    OCL AI Assistant's primary pick 14 / 20
    AutoMatch's proposal (score order) 8 / 20
    Expert code anywhere in the candidates 17 / 20

    The proposal and the AI's pick differed on 10 rows:

    • 8 rows had a proposal other than the AI's pick. The AI matched the expert on 6 of them (Essential hypertension, Primary osteoarthritis of both knees, Malignant neoplasm of ascending colon, Right inguinal hernia, Anemia in end-stage renal disease, Squamous cell carcinoma of left lung), the proposal on 1 (Gonococcal pericarditis), and neither on 1.
    • 2 rows got no proposal at all although the AI recommended a code: Hematuria (RECOMMEND MF50.4Z, the expert answer) and diet-controlled gestational diabetes (RECOMMEND JA63.Y&XT77; the expert has JA63.2&XY8U).

    On some rows several candidates had rerank scores at or near 100% (Essential hypertension, for one), so the rerank score couldn't separate them. Related: #2593.

  8. added 8 commits that reference this issue on Oct 20, 2026
  9. added a commit that references this issue on Oct 23, 2026
  10. paynejd commented on Oct 26, 2026

    @paynejd
    MemberAuthor

    Docs follow-up: when OpenConceptLab/oclmap#110 ships, update the OCL AI Assistant section of the Matching Algorithms page in OCL Docs (docs/source/oclmap/matching-algorithms.md, from OpenConceptLab/ocl-docs#75). It says the assistant doesn't change which match AutoMatch proposes, which this rule reverses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

component/mapperMapping toolsdecision/ai-readyReady for autonomous AI executionsignal/low-riskSafe to execute with minimal downsidesignal/well-specifiedClear requirements and acceptance criteriastage/triagedAI triage complete — scored and classifiedtype/featureNew or improved functionality

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions