Repository navigation
fix: project a file's heat strip once instead of on every frame - #628
Merged
Merged
Conversation
breferrari
added a commit
that referenced
this pull request
Sep 30, 2026
* Label a PR by what ships Step 7 chose the label by what a user can see, so a change to shipped code with no visible symptom, such as a frame-path cost fix, fell to internal by the tie-break. The label now follows what the binary is built from: src under crates, a dependency, a theme or install is release; process, CI, skills, the spec, the roadmap, tests and gates alone are internal. Ruled 2026-09-30, reader, on #628. Release-note: none Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Decide the label by path in every file that states it The skill's rule now reads off the changed paths: crates/*/src, crates/*/assets or a dependency line is release, a comment or refactor included; everything else is internal. CONTRIBUTING.md and the pull request template said release meant a user can see the change, which contradicted the skill on the case that prompted it, so both say the same thing in plain English now. Release-note: none Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Say the same rule in all three files The skill names install again, which the public files never stopped naming, excludes dev-dependencies from the dependency clause, and carries the ruling in the house form with its User-facing line. The template and CONTRIBUTING.md stop saying that a release note describes what a user sees and that a refactor is internal, since neither holds under the path rule. Release-note: none Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
A drawn heading's heat strip was projected on every frame by walking every hunk line of its file, which was the one drawn thing whose cost followed the file rather than the window. The frame now keeps a value derived from a cached diff beside that diff, so the projection is paid when the diff is computed and served while the diff is reused. Frame::diff_with hands back the diff and the derived value from one call, so the list and the diff walk spend no second stat. FrameStats::derived counts the derivations, and two gates hold it: a second screen over settled diffs derives nothing, and a rewritten file derives exactly once with a strip that follows its new diff. Release-note: none Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
SPEC.md section 10 closes the bullet that tracked #55, with the mechanism and the rail frame measured on both sides of the change. The paragraph that told the next pass how to re-measure it goes with it. ROADMAP.md flips the Shelf row and records the pull-forward. Release-note: none Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
diff_with resolves the cached entry or the failure first, then derives and counts once, so the two match arms no longer repeat the count. A failed read is not cached, so its diff derives without counting: the counter says once per diff, and a value nothing keeps is not one. The reads gate inserts its edit with insert_str rather than an empty-range replace. Release-note: Each file's heat strip is projected once per change instead of on every frame. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The reads gate takes the number of diffs the rewrite recomputed from the frame's own counters and holds the next screen's projections to it, rather than to the constant one. The gate's name drops a word. The closed bullet names the gate and the budget fixture it was measured with, and says what holds: a drawn heading costs a copy, and the walk over the hunks is paid once per computed diff. Release-note: none Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The doc on diff_with states the contract in full: one value per diff, a second derivation of the same type is served the first's value, and another type replaces it. The failure path's note says the derive there is uncounted on purpose. The roadmap's pull-forward row takes the column value its siblings use. Release-note: none Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
breferrari
force-pushed
the
issue-55-heat-once-per-diff
branch
from
September 30, 2026 19:10
2d6c517 to
fd18d81
Compare
breferrari
marked this pull request as ready for review
September 30, 2026 19:10
This was referenced Sep 30, 2026
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.
Summary
A drawn heading's heat strip is now projected once per computed diff and served from the frame while that diff is reused. Before,
heat_ofwalked every hunk line of every drawn file on every frame, whichSPEC.md§10 recorded as the one drawn thing whose cost followed the file rather than the window. Closes #55. Plan: #55 (comment).The mechanism is one slot beside the cached diff.
Frame::diff_withreturns the change, the diff and a value derived from the diff in one call, so the diff walk and the list walk spend no second stat. The slot is dropped with the diff, so nothing new can go stale and nothing new grows.FrameStats::derivedcounts the derivations.Scope:
full. The change class script reads the diff as code.Labelled
releaseon the reader's call of 2026-09-30, now the rule in #629: the change is invigia-coreand ships in the binary. Two public additions invigia-core, thederivedfield onFrameStatsandFrame::diff_with, widen the crate's API, so the bump this ships in is not a patch.Test plan
crates/vigia/tests/reads.rs::heat_once_per_diff: a second screen over settled diffs derives 0; after one file is rewritten, the next screen derives exactly as many strips as the rewrite recomputed diffs (one), and that file's strip follows its new diff.crates/vigia-core/tests/frame.rs::derived_once_per_diff: two asks over one reused diff derive once and recompute nothing; a longer file derives again and the value follows the new diff..claude/scripts/mutate.mjs, run on the final code: killed never serve the kept value, never keep the value, keep the slot across a recompute, count nothing. A fifth, the shell projecting per frame while ignoring the frame's value, survives the two gates and is refused by CI'sRUSTFLAGS=-D warningsas an unused parameter.a_frame_beside_a_rail_holds_the_frame_budget, release, 200x40 pane drawing 36 pinned rows, two rounds each interleaved: p50 5.69ms and 5.65ms on main, 5.67ms and 5.64ms here; p99 7.05ms and 7.11ms against 6.74ms and 6.96ms, all against I9's 16ms. The frame did not move measurably; the shape did.-D warnings;vigia-coreunit tests 101 passed;register49 andpackage9 passed after the rebase. The full suite and the budgets run in CI.Review
/simplify: folded the derive-and-count into one path;insert_strin the gate. Skipped: a once-per-diff derive for the one file the viewport is scrolled inside on a pane too short for a list, because avoiding it needs a second frame call, which costs a stat; aTypeId-keyed map for the slot, because there is one consumer and the doc states the limit./two-axis-review: the third screen's bound is now taken from the run (diffs the rewrite recomputed) rather than a constant; the gate's name dropped a word; the closed bullet names its gate and the budget fixture and says what holds. Skipped: a ruling line on the closed bullet, because the three earlier closed bullets in §10 carry numbers and no ruling line; the typed slot, because it needs the strip's constant invigia-core, which the plan rejected./code-review high: the doc ondiff_withnow states one value per diff; the failure path's note says its derive is uncounted on purpose; the roadmap row takes its siblings' column value. Skipped: the third hash lookup indiff_with(one short-string hash on a path the numbers above put within noise, and the borrow shape is why); printingderivedin the timings example, which drives the core withdiffand never callsdiff_with.Release note
Release-note: Each file's heat strip is projected once per change instead of on every frame.
🤖 Generated with Claude Code