CloudSocialClient now parses the modern JSON inbox instead of the host-gated legacy Atom feed (which 404s on a normal cloud base URL), so the cloud inbox can actually sync; the dead Atom parser is removed. CloudSignIn records lastError and settings shows it (e.g. an unverified email is denied with access_denied). Suite 1,602.
The audiobook speed restore ran on Dispatchers.Default (DoradoApp connects
from appScope), so every app launch died with 'MediaController method is
called from a wrong thread' — the emulator entry crawl caught it (63/63 crash,
now 63/63 ok; flow crawl 63/63). connect() resumes the controller calls on
Dispatchers.Main.
- PGR: four cars per class (12), three more code-spline city circuits (6),
six more career events (18) with unlock/reward graph integrity tests; menu
event count is dynamic now.
- Echoes: 24 authored arenas (was 12), all corridor/crystal-validated for the
radius-21 puck; existing indices unchanged.
- Bowling: 8 lanes/balls/rivals at the existing 1:1:1 proportion with a setup
layout that fits; per-lane determinism tested.
- Labyrinth verified at device parity (112+4 mazes); documented.
- Echoes and PGR entry goldens re-recorded for the new counts; specs updated.
- Suite 1,598/0.
- media/QueueEngine.kt: bounded queue (500) + played-history (100) with
back/forward branches, insert-next/move/clear; PlaybackController mirrors
mutations to Media3, previous() restarts within 3 s else steps through
history, and a PlaybackEvent flow exposes positioned/playing/paused/stopped.
- Built-in playlists (BuiltIn-FavoriteTracks/MostPlayedArtists/RecentTracks)
derived from hearts, play counts and history; rendered read-only in the
playlists pivot and unit-tested.
- PIN screen lock (device GemSettingPinLockScene): PBKDF2-HMAC-SHA256 salted
hash in DataStore (never plaintext), settings ▸ screen lock set/change/clear,
auto-lock toggle, lock-now; LockShade shows a tokenized numeric keypad with
a 5-try/30 s limiter and back cannot bypass; no-PIN drag-unlock unchanged.
- 30 new tests; suite 1,598/0.
- social/CardRenderer.kt: deterministic Zune Card bitmap (our own mark, Selawik,
stats); social/CardExporter.kt: ACTION_SEND PNG via FileProvider + save to
Pictures (API 29+). Social screen gains export actions.
- CloudSocialClient (feed/card/inbox) is settings-gated; inbox is local-first
via a new inbox_messages Room table (v8 + MIGRATION_7_8), InboxRepository
with mark-read and cached-offline behaviour and explicit offline labels.
- Social screen and the zunesocial mock gain feed/inbox/card tabs; zunesocial
goldens re-recorded. Server caveat documented: the cloud inbox is read-only,
so read state stays local.
- Tests: CardRenderer, CloudSocialClient, InboxRepository, Inbox migration,
plus the audiobook migration chain update. Suite 1,598/0.
- Model: Audiobook/AudiobookPart with a pure progress codec and speed ladder
(0.75/1.0/1.25/1.5/2.0).
- Scanner: a second MediaStore pass detects books by genre signal or
numbered-chapter sibling directories; grouping heuristics are pure and
unit-tested; the music scan is unchanged.
- Room v7 (MIGRATION_6_7): audiobooks + audiobook_parts tables, DAO,
AudiobookRepository with group-keyed rebuild that preserves resume and one
bookmark per book.
- UI: 'audiobooks' as the sixth music crossbar pivot (canon §3.1 home menu
untouched; GemLibraryAudiobookPartScene parity), book list, book detail with
resume CTA, parts list, bookmark jump, compact player with speed steps.
- PlaybackController: PlaybackSource.AUDIOBOOK, playAudiobook(startPositionMs),
setSpeed, speed/currentAudiobookId flows, reset on non-book queues; resume
persisted from controller state.
- Canon §3.3/§10 and roadmap D4 updated. 30 new tests; suite 1,551/0.
- PlaybackController gains an explicit PlaybackSource (LIBRARY/RADIO) set by
the radio screen; Now Playing renders station name/dial/live with no
seekbar, queue, hearts or lyrics, plus a matching screensaver.
- Picture presentation: full-bleed pager with wrap-around, title/date caption,
auto-hiding chrome (DoradoMotion), entered from both picture viewers; pinch
zoom/double-tap untouched.
- Shell hides the MiniPlayer during full-bleed presentations via a graph
immersive signal.
- Canon §4 + roadmap updated.
- Podcast search: local subscribed-feed filter + dorado-cloud podcast
directory when enabled; debounced panel mirroring the music search states;
cloud hits subscribe-and-play; explicit local-only/offline labels.
- Artist photos: cloud artwork module -> MusicBrainz release groups -> Cover
Art Archive -> cached wallpaper fallback, grid + full-bleed viewer; source
selection and URL shaping are pure and unit-tested (22 new tests).
Music screen action row gains 'smart dj': a menu that builds and plays a mix
from the current track (SIMILAR_TO_TRACK), the hearted favorites, or the most
played tracks via CloudMixService (local-first, cloud-enhanced).
- DoradoMediaNotificationProvider: dedicated public low-importance channel,
compact transport from the session command layout, album art via a caching
session bitmap loader (async re-post), content intent to the app; wired via
setMediaNotificationProvider + CacheBitmapLoader(SimpleBitmapLoader).
- Robolectric provider test builds a real session notification.
- Goldens: the fixed 900ms virtual advance rendered blank frames under load;
replaced with a settle loop (100ms steps until idle) and actual-frame dumps
on mismatch. fan-prediction's device id now derives from AppClock instead of
a random UUID so entry frames are deterministic. Two full executions green
(1,488 tests).
- TapRenderersFactory installs TeeAudioProcessor into the audio sink so
VisualizerBus mirrors rendered PCM into a mono ring buffer (no RECORD_AUDIO
permission; buffers pass through untouched).
- SpectrumBands: log-spaced band mapping, sqrt perceptual scaling, per-frame
peak-hold decay (pure, unit-tested).
- SpectrumVisualizer accepts live levels and falls back to the procedural
animation before the first window; Now Playing polls per frame and resets
the bus on pause.
- Tests include an end-to-end PCM-tap integration test. Suite 1487/1487.
- FadeRamp.kt: pure linear ramp math (window, steps, bounds) with tests.
- PlaybackController: live crossfade setting provider; tail fade-out via the
position ticker, fade-in on AUTO transitions, quick fade for manual skips,
pause resets volume; sleep timer with remaining StateFlow that fades out and
pauses on expiry; countdown surfaced in the Now Playing status OSD.
- Settings ▸ playback: crossfade off/2/4/6/8 s and sleep timer
off/15/30/45/60/90 min (persisted; canon §10 labelled as extensions).
- Canon §10 + roadmap M6/M10 updated.
Scans the external decompiled corpus and reports per-app framework/GL
classification plus the Zune framework families each app uses. Writes a
prose-only summary for dorado-emu docs.
Adds zune-homebrew-pack-v1, zune-Stuff, zune-4.8-beta-2098,
hexic-for-zune-hd and zune-firmware-x-86 to the mirrored categories with
a dedicated --stage intake, and merges per-item results into the shared
_mirror-report.json instead of overwriting prior runs.
- AppClock seam: production reads the system clock; tests freeze it. All
app seeds/time reads route through it, so entry frames are deterministic.
- GoldenCaptureTest now covers every app at device 480x272 and adaptive
landscape (126 goldens) with the clock frozen at 2024-06-15T12:34Z; the
four clock-screen exclusions are gone.
- Checklist regenerated (goldens 126/126, flow crawl 63/63).
- Audit §8 records the Track A hardening results. 1,477/1,477 tests.
- AppTouch.kt: appTap (clickable with null indication: TalkBack click action,
always-latest lambda, no Material ripple), appHold (press/release with an
accessible click), appDescription (screen-reader summaries for boards and
readouts).
- Converted button/row/tab controls across the catalog; positional board
taps and drags stay raw but now carry board state descriptions; 3D hosts
describe mode/score.
- Six entry menus gained verticalScroll because the new semantics exposed
zero-height rows at the adaptive canvas (previously untappable).
- Goldens re-recorded for the six layout-affected screens.
1410/1410 tests; ui_lint clean; LayoutBounds 126/126; flow crawl 63/63.
- CI now runs lintDebug, tools/ui_lint.py and a py_compile check on the
corpus tools after the unit/UI suites.
- tools/emulator_flow_crawl.py drives each app's primary flow (element taps
by text bounds since pointerInput controls lack click semantics), then
backgrounds/relaunches and cold-restarts it, scanning logcat per step.
Baseline: 63/63, 0 crashes (reports/emulator/flows/, git-ignored).
- tools/ui_lint.py + DesignInvariantTest guards: MiniSynth must start,
pointerInput(Unit) must be reviewed, sub-screens must forward onBack, IME
wiring must exist. The synth rule immediately caught ColorSpill,
Supernova and Tiles shipping silent SFX — fixed.
- docs/ui-parity-checklists.md: 63-app coverage (spec/smoke/bounds/golden/
crawl, zero open gaps).
- 1,410/1,410 tests; lint green.
For every app at adaptive portrait and landscape, no clickable semantics
node may sit entirely outside the viewport unless it has a scrollable
ancestor. 126/126 green — the off-screen-control class from the audit is
closed for tappable (clickable-semantics) UI.
- GoldenCaptureTest (ParameterizedRobolectric + native graphics) captures
each app's entry screen at device size 480x272 and compares within a
per-channel tolerance; goldens recorded to app/src/test/goldens (880KB).
- The goldens directory is a declared test input so CI re-runs on change;
-Dgolden.update=true re-records after intentional visuals.
- Harness root tagged for exact-canvas capture.
Verified: corrupted golden fails, restored golden passes.
- BackContractTest proves system back returns from a game sub-screen to its
in-app menu (checkers records, hexic difficulty).
- Fix the class of sub-screens that declared an onBack parameter but never
passed it to DetailScaffold (checkers/chess records+learn, trash throw
about, bowling records, hexic difficulty), so the H-01 contract applies.
1221/1221 tests green.
- fan-prediction: duplicate offline banner removed.
- audiosurf: ride rows 46dp so artist lines are not clipped.
- shuffle by album: transport wraps (FlowRow) so 'shuffle' is readable.
- sudoku/reversi: duplicate in-content headings removed (H-13).
- weather: condition glyph clipped so no stroke bleeds into neighbours.
- DetailScaffold now routes hardware back through its in-app onBack (the
header contract), so sub-screens no longer exit the whole mini-app; the
context menu/prompt intercepts back to dismiss (H-01, H-02/03).
- ContextMenuOverlay anchored bottom-center inside a full-size Box (menus no
longer render over the cropped header); PromptPanel resets per request so
nested prompts no longer inherit the previous text (H-02/03).
- Root imePadding + windowSoftInputMode=adjustResize keep text fields above
the keyboard (H-04).
- Wake shade on ON_STOP instead of ON_PAUSE: permission dialogs and
deep-link relaunches no longer raise the unlock shade (H-07).
- Checkers/Chess/Hexic start MiniSynth so game SFX actually play (H-10).
Full suite 1150/1150 (includes 63-app smoke suite).
Launches every registry app via the debug deep link, screenshots it, and
reports crashes (filtered to the app package) and blank screens. Baseline
run: 63/63 launch, 0 crashes, 0 blanks. Screenshots + JSON land in
git-ignored reports/emulator/.
Every registered mini-app renders through the real host path at device
480x272, adaptive portrait and adaptive landscape with a non-empty
semantics tree and no composition crash. ParameterizedRobolectricTestRunner
keeps Robolectric active per parameter; the harness provides the
MenuController the real root injects. 63/63 green.
- Add ui-test-junit4/ui-test-manifest (test classpath) and enable
unitTests.includeAndroidResources; pin Robolectric sdk=34.
- Debug-only deep link dorado://app/<slug> (release ignores) for automation.
- TestDoradoApp disables the app-level Media3 connect, which cannot bind
under Robolectric; DoradoApp is open with an autoConnectPlayback flag.
- MiniAppTestSupport: real app graph + real host path (MiniAppScreen) inside
DoradoTheme/DeviceCanvas at DEVICE 480x272, PORTRAIT 400x800 and
LANDSCAPE 800x360; MiniAppHarnessTest proves it renders.
- Canon §8 now enumerates all 62 implemented packages by category with the
provenance rule (re-derived behavior, re-authored content).
- README counts and the mini-app section describe the full 62-app matrix,
the engine3d core and the dead-service local UIs.
- Parity roadmap gains §9 (M16 program record: waves, evidence, gates,
known deltas, corpus acquisition results).
- Audit/gaps regenerated: 55 native + 7 dead-service shells, zero unmapped
catalog rows.
- Lint: replace unused BoxWithConstraints scopes with Box (8 apps) and read
the locale from LocalConfiguration in Animalgrams.
Gates: assembleDebug + test 1086/1086 + lintDebug all green.
A resumed mirror was blocked because the pre-flight summed every item,
including the 48 GB already verified on disk. The gate now subtracts present
files and reports total vs still-missing; the full archive (70 items,
51.4 GB) then completed with 0 failures.
Email, Facebook, Twitter, Messenger, Weather, MSN Money, Zune Reader and
Zune Social rebuilt from the decompiled screen inventory as offline local
surfaces (simulated content, clearly labelled): mail chooser/inbox/viewer/
composer with validation, the Facebook pivot shell with composer and
threads, the Twitter timeline/replies/favourites/DM shell with 140-char
compose and @-to-DM retargeting, the Messenger presence/thread/roster hub,
paged city weather with a deterministic forecast model, Money
watchlist/markets/converter/articles, the Reader library/pagination/TOC/
bookmarks with original sample text, and the Social memorial card.
Pure-Kotlin models (EmailModel, FacebookModel, TwitterModel, MessengerModel,
WeatherModel, MoneyModel, ReaderModel) with persistence via appState; 55 new
tests. Registry migrated to the new *App() names. Full suite 1086/1086.
- echoes: deterministic arena with input-path echo replay, 12 original maps,
five modes, power-up table, achievements, lives/invulnerability.
- labyrinth: engine3d tilt-marble with swept physics, 116 seed-generated
mazes across five acts + bonus, checkpoint rewind, par stars.
- audiosurf tilt: AudioFeatures-driven deterministic courses (Normal/Hard/
Visualizer), lane steering, chain/perfect scoring, exact medal fractions.
- lucky lanes bowling: deterministic pin physics, full 10-frame scoring,
Exhibition/Blackjack/Golf, five original lanes and 3D lane rendering.
- pgr ferrari: fixed 30 Hz sim (torque/gears/grip/drag/downforce), three
spline circuits, 4-car AI, full kudos catalogue + combo/stash, 12-event
career and garage economy, engine3d city rendering.
- vans sk8: paraboloid pool physics, swipe trick table, grinds with balance,
combo/multiplier rules, 12 events, 27 achievements, engine3d bowl.
All six registered and catalog-wired; audit regenerated. ~250 new tests;
full suite 1032/1032 green.
- 3d picture puzzle: engine3d OpenGL board with 3x3/4x4 grids, one/two-sided
play (single shared empty slot model), generated 7-category artwork via
PuzzleTextures, ray-picked tiles, flip/hint/timer and per-config best times.
- dr optics: pure-Kotlin 2D optics tracer (mirrors, arcs, polygons, lenses,
Snell + TIR) with 41 authored levels and the 6/16/20/24 unlock ladder.
- finger physics: shared sequential-impulse Physics2d solver (circles + OBBs,
joints, explosions, gravity variants) with 10 modes x 9 authored levels.
- tiki totems: physics block-removal with 13 packs x 8 authored levels.
- fingerpaint: stroke model with undo/redo/eraser/RDP + local pass-and-play
draw-and-guess rounds (original networked play replaced by local mode).
All 5 registered and catalog-wired; audit regenerated. 69 new tests; full
suite 872/872 green (DesignInvariantTest included).
Phase 2 infrastructure for the 3D official titles:
- Math3d: pure-Kotlin Vec3/Mat4 (column-major, inverse/normal matrices),
Camera3d with NDC ray construction, ray/sphere and ray/plane intersection.
- Mesh3d: procedural box/plane/cylinder/quad builders with bounds for picking.
- Scene3d: tagged nodes, materials (flat/textured/unlit/emissive), directional
light, ambient, fog, bounding-sphere picking and ground picking.
- GlSceneView: GLSurfaceView renderer (cached mesh/texture uploads, context-
loss safe) plus a Compose AndroidView host with tap-to-pick; no third-party
dependency, all geometry/textures authored in code.
- Engine3dTest: 11 pure-JVM tests for matrix/ray/pick/mesh invariants.
Full suite 803/803 green.
- hearts: Standard/Wildcard/Turbo modes, shoot-the-moon, passing rotation
(Left/Right/Across/None) with simultaneous passing, first-trick point ban,
Easy/Hard AI, 100-point games, autosave; stall fixes in the trick loop.
- spades: Easy/Hard bidding and play AI, Nil/Blind Nil (+/-100/200), official
bag-out formula, 500/300 targets, round-history scoreboard, deterministic
one-action-per-state loop (fixes the 'ai playing' stall).
- texas hold 'em: new 6-seat PokerTableEngine with layered side pots, six AI
personalities across Easy/Medium/Hard, pot/blind-aware sizing, seven-event
tournament ladder with bankroll gating and hand history; heads-up hand
ranking APIs preserved for LogicTest.
34 new tests; full suite 437/437 green.
Pure move in the same package: solitaire/sudoku/hexic/reversi and
hearts/spades/checkers/chess/poker each get <Game>Engine.kt and <Game>App.kt;
shared card chrome moves to CardViews.kt (EdgeText/rankLabel/suitGlyph/
PlayerHand/PassPicker widened from private to internal). No behavior change;
330/330 tests green.
- alarm: four-page clock/alarm/sleep/settings flow, minute-match firing with
snooze and 30-min bow-out, source fallback to buzzer, sleep timer with
shake-to-reset via rememberTilt(); existing Room alarm list preserved.
- level: all three instruments on one canvas with 90-degree travel clamps,
0.1-degree readouts and peak-hold memory; shared rememberTilt() replaces
the inline sensor, with a graceful no-sensor state.
- metronome: 40-340 BPM dial with drag, tap tempo, 16-cell accent grid,
beat-count handling; synth clicks.
- chord finder: 12 enharmonic roots x 8 qualities with multiple voicings,
fret-window shift, finger-number dots, built-in metronome.
39 new engine tests; full suite 330/330 green.
Pure move: CalculatorApp, NotesApp, StopwatchApp, MetronomeApp, LevelApp,
ChordFinderApp, ShuffleByAlbumApp, MusicQuizApp, AlarmClockApp, CalendarApp
each get their own file in the same package (private helpers travel with
their app). No behavior change; unblocks parallel fidelity work per app
without shared-file conflicts.
Phase 1 completion: every official package now has a synthesized spec with
screens/flow, rules/scoring/AI, controls, content inventory, implementation
plan and an Assembly!Type.Method citation log. 62 specs / ~9,000 lines;
documentation-first gate is closed.
Notable corpus findings recorded in the specs:
- color-spill is blocked upstream: its marketplace package shares a GUID with
Reversi, so the archive payload is Reversi.exe (register notes + spec gap).
- W2 AI tiers, W3 score/simulation constants, W6 30 Hz deterministic
simulation and content inventories are now pinned for implementation.
No Microsoft content is committed; analysis only.
Phase 2 infrastructure for the official-app program:
- Room v6 app_state table (AppStateEntity/Dao/MIGRATION_5_6) behind
AppStateRepository, wired into the graph for save/resume and board snapshots.
- Sfx.kt: deterministic LCG noise, tone/sweep/noise/arpeggio generators, and a
cached 16-cue SfxBank for games (synthesized only; no sampled audio).
- AppSensors.kt: rememberTilt() accelerometer helper (level, tilt calculator,
motion games).
- OfficialCatalog: the seven dead-service mocks now carry installedIds so the
marketplace resolves them.
- Tests: AppStateStoreTest (round-trip + reopen), SfxTest (determinism,
inventory), OfficialAppsTest (register⇔catalog⇔registry⇔spec gate).
186/186 unit tests green (JDK 21).
Phase 1 of the official-app reimplementation program:
- tools/app_mine.py: batch-decompiles the external corpus with ilspycmd,
emits per-app indexes (types/methods/strings/constants/content with PNG
dimensions and XNB headers), generates spec skeletons, and regenerates the
audit matrix + machine-readable gaps register.
- docs/official-apps.json: the 62-package register (slug/title/exe/category/
corpusDir/installedId/status/wave/spec) that drives tooling and tests.
- docs/apps/: a behavioral spec per package (documentation-first gate).
- docs/official-apps-audit.md + official-apps-gaps.json: tracked matrix.
61/62 packages mined (weather is a dead service with no shipped package). No
Microsoft content is committed; counts and synthesized analysis only.
Phase 0 of the official-app reimplementation program:
- zune_archive_mirror.py: staged, resumable, checksum-verified mirror of the
Zune Archive (70 items, 51.4 GB pre-flight) into an external untracked dir,
with a capacity gate, --root override, and per-item manifests.
- zune_app_corpus.py: extracts the 61 decompiled official-app ZIPs and
verifies every file against the published hashes.txt (7843/7844 ok; the
one miss, sudoku Database.xml, is absent upstream).
No Microsoft content is committed; both scripts write to the external corpus
only.
- Add scripts/reconstruct_nk_modules.py to rebuild the kernel-only modules
(zcstfs.dll, keyvault.dll, DwXfer.dll, zcblock.dll, zpartstream.dll) from
NK.bin into the external corpus.
- Update the module inventory and API reference: 114/114 modules, 67,399
functions decompiled, 4,236 exports.
- Correct the ZCP inventory and asset notes: the payload is a ZCSTFS volume
(plaintext for the runtime), and marketplace keys are per-package AES keys
unwrapped from an RSA-2048 blob by a device-provisioned keypack.
Document the follow-up fixes that were listed but not applied in the first
pass, update the deferred register (fling cap, visualizer and eager
device-link items are done), and add close-out on-device evidence.
Radio actions move onto the dial so the station list gets a full-height
region; Device Link becomes a LazyColumn (keyed device/pending items) and
long titles crop at their column instead of overlapping 'copy back'.
- Fling velocity cap scales with the adaptive density multiplier so it no
longer shrinks on scaled layouts (device-mode behavior unchanged).
- Adaptive scale ceiling 2.1 -> 2.6 for tablets/foldables.
- Visualizer reads phase in the draw scope (no per-frame recomposition)
and the 60s loop is seamless (integer harmonics over 2pi).
- Screensaver drift expressed in dp instead of raw px.
Glance 1.2 has no URI-based ImageProvider, so the updater decodes a
128px PNG off-main and the widget renders it beside title/artist/album;
declared size raised to 110dp/2 cells with description and preview image;
removed the dead legacy albumArtUri helper.
Album/artist/genre/playlist track lists reserve the MiniPlayer strip;
album-not-found and empty-genre states replace blank panes; album play/
shuffle hide when there are no tracks; the related-artists explanation
wraps instead of cropping and links to MusicBrainz search (artist pages
require an MBID).
Adds docs/ui-ux-audit.md: scope, severity table of the 42 defects found and
fixed across screens and all 29 mini-apps, on-device verification evidence,
and the deliberately deferred items (mediaId namespacing, eager device-link
composition, fling-cap density, visualizer recomposition).
- Hexic circles derive their radius from the tighter axis, so tiles no
longer overflow their cells or overlap the score line; Sudoku/Reversi
subtract the inter-cell gaps so the last row fits the viewport.
- Every mock page scrolls, reserves MiniPlayer space and wraps long
sentences instead of clipping them at the screen edge.
- Podcast RSS parser scopes titles to channel vs item, reads
itunes:duration and summary, and no longer mis-attributes episode
titles; feed fetch runs on IO; feeds gain a refresh action; feed
screen shows the real title and an empty state; the video pivot says
it is unsupported rather than duplicating audio.
- Radio: drag detector no longer re-keys while dragging; needle maps
frequency left-to-right and ticks align to 87.5–108; list padding.
- Marketplace: details' back returns to the list (was popping the whole
marketplace), description wraps and scrolls, videos show a loading
state, music has an empty state, lists reserve MiniPlayer space.
- Settings: multi-line info rows wrap instead of clipping, sign-in
reports success/failure, update check distinguishes unreachable from
up to date; lyrics reserve bottom space.
- Device link: status copy derives from pairing state; manifest shows
'+N more' instead of silently truncating.
Home: Smart DJ uses the full library; history long-press can pin (unpin was
a no-op); watermark clears the MiniPlayer; 'new' has an empty state.
Music: album tiles are square; search long-press menu; per-pivot empty
states; MiniPlayer/footer padding so rows are never covered.
Videos: playback is a fullscreen route (MiniPlayer suppressed, header
returns to the list), seek bar accepts tap/drag, music pauses on entry.
Pictures: tapped photo opens at its index; favorites open the viewer;
albums pivot scrolls; system Back closes the viewer; pan is edge-clamped.
Internet: WebView released on exit; bookmarks/history are tappable.
Social/Radio/Marketplace lists reserve MiniPlayer space.
Now Playing: back arrow exists with nothing playing; control taps reset
the screensaver timer; volume readout times out and shows 0; dim is a
translucent veil above the saver; OSD clock ticks; skip deadband is
density-corrected.
Components: AlbumArt falls back on load error; crossbar hit targets fill
the bar and gaps no longer select neighbours; the alphabet rail only
appears on long lists and reserves end padding.
Lock shade: unlock animates before dismiss, offset resets, Back closes it,
wallpaper is decoded off-main and downsampled.
Cloud: token exchange is IO-dispatched, malformed JSON cannot crash,
state must match exactly, sign-out disables cloud, redirect host checked;
POST_NOTIFICATIONS requested for the media notification.
- Sudoku: generated puzzle (not the solution) is dealt; given-mask fixed;
win compares against the stored solution; board scales to the viewport.
- Hexic: clearing no longer re-creates clusters (infinite loop/freeze);
board is observable state; canvas draws and hit-tests with one mapping.
- Solitaire: exposed cards flip, waste pile is playable, black suits are
readable, compact layout fits 272dp.
- Reversi: board scales; game-over result + new game; win/loss recorded.
- Hearts: passing phase completes (was stuck forever); opponent hands are
summaries; 13-card hands fit; scores recorded once.
- Spades: spadesBroken flag, correct follow/discard rules, team scoring
with bags, AI auto-advances (a fresh deal no longer stalls).
- Checkers: winner detection fixed; multi-jump AI continues; board and
taps share one canvas (overlay was offset and covered the header).
- Chess: castling rights revoked on rook capture (NPE fix, in-place masks
corrected); piece letters drawn; AI search off the main thread at depth
2; only terminal results recorded.
- Hold'em: per-street contributions/acted tracking actually deals flop/
turn/river; showdown compares kickers and awards the pot; AI hole cards
hidden until showdown; cards rendered by SolCardView.
- Calculator keypad rows are weighted so the full basic/scientific pad fits
the 224dp device-mode content area; +/- no longer corrupts subtraction;
engine gains ^ and sin/cos/tan/ln/log/sqrt.
- Synth: piano no longer multiplied by exp(-6) (was ~-52dB inaudible);
AudioTrack writes move off the main thread (suspend playSamples).
- Piano gains black keys; drum machine gains a BPM control and re-reads
tempo each bar; metronome retimes on BPM change with one click loop.
- Notes placeholder overlays the field; back is the cropped header and
autosaves (DetailScaffold grew an optional onBack).
- Stopwatch shows centiseconds, split laps, scrollable lap list.
- Shuffle-by-album play button fits 272dp (side-by-side layout); quiz no
longer hangs when the library lacks 4 artists/albums; level shows both
axes; chord finder stops substituting C major for unknown shapes;
fretboard draws O/X and fret 5.
- Alarm: time prompt (hour+minute), delete cancels PendingIntent, edit
respects disabled state, full 64-bit request codes, weekly mask fixed.
- Calendar keys appointments by full date; long-press lists/deletes.
- MiniAppScreen no longer wraps apps in a second DetailScaffold; every
mini-app already provides its own cropped header. Removes the stacked
double header that consumed 96 of 272 device-mode design units.
- MiniPlayer is suppressed on mini-app and fullscreen viewer routes
(canon 8) and its transport target is a bare 32dp box instead of a
48dp Material IconButton that overhung the bar.
- safeDrawingPadding moved outside the scaled canvas so real insets no
longer shrink/offset the 480x272 device composition.
- Device mode keeps the landscape 480x272 canvas in portrait instead of
swapping axes (screens are landscape-authored).
- Widget transport actions run on the main looper (MediaController).
- add publish job on main push / dispatch (PRs build+test only)
- dorado-hd-<sha7> prerelease with dorado-hd-<sha7>.apk
- keep last 10 prereleases; serialized via concurrency group
rememberZuneFlingBehavior(frameRetention) exposes the decay retention.
Vertical lists keep the device value (0.95/frame); horizontal lanes use
DoradoMotion.KINETIC_LANE_FRAME_RETENTION (0.94/frame) so carousels do not
over-glide. Labelled post-device in the new canon §10; DesignInvariantTest
and DoradoMotionTest (3/3, incl. lane-shorter-than-list) green.
Home Quickplay/New, marketplace (installed/featured/dead-services) and
artist-album LazyRows now share the device kinetic decay instead of the
platform spline fling. All scrolling surfaces (KineticList, album grid,
lanes) now use rememberZuneFlingBehavior().
- MusicScreen album grid now uses the shared Zune fling (was platform spline),
matching the kinetic lists.
- docs/zune-hd-touch-settings.md §6: document the xuidll scroll tick
(VA 0x41841D58) and its velocity/position/decay state for provenance.
Mine the reconstructed firmware corpus for the shell's real kinetic
parameters and wire the corroborated ones into the app.
- docs/zune-hd-touch-settings.md: exact XuiTouchSettings struct (80 bytes,
xuidll.dll VA 0x41874314), XUI defaults and gemstone.exe effective values,
accessor/override model, provenance and confidence.
- canon §6/§9 + design-tokens cite the extraction; fix stale AlphabetJumpRail
reference in zune-hd-disassembly.md.
- DoradoMotion: KINETIC_FRAME_RETENTION 0.95 (XuiTouchSettings[0x1C], shell
value) and kineticFrictionMultiplier().
- ZuneFling: exponential-decay FlingBehavior wired into KineticList for the
device's long deceleration (no springs).
- DoradoTokens.SKIP_DRAG_PX: 24 -> 25 (XuiTouchSettings[0x10]).
- KineticList: the alphabet rail's onLetterFocus/onDragEnd were dead code;
implement drag-to-scrub (tap still opens the A-Z index).
Verified: assembleDebug, testDebugUnitTest (DesignInvariantTest 6/6,
DoradoMotionTest 2/2), lintDebug all green.
WinCE e32_rom e32_unit entries are 1-indexed relative to standard PE
(unit[1]=Export ... unit[7]=Debug). Map them accordingly, clear the
security directory (PE expects a file offset), and zero any directory
whose RVA falls outside reconstructed section bounds. Verified: all 109
modules reconstruct and xuidll.dll/zhud_serv.dll export tables resolve.
Fixes an issue where top hub titles (e.g. 'music', 'videos', 'settings')
were horizontally sliced in half across their midsection.
- EdgeCropText.kt: Remove negative vertical offset (visibleHeight - fontSize)
in CroppedHeader; align text to CenterStart with EDGE.dp leading margin.
- DoradoTokens.kt: Introduce HEADER_HEIGHT = 48dp and align
TYPE_HEADER_CROP_VISIBLE to 48dp to accommodate full 40sp typography.
- MiniAppsUtilities.kt & Mocks.kt: Use TYPE_NOW_TITLE (26sp) for scaled
numerical readouts formerly tied to TYPE_HEADER_CROP_VISIBLE.
- docs/zune-hd-ui-canon.md & design-tokens.md: Update canon section 3.4
and design tokens to reflect vertical integrity and horizontal signature crop.
- Add DetailScaffold / CroppedHeader back navigation to MusicScreen and MarketplaceScreens
- Fix NowPlayingScreen gesture conflict, pointerInput keys, and enlarge back button touch target
- Add SpectrumVisualizer with 24 zero-radius equalizer bars for Now Playing screensaver mode
- Redesign KineticList jump grid into 4-column authentic Metro tiles with instant letter jump
- Enable vertical scrolling on QuickplayScreen
- Enhance CrossbarBar with BringIntoViewRequester auto-scroll and typography weight emphasis
- Preserve LockShade on app resume until explicit upward drag gesture
- Correct DeviceCanvas orientation to support 272x480 portrait and 480x272 landscape
- Declare Android 13+ granular media permissions and remove crashing LIMIT queries
- Add bug hunt report documentation