Public Release, October 2026

H1: The Hidden-Identity
Linking Benchmark

Across a patient's report mentions, does a system keep one continuing finding together, and keep two look-alike findings with the same key apart?

What it is. 400 synthetic worlds. Each world holds 8 to 14 mentions of findings across 3 to 5 reports. A system groups the mentions. A scorer compares the groups with the groups the authors wrote.

What it is not. The worlds are synthetic. The inputs are structured frame slots (oracle frames), not raw report text. The benchmark tests linking only, not extraction. No clinician labelled anything, and the labels encode the scenario the authors wrote. This is not clinical validation.

Ranking caveat. The team that wrote the benchmark also wrote the FindingFrame linker. Its results appear below as author reference baselines and carry no rank.

github.com/Sher110106/findingframe-h1

The Task

A patient has several reports over time. A report may mention the same liver lesion in March and again in June, with different wording. Another report may mention a second lesion at the same site. A tracking system must decide which mentions belong together.

H1 asks for two groupings of every world's mentions:

Plain scope. The inputs are frame slots (finding type, anatomy, laterality, measurement, change, assertion), each with an opaque mention ID. The benchmark gives no patient ID, category ID, or entity ID. The scorer holds the labels, and they come from the authored scenario. They are not clinician judgments.

How It Works

World 8 to 14 mentions 3 to 5 reports 2 to 3 categories Your system sees slots only Category partition Entity partition Scorer holds labels labels travel to the scorer only, never to the system

The system never sees a label. The scorer reports category and entity quality separately, so a system cannot hide a weak entity result behind a strong category result.

The eight v2 families

The test split has 400 worlds, 50 per family. Each world holds a target category and one or two look-alike distractor categories.

Source: DATA_CARD.md and the contracts/ folder in the repository.

Metrics

Why v2 exists. In v1, every test world held one gold category. A system that put every mention of a world in one group scored a category F1 of 1.000, and a category merge error could not happen. We found this on 2026-09-27, while reviewing an interim look at v1 results. v2 puts 2 to 3 categories in every world, so merging distinct findings now costs as much as splitting one. Read v1 results only with this flaw in mind. We keep v1 in the repository, marked as flawed. Only v1 train and dev worlds ship. There is no v1 test split in the repository. Every v1 test world had one gold category. In the shipped v1 dev data, two families hold more than one: laterality_change (two categories in all 100 worlds) and report_order_permutations (two in 51 of 100).

In v2 the same one-group baseline scores a category F1 of 0.676, and the one-group-per-mention baseline scores 0.344. Trivial baselines sit beside every model result below for this reason.

Results on the v2 Test Split

Read this before using the scores.
  • Simple rules solve the Category axis. The strict-laterality ablation scores 1.000, and so does a rule written by hand from the public contract.
  • Entity is the axis that separates systems.
  • That hand-written rule reached Entity F1 0.955 on the private test labels. This is above every published row (the best is 0.927, the strict-laterality ablation).
  • Treat v2 as a diagnostic of linking behaviour. It is not a leaderboard.
  • Raw-text v3 is planned to remove this ceiling.

All rows use the same 400 test worlds. GLM answered 342 of them. GLM spent its whole token budget on reasoning in all three tries for the other 58. Those worlds stay in the denominator and score as unresolved singletons. This earns partial credit, not zero: mean category F1 on the 58 failed GLM worlds is 0.326. The rows labelled "author reference baseline, unranked" come from the linker the benchmark authors wrote. Do not compare a model against them as if they were an independent entrant.

Method Category F1 Cat. split Cat. merge Entity F1 Ent. split Ent. merge Unresolved
Trivial baselines (no model, no key logic)
One group per world0.676 CI [0.669, 0.682]0.0000.5390.599 CI [0.590, 0.608]0.0000.6280.000
One group per mention0.344 CI [0.340, 0.348]1.0000.0000.392 CI [0.385, 0.398]1.0000.0000.000
Raw surface equality0.603 CI [0.594, 0.612]0.5470.4370.575 CI [0.567, 0.584]0.5530.5680.000
Language models (author runs)
DeepSeek-v4.1-flash, category partition0.925 CI [0.911, 0.938]0.1420.0000.852 CI [0.840, 0.864]0.1420.1760.000
DeepSeek-v4.1-flash, entity partition0.886 CI [0.875, 0.898]0.2550.0010.888 CI [0.876, 0.900]0.1700.0880.000
GLM-5.3-flash, category partition (342 of 400 answered)0.850 CI [0.825, 0.873]0.2450.0000.780 CI [0.759, 0.801]0.2450.1710.145
GLM-5.3-flash, entity partition (342 of 400 answered)0.818 CI [0.795, 0.840]0.3350.0000.817 CI [0.794, 0.839]0.2540.0890.145
Author reference baselines, unranked (written by the team that wrote the benchmark)
Exact normalized key0.920 CI [0.906, 0.933]0.1510.0000.847 CI [0.835, 0.860]0.1510.1760.000
Compatibility linker0.947 CI [0.933, 0.960]0.0930.0000.874 CI [0.860, 0.888]0.0930.1760.000
Strict laterality (ablation)1.000 CI [1.000, 1.000]0.0000.0000.927 CI [0.918, 0.937]0.0000.1760.000
Descriptor comparator0.909 CI [0.895, 0.922]0.1770.0000.858 CI [0.845, 0.871]0.1510.1500.000
No anatomy hierarchy (ablation)0.913 CI [0.898, 0.928]0.1510.0430.841 CI [0.827, 0.854]0.1510.2190.000

