All findings · Lucene finding · LFV-948 · changes-10-6-0-advertises-stabletfl-k3-removed-by-backport

The Lucene 10.6.0 release notes say StableTflSimilarity also supports k3, but 10.6.0 has no k3

The 10.6.0 release notes say the new StableTflSimilarity "also supports k3 query-term frequency saturation", but the 10.6.0 class has no k3: new StableTflSimilarity(1.2f, 0.917f, 7f) does not compile. The 10.6 backport had left k3 out and dropped this sentence on purpose; a later, unrelated backport put the sentence back.

Summary

Priority
Low, rank 1270A released 10.6.0 release-notes sentence advertises a k3 parameter the release lacks, which fails loudly at compile time only for opt-in experimental StableTflSimilarity users.
Impact
minor
Since
10.6.0 (the sentence came back on the 10.x branch in 3a75616c943, 2026-07-08)introduced 2026-07-08
Affected
the 10.6.0 release notes (CHANGES.txt, the Changes page); still on branch_10_6 and in main's 10.6.0 section
Status
documented
Found by
semi-formal: a check of the 10.6.0 release notes against the 10.6.0 jars, then git history

AI-assisted page: this finding was first signalled by a semi-formal check (an exact check of the real jar, or a modelling hypothesis that a tool then witnessed) and then checked with AI tools; the checks it went through, and what each found, are under Prior reports, history and checks. Not yet triaged by a human. Snapshot of 2026-11-06.

The finding in 30 seconds

One sentence in the 10.6.0 release notes describes code that is only on main.

Background: k3 and the release notes

  1. k3 is a BM25-style knob for queries that repeat a word: with k3 set, a term that appears n times in the query weighs ((k3 + 1) * n) / (k3 + n) instead of n. With k3 = 7 and n = 2 that is 16/9 = 1.78 instead of 2. On main, BooleanQuery applies this weight only when it merges unboosted duplicate SHOULD clauses (with minimumShouldMatch <= 1) or MUST clauses, as for the query a a; boosted duplicates keep their linear sum (BooleanQuery.java:438-454, 740-746).
  2. lucene/CHANGES.txt has one section per release. Main keeps a copy of each stable release's section, and the two copies are meant to match each other and what was actually backported to that release.
Diagram of the bug: the Lucene 10.6.0 release notes entry for StableTflSimilarity ends 'It also supports k3 query-term frequency saturation.' An application writes new StableTflSimilarity(1.2f, 0.917f, 7f) against lucene-core 10.6.0 and javac fails with 'no suitable constructor found for StableTflSimilarity(float,float,float)', because the 10.6.0 class has only the (k1, c) and () constructors; main's class has the (k1, c, k3) constructor. A timeline shows the 10.6 backport #16322 removing k3 and the sentence on 2026-07-01, and the #16300 test backport re-adding the sentence on 2026-07-08, before 10.6.0 was released.
The notes and the code side by side: the 10.6.0 entry says StableTflSimilarity "also supports k3", but new StableTflSimilarity(1.2f, 0.917f, 7f) fails javac against 10.6.0, which has only (k1, c) and (); the timeline shows #16322 removing the sentence and the #16300 backport bringing it back. Select the still to open it at full size. Generated with AI, checked against the code.

