diff --git a/1020084/META.json b/1020084/META.json index 0681f71..a3edd6f 100644 --- a/1020084/META.json +++ b/1020084/META.json @@ -6,13 +6,13 @@ "main.navbar.link.wrapper": "verified_cdp", "main.playbar.buttons.button.wrapper": "verified_cdp", "main.topbar.wrapper": "verified_cdp", - "modal.track_credits.container": "verified_static", - "modal.widget_generator.container": "verified_static", + "modal.track_credits.container": "verified_cdp", + "modal.widget_generator.container": "verified_cdp", "search_box.container": "verified_cdp", "search_chips.wrapper": "verified_cdp", - "settings.button.wrapper": "verified_static", + "settings.button.wrapper": "verified_cdp", "settings.header.container": "verified_cdp", - "settings.section.container": "verified_static", + "settings.section.container": "verified_cdp", "sort_box.list.button": "verified_cdp", "tracklist.column_header": "verified_cdp" }, @@ -21,17 +21,13 @@ "key": null, "method": "derived" }, - "spotify_version": "1.2.84.476", + "spotify_version": "1.2.84.475", "stale_leaves": [ "main.topbar.right.upgrade_button.wrapper", "search_chips.chip", "search_chips.wrapper_wrapper" ], "status": "verified", - "unverified_leaves": [ - "main.playbar.buttons.button.wrapper__active", - "main.playbar.buttons.button.wrapper__indicator", - "main.topbar.left.button_t.wrapper" - ], - "verified_classmap_sha256": null + "unverified_leaves": [], + "verified_classmap_sha256": "027bd34749eb1a3cd4318316e15127db87f09f839537e802c89fe5137b954cf0" } diff --git a/1020084/VERIFICATION.md b/1020084/VERIFICATION.md index 053aadf..b2dbd78 100644 --- a/1020084/VERIFICATION.md +++ b/1020084/VERIFICATION.md @@ -1,9 +1,42 @@ -# Spotify 1.2.84.476 (1020084) +# Spotify 1.2.84.475 (1020084) -Pipeline: css-map inversion over stock target CSS + migrate(1020040) cross-check + static target-CSS verification + CDP e2e (deep, live Linux client). +Pipeline: derive(stock CSS -> 1020084) + static target-CSS verification + CDP e2e (deep). Published 2026-09-30. ## Notes +- Classmap derived from the stock CSS. +- Static verification found 33/36 paths in the target CSS. +- CSS-only misses observed live by their stock class, which remain verified: 0. +- Deep CDP verification observed 30/36 paths with 10/10 successful navigation steps. +- Unresolved new misses remain usable but are marked unverified; stale paths stay blocked. +- Replaces an earlier verification of this key, kept below under Earlier verification. +- Kept the earlier live status of search_chips.wrapper, which this run didn't reach. + +## Statistics at publication + +| Field | Value | +| --- | --- | +| leaves | 36 | +| static_present | 33 | +| verified_cdp | 30 | +| live_only | 0 | +| unresolved_missing | 3 | +| cdp_hit_rate | 0.8333 | +| overlay_entries | 0 | + +## Evidence + +- Classmap SHA-256: `027bd34749eb1a3cd4318316e15127db87f09f839537e802c89fe5137b954cf0` +- Overlay SHA-256: none +- Target CSS SHA-256: `24756a80b952a94905c7543dee11c43e001010c24b7c3503d65af93deee80e31` +- CDP report generated: 2026-09-30T13:34:18.079Z + +## Earlier verification + +Pipeline: css-map inversion over stock target CSS + migrate(1020040) cross-check + static target-CSS verification + CDP e2e (deep, live Linux client). + +### Notes + - 1.2.84 is the current Linux build; its hashes match no published key (verified: 0/36 raw-hash hits for both 1020045 and 1020092 against this build), so this key was derived rather than inherited. - Primary derivation inverts the CLI's embedded css-map over the classes present in the stock 1.2.84 bundle: 27/36 paths resolve to a unique hash whose semantic matches the 1020097 ABI meaning; a migrate(1020040) run agreed on 14 and was overruled on 13 where the inversion disagreed. - The three main.playbar.buttons.button.* leaves were corrected from the migration's collapse onto the player-controls__buttons container (the known text-theme ghost-button drift); the live fullscreen button carries the corrected wrapper hash. @@ -11,7 +44,7 @@ Pipeline: css-map inversion over stock target CSS + migrate(1020040) cross-check - Three leaves keep dead 1020097-era hashes deliberately (upgrade button not rendered on this build's sessions observed, category grid items not present in css-map for this build): a dead class is a harmless no-op where a wrong live class would misstyle. - Deep CDP verification observed 20/36 paths by raw hash on the routes and surfaces exercised by the verifier; modal and playback-state leaves need surfaces the verifier does not open. -## Statistics at publication +### Statistics at publication | Field | Value | | --- | --- | @@ -25,7 +58,7 @@ Pipeline: css-map inversion over stock target CSS + migrate(1020040) cross-check | cdp_hit_rate | 0.5556 | | overlay_entries | 0 | -## Verification summary at publication +### Verification summary at publication - Needs manual check: 31 - Missing in CSS: 5 diff --git a/1020092/META.json b/1020092/META.json index 91315e7..5b93571 100644 --- a/1020092/META.json +++ b/1020092/META.json @@ -2,32 +2,34 @@ "classmap_key": "1020092", "generated": "2026-07-21", "required_paths": { - "context_menu.menu_item": "verified", - "main.navbar.link.wrapper": "verified", - "main.playbar.buttons.button.wrapper": "verified", - "main.topbar.wrapper": "verified", - "modal.track_credits.container": "verified", - "modal.widget_generator.container": "verified", - "search_box.container": "verified", - "search_chips.wrapper": "verified", - "settings.button.wrapper": "verified", - "settings.header.container": "verified_targeted", - "settings.section.container": "verified_targeted", - "sort_box.list.button": "verified", - "tracklist.column_header": "verified" + "context_menu.menu_item": "verified_cdp", + "main.navbar.link.wrapper": "verified_cdp", + "main.playbar.buttons.button.wrapper": "verified_cdp", + "main.topbar.wrapper": "verified_cdp", + "modal.track_credits.container": "verified_cdp", + "modal.widget_generator.container": "verified_cdp", + "search_box.container": "verified_cdp", + "search_chips.wrapper": "verified_static", + "settings.button.wrapper": "verified_cdp", + "settings.header.container": "verified_cdp", + "settings.section.container": "verified_cdp", + "sort_box.list.button": "verified_cdp", + "tracklist.column_header": "verified_cdp" }, "schema_version": 2, "source": { - "key": "1020040", + "key": null, "method": "derived" }, - "spotify_version": "1.2.92.148", + "spotify_version": "1.2.92.147", "stale_leaves": [ "main.topbar.left.button.icon.wrapper", "main.topbar.right.upgrade_button.wrapper", "settings.text_input" ], "status": "verified", - "unverified_leaves": [], - "verified_classmap_sha256": null + "unverified_leaves": [ + "main.playbar.buttons.button.wrapper__indicator" + ], + "verified_classmap_sha256": "7b0ec24ad5bf62b6d71279e6311dd36222938b63f6968e1719250596317b7812" } diff --git a/1020092/VERIFICATION.md b/1020092/VERIFICATION.md index cc3ffe2..a169237 100644 --- a/1020092/VERIFICATION.md +++ b/1020092/VERIFICATION.md @@ -1,9 +1,42 @@ -# Spotify 1.2.92.148 (1020092) +# Spotify 1.2.92.147 (1020092) -Pipeline: migrate(1020040 -> 1020092) + static verify + CDP e2e (deep) + manual DOM probe. +Pipeline: derive(stock CSS -> 1020092) + static target-CSS verification + CDP e2e (deep). Published 2026-09-30. ## Notes +- Classmap derived from the stock CSS. +- Static verification found 32/36 paths in the target CSS. +- CSS-only misses observed live by their stock class, which remain verified: 0. +- Deep CDP verification observed 25/36 paths with 10/10 successful navigation steps. +- Unresolved new misses remain usable but are marked unverified; stale paths stay blocked. +- Derived from 1020040, which is no longer published. +- Replaces an earlier verification of this key, kept below under Earlier verification. + +## Statistics at publication + +| Field | Value | +| --- | --- | +| leaves | 36 | +| static_present | 32 | +| verified_cdp | 25 | +| live_only | 0 | +| unresolved_missing | 4 | +| cdp_hit_rate | 0.6944 | +| overlay_entries | 3 | + +## Evidence + +- Classmap SHA-256: `7b0ec24ad5bf62b6d71279e6311dd36222938b63f6968e1719250596317b7812` +- Overlay SHA-256: `8c05d9ca347e4e13fb31013df4c42bdbf16046408b989afe4d0ea6a25037800e` +- Target CSS SHA-256: `3886e4c8961e0c187af7a9f9862a259d82a040b05ba25c57f234fb4a093436f2` +- CDP report generated: 2026-09-30T13:36:40.937Z + +## Earlier verification + +Pipeline: migrate(1020040 -> 1020092) + static verify + CDP e2e (deep) + manual DOM probe. + +### Notes + - CDP e2e (deep navigation: home/search/library/playlist/context menu/settings) verified 19 leaves by hashed-class DOM presence on a stock 1.2.92.148 client. - modal.track_credits.* remapped to trackCreditsModalV2 classes (Spotify replaced the V1 modal); V2 hashes verified in live DOM via View credits. - modal.widget_generator.* verified in live DOM via Share > Embed, including content.container (ywtSYUL2xRwVlvSo, previously stale). @@ -12,7 +45,7 @@ Pipeline: migrate(1020040 -> 1020092) + static verify + CDP e2e (deep) + manual - main.topbar.left.button_t.wrapper remapped to main-globalNav-link-icon (_Bg_zSvFrEutyacG), live on the nav buttons custom navlinks clone. - Retired in 1.2.9x (kept stale, no candidate hash anywhere in the spa): topbar.left.button.icon.wrapper (icon span unclassed), topbar.right.upgrade_button.wrapper (no Upgrade button surface), settings.text_input (settings inputs are Encore form controls now). -## Statistics at publication +### Statistics at publication | Field | Value | | --- | --- | @@ -25,7 +58,7 @@ Pipeline: migrate(1020040 -> 1020092) + static verify + CDP e2e (deep) + manual | threshold | 0.55 | | css_map_entries | 2585 | -## Migration guards +### Migration guards - playbar!=actionBar - content!=closeBtn diff --git a/1020095/META.json b/1020095/META.json index a5f6054..dcc625a 100644 --- a/1020095/META.json +++ b/1020095/META.json @@ -6,12 +6,12 @@ "main.navbar.link.wrapper": "verified_cdp", "main.playbar.buttons.button.wrapper": "verified_cdp", "main.topbar.wrapper": "verified_cdp", - "modal.track_credits.container": "verified_static", - "modal.widget_generator.container": "verified_static", + "modal.track_credits.container": "verified_cdp", + "modal.widget_generator.container": "verified_cdp", "search_box.container": "verified_cdp", "search_chips.wrapper": "verified_cdp", "settings.button.wrapper": "verified_cdp", - "settings.header.container": "unverified", + "settings.header.container": "verified_static", "settings.section.container": "verified_cdp", "sort_box.list.button": "verified_cdp", "tracklist.column_header": "verified_cdp" @@ -28,8 +28,7 @@ ], "status": "verified", "unverified_leaves": [ - "main.playbar.buttons.button.wrapper__indicator", - "settings.header.container" + "main.playbar.buttons.button.wrapper__indicator" ], - "verified_classmap_sha256": null + "verified_classmap_sha256": "98a516adfa3161e7ace6ff4d28e9048f953aa88027ab3d55bff25920ef6d9aac" } diff --git a/1020095/VERIFICATION.md b/1020095/VERIFICATION.md index 9153198..c798de1 100644 --- a/1020095/VERIFICATION.md +++ b/1020095/VERIFICATION.md @@ -1,9 +1,41 @@ # Spotify 1.2.95.453 (1020095) -Pipeline: derive 1020094 with three settings corrections + stock source/CSS verification + deep CDP + Linux workflow verification. +Pipeline: derive(1020094 -> 1020095) + static target-CSS verification + CDP e2e (deep). Published 2026-09-30. ## Notes +- Classmap derived from 1020094. +- Static verification found 33/36 paths in the target CSS. +- CSS-only misses observed live by their stock class, which remain verified: 0. +- Deep CDP verification observed 29/36 paths with 10/10 successful navigation steps. +- Unresolved new misses remain usable but are marked unverified; stale paths stay blocked. +- Replaces an earlier verification of this key, kept below under Earlier verification. + +## Statistics at publication + +| Field | Value | +| --- | --- | +| leaves | 36 | +| static_present | 33 | +| verified_cdp | 29 | +| live_only | 0 | +| unresolved_missing | 3 | +| cdp_hit_rate | 0.8056 | +| overlay_entries | 2 | + +## Evidence + +- Classmap SHA-256: `98a516adfa3161e7ace6ff4d28e9048f953aa88027ab3d55bff25920ef6d9aac` +- Overlay SHA-256: `108d9a0fcd9f6a23da409da11fce3cdfde6dc854ba0795be73ffd49d1ea266ba` +- Target CSS SHA-256: `3ff74770ffd77b4fca017cff20a83475bf2fa9b5b3f270b19c2b153c4206e4c6` +- CDP report generated: 2026-09-30T13:39:46.364Z + +## Earlier verification + +Pipeline: derive 1020094 with three settings corrections + stock source/CSS verification + deep CDP + Linux workflow verification. + +### Notes + - Linux stable Spotify 1.2.95.453.g0eeebbed tested on Ubuntu 24.04.5 x86_64, X11, emulated on Apple Silicon. No Windows, macOS or Wayland runtime claim. - Settings header KsnD09q3oqAjJX3e belongs to the output-device section in xpui-routes-desktop-settings.js. It did not render in this Linux session and remains unverified live. - Settings section fNaaQ0Cp8Yzy19j8 wraps real settings groups; settings buttons use the observed small Encore secondary-button classes. nHgEqWYM1q0omZ6y is a proxy-settings container, not a button. @@ -16,7 +48,7 @@ Pipeline: derive 1020094 with three settings corrections + stock source/CSS veri - The managed installer intentionally restarted the daemon during activation. Its health returned with both watchers active; service and protocol-registration files were unchanged. This is not a daemon-continuity claim. - At an 800px-wide Flow window, scrolling a control into view shifted the settings view horizontally. The paired initial layouts matched; the full-width Store and final default-settings captures were aligned. Queue toggled active, and its empty-state panel was visible after removing Flow. Playback, credits/embed dialogs and external navigation were not exercised. -## Statistics at publication +### Statistics at publication | Field | Value | | --- | --- | @@ -31,12 +63,12 @@ Pipeline: derive 1020094 with three settings corrections + stock source/CSS veri | cdp_hit_rate | 0.6111 | | overlay_entries | 2 | -## Verification summary at publication +### Verification summary at publication - Needs manual check: 31 - Missing in CSS: 5 -## Linux verification +### Linux verification - Platform: linux-x86_64 - Spotify package SHA-256: `256e2eb1ec96fbc0c51afab247298e4e6eabfabbafafd4617584f44cca2fb31f` diff --git a/1020096/META.json b/1020096/META.json index 12038e8..fa7fcc4 100644 --- a/1020096/META.json +++ b/1020096/META.json @@ -6,13 +6,13 @@ "main.navbar.link.wrapper": "verified_cdp", "main.playbar.buttons.button.wrapper": "verified_cdp", "main.topbar.wrapper": "verified_cdp", - "modal.track_credits.container": "verified_static", - "modal.widget_generator.container": "verified_static", + "modal.track_credits.container": "verified_cdp", + "modal.widget_generator.container": "verified_cdp", "search_box.container": "verified_cdp", "search_chips.wrapper": "verified_cdp", "settings.button.wrapper": "verified_cdp", - "settings.header.container": "verified_static", - "settings.section.container": "verified_static", + "settings.header.container": "verified_cdp", + "settings.section.container": "verified_cdp", "sort_box.list.button": "verified_cdp", "tracklist.column_header": "verified_cdp" }, @@ -30,5 +30,5 @@ "unverified_leaves": [ "main.playbar.buttons.button.wrapper__indicator" ], - "verified_classmap_sha256": null + "verified_classmap_sha256": "dc5212855a7b460980548d296313bfaf76696d9f5a43aa456289990273eefec3" } diff --git a/1020096/VERIFICATION.md b/1020096/VERIFICATION.md index 7103bdf..160080d 100644 --- a/1020096/VERIFICATION.md +++ b/1020096/VERIFICATION.md @@ -1,16 +1,48 @@ # Spotify 1.2.96.518 (1020096) -Pipeline: inherit(1020094 -> 1020096) + static target-CSS verification + CDP e2e (deep). +Pipeline: inherit(1020094 -> 1020096) + static target-CSS verification + CDP e2e (deep). Published 2026-09-30. ## Notes +- Classmap inherited byte-for-byte from 1020094; no migration guesses were accepted. +- Static verification found 33/36 paths in the target CSS. +- CSS-only misses observed live by their stock class, which remain verified: 0. +- Deep CDP verification observed 30/36 paths with 10/10 successful navigation steps. +- Unresolved new misses remain usable but are marked unverified; stale paths stay blocked. +- Replaces an earlier verification of this key, kept below under Earlier verification. + +## Statistics at publication + +| Field | Value | +| --- | --- | +| leaves | 36 | +| static_present | 33 | +| verified_cdp | 30 | +| live_only | 0 | +| unresolved_missing | 3 | +| cdp_hit_rate | 0.8333 | +| overlay_entries | 3 | + +## Evidence + +- Classmap SHA-256: `dc5212855a7b460980548d296313bfaf76696d9f5a43aa456289990273eefec3` +- Overlay SHA-256: `8c05d9ca347e4e13fb31013df4c42bdbf16046408b989afe4d0ea6a25037800e` +- Target CSS SHA-256: `bd8dcdebe8e9a6b33939f17fddf410d50dab7b6215821ed73eab21def3f1dd96` +- CDP report generated: 2026-09-30T13:42:12.980Z + +## Earlier verification + +Pipeline: inherit(1020094 -> 1020096) + static target-CSS verification + CDP e2e (deep). + +### Notes + - Classmap inherited byte-for-byte from 1020094; no migration guesses were accepted. - Static verification found 32/36 paths in the target CSS. - One CSS-only miss was observed live and remains verified. - Deep CDP verification observed 20/36 paths on the routes and transient surfaces exercised by the verifier. - Unresolved new misses remain usable but are marked unverified; inherited stale paths stay blocked. -## Statistics at publication +### Statistics at publication | Field | Value | | --- | --- | @@ -24,7 +56,7 @@ Pipeline: inherit(1020094 -> 1020096) + static target-CSS verification + CDP e2e | cdp_hit_rate | 0.5556 | | overlay_entries | 3 | -## Verification summary at publication +### Verification summary at publication - Needs manual check: 32 - Missing in CSS: 4 diff --git a/index.json b/index.json index 2b7eb81..5adb41f 100644 --- a/index.json +++ b/index.json @@ -11,9 +11,9 @@ }, "meta": { "file": "META.json", - "sha256": "842511cbd0e59665dbb3c08329283640c3059be197701437bfbe8a681cacf53a" + "sha256": "8d29a73dead5ed2545473a6eabf1bcd46222e21fced7c2de4920a58a6d4b676e" }, - "spotifyVersion": "1.2.84.476", + "spotifyVersion": "1.2.84.475", "status": "verified" }, "1020092": { @@ -27,9 +27,9 @@ }, "meta": { "file": "META.json", - "sha256": "2dadd1c404fe29bffb8db83ac84ae59fc9e76dee8bcf12e4710819d5218d5749" + "sha256": "55c303d2b977ccf359e718f508c3784d34e82b392d380ed1b1e231f02140e043" }, - "spotifyVersion": "1.2.92.148", + "spotifyVersion": "1.2.92.147", "status": "verified" }, "1020094": { @@ -59,7 +59,7 @@ }, "meta": { "file": "META.json", - "sha256": "a3df356bfd3a72ddc85ed65076e3f4fbaae7357c84fe5efa9e4b8abc2b8acfb2" + "sha256": "898b94e33efb3d032219153169730618296f7f64f5374b6b1f2e3018c3a4a2e2" }, "spotifyVersion": "1.2.95.453", "status": "verified" @@ -75,7 +75,7 @@ }, "meta": { "file": "META.json", - "sha256": "981db11376e8aa077fa1a6c54c6e2131b882cb0be544676ccc18c5cb0e447a31" + "sha256": "e7739ae3ad6c4740b05a008d127ea821d802d357133ad18567197b4ef62e8486" }, "spotifyVersion": "1.2.96.518", "status": "verified" diff --git a/scripts/publish-key.test.mts b/scripts/publish-key.test.mts index fcfa4fc..6117b74 100644 --- a/scripts/publish-key.test.mts +++ b/scripts/publish-key.test.mts @@ -456,7 +456,15 @@ test("refuses a derived candidate that stores Spicetify names", () => { assert.ok(!existsSync(path.join(root, "1020096"))); }); +test("an inherited key can keep an overlay of its own", () => { + const overlay = path.join(root, "overlay.json"); + writeFileSync(overlay, renderJson({ ownHash: "own-name" })); + const target = publishRelease(options({ overlayPath: overlay })); + assert.deepEqual(JSON.parse(readFileSync(path.join(target, "css-map.json"), "utf8")), { ownHash: "own-name" }); + assert.deepEqual(readFileSync(path.join(target, "classmap.json")), readFileSync(path.join(source, "classmap.json"))); +}); + test("refuses stale paths or required-path changes for an inherited key", () => { - assert.throws(() => publishRelease(options({ stale: ["main.topbar.wrapper"] })), /takes its map, overlay and stale paths/); + assert.throws(() => publishRelease(options({ stale: ["main.topbar.wrapper"] })), /takes its map and stale paths/); assert.throws(() => publishRelease(options({ dropRequired: ["main.topbar.wrapper"] })), /tracks its source's required paths/); }); diff --git a/scripts/publish-key.ts b/scripts/publish-key.ts index 8ad6c07..a9b35ae 100644 --- a/scripts/publish-key.ts +++ b/scripts/publish-key.ts @@ -14,7 +14,7 @@ // Flags: // --inherit-from KEY copy KEY's map and overlay (an unchanged patch release) // --classmap FILE candidate map for a derived key, in canonical form -// --overlay FILE css-map overlay for a derived key +// --overlay FILE css-map overlay (default for an inherited key: its source's) // --derived-from KEY key the candidate was migrated from; its stale leaves carry over // --migrate-report FILE migrate report; the leaves it kept as stale stay stale // --stale PATH mark a leaf stale (repeatable) @@ -329,8 +329,8 @@ export function publishRelease(o: PublishOptions, index = false): string { throw new Error("pass exactly one of --inherit-from or --classmap"); } const inherited = o.inheritFrom !== undefined; - if (inherited && (o.overlayPath || o.derivedFrom || o.migrateReport || o.stale?.length)) { - throw new Error("an inherited key takes its map, overlay and stale paths from its source"); + if (inherited && (o.derivedFrom || o.migrateReport || o.stale?.length)) { + throw new Error("an inherited key takes its map and stale paths from its source"); } if (inherited && (o.requiredFrom || o.dropRequired?.length)) { throw new Error("an inherited key tracks its source's required paths"); @@ -357,8 +357,10 @@ export function publishRelease(o: PublishOptions, index = false): string { let overlayText: string | null = null; if (inherited) { classmapBytes = readFileSync(path.join(o.root, o.inheritFrom as string, "classmap.json")); + // The map is inherited byte-for-byte; the overlay can carry fixes of its own. const sourceOverlay = path.join(o.root, o.inheritFrom as string, "css-map.json"); - if (isFile(sourceOverlay)) overlayText = readUtf8(sourceOverlay); + if (o.overlayPath) overlayText = readUtf8(o.overlayPath); + else if (isFile(sourceOverlay)) overlayText = readUtf8(sourceOverlay); } else { classmapBytes = readFileSync(o.classmapPath as string); if (o.overlayPath) overlayText = readUtf8(o.overlayPath);