Skip to content

OpenConceptLab/ocl_issues#2872 | auto match should not run when no algos are configured and/or without any existing candidates - #92

Merged
snyaggarwal merged 4 commits into
mainfrom
issues#2872
Oct 6, 2026
Merged

snyaggarwal merged 4 commits into
mainfrom
issues#2872

Conversation

@snyaggarwal

Copy link
Copy Markdown
Contributor

Linked Issue

Closes OpenConceptLab/ocl_issues#2872

… are configured without any existing candidates
@snyaggarwal
snyaggarwal requested a review from paynejd October 5, 2026 15:29
@snyaggarwal snyaggarwal self-assigned this Oct 5, 2026
@snyaggarwal snyaggarwal changed the title OpenConceptLab/ocl_issues#2872 | auto match should not run when algos are configured without any existing candidates OpenConceptLab/ocl_issues#2872 | auto match should not run when no algos are configured and/or without any existing candidates Oct 5, 2026

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, Sunny. I reviewed this against the acceptance criteria in OpenConceptLab/ocl_issues#2872, and Codex reviewed it independently; its review follows this one. Lint and all 418 tests pass locally at 6c96eaf, as in CI.

Where it stands: criteria 1–3 are met, and 6 is met in the normal cases. The empty-run guard (4 and 5) covers a project with no algorithm, but not one whose algorithms this user can't run. That's the one change I'd make before merging.

Before merge

  • Algorithms the user can't run (inline, on hasAutoMatchWork): if a project's only algorithm is a bridge or ScispaCy that the person opening it can't run, Auto Match still starts a run that does nothing and records it as failed, 0/0. That's the ticket's symptom again. Codex's finding 2 is the same issue.
  • Copy (one-click suggestions on en): the new strings should name the OCL AI Assistant, as the newer quota strings do ("OCL AI Assistant calls"), and avoid "AI recommendations". es and zh need the same change; those catalogs already use "asistente de IA de OCL" and "OCL AI 助手". The older preview_estimate_ai_* strings (lines 518–520) have the same problem, and AI-only runs now show them too. Fixing those here or in a later PR are both fine.

Smaller

  • A rerank throttle shouldn't mark an AI-only run partial (one-click suggestion on attribution.js): this is Codex's finding 5.
  • Opening the dialog scans every row (inline, on onGetCandidates): it takes about 0.25–0.5 s per open on a 2,000-row project, for everyone with AI access. It's also why the count goes stale while the dialog is open (Codex's finding 3).
  • Codex's findings 1 and 4 are real, but each needs narrow timing. Finding 1 needs a Stop and a restart while an AI call is still in flight, and finding 4 needs a candidate response that lands mid-run and restores an earlier pool. Codex rates 1 as P1; I'd treat both as follow-ups. For 1, the AI step's stage writes could get the same isCurrentRun() guard that processBatch already gives algorithm stages through setStage.

Comment thread src/components/map-projects/MapProject.jsx Outdated
Comment thread src/components/map-projects/MapProject.jsx Outdated
Comment thread src/services/attribution.js Outdated
Comment thread src/i18n/locales/en/translations.json Outdated
Comment thread src/i18n/locales/en/translations.json Outdated
Comment thread src/i18n/locales/en/translations.json Outdated

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Codex adversarial review, pass 1 (codex-cli 0.160.1, commit 6c96eaf)

Read-only, reasoning effort xhigh, given the acceptance criteria in OpenConceptLab/ocl_issues#2872. Posted verbatim; file references link to this commit. The review above says which findings I'd fix before merge.


The PR fixes the original empty-algorithm case, but does not fully satisfy OpenConceptLab/ocl_issues#2872. Five findings, ranked by severity:

  1. [P1] Stopped AI requests can corrupt a later run’s counts — src/components/map-projects/MapProject.jsx:5802. Stop run A while row 0’s AI request is pending, then start B on rows 0–1. B’s row 0 fails; A’s late success overwrites its shared recommend stage while B processes row 1. B then records completed 2 / failed 0, instead of completed 1 / failed 1, partial. Reproduced using the extracted functions with deferred responses. Fix: associate AI stage, failure and quota writes with a captured run ticket, or maintain outcomes per run.

  2. [P2] Configured but unavailable algorithms still permit empty runs — src/components/map-projects/MapProject.jsx:2910. Load a project containing only a bridge with canBridge=false, or ScispaCy with canScispacy=false. With AI off, the guard accepts Submit and opens an AutomatchRun, but the executor skips retrieval; it closes failed, 0/0. With AI on, successful recommendations still produce failed, 0/0, because the selected algorithm prevents aiOnly classification. Fix: use executable algorithms consistently for dialog availability, work detection and run classification.

  3. [P2] AI eligibility freezes when the dialog opens — src/components/map-projects/MapProject.jsx:2899. Start a manual AI request, then open Auto Match before it finishes and choose AI only. When the manual request succeeds, the dialog still says analyze 1 / skip 0 and enables Submit. Submit recomputes eligibility and rejects the run. Candidate changes can conversely leave useful work blocked. Fix: derive eligibility from current analysis and candidate state while the dialog is open.

  4. [P2] Skipped AI rows can count as newly completed analyses — src/components/map-projects/MapProject.jsx:5842. A row has an earlier analysis for pool A and currently has pool B, so the AI-only prefilter includes it. A pending manual candidate response restores pool A before AI processing. fetchRecommendation skips invocation but writes recommend=1 because analysis history exists. The run records completed 1 despite zero AI invocations; reproduced in memory. Fix: distinguish skipped rows from successful invocations in run accounting.

  5. [P2] Unrelated rerank outcomes affect AI-only completion — src/services/attribution.js:175. A background manual rerank finishes throttled during an AI-only run. Every AI invocation succeeds, but stage.rerank === -4 makes the run partial. Fix: ignore rerank stages when aiOnly is true.