The finding, step by step

  1. You read the Lucene 10.6.0 release notes. The entry for the new StableTflSimilarity (GITHUB#16243) ends: "It also supports k3 query-term frequency saturation." k3 caps how much a word repeated in a query counts.
  2. You write new StableTflSimilarity(1.2f, 0.917f, 7f) (the default k1 and c, plus k3 = 7) against lucene-core 10.6.0. You expect it to compile, as it does on main, and a query term typed twice (two unboosted SHOULD clauses, the query a a) to count 16/9 (about 1.78x) instead of 2x.
  3. Instead javac stops: "no suitable constructor found for StableTflSimilarity(float,float,float)", and there is no getK3(). The 10.6.0 class has only the (k1, c) and () constructors; a term typed twice counts 2.0x.
  4. Why: k3 exists only on main (the future 11.0). The 10.6 backport (#16322) left it out and, on the feature author's review request, removed this sentence. A week later a test-only backport rewrote the entry back to main's wording, and 10.6.0 shipped with it.

Who is affected

Developers adopting the new, opt-in, experimental StableTflSimilarity on 10.6 who read the release notes: the advertised k3 constructor and getK3() fail to compile, and 10.6 has no built-in saturation of repeated query terms. No wrong results and no runtime or index effect. Unfixed, every later CHANGES file (10.6.1, 11.0) repeats the sentence.

Mechanism, terms and numbers538 words

The 10.6.0 New Features entry for GITHUB#16243 reads: "Add StableTflSimilarity, a similarity that estimates term rarity from term length and document length instead of corpus statistics such as document frequency. It also supports k3 query-term frequency saturation. (Tianxiao Wei)". The second sentence describes main (the future 11.0), not 10.6.0. The 10.6.0 class has only the (k1, c) and () constructors and no getK3(), and 10.6.0's Similarity lacks the computeQueryTermWeight hook that k3 needs. The 10.x backport #16322 left k3 out on purpose ("remove k3 which isn't in 10") and, at the feature author's request in review, dropped the sentence as well. A week later 3a75616c943, the 10.x backport of a test-only change (#16300), rewrote the entry back to main's wording in one of its CHANGES hunks. branch_10_6 inherited the sentence, 10.6.0 shipped with it (CHANGES.txt and the published Changes page), and main's copy of the 10.6.0 section has the same sentence. It is a documentation defect: nothing runs differently, and code written from the notes fails loudly at compile time. The fix is to delete the sentence from the 10.6.0 entry on main and branch_10_6.

The claim

  • On main 645d4fe14a20, CHANGES.txt:456 is the Lucene 10.6.0 heading and CHANGES.txt:506-508 is the GITHUB#16243 entry ending "It also supports k3 query-term frequency saturation." The release 10.6.0 has the same text at CHANGES.txt:56-58, and the published 10.6.0 Changes page shows it.

What 10.6.0 has

  • StableTflSimilarity.java at the 10.6.0 tag: the class javadoc lists only k1 and c (lines 45-49), @lucene.experimental (line 54), and the constructors (float k1, float c) (line 96) and () (line 117). There is no k3 field, constructor or getter.
  • 10.6.0's Similarity has no computeQueryTermWeight, so no 10.6 similarity can apply k3.

What main has

  • StableTflSimilarity.java on main: the javadoc bullet "k3 - query-side saturation for repeated query terms (disabled by default)" (line 50), DEFAULT_K3 = -1f (line 66), the (float k1, float c, float k3) constructor (line 110), computeQueryTermWeight with ((k3 + 1) * qtf) / (k3 + qtf) (lines 159-163) and getK3() (line 362).
  • It overrides the main-only hook Similarity.computeQueryTermWeight (Similarity.java:175), which came with GITHUB#15818, listed in main's 11.0.0 section (CHANGES.txt:172, "Add BM25 k3 query-term frequency saturation to BM25Similarity").

How the sentence got into 10.6.0

  1. 2026-07-01, main, e3a7a733c8a (#16243, txwei): the entry is written under main's 10.6.0 heading with the k3 sentence. True of main's class.
  2. 2026-07-01, the #16322 review (the 10.x backport): on lucene/CHANGES.txt txwei asked to "remove the last part of supporting k3" and mccullocht replied "Done"; txwei also wrote "This major difference between the 10x backport and main is k3 is not supported on 10x".
  3. 2026-07-01, branch_10x, 8e40c912555 (#16322): "remove k3 which isn't in 10". The entry ends "...such as document frequency. (Tianxiao Wei)". Correct.
  4. 2026-07-08, branch_10x, 3a75616c943 (dweiss, "Backport changes to TestTermInSetQuery. #16300", pushed directly): its CHANGES diff adds the #16300 entry and, in a separate hunk, rewrites the #16243 entry's second line to main's wording, which brings the k3 sentence back. The message does not mention it.
  5. 2026-10-14: branch_10_6 is cut from branch_10x and inherits it. The sentence survives the release manager's changelog clean-ups of 2026-10-20/21 (f79709fd57e, 7cecf795236), which do not touch this entry. 2026-10-26: RC1 4ae946e5a9b, released as 10.6.0.
Exposure and likelihood155 words
  • Who reads it: everyone who reads the 10.6.0 notes: CHANGES.txt in the source release, changes/Changes.html in the release folder, and the website's 10.6.0 Changes page.
  • Who is hit: developers who adopt StableTflSimilarity on 10.6 and want k3. It is new in 10.6.0, not the default similarity, and @lucene.experimental.
  • What they get: a compile error as soon as they try the advertised constructor or getK3(); someone who reads only the notes may plan for a feature that arrives in 11.0.
  • What does not happen: no wrong results, no exception at run time, no index effect. Without k3 a repeated query term keeps its linear weight, which is normal 10.x behaviour.
  • Scale: one sentence in one release line (10.6.x). On main the sentence is text only, since main's class has k3. The released 10.6.0 files stay as released; the fix corrects the 10.6.0 section that 10.6.1 and 11.0 will carry.

Minimal repro

One JUnit test, one method, no index, nothing random: it asks whether StableTflSimilarity has a public constructor with 3 parameters, a stand-in for the (k1, c, k3) constructor the 10.6.0 notes advertise. It fails on 10.6.0 and passes on main, which has k3.

TestStableTflSimilarityK3.java (one test class)31 lines
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.lucene.search.similarities;

import java.lang.reflect.Constructor;
import java.util.Arrays;
import org.apache.lucene.tests.util.LuceneTestCase;

public class TestStableTflSimilarityK3 extends LuceneTestCase {

  public void testK3ConstructorAdvertisedByChanges() {
    Constructor<?>[] ctors = StableTflSimilarity.class.getConstructors();
    boolean hasK3 = Arrays.stream(ctors).anyMatch(c -> c.getParameterCount() == 3);
    // 10.6.0 CHANGES (GITHUB#16243) "also supports k3": expected a (k1, c, k3) constructor
    assertTrue("expected StableTflSimilarity(k1, c, k3); actual: " + Arrays.toString(ctors), hasK3);
  }
}
Command
cd $LUCENE && ./gradlew :lucene:core:test --tests org.apache.lucene.search.similarities.TestStableTflSimilarityK3 -Ptests.seed=DEADBEEF -Ptests.asserts=true
Expected
The test passes: the 10.6.0 notes say StableTflSimilarity supports k3, so a 3-parameter (k1, c, k3) constructor should exist, as it does on main.
Observed
AssertionError: expected StableTflSimilarity(k1, c, k3); actual: only StableTflSimilarity(float,float) and StableTflSimilarity().

All files of this repro: repro/LFV-948/

More files, environment, full output335 words

The test counts parameters only: on main the only 3-parameter constructor is (float k1, float c, float k3) (StableTflSimilarity.java:110), and 10.6.0 has none. Because it does not check the parameter types, the javac error, which names the exact (float,float,float) constructor and getK3(), is the stronger evidence. Reflection is used only so the same file compiles on both lines (10.6 and main); the user-facing symptom is the javac error of new StableTflSimilarity(1.2f, 0.917f, 7f), shown in the full output below. The result does not depend on the seed or on assertions.

No regression test applies. The fix is a CHANGES.txt edit. After it, this test still fails on branch_10_6 (the class correctly has no k3) and passes on main either way, so it is evidence, not a regression test.

Environment

lucene10.6.0 (`4ae946e5a9b9`, tag releases/lucene/10.6.0): fails; main `645d4fe14a20` (11.0.0-SNAPSHOT): passes (main has k3)
jdkOpenJDK 25.0.3
osLinux aarch64 (the only platform run)
Command (environment)
cd $LUCENE && git checkout releases/lucene/10.6.0      # or branch_10_6
cp $REPRO/TestStableTflSimilarityK3.java $LUCENE/lucene/core/src/test/org/apache/lucene/search/similarities/
./gradlew :lucene:core:test --tests org.apache.lucene.search.similarities.TestStableTflSimilarityK3 -Ptests.seed=DEADBEEF -Ptests.asserts=true
# same failure with -Ptests.asserts=false

Observed output

# gradle on a worktree of releases/lucene/10.6.0 (4ae946e5a9b), seed DEADBEEF, -Ptests.asserts=true (identical with false)
TestStableTflSimilarityK3 > testK3ConstructorAdvertisedByChanges FAILED
    java.lang.AssertionError: expected StableTflSimilarity(k1, c, k3); actual: [public org.apache.lucene.search.similarities.StableTflSimilarity(float,float), public org.apache.lucene.search.similarities.StableTflSimilarity()]
:lucene:core:test (FAILURE): 1 test, 1  failure
BUILD FAILED

# released 10.6.0 jars (Maven Central, core sha1 9b71af62d7d3b5b99235187514a0d4d74817ccdd), standalone, -ea and -da: FAIL tests_run=1 failures=1, same message
# main 645d4fe14a20: PASS tests_run=1 failures=0 (main has k3)

# the user-facing symptom: javac of a two-line program against the same 10.6.0 jar (excerpt: path prefix, caret lines and javac's 'argument lists differ' / 'location' lines left out; every line shown is verbatim)
UseAdvertisedK3.java:8: error: no suitable constructor found for StableTflSimilarity(float,float,float)
    StableTflSimilarity sim = new StableTflSimilarity(1.2f, 0.917f, 7f);
    constructor StableTflSimilarity.StableTflSimilarity(float,float) is not applicable
    constructor StableTflSimilarity.StableTflSimilarity() is not applicable
UseAdvertisedK3.java:9: error: cannot find symbol
    System.out.println(sim + " k3=" + sim.getK3());
  symbol:   method getK3()
2 errors
# on main the same program compiles and prints: StableTflSimilarity(k1=1.2, c=0.917, k3=7.0) k3=7.0

Why it looks unintended

  • The 10.6 backport removed k3 on purpose, and its review asked to drop this very sentence ("remove the last part of supporting k3" / "Done").
  • A test-only backport (#16300) put it back; its message does not mention this entry.
  • Lucene's own tooling asks release entries to match "what changes were actually backported".
The full argument176 words
  • Removed on purpose. 8e40c912555 (#16322): "non-trivial integrations: symbol renames and remove k3 which isn't in 10". Review on lucene/CHANGES.txt: txwei, "remove the last part of supporting k3"; mccullocht, "Done". txwei, in a PR comment that says the changes LGTM: "This major difference between the 10x backport and main is k3 is not supported on 10x".
  • Re-added, most likely by accident. 3a75616c943 (dweiss) backports a TestTermInSetQuery change (#16300) and has no PR of its own; besides adding the #16300 entry, one hunk of its CHANGES diff rewrites the #16243 entry's second line to main's wording, and its message does not mention #16243. Why is not recorded, so "by accident" is an inference.
  • Release sections describe the release. dev-tools/scripts/diff_lucene_changes.py:24-29: keep main's and the stable branch's entries "identical and 2) matching what changes were actually backported to be honest to users". The 10.6 class javadoc itself lists only k1 and c.
  • Precedent. Main's 10.6.0 section listed GITHUB#16794, which is not in 10.6.0; #16912 (mayya-sharipova, merged 2026-10-26, "Move CHANGES entry for GITHUB#16794 from 10.6.0 to 11.0.0") moved it.
The devil's-advocate check157 words

Strongest case for leaving it: CHANGES is an informal summary; the authoritative 10.6 javadoc is correct; the sentence is literally true of main, where its author wrote it; the class is experimental; and the failure is a loud compile error that hurts no one, so it is a cosmetic nit.

Why it fails: it is not a wording slip but a false feature claim under the 10.6.0 heading, the exact claim the maintainers chose to drop for 10.x. Experimental status lets the API change between releases; it does not make the notes describe an API the release lacks. And the sentence is now on the published 10.6.0 Changes page and would be copied into every later CHANGES file. An independent reviewer from another model family (OpenAI GPT-5.6, reading only) rated the 'intended' argument weak; the earlier refute review's "not real" was procedural (it could not execute) and it called the evidence a genuine documentation discrepancy.

Suggested fix

Recommended Delete the k3 sentence from the 10.6.0 entry (validated)

Delete "It also supports k3 query-term frequency saturation." from the 10.6.0 GITHUB#16243 entry on main and branch_10_6, restoring the text #16322 merged. Validated: the CHANGES-vs-release-jar check fails before and passes after (-ea, -da); gradle renders the fixed CHANGES.txt.

@@ -504,8 +504,7 @@
   enable with IndexWriterConfig#setMaxDocValuesOverlays(n). (Jim Ferenczi)
 
 * GITHUB#16243: Add StableTflSimilarity, a similarity that estimates term rarity from term length
-  and document length instead of corpus statistics such as document frequency. It also supports k3
-  query-term frequency saturation. (Tianxiao Wei)
+  and document length instead of corpus statistics such as document frequency. (Tianxiao Wei)
 
 * GITHUB#16371, GITHUB#14389: Add CaseFoldingFilter for Unicode simple case folding without
   requiring the ICU analysis plugin. Uses a generated switch for fold exceptions with
All options and trade-offs2 options · 366 words

One CHANGES.txt edit, the same three lines on both branches. The released 10.6.0 files stay as they are; the fix shows from 10.6.1's and 11.0's CHANGES on. branch_10x needs nothing: it was decommissioned on 2026-10-29 (#16911). Optionally, main's 11.0.0 section can then say that StableTflSimilarity has k3 there.

Delete the k3 sentence from the 10.6.0 entry (validated) (recommended)

Main's copy (CHANGES.txt:506-508 at 645d4fe14a20) and branch_10_6's (CHANGES.txt:56-58 at the 10.6.0 tag; today lines 63-65, below the new 10.6.1 section). The sibling LFV-957 (the 10.6.0 CheckIndex entry cites GITHUB#17820 instead of GITHUB#7820) is in the same section.

@@ -504,8 +504,7 @@
   enable with IndexWriterConfig#setMaxDocValuesOverlays(n). (Jim Ferenczi)
 
 * GITHUB#16243: Add StableTflSimilarity, a similarity that estimates term rarity from term length
-  and document length instead of corpus statistics such as document frequency. It also supports k3
-  query-term frequency saturation. (Tianxiao Wei)
+  and document length instead of corpus statistics such as document frequency. (Tianxiao Wei)
 
 * GITHUB#16371, GITHUB#14389: Add CaseFoldingFilter for Unicode simple case folding without
   requiring the ICU analysis plugin. Uses a generated switch for fold exceptions with

Trade-offs

None in code. After it, main's CHANGES.txt says nowhere that StableTflSimilarity has k3 (see the next option).

What the checks validated

In a scratch worktree of 645d4fe14a20 (OpenJDK 25.0.3): the diff applies and the 10.6.0 section then has no k3 line; the CHANGES-vs-release-jar text check (the 10.6.0 GITHUB#16243 entry against the released 10.6.0 core jar) fails on stock main's CHANGES.txt and passes on the fixed one, -ea and -da; ./gradlew :lucene:documentation:changesToHtml renders the entry without the sentence; :lucene:core:test with the repro and TestStableTflSimilarity passes, 15 tests, assertions on and off (main has k3, so this only shows nothing breaks). The branch_10_6 diff applies to the 2026-10-29 branch head with a 7-line offset.

Also say in main's 11.0.0 section that StableTflSimilarity has k3 (optional, not run)

A new 11.0.0 line, or extend the GITHUB#15818 entry (CHANGES.txt:172, "Add BM25 k3 query-term frequency saturation to BM25Similarity") to name StableTflSimilarity too. No CHANGES or MIGRATE.md text says today that k3 was left out of 10.6.

Trade-offs

Wording and placement are the committers' call; on main, StableTfl's k3 came with #16243 itself, so either placement needs a short explanation.

Downstream note

Downstream search servers had no reference to StableTflSimilarity when searched (Elasticsearch, OpenSearch, Solr, 2026-10-28), so no downstream setting builds on the advertised k3.

How it was found

Semi-formal. A probe checked the class and method names cited in the 10.6.0 release notes against the 10.6.0 jars and flagged k3; a finder then wrote a differential checker of the CHANGES entry against the release jar's class files, with a fixed-text control, and traced the sentence through git history.

The method in full161 words
  • Probe: a name-level check of all 39 Class#method and 129 class references in the RC's 10.6.0 section against the RC jars found no other missing API; javap of the RC core jar showed StableTflSimilarity with only (float,float) and (), and a probe calling new StableTflSimilarity(1.2f, 0.917f, 7f) ran on main and was a compile error on the RC.
  • Finder (a hunt unit): a claim checker that reads a CHANGES file's 10.6.0 GITHUB#16243 entry and scans the release jar's class files (MISMATCH for the RC text and for main's 10.6.0 text against the RC jar; CONSISTENT for the fixed text and for main's text against main's jar), the git provenance (git log -S, blame), and a public-API JUnit test.
  • Verification: an independent reproducer, an independent reviewer from another model family (OpenAI GPT-5.6) and an intended-behaviour devil's advocate all called it real; an adjudication confirmed it (high). The repro was then reduced to one test with one assertion.

Prior reports, history and checks

Prior reports

No public report found (2026-10-28: 100 scripted queries and 22 manual GitHub searches, the RC1 vote thread, open PRs' CHANGES patches; rechecked 2026-11-01). The closest item is the #16322 review that removed the sentence before merge: the statement of intent.

Searches2 searches

Nobody has reported that the 10.6.0 entry advertises k3. Related, not this bug: #16322 (the 10.x backport and its review), #16243 (the feature on main, where the sentence is true), #15818 and #15768 (BM25 k3, 11.0), #16912 (moved another main-only entry out of main's 10.6.0 section; precedent), the commits@ mails of 3a75616c943 and 7cecf795236 (no discussion), and tracking issue #16937, which lists no individual bugs.

Recheck 2026-11-01: the sentence is still on main f815e679bf6c (lines 537-539) and branch_10_6 91eaab4fb298 (lines 63-65). Searches for StableTfl issues, k3 issues and PRs updated since 2026-10-28 and "CHANGES 10.6.0" since 2026-10-29 returned nothing; the only StableTflSimilarity PRs are #16243 and #16322.

What was searched, when, and what turned up
WhereWhenHowFound
GitHub issues, PRs and commits (apache/lucene incl. the migrated JIRA archive), downstream repositories (Elasticsearch, OpenSearch, Solr), dev@/java-user@/issues@/commits@ lists, the web2026-10-28scripted prior-report search, two runs (45 and 55 queries), plus 22 manual GitHub searches incl. the last 48 h; the CHANGES/MIGRATE patches of all 189 open PRs updated since 2026-07-01 and of every PR open or updated since 2026-10-26; all 12 mails of the RC1 vote threadnothing reporting the sentence; nearest: #16322 (its review removed it), #16243, #15818, #15768, #16912
apache/lucene upstream (GitHub API: branch heads, raw CHANGES.txt, search, #16322 comments)2026-11-01branch heads and the GITHUB#16243 entry on main and branch_10_6; GitHub search for StableTfl, StableTflSimilarity, k3 and "CHANGES 10.6.0" since 2026-10-28/29still present on both branches; no new issue or PR

History

Introduced on the 10.x line by 3a75616c943 (2026-07-08, the #16300 test backport), which re-added the sentence #16322 had removed a week earlier; 10.6.0 shipped with it. Main's 10.6.0 section has carried it since #16243. 9.x and 10.0.0-10.5.2 have no such class or entry.

Versions tested6 rows

A CHANGES-vs-release-jar text check (the 10.6.0 GITHUB#16243 entry as it stood at each commit, against the 10.6.0 core jar) passes at 8e40c912555 (#16322) and at d60e550b47f (the commit before 3a75616c943) and fails from 3a75616c943 on, through the branch_10_6 fork point 3e416dce059, RC1 and the last branch_10x head before branch_10x was decommissioned (2026-10-29); StableTflSimilarity.java on the 10.x line never had k3. git log -S 'It also supports k3' on branch_10_6 finds only 3a75616c943. On main the sentence dates from e3a7a733c8a (#16243), where it is true of main's class.

Versions and branches executed, with results
Version or commitVerdictResult
10.6.0 (4ae946e5a9b9, released) affectedthe minimal test fails 1 of 1 through gradle on the tag and on the Maven Central jars (assertions on and off); javac of new StableTflSimilarity(1.2f, 0.917f, 7f) fails; the sentence is in CHANGES.txt:56-58 and on the published Changes page
branch_10_6 head 91eaab4fb298 textsentence still at CHANGES.txt:63-65 (2026-11-01)
main 645d4fe14a20 (and f815e679bf6c) text onlythe 10.6.0 section carries the sentence (lines 506-508; 537-539 today); main's class has k3, so the minimal test passes; the text check against the 10.6.0 jar fails
branch_10x 8e40c912555 to d60e550b47f not affectedentry without the k3 sentence; the text check passes
9.x, 10.0.0 to 10.5.2 class absentno StableTflSimilarity and no entry (compile error on 9.12.3, 10.5.0 and 10.5.2)
main + fix not affectedthe 10.6.0 section has no k3 line; the text check passes (-ea, -da)

Independent checks

Confirmed (high) by an adjudication after an independent reproducer, a reviewer from another model family and a devil's advocate all called it real; re-run on main 645d4fe14a20 and, for this doc, on the released 10.6.0 jars.

Checks and verdicts310 words

Every verifier re-ran a failing check on the 10.6 jars and a passing one on main. The only "not real" verdict came from the refute review, which could not execute and said so.

Each independent check and its verdict
CheckVerdictWhat it found
Finder (claim checker, git provenance, JUnit) reproduced, documentation defectJUnit 2 of 2 fail on the RC jars (-ea, -da), pass on main; claim checker MISMATCH for the RC and main 10.6.0 texts, CONSISTENT for the fixed text.
Cross-model refute review (OpenAI GPT-5.6, reading only) not real (low, procedural)Could not execute; called the static evidence a genuine documentation discrepancy and the intended argument weak. Its point that no MIGRATE.md or 11.0 note mentions k3 was accepted.
Independent reproducer realOwn JUnits fail on branch_10_6 and the official RC1 jars (-ea, -da), pass on main; the text check fails on main's CHANGES and passes with the sentence deleted; the user program fails javac on RC1.
Cross-model adversary (OpenAI GPT-5.6, intended lens, reading only) real (medium)Intended argument weak: experimental status permits API change, not advertising a missing feature. Root cause and fix agreed.
Intended-behaviour devil's advocate real (high)The strongest 'intended' case fails against the #16322 decision; re-ran the JUnit, the claim checker with the official RC1 jar and a user-style compile check.
Adjudication confirmed (high)Re-ran the text check on live main's CHANGES.txt (fails -ea, -da; passes with only the sentence deleted) and the code-level JUnit (fails on branch_10_6, passes on main).
This doc's runs (released 10.6.0 jars, fix check) reproduced; fix validatedMinimal test fails 1 of 1 through gradle on the 10.6.0 tag and on the Maven Central 10.6.0 jars, assertions on and off; passes on main; the text check flips from fail to pass with the fix.

Diagram file

The diagram as a still image, generated with AI and checked against the code. It is under 10 MB, the limit for a GitHub attachment.

Sources and provenance

Finding record, Lucene and upstream sources, repro files and diagram notes1,442 words

Finding record

LFV-948, snapshot of 2026-11-06

Registry title
The Lucene 10.6.0 release notes (CHANGES.txt in the 10.6.0 RC1 and in main's copy of the 10.6.0 section) say StableTflSimilarity 'also supports k3 query-term frequency saturation', but 10.6.0 has no k3: the 10.6 backport left k3 out and dropped the sentence on review request, and an unrelated later backport put the sentence back (documentation defect, released in 10.6.0)
Area
release notes / lucene/CHANGES.txt 10.6.0 New Features (GITHUB#16243 entry) x search / similarities (StableTflSimilarity)
Priority
Low, rank 1270: A released 10.6.0 release-notes sentence advertises a k3 parameter the release lacks, which fails loudly at compile time only for opt-in experimental StableTflSimilarity users.
Impact class
minor
Impact note
Documentation only, in the notes of 10.6.0 (released 2026-10-29): every reader of the 10.6.0 CHANGES.txt or Changes page is told that the new, @lucene.experimental, opt-in StableTflSimilarity supports k3, but the 10.6.0 class has only the (k1, c) and () constructors, so code written from the notes (new StableTflSimilarity(k1, c, k3), getK3()) fails to compile and a repeated query term keeps its linear weight; no wrong results, no runtime or index effect, and no earlier release is affected.
Summary
You read the Lucene 10.6.0 release notes, whose GITHUB#16243 entry says StableTflSimilarity 'also supports k3 query-term frequency saturation', and write new StableTflSimilarity(1.2f, 0.917f, 7f) against the 10.6.0 jar. You expect it to compile, as it does on main; instead javac finds no (float, float, float) constructor and no getK3(), because the 10.x backport (#16322) deliberately left k3 out ('remove k3 which isn't in 10') and, on the feature author's review request, also dropped the k3 sentence, which a later, unrelated backport commit (3a75616c943, the #16300 backport) put back. The sentence ships in the RC1 source release's CHANGES.txt and Changes.html and is also in main's copy of the 10.6.0 section.
Introduced
3a75616c9437 (branch_10x, 'Backport changes to TestTermInSetQuery. #16300', by dweiss; a direct push with no PR of its own): its CHANGES hunk adds the #16300 entry and also rewrites the second line of the #16243 entry back to main's wording, re-adding the k3 sentence that the 10.x backport 8e40c912555 (#16322, by mccullocht, 2026-07-01) had removed on review request; branch_10_6 inherited it at its fork point 3e416dce059 (2026-10-14) [exec: the CHANGES-vs-release-jar check passes at 8e40c912555 and at the parent d60e550b47f and fails from 3a75616c943 on, -ea and -da; read: git log -S 'It also supports k3' on branch_10x/branch_10_6 finds only 3a75616c943, blame of branch_10_6 4ae946e5a9b CHANGES.txt:56-58 gives line 56 to 8e40c912555 and lines 57-58 to 3a75616c943]. Main's copy of the 10.6.0 section has carried the sentence since the feature commit e3a7a733c8a (#16243, by txwei, 2026-07-01), where it is true of main's class; it became wrong for 10.6.0 when #16322 left k3 out of 10.x, and the release manager's clean-ups f79709fd57e (branch_10_6, 2026-10-20) and 7cecf795236 (main, 2026-10-21) left it in place [read] (2026-07-08 (author and commit date of 3a75616c943, 2026-07-08T18:54:34+02:00); wording origin on main e3a7a733c8a, 2026-07-01; branch_10_6 cut from branch_10x 2026-10-14)
First affected version
10.6.0 (released 2026-10-29 from RC1, built from branch_10_6 4ae946e5a9b; tag releases/lucene/10.6.0). StableTflSimilarity and the GITHUB#16243 entry do not exist in 9.x or 10.0.0-10.5.2 [exec: compile error on 9.12.3, 10.5.0 and 10.5.2; read: 0 mentions of 16243 in their CHANGES.txt]
Affected versions
10.6.0 RC1 [exec: the official staged artifacts (rev 4ae946e5a9b): the source tarball's lucene/CHANGES.txt (lines 56-58, byte-identical to git) and changes/Changes.html carry the sentence; javap of the checksum-verified lucene-core-10.6.0.jar shows only StableTflSimilarity(float, float) and (), no getK3; the finder's and the independent reproduction's JUnits fail 2 of 2 with -ea and -da on these jars and on the locally built branch_10_6 4ae946e5a9b jars]; branch_10x from 3a75616c943 to its head [exec at 3a75616c943, the fork point 3e416dce059 and 1309534296e; read: head 657014b3c57, line 83]; main's copy of the 10.6.0 section [exec: main a9779ef3c193 CHANGES.txt:496-498 checked against the RC1 core jar fails with -ea and -da; exec 2026-10-29: main 645d4fe14a2 CHANGES.txt:506-508, same result], text only on main, whose class does have k3 (the code-level JUnits pass 2 of 2 on main). Not affected: 9.x and 10.0.0-10.5.2 (class absent; exec on 9.12.3, 10.5.0 and 10.5.2) and branch_10x between 8e40c912555 and d60e550b47f [exec]. All runs JDK 25.0.3 on Linux aarch64
Status
documented (brief, checks and a per-finding doc exist)
Verification
Confirmed by AI-run checks: an independent repro, a cross-model review that could only read the code (its low-confidence “not real” is procedural), an intended-behaviour check, a prior-report search and a skeptical audit; not yet triaged by a person.
Found by
semi-formal
Upstream and prior reports
none found (searched 2026-10-28: two scripted prior-report searches (45 and 55 queries over GitHub issues and PRs, commits, downstream repositories, dev@/java-user@/issues@/commits@, the JIRA archive and the web), 22 manual GitHub searches including items of the last 48 h, the CHANGES/MIGRATE patches of all 189 open apache/lucene PRs updated since 2026-07-01 and of every PR open or updated since 2026-10-26, the CHANGES.txt commits since 2026-10-24 on branch_10_6, branch_10x and main (author dates compared), and all 12 mails of the dev@ '[VOTE] Release Lucene 10.6.0 RC1' thread). Nearest items, not this bug: #16322 (the 10.x backport; in its review the feature author asked on lucene/CHANGES.txt to 'remove the last part of supporting k3' and the backporter answered 'Done', so the merged 8e40c912555 entry was correct: intent evidence), #16243 (the feature on main, where the sentence is true), #15818 and #15768 (BM25 k3 in 11.0), #16912 (moved a different 10.6.0 entry to 11.0.0, merged 2026-10-26: precedent), and the commits@ mails of 3a75616c943 and 7cecf795236 (no discussion). Not fixed upstream. Recheck 2026-10-28: branch_10_6 head still 4ae946e5a9b (sentence at CHANGES.txt:57), branch_10x 657014b3c57 (line 83), main 645d4fe14a2 (line 507); no releases/lucene/10.6* tag; GitHub search for StableTfl and for k3 updated since 2026-10-26: 0 hits; none of the 18 items mentioning CHANGES updated since 2026-10-27 touches the entry; the vote thread still has 12 mails, none about CHANGES; recheck 2026-10-29: heads main 645d4fe14a2, branch_10x 657014b3c57 and branch_10_6 4ae946e5a9b, sentence still present on all three; no 10.6 release tag; no StableTfl or k3 item updated since 2026-10-28
Lucene commit tested
The paste-ready gradle command on a worktree of the 10.6.0 release tag (releases/lucene/10.6.0 = 4ae946e5a9b9, the RC1 commit): the minimal test fails 1 of 1 with assertions on and off, seed DEADBEEF. The same test on the released 10.6.0 jars from Maven Central (core sha1 9b71af62d7d3b5b99235187514a0d4d74817ccdd): fails 1 of 1 with -ea and -da; on main 645d4fe14a20 it passes (main has k3). The two-line user program fails javac against the same 10.6.0 jar. The fix was validated in a scratch worktree of 645d4fe14a20: the CHANGES-vs-release-jar text check fails on stock main's CHANGES.txt and passes on the fixed one (-ea and -da), gradle renders the fixed CHANGES.txt and the StableTfl tests pass. The hunt's checks (2026-10-28) ran on main a9779ef3c193 and branch_10_6 4ae946e5a9b; the 2026-10-29 re-verification and the minimal repro ran on 645d4fe14a20. Upstream state re-read 2026-11-01: main f815e679bf6c and branch_10_6 91eaab4fb298 still carry the sentence. OpenJDK 25.0.3, Linux aarch64.

Lucene and upstream sources

Finding record
  • lucene/CHANGES.txt:446 (Lucene 10.6.0 heading) and :496-498 (#16243 entry with the k3 sentence); lucene/core/src/java/org/apache/lucene/search/similarities/StableTflSimilarity.java:55 (@lucene.experimental), :110 (k1, c, k3 constructor), :362 (getK3)
  • a Lucene clone git: 4ae946e5a9b:lucene/CHANGES.txt:56-58; 4ae946e5a9b StableTflSimilarity.java :96 (k1, c) and :117 () constructors only; commits 3a75616c943 (Dawid Weiss, 2026-07-08), 8e40c912555 (#16322, 2026-07-01), e3a7a733c8a (#16243, 2026-07-01)
  • lucene/CHANGES.txt:456 (10.6.0 heading), :506-508 (the k3 sentence) on main 645d4fe14a2
The finding in 30 seconds
  • a Lucene main checkout (645d4fe14a20) lucene/CHANGES.txt:6, 172, 456, 506-508; lucene/core/src/java/org/apache/lucene/search/similarities/StableTflSimilarity.java:45-55, 66, 110, 159-163, 362; Similarity.java:163-176; lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java:438-454, 740-746
  • a Lucene clone releases/lucene/10.6.0 (4ae946e5a9b) lucene/CHANGES.txt:56-58; StableTflSimilarity.java:45-49, 54, 96, 117; Similarity.java (no computeQueryTermWeight)
  • a Lucene clone git log/blame: e3a7a733c8a, 8e40c912555, 3a75616c943, 3e416dce059, f79709fd57e, 7cecf795236
Who is affected
  • a Lucene clone releases/lucene/10.6.0 StableTflSimilarity.java:54 (@lucene.experimental)
  • a Lucene clone releases/lucene/10.6.0 lucene/distribution/build.gradle:242-258 (Changes.html is assembled into the release folder's changes/ directory)
Why it looks unintended
  • a Lucene clone git show 8e40c912555 (commit message), 3a75616c943 (CHANGES hunk)
  • a Lucene main checkout dev-tools/scripts/diff_lucene_changes.py:24-29
  • GitHub apache/lucene #16912 (read-only API: title, author, merged_at, files); a Lucene clone git log --grep '#16794' (a95c754ee00 on main only; none at releases/lucene/10.6.0)
History
  • a Lucene clone releases/lucene/10.6.0; git log/blame of lucene/CHANGES.txt
Diagrams
  • a Lucene main checkout (645d4fe14a20) lucene/CHANGES.txt:506-508; StableTflSimilarity.java:110, 362
  • a Lucene clone releases/lucene/10.6.0 lucene/CHANGES.txt:56-58; StableTflSimilarity.java:96, 117

Other statements trace to the hunt's working files (models, logs, reviews and briefs), which are not published.

Repro files

About the diagrams

Made in parallel with this doc from the code at 645d4fe14a20 and the 10.6.0 tag, the minimal repro and the executed javac check.

Built 2026-11-06 from the hunt's record of this finding and its doc file. Lucene main under test in this hunt: ea57360912ed. Every listed finding was re-run on Lucene main e1faeba08bde on 2026-11-02.