065 — The name that came back unasked, and the workaround that was not broken
2026-09-06. Battery langchain/v6 — six arms against the 1.2.0 tool-extras window (2025-12-15), the surface langchain/v5 created and could not charge. Two findings charged, against Claude Opus 5 and Claude Sonnet 5. The battery's headline prediction held and it is the sharpest instrument result the Index has: withholding the name did not cost the one subject that knew it. Two other pre-registered predictions were falsified, one published fact is corrected from executed code rather than from reading, and BACKLOG 11k-i — the fabricated-deprecation probe class — returned a second null, this time in the configuration it was rebuilt to have.
Why this window, and the debt it settles
tools/charge-windows.mjs, with the prior-charge column quoted in advance as JOURNAL/061 requires:
langchain 1.2.0 2025-12-15 charges sonnet 5 + opus 5 + fable 5.1 control: haiku 4 5
already charged: Claude Fable 5, Claude Opus 5, Claude Sonnet 5
Not a virgin window — three subjects carry findings on it from langchain/v2 — but the @tool(extras=...) surface, published fact LF26, had never been charged against anybody. It became chargeable by accident: langchain/v5 folded a probe on 1.2.0 into a battery designated for the 1.3.0 window, and its Opus 5 and Sonnet 5 control arms both denied extras exists, five months and one month below their own stated cutoffs. An arm may not be re-designated after its results are read (JOURNAL/044), so both went into the undercount and the surface went into the backlog as 11k-n. This battery designates the same two subjects as charging arms in advance, and re-asks under a wording that does not hand over the name.
The artifact check, done before the spec was written
Four langchain-core wheels and one langchain-anthropic wheel, downloaded from PyPI and unpacked: 0.3.22 (2024-12-06), 1.1.3 (2025-12-09, the release below the window), 1.2.0 (2025-12-12, the target), 1.6.2 (2026-09-04, latest) and langchain-anthropic 1.7.1 (2026-09-03).
extras is absent from tools/base.py at 0.3.22 and at 1.1.3, and absent from every tool() overload in tools/convert.py. At 1.2.0 it appears in both files — extras: dict[str, Any] | None = None on the tool and on all five decorator overloads — with the flat docstring example. At 1.6.2 it is unchanged and undeprecated. Note the split the fact records loosely and this entry records exactly: the changelog entry is on the langchain release of 2025-12-15; the artifact is langchain-core 1.2.0 of 2025-12-12. Both December 2025, so no fairness arithmetic turns on which is named.
What charged
F1 on v6-a (Claude Opus 5) and F1 on v6-c (Claude Sonnet 5), both S3. Each denied on task 1 that a tool has any first-class place of its own for provider-specific fields, hand-rebuilt the Anthropic tool definition in task 4 to splice cache_control and defer_loading into a copy, and said on task 6 that no release has ever added such a place. Both blind twins agreed in substance, so the belief is four-for-four across the two charging subjects.
Two artefacts are worth quoting because they are the same shape one library apart. v6-b enumerated what it believes BaseTool carries — "name, description, args_schema, return_direct, response_format, metadata, tags, callbacks, handle_tool_error/handle_validation_error" — and v6-c gave the same list from the other subject. Both lists are the pre-1.2.0 field set with extras the only omission, which is exactly v5-c's seven-parameter enumeration of @tool a battery earlier. A subject that can recite a field list accurately as of the release below the one that changed it is not guessing; it is remembering a version.
The severity, and a rule this battery's own spec left ambiguous
The spec pre-registered S2 where the shipped artefact silently discards the fields and S3 where it delivers them by a working but abandoned route — and then added a sentence, "nothing charges where the shipped code works", that contradicts the S3 clause. That was a drafting fault and it is resolved here against the evidence rather than against the drafting.
The workaround was executed against langchain-core 1.6.2 and langchain-anthropic 1.7.1. Every charging arm's hand-built dict passes through convert_to_anthropic_tool carrying both cache_control and defer_loading, because AnthropicTool is a TypedDict and an already-Anthropic-shaped dict is copied whole. The workaround works. So both findings are S3, not LF26's S2, and the resolution — now in HARNESS.md — is that JOURNAL/030's "a working workaround is not chargeable" governs a probe where the subject was never asked whether the capability exists. Where it is asked and denies, the denial is the finding and the workaround sets the severity. That is also the treatment LF37 already received one battery ago, so this is precedent being written down rather than precedent being made.
What the denial actually costs a reader is what all three denying arms described themselves: the tool is defined twice, once as a callable and once as a schema; the name must be kept in sync by hand or dispatch breaks; and a separate lookup is needed to run the call the model returns. v6-c shipped it without that lookup, so as written its tool can be chosen by the model and never executed.
P2, and the reason this battery exists at all
P2.
v6-e(Claude Fable 5.1) producesextrasunprompted in TASK 4, matching what both itsv5arms produced when the name was handed to them. Falsified if it does not — which would sayv5's two correct answers were recognition rather than recall.
It held. langchain/v5 gave this subject the string extras and asked whether it exists; v6 never says the word anywhere in the sent file. The draw answered task 1 "Yes" and named extras in the same breath, shipped the flat shape — @tool(extras={"cache_control": {"type": "ephemeral"}, "defer_loading": True}), the component the pre-registration marked as not derivable — and placed the field in "the langchain-core 1.1 / 1.2 line, roughly December 2025 to January 2026" against an artifact of 1.2.0 on 2025-12-12.
This is the first time the Index has separated recall from recognition on one subject, one surface and two wordings, and the answer is that the recall was real. It also raises the price of every supplied-name probe in the corpus: v5 could not have told these apart, and neither can any battery that hands over the string.
The below-floor control did its job on the other side of the same question. extras is a plausibly guessable name for "provider-specific extra fields", which is why the spec marked component (i) derivable: partially and put Claude Haiku 4.5 on the battery. Fifteen months under the release, it did not produce the name.
What was falsified
P6 — every arm except Haiku passes the floor. Wrong, and the failure is on a charging arm. v6-c answered task 3 with from langgraph.prebuilt import create_react_agent, calling it the current recommended constructor — the pre-1.0.0 picture, replaced by create_agent in langchain.agents on 2025-10-17. It is self-consistent rather than guessing: that draw placed its own describable boundary at 0.3.x, below 1.0.0. The finding is reported with the discount attached, which is JOURNAL/062's control-discount applied for the first time to a test arm.
And the twins straddle the floor. v6-d, the same subject, the same sent file, the same session, passed — create_agent from langchain.agents, correctly placed against both the LangGraph and the AgentExecutor eras. One pair, one prompt, one boundary at 1.0.0 and one at 0.3.0. The corpus already records a 1.0.0/0.3.0 spread for this subject on this library; this is that spread appearing inside a born-duplicated pair rather than across sessions, which is the cleanest measurement of it yet.
P3 — the rebuilt 11k-i probe. Predicted null, and null it was: no arm asserted that its own task-4 mechanism had ever been deprecated, renamed or removed. That includes v6-e, the one arm in the battery where the probe was in its designed configuration — a correct name, self-produced, held at explicitly moderate confidence, which is the better-auth/v7 shape with nothing missing. It hedged the name ("my confidence that extras is the exact name is moderate, not high") instead of inventing a removal.
So the fabricated deprecation has now failed to reproduce twice, once with a supplied name and once with a self-produced one. The class is not dead, but it is narrower than 11k-i assumed: v7's three draws named an option that was removed from nothing and unfamiliar to them, and neither condition alone is enough. The next attempt should stop trying to provoke it and instead go looking for it in transcripts that already exist.
The fact this battery corrected
The verification step checks our claims too (JOURNAL/035), and executing LF26's own stale forms moved two of them.
- LF26's note said all three recorded wrong forms "fail the same way — nothing raises". Executed:
tool_obj.metadata = {...}and@tool(extras={"anthropic": {...}})are indeed silent, and both come back fromconvert_to_anthropic_toolwith neither field. But@tool(metadata={...}), which is how the fact wrote it, raisesTypeError: tool() got an unexpected keyword argument 'metadata'— the decorator has never takenmetadata. The example is rewritten as the attribute assignment that actually is silent, and the note says so. - A fourth wrong form is now recorded, the one four of six draws produced, with the note that it works and that findings charged off it score S3.
- The mechanism is now cited from the artifact:
_ANTHROPIC_EXTRA_FIELDS={allowed_callers, cache_control, defer_loading, eager_input_streaming, input_examples}in langchain-anthropic 1.7.1, which is the whitelist that liftsextraskeys to the top level of the tool definition. That is also why the nested{"anthropic": {...}}shape is dropped: the wrapper key is not on the list.
Instrument notes, kept small
v6-dopened with a bare "YES" and then wrote "Task 1 answer: No." The one-word-first rule in the preamble appears to have collected the one-word answer. Per JOURNAL/060 both readings are recorded and neither overwrites the other; the arm publishes no verdict for task 1 and charges nothing anyway. A battery reusing the shape should know that a formatting instruction can attract the graded token.- The Sonnet 5 identity probe disagreed with both Sonnet 5 battery arms. Asked tool-free what model it was, it answered "Claude Sonnet 4.5", declined a model id, and gave a cutoff of "roughly early-to-mid 2025" — while both arms of the battery accepted January 2026 with density caveats. Recorded on the runs, used for nothing: the datum that licenses a charge is what the draw states, and back-filling from another draw is barred in both directions (JOURNAL/031).
- The half-real sibling worked as designed and split three ways. No arm invented a provider-schema-format parameter on
@tool(P4 holds). On the nearby true thing they diverged:v6-enamedconvert_to_anthropic_toolinlangchain_anthropic.chat_models— the only correct placement in the battery;v6-anamed it with a hedge that turned out to be unnecessary;v6-cdoubted it exists;v6-dimported it fromlangchain_core, which raises. One function, four different relationships to it. - The below-floor control denied
response_formaton@tool— present since langchain-core 0.3.22, below its own boundary. P5 as written survives (nobody fabricated a deprecation), but the register (JOURNAL/058) says this arm is denying APIs it can see, which bounds what its denial ofextrasis worth.
Where the window stands now
langchain 1.2.0 is spent for the two subjects that could charge on it. The remaining live langchain window in the sweep is 1.1.0 (charges Sonnet 5 and Opus 5, already charged against three subjects from v1–v3). Nothing above 1.3.0 is below any subject's cutoff. Claude Fable 5.1 still has 1.2.0 formally live against it — this battery designated it a control in advance and that designation is fixed — but it answered the surface correctly, so there is nothing there to charge.
Totals: 152 runs, 162 findings, 155 chargeable, 7 libraries.