Repository navigation
1.0.0 overlay: expanded issue card (step 13) - #25
Merged
Merged
Conversation
Harrys76
force-pushed
the
wp29/overlay-collapsed-card
branch
from
October 23, 2026 18:11
023a479 to
234de72
Compare
Harrys76
force-pushed
the
wp30/overlay-expanded
branch
from
October 23, 2026 18:11
a4c97a4 to
18e1573
Compare
Harrys76
force-pushed
the
wp29/overlay-collapsed-card
branch
from
October 23, 2026 19:22
234de72 to
eee3b63
Compare
Harrys76
force-pushed
the
wp30/overlay-expanded
branch
3 times, most recently
from
October 26, 2026 16:44
d8de8e2 to
3d57320
Compare
Harrys76
force-pushed
the
wp29/overlay-collapsed-card
branch
from
October 26, 2026 16:45
8a43ecb to
10c07b5
Compare
measurement_text.dart formats a measurement by unit and pairs it with a phrase for its family, so the card can read "10.0 ms in one build on the UI thread". The table covers the 43 families whose detectors stamp a measurement. A line explains a severity the value does not reach (held) or one judged on another reading (a debug rate's latest second). splitFixHint separates prose from code in a fix hint. Code starts after a line ending in a colon when the next line has brackets, `;` or `=>`, or is a command or comment; indented lines and closing brackets continue it. Bullets and lines ending in a full stop stay prose, which the plan's first rule got wrong for several hints. A reviewed table pins the split of all 53 FixHintBuilder methods. IssueMetadataBuilder now returns the Evidence line (the detector's reason and the confidence) and the Check in line (the DevTools view). The profile line that said timing "matches production" is gone. The controller keeps when each issue was last in a scan's results and the latest debug snapshot, for the When and Why it rebuilds rows. The issues fingerprint includes the Measured row's text, so the notifier fires when the row changes and not for a change it rounds away. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An expanded card shows its details below a divider at the full card width, as the decided design draws them: - Measured: the value and its phrase, a gauge with the warning and critical lines, and a line when the severity and value disagree. A 2 px gap in the box colour separates the fill from the track, and the fill falls back to the severity text colour where its shade misses 3:1 on the box. Issues without a measurement show their detail. - Where (widget and file:line with Copy), Route, When, Evidence and Check in, with labels that stack above their values at large text. - Why it rebuilds on rebuild and setState cards in debug runs. - Caused by and Effects rows that open the related card: a listed card expands, scrolls into view (the list builds every card for that frame) and takes focus; a hidden or filtered one offers Show, which keeps the open cards expanded; a folded one opens inline. A related issue no longer reported stays as plain text. - Links to Rebuild stats (once the screen has counted rebuilds) and to Startup metrics. - The fix with its effort label and code blocks with Copy code. - Labelled 48 px buttons: Show on screen, Learn more, Ask AI, Copy details, Hide and Not useful. Not useful marks the issue for exports and MCP output; a second tap removes the mark and its toast. A tap on the details no longer collapses the card. Hide moves focus to the card that takes its place and offers no Undo for a card whose issue is gone. "About this detection", the effort badges, the debug fidelity tags and the Ask AI shimmer are gone, so ShaderMask and AnimatedBuilder leave the framework denylist. The guide describes the new card. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The issues fingerprint includes the gauge's line labels, so a detector
that moves only its warning or critical line refreshes the card.
- Value phrases name the measurement's own window ("in the last 4.2 s")
instead of a fixed 10 s, 5 s or 1 s, and name none when it has none,
as raster_dominance's VM leg does.
- A related issue no longer reported stays as a plain row even when the
causal graph drops it from the card's ids: the card remembers the ids
each section showed.
- Show on a target both filtered out and hidden turns both off, so the
target opens.
- Why it rebuilds gives the total forced by several parents and the
busiest parent's own share, and names that parent as the one to fix
only when its share passes the widget's own setState count.
- Hiding the last card clears the list's cached keys, so focus falls back
to the header instead of the removed card.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nows - The controller drops its cached debug snapshot when the evidence key changes (a new page or tab, a hot reload) and on an aborted transition scan, so a card no longer shows the previous page's counts. - The row says "started by the widget itself" instead of "from its own setState": the count also takes changed dependencies and listenables, and a StatelessWidget has no setState. The advice reads "Most of these rebuilds come from X, so start there". - When the debug counters capped their widget types, the row says the counts can be low, gives no parent to start with, and does not claim there were no rebuilds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The controller keeps last-seen times per card, by list key and occurrence id, so a card whose occurrence went no longer reads "Last seen just now" from a twin under the same stable id. - The cached debug snapshot records its screen (route and scaffold hash). A card whose issue was reported on another screen does not read that screen's counts as its own; its row asks to open its screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The detail shows under the Measured row too. For http_error_spike and others it holds what the number does not, such as the failing URLs and status codes; an inline related issue shows its value line and detail. - Last-seen times expire after as many unseen scan cycles as a trend, so structural findings on ever-new elements no longer grow the map for the whole session. - Hide hands focus to the next card through the same path a related row uses: the list builds every card, the card scrolls into view and takes focus. ensureVisibleWithMotion returns the scroll's future, and the host keeps the list built until it completes, so a card scrolled in from outside the cache is not unmounted mid-scroll and loses no focus. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ped with - The controller's currentScreen is the route name and the active route session's scaffold hash, the pair `_aggregateIssues` stamps on issues. The debug snapshot records it, so on a route the config ignores (no session, so issues carry no hash) a card still reads its screen's counts. - The Rebuild stats link shows only on a card from the current screen: the link opens the active session's counts, which a card kept from another screen must not claim. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The issues fingerprint includes the scaffold hash. Two first visits of tabs on one route that report the same issue differ only there, so the card now receives the second tab's issue instead of keeping the first and calling the current screen another one. - Why it rebuilds reads counts only while Sleuth holds the framework's rebuild callback. With debug callbacks on but `advanced.rebuildAttribution` off, or DevTools holding the callback, the row says rebuilds are not counted instead of "No rebuilds". - The Rebuild stats link reads the screen's count on every scan, so an expanded card shows the current total and gains the link once counts start. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The Rebuild stats link's count and tap check that the card is on the current screen each time. A card kept after its issue went, followed by a screen with no issues, leaves the issue list unchanged, and the link read the new screen's counts as its own. - The labelled rows rebuild on the scan pulse, so a card expanded before its last-seen or recurrence data existed gains the When row when the data arrives. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The row floored the snapshot's elapsed time to whole seconds, at least
one, so 20 rebuilds over a 500 ms scan read as 20 in the last second.
RebuildCause carries the Duration and the row formats it as the value
lines do ("last 500 ms", "last 2.5 s").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The gauge ended a quarter past the larger of the value and the lines. A value past the lines, such as a sustained jank count of 77 against a line of 3, then filled 80 % of the track on every scan, and the line's tick moved instead of the fill. The scale now ends a quarter past the higher line, or at 100 for a percent whose lines are at most 100, so a value at or under the line draws as before. A value past the end fills the track with two slanted cuts near its end, as on a chart's broken bar; the text above the gauge gives the number. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copy details and the Ask AI prompt left out the measured value and its
lines, the number the expanded card leads with. Both now add the
Measured row as sentences ("Measured: 244 ms in one build on the UI
thread. Warning at 8.0 ms. Critical at 16.0 ms."): Copy details after
its header lines, the prompt after the confidence.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Evidence row joined the detector's reason and the confidence with ", so", which read badly after a reason that ends in advice: "Structural scan only. Enable debug callbacks for paint evidence, so possible: no runtime signal confirmed it." The confidence is now a sentence of its own: "... paint evidence. Sleuth rates it possible, since no runtime signal confirmed it." Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RateHysteresis turns a held warning critical on the latest window's
rate, while the measured value averages two windows. Windows of 15 then
35 rebuilds per second gave a critical card at 25/s, under the 30/s
line, with the note "Held at critical", a hold that never happened.
HeldRate now keeps the latest window's rate, the rebuild and repaint
debug cards carry it in extraTraceArgs (latestRatePerSec), and the
note reads "Critical: the latest second went over the line" when that
rate is over the line.
The Measured line also placed the window and the value from the
template before putting names in, so a tracked resource named
"sock[1]" or "x{v}" lost its brackets or split the line at the name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The overlay no longer uses AnimatedBuilder, Checkbox, ShaderMask or TweenAnimationBuilder, so they left the framework denylist and an app's own uses count again. The audit lists them with the other app-owned widgets, so they cannot return to the denylist or to the overlay, and the framework section is capped at its new size of 49. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The "is hidden" and "is filtered out" toasts show a card again by removing every key that hides it (hideKeysOf). A key carried over from a store written before 1.0 matches any widget of the stable id, so hideKeysOf now lists that form too, and Show clears it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Harrys76
force-pushed
the
wp30/overlay-expanded
branch
from
October 26, 2026 17:59
3d57320 to
60056ac
Compare
Harrys76
force-pushed
the
wp29/overlay-collapsed-card
branch
from
October 26, 2026 17:59
10c07b5 to
22f281a
Compare
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.
Step 13 of the 1.0.0 overlay plan (
doc/plan_overlay_1_0_0.md): the expanded issue card. Stacked on #24.What the expanded card shows
Below a 1 px
cardDivider, at the full card width from the severity icon's edge:SleuthMeasurementGauge, oneCustomPaint) with ticks at the warning and critical lines. A line explains a held severity ("Held at critical: …") or a debug rate judged on its latest second ("Not critical: …"). The semantics label reads the value and both lines. The issue's detail follows it.file:linewith Copy. When reads "Last seen 2 s ago · in 5 of the last 8 scans" from the controller's recurrence data and refreshes on the scan pulse. Evidence is the detector's reason and the confidence; Check in names the DevTools view. The label column is sized to the widest label and stacks above the values once it passes a third of the row.rebuild_debug_*andsetstate_scope): "0 started by the widget itself · 5 forced by its parent X", from the current page's latestDebugSnapshot. Capped counters make the row say the counts can be low. Without debug callbacks it says how to turn them on; an empty window reads "No rebuilds in the last N s".A tap on the details no longer collapses the card. Hide moves focus to the card that takes its place, and offers no Undo for a card whose issue is gone.
Decisions and deviations
(){};=>or starting withflutter/dart") broke real hints:animation: _controller,ended a call early, bullets like• Call cancel() on …became code, and sentences after a code line were swallowed.splitFixHintalso continues a run on indented lines and closing brackets, treats//lines as code, and keeps bullets and lines ending in.as prose.test/utils/_fixtures/fix_hint_split.txtis the reviewed split of all 53FixHintBuildermethods.ShaderMaskandAnimatedBuilderleave the framework denylist (49 framework entries).Review
The UI and UX design reviews were applied before opening:
cardDivider(borderequalscardDefaultin dark);Material, so the press highlight shows;spacingMd;Each behaviour fix has a test that fails when the fix is reverted.
Codex's first round found six more, fixed in d2a22fb with a regression test each:
The second round found three in Why it rebuilds, fixed in the next commit: the cached snapshot is dropped at evidence boundaries (page, tab, hot reload, aborted transition scan); the count is described as rebuilds the widget started itself, since it takes dependencies and listenables too; capped counters qualify the counts and drop the advice.
The third round found two cases of a kept card reading another card's data, fixed in the next commit: last-seen times are per card occurrence, and the cached debug snapshot records its screen so a card from another screen does not show that screen's counts.
The fourth round found three more, fixed in the next commit: the detail shows under the Measured row too; last-seen times expire after as many unseen cycles as a trend; Hide's focus hand-off builds and scrolls the next card into view, and the host keeps the list built until the scroll ends, so neither a revealed nor a focused card unmounts mid-scroll.
The fifth round found two screen-identity gaps, fixed in the next commit: the debug snapshot records the same screen identity issues are stamped with (
currentScreen: route name plus the active session's scaffold hash, null on an ignored route), and the Rebuild stats link shows only on cards from the current screen.The sixth round found three more, fixed in the next commit: the fingerprint includes the scaffold hash (two first-visit tabs on one route reporting the same issue); Why it rebuilds checks that Sleuth actually holds the rebuild callback and says when rebuilds are not counted; the Rebuild stats link reads its count on every scan.
The seventh round found two live-update gaps, fixed in the next commit: the Rebuild stats link checks the card's screen on every scan and tap, and the labelled rows rebuild on the scan pulse so When appears once its data exists.
The eighth round found that Why it rebuilds floored its window to whole seconds; the next commit carries the snapshot's Duration and names it as the value lines do.
The ninth round found nothing.
Verification
fvm flutter analyze: 0 issues. Format check clean.fvm dart doc --dry-run: 0 warnings.fvm flutter test --exclude-tags benchmark: 4,979 passed.--tags benchmark --concurrency=1): 44 passed.cacheExtentkeeps anignore: deprecated_member_use: its replacement is not in 3.32.Not in this PR
CLAUDE.mdstill names the removed freeze-zone fields here; 1.0.0 release prep: docs, sidecar 0.10.0, CHANGELOG #28 names their 1.0 replacements.Fixes from the iPhone walk
measuredSentenceandcopyDetailsText.Hidden cards across the upgrade (d8de8e2)
The "is hidden" and "is filtered out" toasts show a card again by removing every key that hides it (
hideKeysOf). A key carried over from a store written before 1.0 matches any widget of the stable id (#24), sohideKeysOflists that form too and Show clears it. A test fails without it.Fixes from the final review
HeldRatenow keeps the latest window's rate, the rebuild and repaint debug cards carry it (extraTraceArgs.latestRatePerSec), and the note reads "Critical: the latest second went over the line".🤖 Generated with Claude Code