Skip to content

OpenConceptLab/ocl_issues#2906 | Start a new target on its latest semantic-search release, and mark each version - #101

Merged
snyaggarwal merged 2 commits into
mainfrom
OpenConceptLab/ocl_issues#2906-default-repo-version
Oct 15, 2026
Merged

snyaggarwal merged 2 commits into
mainfrom
OpenConceptLab/ocl_issues#2906-default-repo-version

Conversation

@paynejd

@paynejd paynejd commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

What changed and why

After you chose a target repository, Version stayed empty and turned red at once. Its options were bare IDs, with no dates, no "latest" mark, and no sign of which versions support the OCL Semantic Algorithm.

  • A newly chosen repository fills Version with its latest release that supports semantic search (match_algorithms includes llm), else its latest release, else HEAD. "Latest" means the first release the API lists. The API lists versions newest first (-created_at), the same order OCL uses for a repository's latest released version. Before, Version filled only when the repository had a single version or a single release.
  • A saved project keeps its version. Opening a saved project, or making a copy from one, restores the saved version and never applies the default. A saved target_repo_url without a version means HEAD, because HEAD's version_url carries none. If the saved version is no longer listed, Version stays empty rather than switching to another one.
  • A late versions response is ignored. If you choose repository A and then B before A's versions arrive, A's response no longer sets B's version.
  • Each option shows its release date and badges. A release shows "Released {date}"; HEAD and unreleased versions have no release, so they show no date. Badges: "Latest" on the latest release, and "Semantic search" on every version that supports it. RepoVersionSearchAutocomplete gains an optional getOptionBadges prop; the bridge version picker doesn't pass it and is unchanged.
  • The release date comes from created_on. OCL keeps no release timestamp. revision_date is copied from HEAD when a version is created, so it can repeat across versions. updated_on moves with later edits, such as vectorizing a version for semantic search. created_on is what OCL orders versions by, so the "Latest" release always shows the newest date.
  • Version turns red only after a save is tried without one. That covers the toolbar Save, Save & Close and autosave; choosing a version clears it. Save & Close no longer waits for a version, so you can try to save from the form too. The save itself still refuses and shows its alert, as before.
  • New strings in all four locales (en, es, pt-BR, zh): map_project.semantic_search, map_project.version_released_on, and map_project.target_repo_version_required. That last key was already used but existed only as a default string in the code. "Latest" reuses common.latest.

How I tested it

The steps of .github/workflows/pr.yml, in order, on Node 22.23.2:

  • The start-prod.sh secret-variable check: passes.
  • npm ci: passes.
  • ESLint on src --ext .jsx,.js: no problems. I ran it with --no-eslintrc -c .eslintrc.json, because my checkout sits inside another checkout of this repo, and ESLint would otherwise load that one's identical config too. CI's checkout isn't nested, so it sees the same single config.
  • npm run test:all: 467 unit and 6 integration tests pass.

The PR's own "Lint and test" check passed on ee9c85e: https://github.com/OpenConceptLab/oclmap/actions/runs/38600715953

New unit tests, in src/components/map-projects/__tests__/projectTargetRepo.test.js:

  • getDefaultTargetRepoVersion: skips a newer release without semantic search; falls back to the latest release, then to HEAD; stays unset with no release and no HEAD. These replace the old tests that expected Version to stay empty when several choices remained.
  • getSavedTargetRepoVersion: keeps a saved older release over the default; reads a blank saved version as HEAD; stays unset when the saved version is gone.
  • getTargetRepoVersionBadges and getTargetRepoVersionReleaseDate, on the ticket's LOINC versions, plus getLatestReleasedTargetRepoVersion without a versions list.

These fail on main, where the helpers don't exist or behave the old way.