Cohort: 400 v2 test worlds, 50 per family. Source: results/v2_test_results.json (systems.*.overall). Means are over worlds, and CIs come from the bootstrap in the same file. A model's category-partition row and entity-partition row are two separate outputs from one model, so each row shows all columns for that output.

How to read it. The one-group-per-world baseline merges everything and gets an entity merge of 0.628. The one-group-per-mention baseline splits everything. A useful result has to beat both, on both axes. The strict laterality ablation scores 1.000 on categories, so the top category result on v2 is a rule, not a model.

Paired contrasts against the author baselines

Contrast Difference
DeepSeek category partition minus compatibility linker, category F1, all 400 worlds−0.022 CI [−0.026, −0.018]
GLM category partition minus compatibility linker, category F1, all 400 worlds−0.097 CI [−0.114, −0.081]
DeepSeek entity partition minus exact key, entity F1, all 400 worlds+0.041 CI [+0.031, +0.050]
GLM entity partition minus exact key, entity F1, all 400 worlds−0.030 CI [−0.049, −0.011]

Source: results/v2_test_results.json, contrasts (mean difference and 95% CI, paired world bootstrap, equal-family weights, 10,000 draws).

What the numbers support

Scope note: these are results for two models, one prompt, temperature 0, on synthetic oracle-frame worlds. Each world got one run, except that GLM had up to three attempts per world. They say nothing about extraction from real reports.

Run It Yourself

A clean machine can install the package, run a smoke test, score a model on the development set, and build a test submission. Each step is one command.

git clone https://github.com/Sher110106/findingframe-h1 && cd findingframe-h1
python -m venv .venv && source .venv/bin/activate
pip install -e ".[openai,test]"
pytest -q
h1bench smoke
h1bench baselines --split dev

export OPENAI_API_KEY=...
h1bench run --split dev --base-url https://api.openai.com/v1 --model gpt-4o-mini
h1bench score --split dev predictions_dev_gpt-4o-mini.jsonl

h1bench run --split test --base-url https://api.openai.com/v1 --model gpt-4o-mini
h1bench make-submission predictions_test_gpt-4o-mini.jsonl --model "gpt-4o-mini"

h1bench run calls any OpenAI-compatible endpoint and writes a predictions file named predictions_<split>_<model>.jsonl (change it with --out). h1bench score scores the development set locally, because its labels are public. h1bench make-submission checks the test predictions and writes submission.json.

The repository README lists the full options for each command.

Submitting a Model

Test labels stay private. If they were public, systems could tune to the test set. The maintainer scores test submissions instead.

What stays private. Test labels, per-world scores and predictions, generator code and seeds, and the FindingFrame production modules. The exact-key, compatibility, strict-laterality, and descriptor baselines therefore appear as results only.

Limits and Roadmap

Stated limits.
  • The inputs are oracle frames. A system never has to read report text, so H1 cannot say how a system performs on real reports.
  • The worlds are synthetic and authored. The labels encode the authors' intent, and no clinician checked them.
  • The same team wrote the benchmark and the FindingFrame linker. That is why its rows carry no rank.
  • Six of the eight families are solvable on categories from the raw slots alone. In 300 of 400 test worlds, grouping by the exact slot tuple matches the gold categories. The two granularity families, and the entity axis, carry the harder tests.
  • One of the two LLMs failed to answer 58 worlds. GLM's unresolved mention rate by family: 0.36 in granularity_with_laterality_distractor, 0.32 in granularity_with_organ_distractor, 0.22 in same_site_different_type, 0.18 in laterality_pair_same_type, 0.06 in episode_reuse_with_distractor, 0.02 in simultaneous_distinct_with_distractor, and 0.00 in the other two.

We promise no dates.