fix(annotator): the withheld Finish job explains itself — a focusable tooltip carrying the unresolved count - #432
Merged
Conversation
… tooltip carrying the unresolved count (#427)
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.
Closes #427
What changed
The withheld Finish job on the last frame now explains itself properly (
DESIGN.mdprinciple 9, with principle 4 riding on it):titlespread. The reason renders through the product's tooltip primitive; thetitleattribute is gone from the control.aria-disabled, never the native attribute, for the withheld state.ZoomWidget's finding, applied here: a natively disabled<button>receives no pointer events and cannot take focus, so its reason could never open. The press is refused in the handler instead. Nativedisabledsurvives only where there is nothing to explain — aFinishedjob (the label is the explanation) and the in-flight press.3 frames unresolved — annotate or skip them to finish the job.(singular handled). The number isoutstandingWork(counts)frombatchState.ts—unannotated + review_pending, the two states whose settling is what makes the kernel declarecomplete— so the count and the readout share one progress source and no second derivation exists. The count-less sentence survives only while the counts query has not answered.completeabsent from the job'sallowed_actions) — nothing here computes legality.The e2e stub gains a
jobSettledlifecycle knob so a job can honestly decline to declarecomplete, and the jsdom harness now answers/jobs/{id}/progress.Found, not fixed
title; same pattern, separate control, not expanded here beyond the issue's scope.Test plan
topBar.test.tsx— the principle-9 test now assertsaria-disabled+ notitle+ tooltip prose on hover + a press that sends nothing; plus three new: the count copy (2 unannotated + 1 in review → "3 frames unresolved"), the singular copy, and no-tooltip-once-live.e2e/annotate.spec.ts(chromium) — "a withheld Finish job explains itself on focus, with the count": tooltip opens on focus (principle 4), carries the correct count, and a forced click sends nothing to the wire. Playwright itself refuses to click anaria-disabledcontrol, which is the assistive contract observed from outside;forceis used to prove the handler behind it.Mutation verification, each by its exact diff, reverted after (tree byte-identical to the commit):
outstandingWork(counts) + 1)disabledGate stages (staged; exit codes verbatim):
uv run pytest -q(green except the ten ffmpeg-environment tests recorded on #429)uv run ruff check ./uv run ruff format --check .uv run mypy src/visionset/uv run lint-importspnpm -r build/pnpm test/pnpm -r lintCI=1 playwright test, 228 tests)CI=1 playwright test -c playwright.cycle.config.ts)