Acceptance criterion Verdict
1. No algorithms: warning, Configure, retrieval off/disabled Met
2. AI-only analyze/skip counts match actual work Partly met — correct for stable state; eligibility freezes
3. Messages update with scope and checkboxes Met — recomputed from the cached eligibility set
4. Block only empty runs, with a reason Partly met — unavailable algorithms bypass blocking; stale eligibility can block work
5. Empty runs open no AutomatchRun Partly met — original case guarded; unavailable algorithms remain a counterexample
6. AI-only completion reflects AI work Partly met — straightforward success/error/quota cases work; findings 1, 2, 4 and 5 break accounting

Ordinary algorithm submission, AI-only preservation of row statuses, scope filtering and preview caps look clean. No new hook violations or missing en/es/zh keys or placeholders found.

Validation: 412 tests passed; ESLint and diff whitespace checks passed. No files modified; no network used.

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, Sunny, this covers everything from pass 1. I re-reviewed 87c9775 against those items and OpenConceptLab/ocl_issues#2872, and Codex ran a second pass (posted next). Lint and all 423 tests pass locally, as in CI.

Pass-1 item At 87c9775
Algorithms the user can't run Fixed. canRunAlgorithm drives the dialog, hasAutoMatchWork and _selectedAlgos, so isAIOnly and the run record match what runs.
OCL AI Assistant naming Fixed in en, es and zh, including the older preview_estimate_ai_* strings.
Rerank throttle in an AI-only run Fixed, with a test.
Opening scan and frozen count Fixed. Counted only while the dialog shows an AI-only run, and recounted as analyses or candidates change. One dependency is missing (inline).
Codex 1: a late AI result corrupting the next run Fixed. Superseded calls leave stages and the failure count alone, and an AI-only run is recorded from its own outcomes.
Codex 4: skipped rows counted as analysed Fixed. A skipped row returns null and counts as neither.

I also checked the riskier parts of the commit. No caller used fetchRecommendation's old boolean return. The new memo sits after getAIAnalysableRows, with no early return before it. Every rowMatchStateRef and conceptCacheRef write is paired with its state setter, so the memo sees candidate changes.

Three small items, all one-click:

  • A stopped row can still call the AI (line 5714): Codex pass 2, finding 1. isSuperseded() already covers it.
  • The AI-only count misses the target repo loading (line 5676): Codex pass 2, finding 3.
  • Spanish register (es): the new strings switched to usted, while the strings around them use tú, and the preview estimate joins both into one alert.

Codex's pass-2 findings 2 and 4 come from older shared state, and both need narrow timing:

  • Finding 2: a stopped run's late quota refusal still sets the page-wide AI quota flag.
  • Finding 4: a submit while a single-row AI call is in flight reads the analysis history from before that call lands, so it can analyse the row again.

I'd take both in a follow-up rather than hold this PR. With the three suggestions applied, it's ready from my side.

Comment thread src/i18n/locales/es/translations.json Outdated
Comment thread src/i18n/locales/es/translations.json Outdated
Comment thread src/i18n/locales/es/translations.json Outdated
Comment thread src/components/map-projects/MapProject.jsx Outdated
Comment thread src/components/map-projects/MapProject.jsx Outdated

@paynejd paynejd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Codex adversarial review, pass 2 (codex-cli 0.160.1, commit 87c9775)

Read-only, reasoning effort xhigh, given the acceptance criteria in OpenConceptLab/ocl_issues#2872 and both pass-1 reviews. Posted verbatim, except that file references link to this commit and its "Your #N" labels read "Pass-1 finding N".


