Align TV fidelity and recovery behavior #37
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fm/tv-fidelity-followups"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Outcome
Close the reproducible TV fidelity offsets and the specified small behavior gaps before the next test build. The locked prototype and TV specification remain the acceptance criteria. Platform Roboto and the prototype's baked-in CSS behavior are retained; no per-title compensation is added.
AI-assisted (fork-internal) — the fork-internal AI policy waiver applies.
Visible fidelity
Measurements are native 1920×1080 at density 2.0. Row/box coordinates are separate from glyph ink. Reviewer references below name the supplied Sonnet review reports, linked to the corresponding screen pull requests.
The supplied
tv-slice2-shell/compare.pyimplementation generated the full native pairs and the same numeric columns: mean absolute RGB error, pixels over 12 RGB, and nav mean RGB error. Its output/capture directories and state lists were selected for these screen families. Exact RGB summaries and pairs live with the task proof below; they are measurements, not an automatic visual approval.Existing accepted font-only differences remain named: the narrower request subtitles in st-073/st-080/st-110 remove one 36.4 px body line; st-074's previously approved omission of the prototype-only Simulated prefix removes one 31.2 px caption line. The Titles review measured st-062's recovery body as one native line versus two reference lines, with button fill top 322 versus 357.6 (−35.6 px). No font substitution or per-title offset is introduced.
Behavior
HomeRatingCacheTest.episodeScoresShareSeriesSeasonIdentityWithoutCrossingEpisodesOrSeasonsandseasonCapacityCountsSeasonsNotEpisodesAndIsIndependentOfTitleCapacityfailed before the fix and pass after it. A season retains episode-specific scores/timestamps; another Jellyfin UUID for the same series/season/episode finds the observation. Different episodes/seasons never borrow its score. Six-hour expiry and independent 300-title/300-season limits remain.HomeKeysTest.heldOkRepeatEventsDoNotReplayButtonsOrActivateCardsBeforeReleasedispatches repeatCount=3 and passes. It checks one button activation and no card activation until release. No duplicate test or weaker assertion was added.LibraryReadFacadeTest.firstTwoHundredTitlesPublishWhileTheNextChunkIsSuspendedproves 200 titles publish while the later SDK call waits, then verifies deduplication and the complete disk copy.LibraryProgressiveSurfaceTest.firstChunkPaintsAndAcceptsRemoteInputBeforeTheLastChunkrenders the real host, moves focus with a remote key before the final chunk, and keeps the exact title after a new title sorts ahead of it. Native proof:library-first-chunk.png.LibrarySnapshotStoreTestassertions remain. NewfailedLaterChunkKeepsTheCompleteSavedCopyOrTheColdPartialWithoutSavingItproves saved-copy retention and that a cold partial remains usable with a retry tail but is not persisted. Loading-focus publication also respects intervening nav input.LibraryKeysTest.mixedCatalogueRowsKeepMovieAndSeriesWithTheSameNumericIdentityDistinctrenders rows whose movie and series share numeric IDs, navigates to the series and opens the correct title. Row keys now match the cards' canonical identity.DiscoverKeysTest.notInterestedInEightPressesAndUndoRestoresEveryIndexkeeps every original assertion and adds silent-Undo coverage.showAgainRestoresTheHiddenPickAndAnnouncesItsReturndrives real keys through Hidden picks and checks the announcement. Title pages retain ownership of their own toast, avoiding a duplicate adapter toast.RecoveryCaptureTestsaved-Discover capture; the retry action remains Try again.OwnedSourceAuditTestruns in the design JVM task already required bymake test. It scans owned Kotlin sources for untokened dp/sp conversions, numeric Color constructors, generated font sizes below 12 sp, raw household library labels and pagination wording.plantedViolationsFailEachDoneBarRulecovers 13 negative cases;ownedScreensUseTokensReadableTextAndViewerFacingNamesaudits the real sources. Existing rendered-font/wording checks remain.Small wiring hygiene
ConductarrAudienceRecoveryTest.retryingSignedInPeopleKeepsTheUncertainSubmissionLedgeruses real local HTTP replies: an uncertain 503 POST, People retry, then the same request still yields one POST, not a second submission. Signed-out identities still rebuild; changed credentials/person/URL still select a new identity.HomeRecoveryTest.renamedHouseholdProfileKeepsItsOwnJellyfinLibraryWithoutAConductarrIdentitykeeps the viewer's library with a renamed household key and no Conductarr identity, then verifies a different saved Jellyfin user ID fails closed even with the matching display key. All affected Home callers migrate to the person model.docker/README.mddocuments the layouts, progressive/saved publication, cache identity, retry safety and durable checks. No existing assertion is weakened or removed.Not done
Proof location
/root/.treehouse/firstmate-7bab20/2/firstmate/data/tv-fidelity-followups/geometry.md,before/,visual-after/,visual-comparisons/,final-native/,final-comparisons/,final-native-manifest.jsonlibrary-first-chunk.png,discover-saved.png, behavioral result recordsThe next Sonnet review is one round, blocking only for breaking behavior or a visible deviation. Merge authority remains with Justin; this PR does not merge itself.
Commands and results
Final head:
81073c410d8118d892e60e9cf6c0d0c97ef710cf.git fetch origin main && git merge --no-edit origin/maincompleted before the final gate pair; main was already current.:wolfskin-design:testDebugUnitTestmake teston final head (one invocation)make apk-debugon the same final head (one invocation)org.justinvisser.wolfskin.tv.debug; existing versionCode remains 64. No install or release was performed.final-comparisons/; PNG SHA-256 manifest records the final head.An earlier full gate on
04b1bdd6found the new native progressive test reading the title immediately after its source-size wait (665 app tests, one focus assertion failure). The final commit keeps both exact assertions and runs them through ComposerunOnIdle, after UI publication. The full gate then passed on81073c41; no assertion or scenario was removed. Earlier implementation runs also exposed and corrected the test fixture's SDK overload matcher; a fail-fast source-error assertion prevents that mismatch from hiding behind a deferred wait.Proof includes
final-make-test.log,final-make-apk-debug.log,final-test-counts.json, final JUnit XMLs and APK checksums. Existing build warnings remain: missing optional Media3/MPV binaries use the configured stub, upstream deprecations/configuration-time classpath resolution, codec diagnostics and GC allocation warnings. They did not fail either final gate.Review (Claude Sonnet, one round): PASS, no blocking finding. Reviewed head
81073c410d8118d892e60e9cf6c0d0c97ef710cf.Visual (my own native 1920x1080 measurement against the locked frames):
Behaviour (read against the code and tests):
OwnedSourceAuditTestreally reads the sources (13 planted cases, token file exempt). My regex simulation over 99 files found 0 violations in 0.03 s. It runs undermake testthrough the app test task's dependency on the design unit tests.Scope: no existing test weakened, nothing under
app/src/main, no release/signing/version change.Non-blocking notes:
DiscoverState.restorenow requiresshowToast; all callers are migrated.conductarr-home-real.pngdiffers in tile-art loading state, a capture-timing artefact.I did not regenerate the captures (no Gradle, per brief); the measurements are mine, taken on the lane's native PNGs. Their mean-error figures reproduce the PR table. Full report:
data/review-wolfskin-37/report.md.