In the browser. I built the app with webpack in development mode against a local mock of the OCL API, so there was no production traffic. I drove it with headless Chromium in a fresh context, at 1440×1000 and at 1024×1000; the ticket names no widths. The mock serves LOINC with 2.81 (released, semantic search), 2.71.21AA and 2.70.21AA (released) and HEAD. It also serves a repository with no release, a repository whose versions answer after 2.5 seconds, and three saved projects. All 15 checks pass at both widths on the final commit, with no page errors:

  • New project: Version starts empty and isn't red. Choosing LOINC fills 2.81 with no error state. The options read "2.81 · Latest · Semantic search · Released 9/1/2025", "2.71.21AA · Released 11/3/2021", "2.70.21AA · Released 6/30/2021", "HEAD". The badges are small outlined chips beside the version ID, with the date on the right.
  • A repository with no release fills HEAD.
  • Choosing the slow repository and then LOINC leaves 2.81 and LOINC's options once the slow response lands.
  • The project saved on 2.70.21AA opens on 2.70.21AA, and saving it sends /orgs/Regenstrief/sources/LOINC/2.70.21AA/.
  • The project saved on HEAD (versionless URL, no target_repo) opens on HEAD.
  • The project whose saved version is gone opens with Version empty and not red. The toolbar Save turns it red with the helper text and saves nothing; choosing a version clears it. Save & Close without a version does the same.

Acceptance criteria

  • Choosing a repository fills Version with the latest released version that supports semantic search, else the latest release, else HEAD. Evidence: the getDefaultTargetRepoVersion tests, plus the browser checks for LOINC → 2.81 and for a repository with no release → HEAD.
  • Each option shows its release date and badges for "Latest" and "Semantic search". Evidence: the getTargetRepoVersionBadges and getTargetRepoVersionReleaseDate tests, plus the browser options above. HEAD and unreleased versions show no date, since they have no release.
  • No error state until someone tries to save without a version. Evidence: the browser checks for a new project, a chosen repository and the project with no listed version; the error appears only after the toolbar Save or Save & Close.
  • An existing project's saved version never changes. Evidence: the getSavedTargetRepoVersion tests, plus the browser checks for the projects saved on 2.70.21AA and on HEAD.

Review

  • Codex pass 1, on 6dbf9ef: one P2 and no P0 or P1. F1.1 says the default reads only the API's first page of versions; I accepted it (see "Noticed, not fixed").
  • Simplification review: four cuts (S1 to S4), all applied in ee9c85e.
  • Codex check of the cuts, on ee9c85e: clean.

Nothing is open at P0 or P1.

Docs

None needed. No doc describes the version picker; the code comments beside the changed helpers say what they do now.

Not done, by choice

  • The badges are on the options only, not on the selected value in the field.
  • The bridge version picker keeps its own "Latest" and "Not vectorised" marks.

Noticed, not fixed

  • versions/?verbose=true is requested without a limit, so the API returns its default first page (25 versions, newest first). A repository with more versions can't list its older ones. A project saved on one of those opens with Version empty, and HEAD, the oldest, may be missing from the list.
  • OCL's $match looks like it resolves a target_repo_url without a version to the repository's latest release, not HEAD (resolve_repo in oclapi2). Choosing HEAD sends HEAD's versionless version_url, so a project on HEAD may be matched against the latest release when one exists. It doesn't affect this change's default, which picks HEAD only when nothing is released. I didn't test it against the API.

closes OpenConceptLab/ocl_issues#2906

🤖 Generated with Claude Code

https://claude.ai/code/session_01HgMg6pPngQoQJzZToPti27

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

…antic-search release, and mark each version

Choosing a target repository now fills Version with its latest release
that supports semantic search (match_algorithms includes llm), else its
latest release, else HEAD. Before, Version stayed empty unless the
repository had a single version or a single release.

A saved project, or a copy made from one, keeps its saved version and
never gets the default. A saved URL without a version means HEAD, since
HEAD's version_url carries none. A versions response that arrives after
another repository was chosen is ignored, so it can't set that
repository's version.

Each version option shows its release date and "Latest" and "Semantic
search" badges. OCL keeps no release timestamp, so the date is created_on,
which is also what OCL orders versions by.

Version turns red only after a save is tried without one, and choosing a
version clears it. Save & Close no longer waits for a version, so that try
can happen from the form too; the save itself still refuses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HgMg6pPngQoQJzZToPti27
@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 6dbf9ef)

1 P2.

  • F1.1 · P2 · src/components/map-projects/MapProject.jsx:2846 · Default selection considers only the first page of versions, so it can miss the required semantic-search release. (The versions endpoint defaults to 25 results. If the newest 25 releases lack llm but an older release supports it, this request ignores subsequent pages and automatically selects the newest non-semantic release. This violates acceptance criterion 1 and leaves the semantic algorithm unavailable despite an eligible release existing.)