Reviewed both diffs at 87c9775. Most pass-1 fixes work, but OpenConceptLab/ocl_issues#2872 is not fully met.

  1. [P1] Stopped AI work can resume under a newer run — src/components/map-projects/MapProject.jsx:5714. Stop A while it awaits a candidate lookup, then start B. B resets abortRef; A’s lookup finishes and A sends an AI invocation, consuming quota with B’s current attribution. Reproduced using extracted functions. Fix: check the captured run ticket after awaits, before sending, and in retry cancellation.

  2. [P2] Late quota responses still corrupt another run’s outcome — src/components/map-projects/MapProject.jsx:5847. Passing null as the row ID prevents stage writes, but handlePreviewLimitError still sets shared quota state. A stopped A’s late quota rejection can make B record completed 2 / failed 0, partial, although both B invocations succeeded. Reproduced. Fix: suppress superseded requests’ run-state writes and retain quota-stop state per run.

  3. [P2] The eligibility memo misses target-repository changes — src/components/map-projects/MapProject.jsx:5676. Open AI-only Auto Match before the asynchronous canonical-URL fetch finishes. For a saved candidate identified by its canonical reference, eligibility changes from zero to one when metadata arrives, but the dialog stays analyze 0 / skip 1 and blocks Submit until scope changes. Reproduced with the actual payload builder and memo expression. Fix: include repository/context and other payload inputs in memo dependencies.

  4. [P2] Execution uses an outdated analysis snapshot — src/components/map-projects/MapProject.jsx:5705. Submit AI-only while a manual analysis is pending; that analysis succeeds before the delayed bulk invocation. The bulk closure still sees the pre-Submit history and analyses the same candidates again, spending another call. Reproduced. Fix: read current analysis through a synchronized ref when filtering rows and immediately before invocation.

The cancellation and analysis-snapshot races already existed at pass 1. The new memo remains incomplete; I found no separate regression in the other areas checked.

Pass-1 item Status at HEAD Location
Reviewer: use executable algorithms consistently Fixed — dialog, guard and executor agree src/components/map-projects/MapProject.jsx:628, :2439, :2916; AutoMatchDialog.jsx:88
Reviewer: OCL AI Assistant naming in en/es/zh Fixed src/i18n/locales/en/translations.json:601; es/translations.json:565; zh/translations.json:590
Reviewer: ignore rerank for AI-only completion Fixed src/services/attribution.js:176
Reviewer: avoid full-project opening scan; keep counts live Partly fixed — scans only the AI-only scope and responds to candidate/analysis changes; finding 3 remains src/components/map-projects/MapProject.jsx:5671
Pass-1 finding 1: stopped requests corrupt later counts Partly fixed — original late-success reproduction now correctly records 1 completed / 1 failed, partial; quota isolation remains incomplete src/components/map-projects/MapProject.jsx:1940, :5847
Pass-1 finding 2: unavailable algorithms permit empty runs Fixed src/components/map-projects/MapProject.jsx:2439, :2916
Pass-1 finding 3: eligibility freezes while dialog is open Partly fixed — manual-success scenario works; repository changes still freeze it src/components/map-projects/MapProject.jsx:5676
Pass-1 finding 4: skipped rows count as completed analyses Fixed — skipped calls return null, excluded from run outcomes src/components/map-projects/MapProject.jsx:2673, :5865
Pass-1 finding 5: rerank affects AI-only completion Fixed src/services/attribution.js:176
Acceptance criterion Verdict
1. No algorithms: warning, Configure, retrieval off/disabled Met
2. Accurate AI-only analyse/skip eligibility Partly met — findings 3–4
3. Messages update with scope and checkboxes Met
4. Block only empty runs, showing the reason Partly met — finding 3 blocks useful work
5. Empty runs open no AutomatchRun Partly met — finding 4 permits a redundant run after its useful work finishes
6. AI-only completion reflects its AI work Partly met — finding 2

Retrieve Candidates state ownership, runnable-algorithm filtering, AI-only row-status preservation, preview-cap and quota-estimate arithmetic, hooks order and TDZ checks are clean. Changed locale keys and placeholders match across en/es/zh.

Validation: 417 unit tests and 6 integration tests passed; ESLint and both diff whitespace checks passed. Adversarial reproductions ran in memory. No files modified; no network used.

snyaggarwal and others added 2 commits October 6, 2026 21:39
Co-authored-by: Jonathan Payne <paynejd@gmail.com>
Co-authored-by: Jonathan Payne <paynejd@gmail.com>
@snyaggarwal
snyaggarwal merged commit 33cc44c into main Oct 6, 2026
2 checks passed
@snyaggarwal
snyaggarwal deleted the issues#2872 branch October 6, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mapper: Auto Match starts a run with no matching algorithm, does nothing, and records it as failed

2 participants