`config-section .header` is ambiguous once a section holds a job, and
`failure-voice.spec.ts` was the one I did not grep for. It passed on
chromium and failed on webkit in the same CI run, which is the tell:
the two engines share one app, so the second one runs with a finished
scan the first one left behind.
The NOTES entry already says a class name is not a selector's contract;
this is the same fix, by role and name.
The retired-destination note sits beside #25's storage paragraph
because it is the exception to it: an absent key is free, a value is
not.
`config-section .header` resolving to two elements is in NOTES because
it cannot be reproduced by opening Settings and looking -- the drawer
only exists once a job does.
The spec worth having is not that the tab is gone -- that is one line
of a table -- but that nothing became unreachable when it went. #24
promises that no action is ever unreachable at any supported size, and
deleting a destination is exactly the change that quietly breaks it.
Two existing selectors had to give. `config-section .header` is
ambiguous the moment a section holds a job, because `job-details-drawer`
carries that class too -- so `settings-reach.spec.ts` locates a
disclosure by role and name instead. And `page-header`'s and
`offline-icons`'s view lists lose an entry each.
Closes#27
Nothing it carried is gone -- the two commits before this put all of it
somewhere the work is already being done.
A retired destination is the one shape #25's storage decision does not
make free. A visibility entry is a map key and an unknown key is
dropped on load; a launch page is a *value*, and an unknown one fails
validation -- which on the load path means the app refuses to start for
whoever had Jobs selected. `RetiredViews` is that list, read by
`ApplyDefaults`, which treats a retired name as a zero value. An
unknown-but-not-retired name still errors, because that is a typo and
saying so is the useful answer.
Scanning goes back where libraries are managed -- the Jobs tab's own
comment said the per-library controls had been taken out of Settings to
build it. "Scan All" and "Full Rescan" join "Add Library", "Scan now"
joins the per-library overflow menu beside Rename and Remove, and a
library being scanned says so where its track count goes.
Each surface then gets the job rows for its own kind: scans under
Libraries, index and enrichment under Search Index, downloads under the
download clients, and the autotag apply in the Autotag view -- where
stopping a run matters most, since applying rewrites tags on disk and
that view had no cancel at all.
The autotag panel shares the header's grid row through a wrapper rather
than taking a third row: it is display:none while nothing is applying,
which is nearly always, and a grid row would still spend the
container's gap on it.
The Launch Page select is derived from `VIEW_META` instead of listing
its ten options, since removing a destination is exactly the change
that leaves two hand-written copies disagreeing.
Reading the app before moving anything turned up that four of the five
job kinds already have a home showing their work: Settings → Search
Index draws per-tier index progress, `downloads-view` draws every
download's lifecycle state, `autotag-view` draws its own apply ring,
and only `library-scan` had nowhere but the Jobs tab. What none of the
four had is the *generic* affordances — pause, cancel, Details, the
log, and a finished job you can dismiss.
So this is a panel embedded beside each of them rather than one
"Background jobs" section in Settings, which would have been the tab
again under another name.
Three rules in it. The controls are `applyJobControl`, not a
reimplementation, which is what keeps the index build's "you will
discard hours of downloading" confirmation alive across the move. A
panel with nothing to say is `hidden` rather than empty, host margin
included, because an idle panel in four places is four pieces of
furniture describing an absence. And there is no "Clear finished":
`ClearFinishedJobs` is global, so a Clear under Libraries would discard
the index build's history too.
`JobKind` also gains `download`, which the backend has had all along.