Repository navigation
fix(render-stats): count no lock in the floor outside kv-unified, and pin the relief rule's failure orders - #4
Open
nissa-seru wants to merge 5 commits into
Conversation
added 5 commits
October 30, 2026 14:19
…lace behind the L1s The relief rule (mergeTakesTurnByRelief) keeps a merge that has failed or been refused before behind the queued L1s, but two of its checks had no case that fails without them: - `(head.attempts ?? 0) > 0`: the refused-once case also sets hadRefusal, which covers it alone. A merge cut off at max_tokens now has a case. - `this.mergeFailureOrder.has(key)`: a merge whose call failed is still at the head of the queue when the lane's pause ends, and without the check it goes first again. A case sets the pause's backoff to 0 and ticks once more. Both run on openOrder, which gains truncateMerges and failFirstMerge. The new cases, and the refused-once case beside them, assert that the merge is still queued after its failed call. Each new case fails with its check removed, and passes at 01f3a85.
The floor builds kv-unified's constraint model under every folding strategy. The other folding strategies give pins precedence over locks in ways that model doesn't follow: a classic pin overrides a lock (lockChunk's doc), and under kv-stable a level pin holds its summary's group at its level, a lock under it included. So a message locked at one level and pinned at another left the floor missing while every compile went on, and a lock that a sibling's level pin overrode through their shared summary raised the floor above the plan kv-stable makes. - floorTokens: under kv-unified the floor still takes that solver's constraints, locks included, and is exact. Under the other folding strategies it counts no lock, so it is a lower bound there: a floor over the budget still means every compile refuses. - initialize clears the last floor failure's cause, beside the strategy's other once-per-load logs, so a store opened again says a failure that lasts. - Cases: under kv-stable, flat-profile and oldest-first, a raw pin over a locked, folded message keeps the floor, at or under the plan, and raises it; under kv-stable, a lock that a sibling's level pin overrides leaves the floor as it is, and a level pin over a message locked raw keeps it, where kv-unified refuses the compile for the same pair; under kv-unified a lock that holds a message raw raises the floor; a failing computation is said once, again for another cause, again when that cause recurs after the floor came back, and again for the store opened anew. Each case fails at 01f3a85 but the kv-unified one, which pins the floor as it stands there, and each fails with the change it covers removed.
- The fragment and RenderStats.planVsActual.floorTokens: `hardBudget - floorTokens` is how far the store is from the point where every compile refuses, since a refusal can come earlier; it usually shrinks as history arrives. Outside kv-unified the floor counts no lock and is a lower bound. A floor that can't be computed is said once per cause, and once more by each load that meets it. - OverBudgetDiagnostics: the floor comes on the adaptive refusals made after the plan, when it was computed; the refusal for a head and tail that alone exceed the budget comes first and carries neither field. At or under the budget a plan fits, outside kv-unified unless a lock holds a message above its cheapest form. Queued relief is an estimate, and fewer messages or a released pin or lock can lower the floor too.
A floor at or under the budget doesn't promise a plan fits outside kv-unified: besides locks, kv-stable holds every message under a level pin's summary at the pin's level, which the floor's constraints don't follow either. The fragment, the refusal paragraph and OverBudgetDiagnostics.floorTokens now say only that: a floor over the budget means every compile refuses, and one at or under it doesn't promise a plan fits.
A compile refuses only once its plan passes hardBudget, the input budget with overBudgetGraceRatio added, and OverBudgetDiagnostics carries two budgets. A floor between the input budget and hardBudget leaves room for plans that don't refuse, so "a floor over the budget means every compile refuses" was false under the input-budget reading. Name hardBudget in each sentence that ties the floor to a refusal or to what draining the queue can clear, and say in OverBudgetDiagnostics' floor doc what hardBudget is. The kv-unified sentences, that a plan fits at or under the budget, hold for either budget and stay as they were.
1 task done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds cases for two checks in the relief rule that no test pinned, has the floor count no lock outside kv-unified, so it no longer goes missing when a pin meets a lock there, and narrows texts in the fragment and in doc comments where they say more than the code does, among them that outside kv-unified the floor is a lower bound. It's five commits on
01f3a85107, the head of anima-research#416 when they were made. At910749152,test/liveness-floor.test.tsgives 19 of 19, and each new case fails with the check or the change it covers removed. Merging it is the only step it needs.Problem
At
01f3a85107, line numbers insrc/strategies/autobiographical.ts:mergeTakesTurnByReliefcan be removed, changing the order, with all 10 tests intest/liveness-floor.test.tspassing.attempts > 0half of:6332. With the line cut toif (head.hadRefusal) return false;, a merge whose answer was cut off (stopReason: 'max_tokens'), or whose request was rejected, goes first again on the next tick.this.mergeFailureOrder.has(key)in:6334. With it removed, a merge whose call failed goes first again once the pause the failure caused has passed.lockChunk's doc says a classic pin "still overrides the lock while it stands: under the greedy solvers and kv-stable, the pinned message renders raw" (:2979–2981), while kv-unified treats a pin and a lock as constraints. The floor builds kv-unified's constraints under every folding strategy, so under kv-stable, flat-profile and oldest-first a message folded at level 1 or above, locked, and then pinned raw leaves no feasible floor, and under kv-stable so does a message locked raw and then pinned at level 2. The compile goes on withfloorTokens,hardBudgetandqueuedReliefTokensabsent, and nothing says why (:6398). Four of this branch's floor cases, run over01f3a85107'ssrc, fail because the floor isn't reported.01f3a85107is 1322 with the lock and 1292 without it.OverBudgetDiagnosticsgains the floor "on adaptive refusals". The head-and-tail refusal (:13818) is thrown before the floor is computed (:14141), and carries neither field.hardBudget - floorTokensis called how far the store is "from its first refusal", in the fragment and inRenderStats.planVsActual.floorTokens. A compile refuses once its plan passeshardBudget, which can come before the floor does.expectedPairCost's comment (:6358–6360), a new summary is priced at the mean of the latest summaries at its level, or at the summary target before any exists. The fragment andOverBudgetDiagnostics.queuedReliefTokenssay draining the queue alone won't clear a floor still over the budget less the relief.Changes
test/liveness-floor.test.ts, on theopenOrderharness:max_tokens. After that tick the merge is still queued, and the calls made are['merge', 'l1'].backoffUntilset to 0, the next tick runs an L1, and the calls are['merge', 'l1'].floorTokens). Under kv-unified it takes that solver's own constraints, locks included, as before. The other folding strategies give pins precedence over locks in ways those constraints don't follow, so there a lock leaves the floor's inputs, and the floor is a lower bound.initializeclears the floor's last failure cause, beside the strategy's other once-per-load logs, so a store opened again says a lasting failure again.openReaderharness:CanonicalSummaryForest.prototype.minimumTokensmade to throw, two compiles go on with the floor andhardBudgetabsent and one warning naming the error. Another error gives a second warning. With the method restored the floor is back, the second error again gives a third warning, and with the store closed and opened again, a fourth.changelog.d/415-floor-headroom.added.md:hardBudget - floorTokensis how far the store is from the point where every compile refuses. Under kv-unified the floor takes that solver's own constraints, locks included, and is exact, and elsewhere it counts no lock. "Outsidekv-unifiedthe floor is a lower bound: a floor overhardBudgetmeans every compile refuses, and one at or under it doesn't promise a plan fits." A floor that can't be computed is said once per cause, and once more by each load that meets it.OverBudgetDiagnosticscarries the floor on the adaptive refusals that come once the plan is made, when it was computed, and the head-and-tail refusal carries neither. Under kv-unified a floor at or under the budget means a plan that fits exists. Queued relief is an estimate.OverBudgetDiagnostics.floorTokensandqueuedReliefTokens, insrc/adaptive/picker.ts: the same split between kv-unified and the other strategies, and overhardBudget, which the doc defines asinputBudgetwithoverBudgetGraceRatioadded, no plan fits until the floor drops under it or the budget rises. Where the doc said "only new summaries, a larger budget or a smaller tail clear the refusal", its list now also names fewer messages and a released pin or lock, each of which a probe in Tests shows lowering a floor.RenderStats.planVsActual.floorTokens, insrc/types/strategy.ts, andfloorTokens' own doc comment: the distance to the point where every compile refuses, with locks counted under kv-unified and none elsewhere, where it's a lower bound, and absent where the forest couldn't be built or its computation fails.Tests
On Linux with Node 24.22.2 and npm 11.19.1:
At
910749152, in a clean checkout,npm ci,npm run buildandtsc --noEmitare clean, andtest/liveness-floor.test.tsgives 19 of 19. On a GitHub-hosted Linux runner with Node 24.22.1 and npm 11.19.1,npm ciand thennpm test, whosepretestbuilds first, pass all 3570 tests, in 393 suites, at910749152.Red first: this branch's
test/liveness-floor.test.ts, run over01f3a85107'ssrcin a clean checkout, fails six cases:The kv-unified case passes, since it pins the floor as it stands there, and so do the order cases.
Each case against the change it covers, with each one-line change made in the built strategy by a pattern that had to match exactly once:
attempts > 0half removed from the relief rule fails exactly the cut-off case;hadRefusalremoved fails nothing, sincerecordMergeRejectionadds toattempts(:7124) before it setshadRefusal(:7131);initializeno longer clearing it each fails exactly the failing-computation case.Lowering the floor, at
01f3a85107, by a probe outside this branch, with the same figures under kv-stable and kv-unified. In one case, the floor starts at 3,152. A raw pin over ten middle messages raises it to 4,372, and releasing the pin brings it back to 3,152. Removing the newest two messages then lowers it to 2,908, and removing two middle messages after that leaves it at 2,908. In a second case, in a test of its own, locking the same ten messages while raw, before any compile, gives 4,372, and releasing the locks gives 3,152, the first case's starting floor.Not verified
backoffUntilto 0, in place of running the clock past the backoff.OverBudgetDiagnostics.floorTokens' doc rests on the probe in Tests, not on a case in this branch. The probe lowers a floor by each of fewer messages, a released pin and a released lock, though not every removal lowers it.changelog.d/415-floor-headroom.added.md, from this branch.Esther-2584 built and ran this change, and Alfred-2570 found where the floor missed a pin's precedence over a lock. Fiona-2757 wrote this description.