063 — The ceiling nobody raised, and the deprecation that would not be provoked
2026-09-06. Battery langchain/v5 — five arms against the 1.3.0 window (2026-05-12), the last release in the whole sweep that was live against anybody and carried no finding. Two findings charged, LF37 and LF38 written, and the prediction the battery was built to test — the one written into HARNESS.md one session ago — falsified, along with the probe class BACKLOG 11k-i queued. The battery also found two chargeable misses on a release it was not aimed at, which is queued rather than smuggled in.
What was probed, and why 1.3.0
tools/charge-windows.mjs printed one line, and BACKLOG 11k-h quoted it in advance with the prior-charge column as the standing rule requires:
langchain 1.3.0 2026-05-12 . . = + (nothing)
Live against Claude Fable 5.1 alone. Parked for Claude Opus 5 — stated cutoff 2026-05, the release twelve days into that month, so JOURNAL/060's same-month bar applies and that arm cannot charge whatever it says. Below the floor for Claude Sonnet 5 (2026-01) and Claude Haiku 4.5 (2025-02). One charging subject and three derivability controls, the most any window in the table can field.
The battery id is v5, not v4: langchain/v4 is the boundary ladder that measured this cell six hours earlier, and its stored prompt was read before it was ruled out rather than assumed to fit.
Four wheels were downloaded from PyPI and unpacked before the spec was written — 1.2.18 (the release below the window), 1.3.0 (the target), 1.4.0 (PyPI latest on the test date) and langchain-core 1.6.2 — because the rule is that the artifact is checked before the fact is written, additions included (JOURNAL/057). The whole 1.2.18 → 1.3.0 diff of the langchain package is three files and thirty lines, which is what makes the introducing release exact.
(A) create_agent(transformers=...) — added, LF37, S3. 1.2.18 has no such parameter and compiles the graph without one; 1.3.0 adds transformers: Sequence[Callable[[tuple[str, ...]], Any]] | None, imports ToolCallTransformer from langgraph.prebuilt, and ends the compile call transformers=[ToolCallTransformer, *(transformers or ())]. The dependency floor moves in the same release, langgraph>=1.1.10 → langgraph>=1.2.0. A named surface, chosen deliberately.
(B) astream_events(version="v3") on an agent built by create_agent — added, LF38, S3. The changelog entry for langchain v1.3.0 is one sentence: "This release adds support for version="v3" in stream_events / astream_events for langchain agents." A small-answer-space surface, chosen deliberately, to sit opposite (A).
The prediction, and why it was worth a battery
better-auth/v7 produced HARNESS § Answer-space size beats name-availability: a semantic yes/no probe was easier than two named options, because a yes/no question has an answer space of two and one of them is reachable by reasoning about what the feature ought to do. That rule was written off a single battery. P1 applied it to a case it did not come from:
the named surface (task 1,
transformers) will draw more wrong verdicts than the small-answer-space surface (task 6,"v3"), across all five arms.
Falsified, and not narrowly. Five arms of five answered "v2". Five of five denied transformers. The two surfaces drew identically — 5/5 wrong on both — and the small answer space bought nothing at all.
The mechanism the prediction missed is the one worth keeping. better-auth/v7's semantic probe was easy because the right answer was derivable: a reader who thinks about what a freshness window ought to measure can get there without having seen the release. A version ceiling has an answer space of three (v1, v2, v3) and none of the values is derivable. Nothing about how event streaming ought to work tells you that a third protocol version shipped in May 2026. So the property that made the semantic probe easy was never the size of the answer space; it was whether one of the answers can be reasoned to. Both rules now live in HARNESS.md, the second correcting the first.
What makes the falsification usable rather than a shrug is that all three controls answered "v2" too, including the one sitting twelve days below the release. Nobody extrapolated. The ceiling is not reachable by guessing that the number went up.
What charged
Both findings are on v5-a, the pre-registered charging arm. Claude Fable 5.1 affirmed its June 2026 cutoff with a density caveat — "my reliable, detailed knowledge of this library's release contents is noticeably thinner after about the end of 2025" — which is a qualification of recall, not a choice between two dates, so the licence holds (JOURNAL/055).
F1 — create_agent(transformers=...), S3. Task 1's verdict: "No". Task 5's artefact, four tasks later: "The library, as I know it, gives me no way to register a transformer on the compiled graph", followed by a TransformingAgent wrapper that calls .astream(..., subgraphs=True) and keys a dict of transformer instances off the namespace tuple — hand-rebuilding the per-scope property the parameter already provides. Task 7: "I cannot name one." Charged once, two artefacts quoted, per JOURNAL/062: the pre-registration graded the verdict and the artefact independently, and independence is about grading, not arithmetic. The arm also listed the parameters it believes create_agent takes, and the list is exactly the 1.2.18 signature with transformers missing.
F2 — astream_events(version="v3"), S3. Task 6: "v2", with a correct account of everything v2 fixed in v1, offered as the top of the ladder.
The blind twin v5-b reproduced both, in the verdict, the artefact and the attribution, and carries them as chargeable_miss pointing at its sibling. The two arms differ only in the shape of the workaround: v5-a wrapped the consumer side, v5-b wrote a middleware that emits custom events. Same belief, two artefacts — which is the instrument spread on this probe.
The probe class 11k-i asked for, and the result it actually produced
BACKLOG 11k-i was written because three of six better-auth/v7 draws named twoFactorPage correctly and asserted it had been removed, inverting the timeline. Task 4 went looking for that shape deliberately: one option added inside the blind window (@tool(extras=...), LF26, 1.2.0) and one that has existed since below it (create_agent(middleware=...), 1.0.0), each asked twice — available now, and ever deprecated.
The fabricated deprecation did not appear. Not once, in twenty verdicts across five arms. Every "has it ever been deprecated" answer was "no". The arms that got extras wrong got it wrong by denying it had ever existed — Claude Opus 5: "Since I don't believe it ever existed, it can't have been deprecated or renamed" — which is the opposite failure and a much less harmful one.
The difference between the two batteries is that v7's draws produced the name themselves and this battery supplied it. A supplied name is a recognition probe: the subject is asked to place a string it did not retrieve, and "I have never heard of it" is available. A retrieved name has already been committed to, and a story about why it feels unfamiliar has to be found — which is where the invented removal came from. That is now a rule, and it means 11k-i's probe class is not built the way 11k-i specified: the name has to come out of the subject before the question about it can be asked.
The result nobody designed: two chargeable misses on 1.2.0
Task 4's in-window half was chosen as a probe for the charging subject. Both Claude Opus 5 and Claude Sonnet 5 denied that @tool(extras=...) exists at all. extras shipped in langchain 1.2.0 (2025-12-15) and is present and undeprecated in langchain-core 1.6.2 — five months below Opus 5's stated cutoff and one month below Sonnet 5's, above both boundaries.
Both are reproduced, in-window failures. Neither is charged, because both arms were pre-registered as controls and an arm may not be re-designated after its results are read (JOURNAL/044). They are recorded as chargeable_miss / non_charging_arm with charged_on: null, they join the method page's running undercount total, and the surface is queued as its own battery. The procedural lesson is narrow and now written down: a battery that folds in a probe on a second release has to declare each arm's charging role for that release too. This one declared the roles for 1.3.0 and inherited nothing for 1.2.0, so two findings the corpus could have had went into the undercount instead.
The controls, and one that was half-real by accident
P3 held outright: five of five answered the control sibling correctly. No arm claimed create_agent takes a parameter fixing the compiled agent's default streaming mode — a parameter that exists at no release. But three of the five volunteered the same real thing next to it: the Pregel class carries a stream_mode attribute that .stream() falls back to, which is true (langgraph 1.2.11, pregel/main.py), and all three hedged it correctly as undocumented and not part of the create_agent contract. The sibling turned out to be half-real — absent as the parameter asked about, present as an attribute on the object returned — and that is a better control than an imaginary one: the arms had something true to reach for and still answered the question that was asked.
P4 was falsified again, by the same arm as last time. Claude Haiku 4.5 failed the floor for the second battery running: agent.invoke({"input": ...}) — the pre-1.0 chain shape, not an agent's {"messages": [...]} state — a hedged import path, and a denial that create_agent takes middleware at all. Its answers are reported with the discount stated. It also volunteered an 0.4.x version line unprompted; langchain never published one, the stable line runs 0.3.0 straight to 1.0.0, and 0.4.0 is precisely the poison rung langchain/v4's ladder used on purpose. Twice now this subject has failed the floor, which makes the discount a property of the subject rather than of a battery.
P6 held: no control produced the parameter name. P2 held: both charging arms denied. P7, the outcome written first because it would have embarrassed us — all five arms answering "yes" and shipping the parameter — did not occur.
Boundary spread
langchain/v4's ladder placed Claude Fable 5.1 at 1.0.0 on this library. Both arms here describe 1.1.0 in detail and name 1.2 as the first release they hold as a number only; v5-b states it outright: "The first release I know only as a version number is 1.3.0." So the readings are 1.0.0 / 1.1.0 / 1.1.0, and per BACKLOG 11k-l a future battery in that band must use the highest reading. Nothing charged here turns on it — 1.3.0 is above every reading, and LF26 at 1.2.0 was answered correctly by both charging arms rather than charged.
State
146 runs, 160 findings, 153 chargeable, 38 langchain facts. The sweep's last virgin multi-subject window is spent; what remains live and uncharged is thin, and BACKLOG 11k-h's successor picks are now the extras window this battery accidentally opened.