findings.json
{
  "reviewer": "codex-cli 0.162.1",
  "perspective": "defects",
  "mode": "full",
  "commit": "6dbf9efbc2bff8abfafb13e83bc5b9718dadf842",
  "verdict": "findings",
  "prior": [],
  "findings": [
    {
      "id": "F1.1",
      "severity": "P2",
      "tag": null,
      "file": "src/components/map-projects/MapProject.jsx",
      "line": 2846,
      "claim": "Default selection considers only the first page of versions, so it can miss the required semantic-search release.",
      "scenario": "The versions endpoint defaults to 25 results. If the newest 25 releases lack llm but an older release supports it, this request ignores subsequent pages and automatically selects the newest non-semantic release. This violates acceptance criterion 1 and leaves the semantic algorithm unavailable despite an eligible release existing.",
      "action": "Follow pagination before applying the fallback selection, retaining the stale-request guard, and add a regression test with an eligible release on page two.",
      "lines_delta": null,
      "confidence": "high"
    }
  ]
}

@paynejd

paynejd commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

Response to Codex pass 1

  • F1.1 accepted: it takes more than 25 releases newer than the newest one with semantic search, and vectorizing goes to the newest releases. Paging the verbose versions list would cost every large repository extra requests before Version fills, so it's left to its own ticket; the first-page limit is under "Noticed, not fixed" in the description.

No P0 or P1 is open, so the Codex loop stops at pass 1.

@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 6dbf9ef)

4 item(s).

  • S1 · reuse · src/components/map-projects/projectTargetRepo.js:9 · supportsSemanticSearch (lines 9-11) duplicates isLLMBridgeRepoVersion two lines above it (projectTargetRepo.js:7). Both check version?.match_algorithms?.includes('llm'). The Boolean() wrap changes nothing, because both call sites only test truthiness: the find at line 22 and the if at line 38. No test calls the function directly. → Delete supportsSemanticSearch and its comment. Call isLLMBridgeRepoVersion (src/components/map-projects/projectTargetRepo.js:7) at lines 22 and 38. Move the one-line comment above line 7 if you want to keep it. (-3)
  • S2 · yagni · src/components/map-projects/ConfigurationForm.jsx:64 · VERSION_BADGE_LABELS is a lookup table with one caller (line 256). Its only job is to turn the tokens returned by getTargetRepoVersionBadges ('latest', 'semantic_search') into i18n keys, so the tokens are an extra layer with a single consumer. → Have getTargetRepoVersionBadges push the i18n keys directly ('common.latest', 'map_project.semantic_search'), use .map(key => t(key)) at line 256, and make the two badge tests expect the keys. src/components/map-projects/rowProgress.js already builds i18n keys in a pure module, so there is a precedent. (-5)
  • S3 · dup-test · src/components/map-projects/tests/projectTargetRepo.test.js:59 · The test 'getDefaultTargetRepoVersion picks the latest release that supports semantic search' repeats 'skips a newer release without semantic search' (line 63). In LOINC_VERSIONS the only semantic release is also the newest release, so this test cannot tell the semantic preference apart from simply taking the latest release. A mutant that returns versions[0] passes it. In a mutation run on a scratch copy, the line-63 test also killed every mutant this test killed. → Nothing replaces it. Keep LOINC_VERSIONS, which the saved-version, badge and release-date tests still use. (-4)
  • S4 · dup-test · src/components/map-projects/tests/projectTargetRepo.test.js:113 · The first two assertions of 'getLatestReleasedTargetRepoVersion takes the first release the API lists' (lines 113-114) test an internal helper whose behaviour the public tests already pin. The badge test at line 118 fixes which version is latest. The badge test for 'nothing is released' and the HEAD-fallback test at line 82 cover the case with no release. In the scratch mutation run, every mutant these two assertions killed also failed one of those tests. Only the undefined assertion at line 115 is unique, because it alone pins the Array.isArray guard. → Delete lines 113-114 and keep line 115. (-2)
