Roadmap: suggested order for the desktop + Android backlog (#5–#72) #73
Open
opened 2026-08-18 14:38:32 +00:00 by logan
·
14 comments
No Branch/Tag Specified
main
fix/146-stub-etxtbsy
fix/175-wizard-follows-the-library
fix/231-setter-rollback
fix/197-duplicate-column-label
docs/225-fixtures-wav-tags
docs/220-skill-check-scope
test/217-fixture-names-in-queue-selection
fix/216-riff-parse-allocation
fix/170-queue-header-action-names
fix/210-nav-sheet-scroll-affordance
docs/50-readme-landing-page
feat/65-art-prefetch-ahead
feat/71-more-as-a-bottom-sheet
feat/54-native-touch-feel
feat/67-entity-links-into-menus
test/196-visual-tier-gates
fix/138-ui-test-storage-leak
fix/104-wav-tags-read
fix/207-sheet-scroll-affordance
fix/204-ui-visual-update-filter
pi-agent-backlog-automation
63-touch-model-phase-2
63-android-touch-model
186-touch-targets-settings
186-touch-targets-page-header
187-seek-bar-hit-area
189-190-explore-correctness
135-android-underrun-instrumentation
51-android-small-screens
fix/171-phone-queue-scrim
fix/137-touch-only-affordances
fix/154-nested-css-check
feat/58-mini-player-progress-line
fix/66-album-page-scrolls-as-one
60-context-menu-action-sheet
64-android-system-volume
59-slim-the-mini-player
55-queue-as-a-screen
feat/57-drop-the-android-top-bar
feat/62-jobs-as-a-notification
fix/53-seek-bar-never-moves
fix/159-android-task-app-id
fix/52-android-activity-recreation-restarts-the-process
fix/150-expand-button-under-the-art
feat/42-inline-volume-and-centred-transport
fix/156-queue-selection-fixture-order
fix/151-fuse-the-scroll-guard-and-the-write
fix/43-queue-panel-selection
fix/143-top-bar-fits-its-window
feat/27-jobs-into-settings
feat/25-configurable-sidebar-tabs
feat/6-global-back-forward
fix/72-active-view-broadcast
fix/69-page-header-action-overflow
fix/quick-wins-batch
fix/118-in-library-clear
fix/61-mini-player-plain-text
fix/68-hover-affordances-pointer
fix/119-dev-headless-port
fix/130-issue-claim-user
fix/131-codegen-check-scope
feat/28-autotag-match-on-album
feat/17-demote-version-selector
feat/38-ownership-visibility
ci/115-manual-release
feat/34-icon-language
feat/7-full-tracklist-toggle
fix/16-tagwriter-totals
fix/unclaim-ca-certs
fix/unclaim-shell
ci/unclaim-on-close
docs/closing-keyword
docs/retire-stale-planning-docs
docs/issue-driven-workflow
integration/small-fixes
fix/small-issue-batch
fix/queue-toggle-state
fix/drag-count-badge
fix/album-card-year
fix/album-tracklist-heading
fix/seek-bar-clock-width
fix/explore-art-scanner-requests
chore/workflow-guardrails
v0.7.0
v0.6.0
v0.5.0
v0.4.0
v0.3.1
v0.3.0
v0.2.3
v0.2.2
v0.2.1
v0.2.0
v0.1.0
v0.0.1
v0.0.0
Labels
Clear labels
Area/Design
Area/Downloads
Area/Explore
Area/Library-UI
Area/Metadata
Area/Packaging
Area/Player
Area/Queue
Area/Settings
Area/Shell-Nav
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Platform/Android
Platform/Desktop
Breaking change that won't be backward compatible
Something is not working
Documentation changes
Improve existing functionality
New functionality
This is security issue
Issue or pull request related to testing
Priority
Critical
1
The priority is critical
Priority
High
2
The priority is high
Priority
Medium
3
The priority is medium
Priority
Low
4
The priority is low
Reviewed
Confirmed
1
Issue has been confirmed
Reviewed
Duplicate
2
This issue or pull request already exists
Reviewed
Invalid
3
Invalid issue
Reviewed
Won't Fix
3
This issue won't be fixed
Status
Blocked
1
Something is blocking this issue or pull request
Status
Need More Info
2
Feedback is required to reproduce issue or to continue work
Status
Abandoned
3
Somebody has started to work on this but abandoned work
Status
In Progress
Somebody is actively working on this right now
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: yonlu/yellowjacket#73
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Meta issue for the 67 reports filed as #5–#72. It records the order they should be worked in and the soft relations that are not expressible as blockers. Hard blockers are set as real Gitea issue dependencies and render on each issue.
Labels in use:
Kind/*,Platform/*,Priority/*,Area/*,Reviewed/Confirmed(I read the code and confirmed the defect),Status/Blocked(has a dependency).Hard dependency graph
Phase 0 — cheap, confirmed, no dependencies
Each is a small, isolated fix I traced to a specific line. Good warm-up work and several are user-visible immediately.
downloadStoresubscription never triggers a re-rendertabular-numsPhase 1 — correctness of "what do I own"
The single most-reported theme. Do it in this order; the later ones are wrong until the earlier ones are right.
tagwritermust write track/disc totals)Phase 2 — desktop shell and responsiveness
#24 is the design decision the rest hang off; settle the queue-panel model before anything else here.
page-headeroverflow, also fixes the Android report)Phase 3 — Android chrome
Sequence matters: the top bar cannot go until the job indicator has somewhere to live, and the queue cannot leave the mini bar until it is a screen.
min-width: 0) can start nowPriority/Critical, independent of all of it, needs a real device andlogcatPhase 4 — Android touch model
Phase 5 — features
Sourcewhile you are there)Sourceis how it announces itself)Phase 6 — presentation and docs
Soft relations, for the record
Source.volume-control; the Android answer is "remove it", the desktop answer is "inline it".utils/selection-controller.tsrather than growing three models.Phase 2's anchor is done, and so is the item hanging off it.
mainis green atc84a906with no open PRs. Since this list was lastreconciled:
bands are written down as a promise, and the queue is an overlay when
available − panelWidth < 480rather than at a breakpoint, becausethe panel's width is user state.
page-headeroverflow (PR #136). Needed an actions APIfirst, not a rule added in one place: a component cannot move another
component's light-DOM children into a dropdown and keep their
behaviour. That is why it was its own PR rather than part of #24.
So Phase 2's first bullet is complete and the next in the stated
order is #6 (global back/forward) → #72.
One thing worth checking before anyone claims #6: the back stack may
already exist.
index.tsrecords each navigation withpushStateandreplays
popstate, and the oldnavStackwas deleted rather than keptbeside it — that landed for Android's hardware back button. #6 asks for
global back/forward, so it is plausibly now a smaller job than this
list assumes, or already partly satisfied. Someone should read it
against the code before estimating it.
Two Phase 3 items were taken out of order and are closed (#61, #68,
in PR #139's quick-wins batch). Both were small and independent, so no
sequence was broken — but noting it here so the phase list is not read
as still owing them. #55 became unblocked at #24 and is still open, with
the overlay to build on.
Two new issues were filed against this backlog and want sequencing:
edit, shortcut reset). The correct fix is the opposite of #68's: on
touch they must be always visible, since hiding them removes the only
route to the action. Sequenced after #60.
play-in-context.test.tsflakes ~1 in 3 on pristinemain. Not in any phase; it is infrastructure, and it can fail CI onan unrelated PR, which is how it was found.
Phase 2's remaining pair should be worked in the opposite order: #72
before #6.
Not a quiet reorder — this list is the sequence, and picking by eye is
how it stops meaning anything. So the case, and the measurements behind
it, for the record.
The list says
#6 global back/forward, then #72 (nav highlight, Android, same mechanism). "Same mechanism" is exactly right and is thereason to invert it.
#72 is not a bug in the nav components; it is a missing broadcast in
the shell.
handleNavigate()setsdata-active-viewon every pathincluding
_isBack, but the navs learn the active view from thenavigateCustomEvent, which only the outbound path dispatches —popstatecallshandleNavigatedirectly. #6 adds a forwardcontrol, which is a second route into that same broken state. Fixing
the broadcast first means #6 lands on a foundation that already works;
doing #6 first means shipping an affordance whose visible effect is
wrong from the first press.
And #72 is worse than its title. Measured against
make dev-headless SEED=default, reading the lit item out of eachnav's shadow root:
data-active-viewalbumsnav-albumstab-albumsexplore-album-detailsnav-albumsalbumsnav-albumstracksnav-trackstab-tracksalbumsnav-trackstab-tracksThe last row is desktop, and both navs highlight the view the user just
left. It is not Android-only, and a confidently wrong highlight is
worse than an absent one — any back across two primary views produces
it. Priorities agree with the inversion too: #72 is
Priority/High+Kind/Bug, #6 isPriority/Medium+Kind/Feature.Nothing is lost by the swap. #6's own groundwork stays where it is
—
pushedEntriesis already the depth counter its Direction asks for —and #72's fix hands #6 something it would otherwise have had to build:
one place that states which view is active, which is what a forward
button has to keep honest.
#72 is done (PR #141). The order for the rest of Phase 2 is unchanged;
#6 is next in it.
Phase 2's back/forward pair is done, in the inverted order argued
above. #72 (PR #141) then #6 (PR #144), and the inversion paid for
itself: #6's Back button is the first thing in the app that had to
state whether going back was possible, and that disabled state
immediately exposed #142 — the app records two launch navigations, so
a fresh session was one entry deep, the first back press replayed home
over home, and on Android the press that should have exited the app
was swallowed by
canGoBack(). Five phases old, invisible untilsomething asked the question out loud.
Phase 2's remaining items are unchanged, and the next by this list is
#25 (configurable sidebar tabs), which unlocks #27 and relates to
#37.
Two things measured while doing #6 that touch other items on this list:
it already overflows at the bottom of the Compact band #24 committed
to.
layout-overflow.spec.tschecks 900 because that is thenarrowest content area; the narrowest header is a different
question and lands at 600. Relates to #48 (top bar rework) and to
#57, whose "search becomes a modal" would fix it as a side effect —
worth doing together rather than twice.
page's "Shuffle album" is clipped by 53px and "Add to queue" by 50px,
both unreachable, with
album-infosqueezed to 78px. Note that #69'sactions API does not reach it — that header is the component's own
markup, not
<page-header>— so it is layout work, not a rule.Phase 2's next item is #25, and its stated order with #27 holds — but
only because of a design choice, so here is the choice.
The list says
#25 configurable sidebar tabs → unlocks #27 (Jobs into Settings). The obvious objection is that it is backwards: #27 deletesa destination from the very list #25 is making configurable, so #25
ships a toggle for something about to stop existing, and somebody has to
migrate that key out of
config.tomllater.That objection is real against the shape you would reach for first —
HiddenViews []string, or a struct with one boolean per view. Both makea removed view into stored garbage: the list carries a
"jobs"stringthat now matches nothing, and the struct carries a
ShowJobsfield thathas to be deprecated in place or removed with a migration.
It does not bite against a map keyed by view id, which is what I am
building. An absent key means "that view's own default"; an unknown key
is dropped on load. So when #27 removes Jobs,
jobs = truesitting insomeone's config is not a migration — it is a key nothing asks about,
discarded the next time the file is written. The same property is what
makes the forward direction free: a view added in a later issue gets
its own default rather than being invisible (a whitelist) or forcibly
visible (a blacklist) to every existing install.
So: order unchanged, #25 then #27, and the reason the order is safe
is written into the storage shape rather than into anybody's memory. If
a future issue swaps that map for a list or a struct, it re-opens this
question and should say so.
One thing the sequence does buy, which is worth stating because it is
the actual dependency: #27's Direction says "removing the tab pairs with
the sidebar-toggles issue", and with #25 landed, #27 does not have to
argue about what happens to a user who wants the Jobs tab. It can
delete the destination outright, because by then the answer to "I liked
that tab" is a toggle list that no longer offers it — a visible,
explicable absence rather than a feature that silently vanished.
Also, one finding in #25 has expired and I am not repeating it. Its
fourth bullet says the sidebar's item count is one of the two reasons
the window minimum is 600px tall. Both reasons were retired by #24 —
backend/config/window.gorecords that the subtitle isdisplay: nonefrom 899px down and that the sidebar host scrolls (
overflow-y: auto;at 600x460 its
scrollHeightis 434 against a 332px client). 800x600 isa comfort floor for desktop chrome now, not a correctness one, so
hiding tabs relieves nothing there.
#25 landed (PR #145, merged as
5af545e), so Phase 2's next item is#27 — and the storage shape argued above is what it should lean on:
removing the Jobs destination costs nothing, because
jobs = truein anexisting config is an unknown key, dropped on load.
One thing #27 inherits:
backend/config.Viewsis now also whatDefaultPagevalidates against, so deleting Jobs is one entry thererather than an entry plus a
switcharm plus a<select>option.#27 landed (PR #147, merged as the tip of
main), so Phase 2 has#48(top bar),#23/#42(transport, volume) and#30(track listchrome) left, plus the newly-filed #143 — the top bar overflows by
11px at 600x600, which is inside the Compact band #24 promised and is
not on this list because it was filed after it.
#143 relates to #48 and to #57 (whose "search becomes a modal" would
fix it as a side effect), so the three are one pass over one component
rather than three.
One thing #27 turned up that is worth recording against the sequence:
the Direction said "split by kind", and four of the five kinds already
had a home showing their work. The tab was carrying the generic job
affordances — pause, cancel, the log — for surfaces that each had their
own progress display and none of those. Worth assuming the same of #62
(jobs as an Android notification): the question there is likely also
"what does the indicator carry that a notification would not", rather
than a straight port.
#143 and #43 landed (PRs #149 and #152). Two notes against the
sequence, one of which is a correction to this list.
#43 was not in any phase, only in the soft-relations line about #5,
#43 and #63 being three answers to "how does selection work in a list".
It was also the last
Priority/Highdesktop item — everything elseat High is Android now. Worth placing rather than leaving to be found:
it belongs beside #5, and #5 should be read before it is started, since
the finding below lands on it.
The finding.
explore-linkstops the click's propagation onpurpose, so a click on any track/album/artist name navigates and
selects nothing. That is app-wide and it means adding
SelectionControllerto a list does not give that list selection on itsnames. Measured by hit-scanning a row: the queue panel is 12% link,
track-listis 21%.explore-album-details's tracklist isnumber/title/artist/duration and is the one that plausibly is mostly
link — so #5 should scan that row before copying the pattern, and if the
number is bad, the answer is #67's (names into the context menu) rather
than a new one.
Phase 2 now has #48, #23/#42 and #30 left. #143 leaves #48 something
to build on rather than something to undo: the top bar's fit is
measured (
services/top-bar-fit.ts), so a three-column header inheritsa working answer to "what does this bar drop when it runs out of room"
and only has to declare the new order. The two things it drops are the
wordmark and the job indicator's label — note that #48's own plan is to
replace the wordmark with "YJ", which makes the first of those cheaper
still.
And #62 keeps the property #27 turned up. #148, filed off #143, is
the second thing the Android top bar has nowhere to put: the library
filter is hidden below 600px and nothing else in the app selects a
library. So #57's blocker list is really "where do the job indicator
and the library filter live", and #62 answers only the first. Worth
knowing before #62 is scoped as a straight port.
Phase 3's second item is done. #57 (PR #167, merged as
880adff),which also closed #148 — the library filter was the second awkward
thing in that bar and #148 says so in as many words.
The bar is out of the phone's grid template rather than hidden: 3.25em
of a 439 CSS px viewport, which is the largest single vertical win the
reference device has. The
h1survives visually-hidden, becausepage-headerrenders noh1when its heading is empty and Settings hasno
page-headerat all.Two things about the sequence, for the record.
#60 stays in Phase 4 and this did not need it. The list's ordering
of these two was worth re-checking, because #57 builds a modal and #60
establishes "the presentation every other item needs" — but they are
different shapes under a rule already written down: a dialog that only
asks a question is a
confirmAction()call; a dialog carrying input isa
<wa-dialog>in the host's own template.<action-sheet>replacesthe six menus; a search box is not one, and nothing in #57 needs
undoing when it lands.
What #57 did take from #60 is the reason it is a dialog at all, and
it is worth naming because it is a constraint on everything Phase 4
touches: on the reference device
wa-popupfalls back toposition: fixed, and.main-panel'scontain: paintclips afixed-position descendant. No tier here can reproduce that — CI's
Chromium and WebKit both have the Popover API — so a guard has to assert
the mechanism (a native
<dialog>in the tree) rather than thesymptom. Phase 4's whole first item is that finding applied six times.
Phase 3's next item is #55 (queue as a screen), then #59 and #61.
One thing filed on the way: #168, e2e state leaking between spec
files — a job staged by
top-bar-fit.spec.tswas still in the storewhen a later spec measured a layout, so the leaking spec passed and an
unrelated one failed, in file order only.
Phase 3, on the #60-before-#55 question — raised at the end of the
#57 session and left for whoever picked up #55. Taking #55 now, and the
answer is that the ordering constraint does not exist, rather than that
it is being ignored.
The recommendation was sound as stated: #55's Direction asks for a
DETAIL_LOADERSmount,.main-panel > *iscontain: layout style paintunder a.main-panelthat iscontain: content, and #60'sfinding is that
position: fixedescapes overflow but not paintcontainment on Chrome 113. So #55-as-specified would move
queue-panel's workingwa-popupcontext menu into the region where#60 exists — a regression no tier here can see.
#55 is not being built that way, and the reason is a measurement rather
than a preference: at 424x439 the overlay #24 shipped is already
424x318, which is exactly
.main-panel's rect. A detail-view mountdraws the same rectangle in the same place. What #55 is actually
missing is the back stack (back navigates the page underneath and
leaves the queue up — measured) and a reachable way out (the scrim has
zero uncovered pixels at phone width). Both are had without moving the
component, so the menu stays where it already works.
Full argument on #55. No change to the roadmap order is being
proposed — #60 keeps its place and its priority, it simply stops
being a precondition for #55. It still blocks #63/#67/#71 and is still
the highest-value unclaimed item in this phase once the queue chain is
done.
Phase 3 items 3 and 4: proposing #59 and #56 as one PR, argued here
rather than done quietly. #55 has merged, so #59 is unblocked and is
next in the stated order; this only asks to pull item 4 forward into the
same change, not to reorder anything.
They are the same component and the same row of pixels. #59 removes
controls from the phone's transport; #56 enlarges what is left of it.
Both issues already say so in their own text:
already tight — which is the argument for the separate issue
slimming the mini player".
small-screen issues."
issue".
Done separately, the bar gets laid out twice and measured twice, and the
first PR ships a state neither issue wants — either three controls still
at 25px, or five controls at 48px in 424 CSS px, which is the overflow
#56 measured. The intermediate state is not a smaller version of the
goal; it is a different, worse layout.
One component decides both.
player-controlsrenders all fivebuttons unconditionally and is composed by
audio-player(the bar) andby
now-playing-view. Neither issue can be done without giving it acontext, and once it has one, both are the same edit:
And the context cannot be a media query alone, which is the part
worth pinning: on a phone the bar wants three controls and Now Playing
wants five larger ones, at the same viewport. So the host says which
context and the viewport says which size band, and neither alone is
enough — #56's Finding already says this ("sizing must be per-context, a
size property or a host-set custom property, not a global bump"), and it
is the exception to the rule that a component states what it drops at
phone width itself.
What must not break is the matrix's promise from plan 018: no
action is ever unreachable at any supported size. Shuffle, repeat and
the queue leave the phone's bar and must still be reachable — they are,
on Now Playing, which the mini player's art opens (
.expand, phoneonly) and which #55 just gave the queue a back stack from. That
reachability is the acceptance criterion, not the pixel count.
If there is disagreement, say so and I will split them; the argument is
about laying one bar out once, not about batching for its own sake.
Taking #64 (Phase 4, "independent") ahead of Phase 3's #58 and #51.
Recording the argument rather than doing it silently.
#51 is the phase's verification pass — this issue says to do it last
"since each buys vertical space". #172 is what that verification will be
run against, and it measures Now Playing at the reference device's
424x439 after #56:
#64 is the only unspent vertical win in the backlog that is pure
gain — ~30px including its gap — and #172's own Direction says to do
it first and re-measure. Everything else on that screen is a trade:
#172 already considered and rejected folding shuffle and repeat back
onto the primary row (buys 52px, leaves the art at 91px, costs a third
arrangement of the same five buttons). So verifying #51 before spending
the free 30px is verifying the wrong build, and #58 adds a progress
line to the same screen — it spends vertical space rather than
banking it, and is better judged once the budget is settled.
The ordering cost is small: #64 has no dependencies, is not blocked, and
blocks nothing. #58 and #51 keep their order behind it.
Two things I considered instead and did not take. #60 is the
highest-leverage unclaimed item in the tracker (
Priority/High,Reviewed/Confirmed, blocks #63/#67/#71) and is the containment defect#55 worked around rather than fixed — it is the one I would take with
a second session, and it opens Phase 4 properly. #58 is the strict
roadmap next. Both remain available; this is a one-issue reorder inside
the same screen, not a phase swap.
Phase 3 is done. #51 was its last open item and is in PR #188; #62,
#57, #55, #59, #61, #56, #58 and #52 were already closed.
The sequencing this list insisted on paid for itself, so it is worth
recording how. #51 says to verify the umbrella "after the above,
since each buys vertical space", and that turned out to understate it:
the audit's result is that there is no width problem left at
424x439 — the shell does not overflow on any of the ten primary views
plus the queue, nothing is stranded, nothing is occluded — so the whole
of #51 reduced to the vertical axis, which is exactly what its own
Findings predicted and what none of the earlier items could have shown.
Auditing before them would have measured a build nobody will ship.
Two findings came out of it and are filed as #186 (every control
that is not the transport is under the 44px touch floor) and #187
(the seek bar's drag target is 6px). Both are Priority/High and neither
is a reachability failure.
Where they sit in this list is a question rather than an
assumption. #186 is Phase 4's subject matter — it is "the polish pass
over the same surfaces" that #54 and #68 already describe — but it is
also the single most-repeated defect in the app right now, on every
screen, and it is the same complaint #56 was filed for. My reading is
that it belongs at the head of Phase 4, before #63, on the grounds
that #63 adds gestures to lists whose controls are 21px, and that
sizing them first makes the gesture work easier to judge rather than
harder. #187 is small and independent and can go with it.
Not doing that unilaterally, since this list is the sequence. Phase 4's
stated order is #63, then #67 and #71, with #54 and #68 as the polish
pass — so unless someone disagrees, the next item is #63, and #186
is the one I would argue should displace it.
One correction to the record while I am here: this list has #64 under
Phase 4's "independent" group, and it turned out to be a hard
prerequisite for #172 and therefore for #51 — it is the 29px that made
the reflow's arithmetic work. It is closed, so nothing needs
reordering; it is only that "independent" was wrong about it.
Taking #160 next, ahead of #186 and ahead of #135. I recommended #186
earlier today and am changing that recommendation; the argument belongs
here rather than in a commit message.
Phase 3 closed with #51, so the next open work is Phase 4 plus the three
Priority/HighAndroid issues filed since this list was written — #135(static popping), #160 (slog goes nowhere), #186 (touch targets). #186 is
the one I named this morning, on the grounds that it is measured,
confirmed and mechanical. All three of those are still true. It is still
not first.
#135 is the highest-value of the three and #160 is inside it. #135's
Direction opens with "Count the underruns and log them", and its Findings
say why that is the cheapest first move: an underrun makes
BufferedStreamer.Streamzero the caller's buffer and returnok, and arun of zeros spliced into a waveform is a step discontinuity at both
edges — which is what a pop is, and a series of short ones is static.
That is the one candidate of three whose audible signature matches the
report, and
starved/starvedSincealready exist from #122 but feedonly a 3-second give-up threshold, so a hundred 20ms underruns a minute
are invisible to the log, the UI and every tier.
Then #160: every
slogline on Android is discarded. So #135's ownrecommended first step is unreadable on the device that has the bug. Add
a counter, add a log line, run the phone, read nothing. That is the
sequence to avoid, and the ordering constraint is not a preference —
"instrument, then listen" cannot be executed at all until the
instrument has an output.
#160 also pays back permanently, and there is a measured precedent for
what it costs not to have it. #52 sat at
Priority/Criticalformonths as a process that vanished with no tombstone. Its entire
diagnosis is one line
main.goalready writes —sLogger.Error("application error", "err", err.Error())— whereerrnamed the fault exactly. It went to
/dev/null. Every future Androidbug worked from this repo is diagnosed against that same silence until
#160 lands, which is the argument for it being first rather than
merely soon.
What this costs #186 is a session, and nothing else. It is not
blocked by either, shares no surface with either, and its finding — a
device measurement table over 18 controls — does not go stale. Phase 4's
#63/#67/#71 are likewise untouched: this reorders the three post-#73
High issues among themselves and leaves the phase list alone.
So: #160, then #135, then #186, then Phase 4 proper.
#160 is done (PR #191, merged as
25ea1f3), and the reorder arguedabove paid off in a way worth recording against the sequence, because
it changes what the next person should do.
#160 justified itself inside the first minute. The app's diagnostic
stream reached logcat for the first time and immediately produced two
bugs that have been written on every launch and discarded — #189 (a
backfill querying
release_groups, a table plan 013 renamed away, soit has failed on its first statement since
e7748f1) and #190 (SQLitehas no temp directory on Android, so the champion index never builds
and every Explore search on the platform takes the slow path). Neither
is Android-only in origin and #189 is not Android-only at all; they
were simply unread. That is the argument for this class of work
generalised: a platform nobody can read is a platform where every bug
costs what #52 cost.
#135 is now an instrument and a redirection, not a fix. The
Findings ranked the ring-buffer underrun first, on the sound reasoning
that its audible signature matches the report. Measured on the device
it is zero — steady playback, playback under a full index build,
and playback across six seeks, all zero, with the instrument proved
live at 1 Hz by a temporary unconditional build. This issue's own
Direction says what follows: candidates 1 and 3 are out.
Candidate 2 gained hardware evidence in the same pass:
dumpsys audioreports our own stream as
OpenSL ES AudioPlayer (Buffer Queue) ... sampleRate=48000whilespeakerSampleRateis hardcoded to 44100. Sothe remaining work on #135 is the device-rate one, and it now has a
measurement to be judged against rather than three plausible guesses.
#135 is unclaimed and its comment carries the table.
On the sequence itself, nothing else moves. #186 and #187 are next
at
Priority/High, then Phase 4 proper (#63, #67, #71, with #54 and#68 as the polish pass). #189 and #190 are new and both
Priority/High— #190 is a silent performance cliff on the slowest device this app
runs on, and #189 is a feature that has not worked in either platform
for some time, so both have a claim on being taken before Phase 4.
Placing them is a judgement I am leaving rather than making.