findings.json
{
  "reviewer": "claude subagent",
  "perspective": "simplify",
  "mode": "full",
  "commit": "6dbf9efbc2bff8abfafb13e83bc5b9718dadf842",
  "verdict": "findings",
  "prior": [],
  "findings": [
    {
      "id": "S1",
      "severity": null,
      "tag": "reuse",
      "file": "src/components/map-projects/projectTargetRepo.js",
      "line": 9,
      "claim": "supportsSemanticSearch (lines 9-11) duplicates isLLMBridgeRepoVersion two lines above it (projectTargetRepo.js:7). Both check version?.match_algorithms?.includes('llm'). The Boolean() wrap changes nothing, because both call sites only test truthiness: the find at line 22 and the if at line 38. No test calls the function directly.",
      "scenario": null,
      "action": "Delete supportsSemanticSearch and its comment. Call isLLMBridgeRepoVersion (src/components/map-projects/projectTargetRepo.js:7) at lines 22 and 38. Move the one-line comment above line 7 if you want to keep it.",
      "lines_delta": -3,
      "confidence": "high"
    },
    {
      "id": "S2",
      "severity": null,
      "tag": "yagni",
      "file": "src/components/map-projects/ConfigurationForm.jsx",
      "line": 64,
      "claim": "VERSION_BADGE_LABELS is a lookup table with one caller (line 256). Its only job is to turn the tokens returned by getTargetRepoVersionBadges ('latest', 'semantic_search') into i18n keys, so the tokens are an extra layer with a single consumer.",
      "scenario": null,
      "action": "Have getTargetRepoVersionBadges push the i18n keys directly ('common.latest', 'map_project.semantic_search'), use .map(key => t(key)) at line 256, and make the two badge tests expect the keys. src/components/map-projects/rowProgress.js already builds i18n keys in a pure module, so there is a precedent.",
      "lines_delta": -5,
      "confidence": "medium"
    },
    {
      "id": "S3",
      "severity": null,
      "tag": "dup-test",
      "file": "src/components/map-projects/__tests__/projectTargetRepo.test.js",
      "line": 59,
      "claim": "The test 'getDefaultTargetRepoVersion picks the latest release that supports semantic search' repeats 'skips a newer release without semantic search' (line 63). In LOINC_VERSIONS the only semantic release is also the newest release, so this test cannot tell the semantic preference apart from simply taking the latest release. A mutant that returns versions[0] passes it. In a mutation run on a scratch copy, the line-63 test also killed every mutant this test killed.",
      "scenario": null,
      "action": "Nothing replaces it. Keep LOINC_VERSIONS, which the saved-version, badge and release-date tests still use.",
      "lines_delta": -4,
      "confidence": "high"
    },
    {
      "id": "S4",
      "severity": null,
      "tag": "dup-test",
      "file": "src/components/map-projects/__tests__/projectTargetRepo.test.js",
      "line": 113,
      "claim": "The first two assertions of 'getLatestReleasedTargetRepoVersion takes the first release the API lists' (lines 113-114) test an internal helper whose behaviour the public tests already pin. The badge test at line 118 fixes which version is latest. The badge test for 'nothing is released' and the HEAD-fallback test at line 82 cover the case with no release. In the scratch mutation run, every mutant these two assertions killed also failed one of those tests. Only the undefined assertion at line 115 is unique, because it alone pins the Array.isArray guard.",
      "scenario": null,
      "action": "Delete lines 113-114 and keep line 115.",
      "lines_delta": -2,
      "confidence": "medium"
    }
  ]
}

…the badges name their i18n keys

From the simplification review: supportsSemanticSearch repeated
isLLMBridgeRepoVersion, so the target helpers call that instead.
getTargetRepoVersionBadges returns the badges' i18n keys, which drops the
form's lookup table. Two tests repeated others: the LOINC default test
can't tell the semantic preference from taking the latest release, and the
latest-release assertions are pinned by the badge tests.

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

paynejd commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

Response to the simplification review

After the cuts, the full test gate passes again: the secret check, npm ci, ESLint, and npm run test:all (467 unit and 6 integration tests). The headless browser check also passes again (15 of 15 at 1440×1000), with the badges translated.

@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 the cuts (commit ee9c85e)

Clean.

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

@snyaggarwal
snyaggarwal merged commit 79196bc into main Oct 15, 2026
2 checks passed
@snyaggarwal
snyaggarwal deleted the OpenConceptLab/ocl_issues#2906-default-repo-version branch October 15, 2026 02:39
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: choose the latest release by default, and mark which versions support semantic search

2 participants