From e1be8fe7fa04b22456c4cb10fafe57d291a18b95 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Fri, 30 Oct 2026 20:08:36 +0330 Subject: [PATCH 1/2] Publish verified AVR HEX artifacts and replace prototype application artwork --- .github/workflows/build.yml | 3 + README.md | 5 + assets/branding/BOARD-ICONS.md | 4 +- assets/branding/app-icon-1024.png | Bin 0 -> 94542 bytes assets/branding/app-icon-128.png | Bin 0 -> 9332 bytes assets/branding/app-icon-24.png | Bin 0 -> 1478 bytes assets/branding/app-icon-256.png | Bin 0 -> 18753 bytes assets/branding/app-icon-32.png | Bin 0 -> 2155 bytes assets/branding/app-icon-512.png | Bin 0 -> 40492 bytes assets/branding/app-icon-64.png | Bin 0 -> 2570 bytes assets/branding/app-icon.png.base64 | 2 +- assets/branding/app-icon.svg | 44 + assets/branding/application-artwork.json | 14 + desktop/build.rs | 1 + desktop/src/brand_image.rs | 5 + desktop/src/branding.rs | 32 +- docs/BRANDING-PARITY.md | 37 +- docs/FILE-COMPARISON.md | 332 +- docs/REUSE-PREFLIGHT-RECEIPT.md | 44 + docs/assets/app-icon.png | Bin 740 -> 94542 bytes docs/file-comparison-evidence.json | 220 +- docs/file-comparison.csv | 1431 +- docs/legacy-source-ledger.csv | 1301 +- firmware/esp/src/ApplicationArtwork.h | 2 +- firmware/esp/src/BasicUi.h | 4 +- firmware/esp/src/BoardIconAsset.h | 141 +- firmware/esp/src/StaticAssetValidators.h | 6 +- firmware/esp/src/WebAppAssets.h | 2 +- firmware/esp/src/WebUi.h | 6 +- firmware/esp/src/WebUiCompressed.h | 13034 ++++++++-------- .../res/drawable-nodpi/pakar_application.png | Bin 740 -> 94542 bytes mobile/lib/application_artwork.dart | 2 +- tests/branding_test.mjs | 33 +- tests/release_package_test.mjs | 12 +- tests/repository_governance_test.mjs | 2 + tests/script_tooling_test.mjs | 20 +- tests/web_appearance_fixture.mjs | 2 +- tools/build-web.mjs | 2 +- tools/firmware-report.mjs | 19 +- tools/generate-application-artwork.mjs | 27 + tools/generate-branding.mjs | 6 +- tools/generate-readme-artwork.mjs | 4 +- tools/prepare-release.mjs | 7 +- web/index.html | 6 +- 44 files changed, 8688 insertions(+), 8124 deletions(-) create mode 100644 assets/branding/app-icon-1024.png create mode 100644 assets/branding/app-icon-128.png create mode 100644 assets/branding/app-icon-24.png create mode 100644 assets/branding/app-icon-256.png create mode 100644 assets/branding/app-icon-32.png create mode 100644 assets/branding/app-icon-512.png create mode 100644 assets/branding/app-icon-64.png create mode 100644 assets/branding/app-icon.svg create mode 100644 assets/branding/application-artwork.json create mode 100644 tools/generate-application-artwork.mjs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d003dfcd..d1d7fe5e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -187,12 +187,15 @@ jobs: path: | build/avr/avr.ino.with_bootloader.bin build/avr/avr.ino.hex + build/avr/avr.ino.with_bootloader.hex build/SHA256SUMS build/avr-busy-wire/avr.ino.with_bootloader.bin build/avr-busy-wire/avr.ino.hex + build/avr-busy-wire/avr.ino.with_bootloader.hex build/firmware-report.json build/avr-buffered/avr.ino.with_bootloader.bin build/avr-buffered/avr.ino.hex + build/avr-buffered/avr.ino.with_bootloader.hex build/esp32s3-buffered/esp32s3.ino.bin build/esp32s3-buffered/esp32s3.ino.merged.bin build/esp32s3-buffered/esp32s3.ino.partitions.bin diff --git a/README.md b/README.md index eb844c2c..78b80fa5 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,11 @@ Engineering packages are attached to successful [Build workflow runs](https://gi Select the intended commit, not just the newest timestamp. Firmware, Windows and Android outputs are separate artifacts; release packaging adds SHA-256 manifests and provenance. A successful build is not a deployment or a stable-release claim. +The firmware artifact includes AVR application-only `avr.ino.hex` and verified +full-flash `avr.ino.with_bootloader.hex` for polling, busy-wire and buffered +links. Draft release ZIPs include both as well. The latter contains Urboot and +is intended for explicit full-flash/ISP recovery; neither HEX writes EEPROM or +fuses. ESP32-S3 application/OTA images remain raw `.bin`, not Intel HEX. See [release policy and verification](docs/REPOSITORY-GOVERNANCE.md).
diff --git a/assets/branding/BOARD-ICONS.md b/assets/branding/BOARD-ICONS.md index 027dd080..36aeb40e 100644 --- a/assets/branding/BOARD-ICONS.md +++ b/assets/branding/BOARD-ICONS.md @@ -20,7 +20,9 @@ signature and uses the same generic-artwork fallback. Renaming a hostname does not switch identity; fresh capability metadata does. No new protocol selector. OS launcher packaging is separate: these are board identities, not two new -applications. Existing Pakar launcher assets remain unchanged. Dedicated Apple +applications. Pakar's application mark is now app-icon.svg with a 1024px native/ +README/Android master and a bounded 64px peer derivative; see BRANDING-PARITY.md. +Dedicated Apple layered/tinted icon catalogs, Android role shortcuts, and per-role Windows launcher resources are not implemented or tested by this change. Platform references: Apple HIG App icons; Android adaptive icons; Microsoft Windows app diff --git a/assets/branding/app-icon-1024.png b/assets/branding/app-icon-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..d449202b8e91f0f30ab3159bf10c2b9128e776ff GIT binary patch literal 94542 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 literal 0 HcmV?d00001 diff --git a/assets/branding/app-icon-128.png b/assets/branding/app-icon-128.png new file mode 100644 index 0000000000000000000000000000000000000000..f78ecf35ffb5ddf04903d43c9bd0b8921414674e GIT binary patch literal 9332 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 SJpV=nFui7J{Mqn+%>M%?d9mUE literal 0 HcmV?d00001 diff --git a/assets/branding/app-icon-24.png b/assets/branding/app-icon-24.png new file mode 100644 index 0000000000000000000000000000000000000000..d16b3e2c6e2b5082132e5a1d0caa8063eef8d62d GIT binary patch literal 1478 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 R)lQ@xA%W;)4FQqq{{s7)y{!NM literal 0 HcmV?d00001 diff --git a/assets/branding/app-icon-32.png b/assets/branding/app-icon-32.png new file mode 100644 index 0000000000000000000000000000000000000000..37c4337dcc669b2b659be15ac9661aef8b0fef84 GIT binary patch literal 2155 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
  • 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 literal 0 HcmV?d00001 diff --git a/assets/branding/app-icon.png.base64 b/assets/branding/app-icon.png.base64 index e0830070..63a051b1 100644 --- a/assets/branding/app-icon.png.base64 +++ b/assets/branding/app-icon.png.base64 @@ -1 +1 @@ -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 diff --git a/assets/branding/app-icon.svg b/assets/branding/app-icon.svg new file mode 100644 index 00000000..006635d2 --- /dev/null +++ b/assets/branding/app-icon.svg @@ -0,0 +1,44 @@ + + PakarController — illuminated control grid + A luminous emerald control pad with a white cell, active green cells and a circular button, on a deep teal application tile. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/branding/application-artwork.json b/assets/branding/application-artwork.json new file mode 100644 index 00000000..9d781f61 --- /dev/null +++ b/assets/branding/application-artwork.json @@ -0,0 +1,14 @@ +{ + "source": "assets/branding/app-icon.svg", + "source_sha256": "9f554d00ecb84361f5371a1c800db0040b3fec4c63244550905bbad9c9b006ac", + "outputs": { + "assets/branding/app-icon-24.png": "e19239958b712562c6a5914dabc456de5a62cac089aae6334a1c6f0d4056178a", + "assets/branding/app-icon-32.png": "629c70966b7aa843afd473b5c7861fba267e0230b1611bd208224add21ea3111", + "assets/branding/app-icon-64.png": "cdb7ea4ccf02e71eb01107b70e3267e47241b5f2155db070878129fc402bfd0b", + "assets/branding/app-icon.png.base64": "71b8cf5cb03da6097d0776f9e5401a5b5c808ad72bf289e56297e68d413bccdf", + "assets/branding/app-icon-128.png": "1ee56481ded568155c0d5d81a4676db6d2cd9c823b485561e6e51beca0fdc6a2", + "assets/branding/app-icon-256.png": "6ab3f51ac979232a5892d7324d962a33018c8eaf9a81db634169da704f7a105e", + "assets/branding/app-icon-512.png": "383b2cbd51db540c1e3cfb079dd44902a6ae648ae103a46f67b97e7f7c67417e", + "assets/branding/app-icon-1024.png": "35cb15b03ac789701ac0b2e0b0970ac1a0b3a758ce061ec99b365cec2a274fe7" + } +} diff --git a/desktop/build.rs b/desktop/build.rs index fe1a387f..a16543d0 100644 --- a/desktop/build.rs +++ b/desktop/build.rs @@ -58,4 +58,5 @@ fn main() { println!("cargo:rerun-if-changed=src/platform/windows_quick_actions.rs"); println!("cargo:rerun-if-changed=src/brand_image.rs"); println!("cargo:rerun-if-changed=../assets/branding/app-icon.png.base64"); + println!("cargo:rerun-if-changed=../assets/branding/app-icon-1024.png"); } diff --git a/desktop/src/brand_image.rs b/desktop/src/brand_image.rs index d80c5e15..5630e576 100644 --- a/desktop/src/brand_image.rs +++ b/desktop/src/brand_image.rs @@ -3,6 +3,11 @@ use base64::{Engine, engine::general_purpose::STANDARD}; pub fn icon_bytes() -> &'static [u8] { + include_bytes!("../../assets/branding/app-icon-1024.png") +} + +/// Bounded identity-wire derivative of the same editable application master. +pub fn compact_icon_bytes() -> &'static [u8] { static BYTES: std::sync::OnceLock> = std::sync::OnceLock::new(); BYTES.get_or_init(|| { STANDARD diff --git a/desktop/src/branding.rs b/desktop/src/branding.rs index c1ac7b84..8ff081c5 100644 --- a/desktop/src/branding.rs +++ b/desktop/src/branding.rs @@ -1,5 +1,5 @@ //! Actual Pealayer image decoder adapted to Pakar's single cross-surface master. -pub use crate::brand_image::icon_bytes; +pub use crate::brand_image::{icon_bytes, compact_icon_bytes}; use eframe::egui; use std::hash::{Hash, Hasher}; use base64::Engine; @@ -29,7 +29,7 @@ pub fn sync_peer( } let icon = app .and_then(|a| a.icon_bytes()) - .filter(|b| b.as_slice() != icon_bytes()) + .filter(|b| b.as_slice() != icon_bytes() && b.as_slice() != compact_icon_bytes()) .and_then(|b| icon_data_from_bytes(&b)) .or_else(|| { let encoded = match peer.filter(|p| p.known()).map(|p| p.role.as_str()) { @@ -113,6 +113,26 @@ pub fn logo(ui: &mut egui::Ui, size: f32) { mod tests { use super::*; #[test] + fn compact_default_does_not_mask_the_connected_board_role() { + let ctx = egui::Context::default(); + let peer = crate::capabilities::Manifest { + board_kind: "controller".into(), + role: "first-wins".into(), + application: Some(crate::identity::Application { + id: "keys.app".into(), name: "Keys".into(), title: "Keys".into(), + icon_png_base64: include_str!("../../assets/branding/app-icon.png.base64").trim().into(), + }), + ..Default::default() + }; + let expected = base64::engine::general_purpose::STANDARD + .decode(include_str!("../../assets/branding/keys.png.base64").trim()).unwrap(); + let expected = icon_data_from_bytes(&expected).unwrap(); + let mut output = ctx.run_ui(egui::RawInput::default(), |_| { + assert_eq!(sync_peer(&ctx, Some(&peer)).unwrap().rgba, expected.rgba); + }); + output.textures_delta.clear(); + } + #[test] fn peer_icon_lifecycle_reuses_refresh_and_revokes_on_disconnect() { let ctx = egui::Context::default(); let mut peer = crate::capabilities::Manifest { @@ -151,9 +171,9 @@ mod tests { #[test] fn bundled_artwork_decodes_without_files_or_theme_specific_replacements() { let icon = window_icon(); - assert_eq!((icon.width, icon.height), (64, 64)); + assert_eq!((icon.width, icon.height), (1024, 1024)); assert_eq!( - icon.rgba.as_slice(), + crate::brand_image::rgba_at_size(64).as_slice(), &include_bytes!(concat!(env!("OUT_DIR"), "/pakar-icon-64.rgba"))[..] ); assert_eq!( @@ -208,7 +228,7 @@ mod tests { .set .values() .flatten() - .any(|delta| delta.image.size() == [64, 64]); + .any(|delta| delta.image.size() == [1024, 1024]); // Headless tests have no texture backend. Drain before assertions // so a failed assertion cannot cause a second destructor panic. output.textures_delta.clear(); @@ -222,7 +242,7 @@ mod tests { .set .values() .flatten() - .any(|delta| delta.image.size() == [64, 64]); + .any(|delta| delta.image.size() == [1024, 1024]); output.textures_delta.clear(); assert!(!uploaded_again, "do not decode/upload on every frame"); } diff --git a/docs/BRANDING-PARITY.md b/docs/BRANDING-PARITY.md index 36761663..d12b52e8 100644 --- a/docs/BRANDING-PARITY.md +++ b/docs/BRANDING-PARITY.md @@ -1,5 +1,26 @@ # One PakarController application icon +## Current high-DPI control-grid design + +The prototype Circuitry raster is replaced by the editable +`assets/branding/app-icon.svg`: staggered illuminated white/emerald/mint cells +and a circular button on a deep teal tile. It is original vector artwork, +not an enlarged font glyph. Native resources and README use the rendered +1024px master; Android's adaptive launcher uses the same high-DPI PNG. +Windows ICO retains all seven donor-derived sizes (16–256), rendered directly +from that master. Existing role-specific board artwork and custom peer icons +retain their identity and priority. + +`generate-application-artwork.mjs --render` deliberately invokes the external +Sharp rasterizer through PAKAR_SHARP_MODULE. Ordinary generation and `--check` +require no image package: source/output hashes in application-artwork.json +guard every committed derivative. The compact 64px base64 derivative remains +under the 4096-character identity budget for ESP/peer/Web headers. README, +native executable and Android launcher no longer upscale that transport icon. + +The following deployment observations describe the historical prototype +checkpoint only; they are not evidence that these new assets are installed. + ## Android launcher correction The previous mobile import covered only the in-app header, leaving all five @@ -17,8 +38,8 @@ has SHA-256 05bc6ce48c57eb8bf6c8f1acd98f10389ae2e6fcc40b4bf41b09f9ce39c85783, byte-identical to the canonical PNG, not a Flutter density fallback. Physical ADB readback confirms MainActivity in foreground; the actual running UI was captured and inspected. Launcher-grid pixels are not inferred from header pixels. -The existing 64x64 master limitation remains; a high-DPI editable master is not -claimed. Runtime board artwork cannot rewrite the installed Android launcher. +That historical 64x64 limitation is addressed by the current SVG/high-DPI +pipeline above. Runtime board artwork cannot rewrite the installed Android launcher. The mismatch was an incomplete integration: the native PE/window/tray generated Phosphor Circuitry, the native menu/About used a separate theme-tinted font @@ -32,7 +53,7 @@ runtime preferences do not silently rewrite executable or pinned icons. ## Canonical master and exact code imports -`assets/branding/app-icon.png.base64` is a 740-byte lossless PNG encoding of the +The former `assets/branding/app-icon.png.base64` was a 740-byte lossless PNG encoding of the existing 64x64 native Phosphor Circuitry raster. Verified current warm-cache native pixels SHA-256: `d24d849f01bfeaa0cffef1cc9b861062b52e1a320f4c943608fb5fd952ded387`. @@ -80,12 +101,12 @@ their actual Phosphor vocabulary; they are not application-logo variants. - Build metadata, external branding manifest/environment override validation, generic publisher/version/provenance resource fields remain pending. macOS mpv linker probing is excluded by the requested mpv-free controller. -- The preserved master is currently 64x64, not a claimed 512x512 editable icon - pack/PWA artwork. ICO derivatives retain the donor's seven sizes; high-DPI - editable master and full installable PWA manifest/cache remain open. +- High-DPI artwork is now implemented above. Platform-specific Apple layered/ + tinted catalogs and installed/pinned-icon cache refresh still need their + own packaging/runtime acceptance; no OS-wide cache deletion is performed. -`tests/branding_test.mjs` verifies exact preserved native pixels, four identical -embedded Web images, production native consumers and no-write generation. +`tests/branding_test.mjs` verifies high-DPI and bounded derivative identities, +four identical embedded Web images, native consumers and no-write generation. Three Rust tests verify native pixels/window/tray derivatives, all ICO frames and shared texture reuse in both themes. Source tests do not certify compiled resource extraction or deployed runtime/board appearance. CI runs asynchronously; diff --git a/docs/FILE-COMPARISON.md b/docs/FILE-COMPARISON.md index b69f17ba..6b87fbb7 100644 --- a/docs/FILE-COMPARISON.md +++ b/docs/FILE-COMPARISON.md @@ -2,9 +2,9 @@ Whole-repository superiority is **not established**. This report exposes retained code, scoped improvements, omissions and gaps; it does not turn missing reviews into exclusions. -Routing: 1472 paths have no specialist capability match. They remain visible through `consult-reuse.ps1 -Concern donor-audit` and issue #3; lack of a keyword match is NOT an exclusion. Every CSV row includes capability routing and owning issue links. +Routing: 1504 paths have no specialist capability match. They remain visible through `consult-reuse.ps1 -Concern donor-audit` and issue #3; lack of a keyword match is NOT an exclusion. Every CSV row includes capability routing and owning issue links. -Inventory: 4744 files; 437 complete source-file comparisons; 4307 pending comparisons; 311 compared files with known parity gaps. Header/implementation pairs can describe the same gap. Missing sparse files remain pending. +Inventory: 4781 files; 437 complete source-file comparisons; 4344 pending comparisons; 311 compared files with known parity gaps. Header/implementation pairs can describe the same gap. Missing sparse files remain pending. Every inventoried path, source revision/hash, target/proof file and line, omitted code, disposition and concrete reason is in `file-comparison.csv`. Hash-bound manual decisions are in `file-comparison-evidence.json`. Donor SHA-256 values bind original bytes; target/proof SHA-256 values bind UTF-8 without BOM with LF newlines. Anchors are recomputed into exact line numbers. Test-code presence is not test execution; execution receipts are in `FILE-COMPARISON-RECEIPTS.md`. @@ -17,7 +17,7 @@ Every inventoried path, source revision/hash, target/proof file and line, omitte | DRS-jSnake | 18 | 16 | 2 | 16 | | esp32WS2811 | 24 | 16 | 8 | 9 | | PCController | 1517 | 119 | 1398 | 107 | -| Pealayer | 645 | 66 | 579 | 47 | +| Pealayer | 682 | 66 | 616 | 47 | | portable-shell | 23 | 23 | 0 | 0 | | PU850-ESP | 109 | 109 | 0 | 96 | | PuzzleBoard | 22 | 22 | 0 | 1 | @@ -957,7 +957,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `firmware/esp/src/AvrIsp.h:66 [UTF8-LF sha256=03561fd6b5a97e9a178e3dd70888c8e068c7db58a357b26028353d959b5009ad; anchor=void report(]`. - Target: `mobile/lib/upgrade_observation.dart:3 [UTF8-LF sha256=8feabc680770f062a09ec3a5e7e72d1e9aad814335f630ddc00be3770790e8d7; anchor=class UpgradeObservation]`. - Target: `desktop/src/firmware_progress.rs:11 [UTF8-LF sha256=11188ec3c9bc7b89e76b94e5412f0e689fa656e5a636d4964136c2236aabbe31; anchor=pub struct Upgrade]`. -- Target: `firmware/esp/src/WebUi.h:2712 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function upgradeObservation(]`. +- Target: `firmware/esp/src/WebUi.h:2712 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function upgradeObservation(]`. - Retained: Complete canonical donor documentation read through EOF and original-byte SHA matched the inventory. Adapted the actual measured-stage/unknown-denominator/verified-completion/no-write-replay contract, not the donor's AVRDUDE parser: local HTTP raw file bytes, remote download stage bytes, coherent async-to-loop snapshots, finite AVR scheduled text leases and separate client reboot/readback verification. - Retained: Reread the complete canonical update-progress document for actual0.2.8 migration. Explicit exact-board maintenance admits only the older producer's update/backup observations, never ordinary controls; the new boot still passes the default release policy. Missing BOTH newer producer headers is confined to that selected recovery and retains same-address, whole MD5 and before/after board/boot checks. Failed manifest admission can preserve zero image metadata only with the exact pinned manifest/job/boot/target/zero bytes. Added backpressure-aware multipart chunks and explicit upload pacing; no automatic mutation retry. Real fixtures cover these boundaries. Actual HTTPS stage22/new boot/full running SHA and separate Internet control/WSS passed; final direct LAN WS interruption and the false completion_verified bit remain open, not fabricated success. - Retained: Local /update/info now uses boot-captured immutable image metadata rather than whole-image hashing on every progress poll. Status and WebSocket status/ping remain readable during local OTA; mutating commands remain inhibited. No authentication is enabled by the updater; it requires explicit auth-off readback before and after. @@ -1002,7 +1002,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `firmware/esp/src/LcdManagement.h:3 [UTF8-LF sha256=eb800ee4c334b22504f37bd841bda58a7562052df2c7226ff19bc23a454e652d; anchor=String lcdStatusJson()]`. - Target: `desktop/src/display.rs:7 [UTF8-LF sha256=9d73ae63aaa8a2bc4b824219c9cfab9f7924ae7566be7a9206c11b6344a2f18b; anchor=pub struct LcdObservation]`. - Target: `mobile/lib/peer_context.dart:302 [UTF8-LF sha256=c8602a12ccd3009028068aba091d46900c8aa0e345a4426ffe80acfb716362fc; anchor=bool lcdObservationReady(]`. -- Target: `firmware/esp/src/WebUi.h:2538 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function lcdObservation(]`. +- Target: `firmware/esp/src/WebUi.h:2538 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function lcdObservation(]`. - Retained: Complete actual donor source read through EOF. Adapted common PCF8574 0x27/0x3F discovery, 4-bit HD44780 wake/control bytes,16x2 ASCII row normalization/padding, desired frame cache and backlight bit mapping into a transport-independent production class. S3 owns dedicated GPIO15/16 hardware I2C so the confirmed AVR A4/A5 TM1637 and ISP pins remain untouched. - Omitted/replaced code: `Blocking50ms/4.5ms initialization, ignored expander return values and cache validity after failed writes`. Disposition: **replaced**. Reason: Initialization is a paced loop-owned state machine. Every expander write must ACK; no full frame/available status until all initialization and both rows complete. NACK revokes readiness, bounded retry reinitializes/replays current desired text. Missing modules cannot become initialized merely because initialize() returned. - Omitted/replaced code: `Flash-string overload and LCD clear/backlight/generic bus controls on all client surfaces; host-owned LCD prompt/priority/offline policy`. Disposition: **pending**. Reason: This slice implements standalone physical discovery/init/default cell/update text, finite REST presentation and exact completed-frame previews. It does not claim the full donor host presenter, raw I2C bridge, every app editor or USB LCD mutation parity. CompactI2c remains available for a future explicit nonconflicting AVR wiring/build profile after flash/RAM review. @@ -1024,7 +1024,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `firmware/esp/src/LcdManagement.h:3 [UTF8-LF sha256=eb800ee4c334b22504f37bd841bda58a7562052df2c7226ff19bc23a454e652d; anchor=String lcdStatusJson()]`. - Target: `desktop/src/display.rs:7 [UTF8-LF sha256=9d73ae63aaa8a2bc4b824219c9cfab9f7924ae7566be7a9206c11b6344a2f18b; anchor=pub struct LcdObservation]`. - Target: `mobile/lib/peer_context.dart:302 [UTF8-LF sha256=c8602a12ccd3009028068aba091d46900c8aa0e345a4426ffe80acfb716362fc; anchor=bool lcdObservationReady(]`. -- Target: `firmware/esp/src/WebUi.h:2538 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function lcdObservation(]`. +- Target: `firmware/esp/src/WebUi.h:2538 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function lcdObservation(]`. - Retained: Complete actual donor source read through EOF. Adapted common PCF8574 0x27/0x3F discovery, 4-bit HD44780 wake/control bytes,16x2 ASCII row normalization/padding, desired frame cache and backlight bit mapping into a transport-independent production class. S3 owns dedicated GPIO15/16 hardware I2C so the confirmed AVR A4/A5 TM1637 and ISP pins remain untouched. - Omitted/replaced code: `Blocking50ms/4.5ms initialization, ignored expander return values and cache validity after failed writes`. Disposition: **replaced**. Reason: Initialization is a paced loop-owned state machine. Every expander write must ACK; no full frame/available status until all initialization and both rows complete. NACK revokes readiness, bounded retry reinitializes/replays current desired text. Missing modules cannot become initialized merely because initialize() returned. - Omitted/replaced code: `Flash-string overload and LCD clear/backlight/generic bus controls on all client surfaces; host-owned LCD prompt/priority/offline policy`. Disposition: **pending**. Reason: This slice implements standalone physical discovery/init/default cell/update text, finite REST presentation and exact completed-frame previews. It does not claim the full donor host presenter, raw I2C bridge, every app editor or USB LCD mutation parity. CompactI2c remains available for a future explicit nonconflicting AVR wiring/build profile after flash/RAM review. @@ -1130,7 +1130,7 @@ Verdict: **scoped-improvement**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920 - Target: `desktop/src/ui/preferences.rs:262 [UTF8-LF sha256=38bda5597ef69c27761de2bfc820e2d507c8fe29353d3e1f95c118a477d22448; anchor=fn board_controls(]`. - Target: `mobile/lib/api.dart:2109 [UTF8-LF sha256=bbb407cc65ccd54e10d7a21328d07831ce5fa3eff70eebe99a6a10b3815257e8; anchor=Future boardSound(]`. - Target: `mobile/lib/board_sound_preferences.dart:10 [UTF8-LF sha256=888e518c1a85ff594b6c4c778f2eb770a4cbcad3a1d53d3defea19b5e226dc5d; anchor=class BoardSoundPreferences]`. -- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=async function boardSoundTransaction(]`. +- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=async function boardSoundTransaction(]`. - Target: `firmware/avr/BootMelody.cpp:37 [UTF8-LF sha256=fad1505f9cedc196236fc782ae2ec71a3c9fb8784659a1955affdf9e44137247; anchor=case kCueAttention:]`. - Target: `libraries/BoardCore/src/AttentionCues.h:13 [UTF8-LF sha256=02693199ab57f58a0531f46d8afa05ccd46dbd4c28b8db50b55bf5e4d1cff7b6; anchor=class Upload]`. - Target: `tools/test-audio.ps1:18 [UTF8-LF sha256=41500a0595fe030dd36f70175b56ee6f16ff62fe3bd1b2d9bf9bb29e94f90b30; anchor=Audio ·]`. @@ -1164,7 +1164,7 @@ Verdict: **scoped-improvement**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920 - Target: `desktop/src/ui/preferences.rs:262 [UTF8-LF sha256=38bda5597ef69c27761de2bfc820e2d507c8fe29353d3e1f95c118a477d22448; anchor=fn board_controls(]`. - Target: `mobile/lib/api.dart:2109 [UTF8-LF sha256=bbb407cc65ccd54e10d7a21328d07831ce5fa3eff70eebe99a6a10b3815257e8; anchor=Future boardSound(]`. - Target: `mobile/lib/board_sound_preferences.dart:10 [UTF8-LF sha256=888e518c1a85ff594b6c4c778f2eb770a4cbcad3a1d53d3defea19b5e226dc5d; anchor=class BoardSoundPreferences]`. -- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=async function boardSoundTransaction(]`. +- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=async function boardSoundTransaction(]`. - Target: `firmware/avr/BootMelody.cpp:37 [UTF8-LF sha256=fad1505f9cedc196236fc782ae2ec71a3c9fb8784659a1955affdf9e44137247; anchor=case kCueAttention:]`. - Retained: Timer1 OC1A PB1/D9 hardware output without audio ISR; ten-step nonblocking ring queue; silent pauses; begin/stop/mute and active telemetry. - Retained: PCController already uses Timer1 hardware toggling; that is reuse, not a Pakar invention. @@ -1851,7 +1851,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `firmware/esp/src/LcdManagement.h:3 [UTF8-LF sha256=eb800ee4c334b22504f37bd841bda58a7562052df2c7226ff19bc23a454e652d; anchor=String lcdStatusJson()]`. - Target: `desktop/src/display.rs:7 [UTF8-LF sha256=9d73ae63aaa8a2bc4b824219c9cfab9f7924ae7566be7a9206c11b6344a2f18b; anchor=pub struct LcdObservation]`. - Target: `mobile/lib/peer_context.dart:302 [UTF8-LF sha256=c8602a12ccd3009028068aba091d46900c8aa0e345a4426ffe80acfb716362fc; anchor=bool lcdObservationReady(]`. -- Target: `firmware/esp/src/WebUi.h:2538 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function lcdObservation(]`. +- Target: `firmware/esp/src/WebUi.h:2538 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function lcdObservation(]`. - Retained: Complete actual donor source read through EOF. Preserved bounded transaction results, explicit master setup and timeout policy through the real S3 Wire1 adapter at100kHz/5ms transaction timeout. Transport interface isolates controller-specific registers instead of pretending AVR TWI can control an ESP32-S3 bus. - Omitted/replaced code: `AVR TWI register implementation, native AVR bridge receive buffer and host-proxied arbitrary I2C operations`. Disposition: **replaced**. Reason: The S3 uses actual native hardware I2C on separate pins, not the AVR connector already carrying non-I2C TM1637. A private adapter has no public arbitrary-bus mutation path. Copying AVR registers or enabling Wire on AVR A4/A5 would steal the display pins. - Omitted/replaced code: `Flash-string overload and LCD clear/backlight/generic bus controls on all client surfaces; host-owned LCD prompt/priority/offline policy`. Disposition: **pending**. Reason: This slice implements standalone physical discovery/init/default cell/update text, finite REST presentation and exact completed-frame previews. It does not claim the full donor host presenter, raw I2C bridge, every app editor or USB LCD mutation parity. CompactI2c remains available for a future explicit nonconflicting AVR wiring/build profile after flash/RAM review. @@ -1873,7 +1873,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `firmware/esp/src/LcdManagement.h:3 [UTF8-LF sha256=eb800ee4c334b22504f37bd841bda58a7562052df2c7226ff19bc23a454e652d; anchor=String lcdStatusJson()]`. - Target: `desktop/src/display.rs:7 [UTF8-LF sha256=9d73ae63aaa8a2bc4b824219c9cfab9f7924ae7566be7a9206c11b6344a2f18b; anchor=pub struct LcdObservation]`. - Target: `mobile/lib/peer_context.dart:302 [UTF8-LF sha256=c8602a12ccd3009028068aba091d46900c8aa0e345a4426ffe80acfb716362fc; anchor=bool lcdObservationReady(]`. -- Target: `firmware/esp/src/WebUi.h:2538 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function lcdObservation(]`. +- Target: `firmware/esp/src/WebUi.h:2538 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function lcdObservation(]`. - Retained: Complete actual donor source read through EOF. Preserved bounded transaction results, explicit master setup and timeout policy through the real S3 Wire1 adapter at100kHz/5ms transaction timeout. Transport interface isolates controller-specific registers instead of pretending AVR TWI can control an ESP32-S3 bus. - Omitted/replaced code: `AVR TWI register implementation, native AVR bridge receive buffer and host-proxied arbitrary I2C operations`. Disposition: **replaced**. Reason: The S3 uses actual native hardware I2C on separate pins, not the AVR connector already carrying non-I2C TM1637. A private adapter has no public arbitrary-bus mutation path. Copying AVR registers or enabling Wire on AVR A4/A5 would steal the display pins. - Omitted/replaced code: `Flash-string overload and LCD clear/backlight/generic bus controls on all client surfaces; host-owned LCD prompt/priority/offline policy`. Disposition: **pending**. Reason: This slice implements standalone physical discovery/init/default cell/update text, finite REST presentation and exact completed-frame previews. It does not claim the full donor host presenter, raw I2C bridge, every app editor or USB LCD mutation parity. CompactI2c remains available for a future explicit nonconflicting AVR wiring/build profile after flash/RAM review. @@ -1997,7 +1997,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `desktop/src/ui/preferences.rs:262 [UTF8-LF sha256=38bda5597ef69c27761de2bfc820e2d507c8fe29353d3e1f95c118a477d22448; anchor=fn board_controls(]`. - Target: `mobile/lib/api.dart:2109 [UTF8-LF sha256=bbb407cc65ccd54e10d7a21328d07831ce5fa3eff70eebe99a6a10b3815257e8; anchor=Future boardSound(]`. - Target: `mobile/lib/board_sound_preferences.dart:10 [UTF8-LF sha256=888e518c1a85ff594b6c4c778f2eb770a4cbcad3a1d53d3defea19b5e226dc5d; anchor=class BoardSoundPreferences]`. -- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=async function boardSoundTransaction(]`. +- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=async function boardSoundTransaction(]`. - Target: `desktop/src/ui/device_settings.rs:54 [UTF8-LF sha256=c087cbbde3bfc194b6002b10a3b63bb16ac4e253ef33d1a6f951ab2e566a42f6; anchor=fn avr_page(]`. - Target: `desktop/src/device_settings.rs:648 [UTF8-LF sha256=5bce7f14b9d6225d9aaa660838b8d07f7e14bda364c520a51f1c92e83d302ed6; anchor=pub fn finish_avr(]`. - Target: `firmware/esp/src/SceneStore.h:17 [UTF8-LF sha256=4877f4a54061ba25e69104055303781c84eb66f7f5eb49e3ec258370665a7bd2; anchor=template class SceneStore]`. @@ -2058,7 +2058,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `desktop/src/ui/preferences.rs:262 [UTF8-LF sha256=38bda5597ef69c27761de2bfc820e2d507c8fe29353d3e1f95c118a477d22448; anchor=fn board_controls(]`. - Target: `mobile/lib/api.dart:2109 [UTF8-LF sha256=bbb407cc65ccd54e10d7a21328d07831ce5fa3eff70eebe99a6a10b3815257e8; anchor=Future boardSound(]`. - Target: `mobile/lib/board_sound_preferences.dart:10 [UTF8-LF sha256=888e518c1a85ff594b6c4c778f2eb770a4cbcad3a1d53d3defea19b5e226dc5d; anchor=class BoardSoundPreferences]`. -- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=async function boardSoundTransaction(]`. +- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=async function boardSoundTransaction(]`. - Target: `desktop/src/ui/device_settings.rs:54 [UTF8-LF sha256=c087cbbde3bfc194b6002b10a3b63bb16ac4e253ef33d1a6f951ab2e566a42f6; anchor=fn avr_page(]`. - Target: `desktop/src/device_settings.rs:648 [UTF8-LF sha256=5bce7f14b9d6225d9aaa660838b8d07f7e14bda364c520a51f1c92e83d302ed6; anchor=pub fn finish_avr(]`. - Target: `libraries/BoardCore/src/PixelCorrections.h:12 [UTF8-LF sha256=2cffe251bb4f569b99cee3f3a6798f854c502cc983c57355e7947e40ce9f3c4d; anchor=bool enabled = true]`. @@ -2092,7 +2092,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `firmware/esp32s3/src/StatusRgb.h:162 [UTF8-LF sha256=a60111d37be51c4985e01d77821113fd0f97cd5df243e2e521b5ec3075b31b97; anchor=bool service(uint32_t now, Writer writer)]`. - Target: `desktop/src/status_rgb.rs:29 [UTF8-LF sha256=3dbe61cf121e44b14fe047427fbe9d0b8e60735baa445ad3116310560631965e; anchor=pub fn observe(]`. - Target: `mobile/lib/status_rgb.dart:52 [UTF8-LF sha256=458f867c97d38107b37fc399dfc55f1ad2f786ce5e236a9a9b2c048d0b4fbfd0; anchor=class StatusRgbPreview]`. -- Target: `firmware/esp/src/WebUi.h:2567 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function acceptStatusRgb(]`. +- Target: `firmware/esp/src/WebUi.h:2567 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function acceptStatusRgb(]`. - Retained: Full header/implementation read through EOF. Actual absolute elapsed/period evaluation, idempotent state ownership and already-scaled rendered RGB reporting adapted into the S3's board-owned semantic engine. Added bounded 300ms eased state transitions, explicit pin safety and driver-accepted output revision; no independent client-side animation reconstruction. - Retained: Native/Web/mobile now merge compact observed RGB revisions only for the selected exact board/boot. Duplicate/older/foreign revisions cannot overwrite newer RGB, renew command/hardware freshness or replace cells/layout. Complete status snapshots retain only newer same-peer RGB; peer changes discard it. Selected transport capabilities gate settings with no silent Wi-Fi fallback, and writes require saved ACK plus exact persisted readback rather than a local preview. - Omitted/replaced code: `PwmController/EEPROM/StatusProfileAddress dependencies and sixteen-bit phase clock`. Disposition: **replaced**. Reason: Those target AVR RGB PWM wiring and EEPROM allocation, not the identified S3 addressable pixel. Existing S3 persisted configuration owns enable/brightness, writer acceptance owns reported output, and the 32-bit elapsed timer advances without per-loop phase drift. @@ -2128,7 +2128,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `firmware/esp32s3/src/StatusRgb.h:242 [UTF8-LF sha256=a60111d37be51c4985e01d77821113fd0f97cd5df243e2e521b5ec3075b31b97; anchor=static uint8_t scale(]`. - Target: `desktop/src/status_rgb.rs:2 [UTF8-LF sha256=3dbe61cf121e44b14fe047427fbe9d0b8e60735baa445ad3116310560631965e; anchor=clients never synthesize]`. - Target: `mobile/lib/status_rgb.dart:9 [UTF8-LF sha256=458f867c97d38107b37fc399dfc55f1ad2f786ce5e236a9a9b2c048d0b4fbfd0; anchor=Color? statusRgbColor(]`. -- Target: `firmware/esp/src/WebUi.h:2566 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function statusRgbOutput]`. +- Target: `firmware/esp/src/WebUi.h:2566 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function statusRgbOutput]`. - Retained: Full original source read through EOF. Actual unsigned byte-exact scale(value, level) and interpolate(from, to, phase) arithmetic copied into the S3 semantic onboard-pixel engine, independent of the GPIO4 matrix. - Omitted/replaced code: `phaseDeadline distributing 64 phases in a modulo-16-bit AVR clock`. Disposition: **replaced**. Reason: S3 evaluates the present phase directly from uint32 elapsed milliseconds rather than scheduling 64 deadline steps. Late service does not slow the animation; native tests cover real production arithmetic and millis wrap, not optical output. - Test-code evidence: `tests/s3_status_rgb_test.cpp:69 [UTF8-LF sha256=f48af12963f643feca43b77ed5edd181e22981afb761305cf947d5ad053fa6f7; anchor=Already-scaled output bytes]`. @@ -2190,7 +2190,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. Original-byte SHA-256: `862dd06b91efdfbc09f4d895e305ecec71d84637a7bf7d4d95d907bcd3b83566`. -- Target: `README.md:43 [UTF8-LF sha256=6ef2bde812ca8aaf889f5ad1c8313ae6e4e5ac079b93424ef4be6e2cdd007da5; anchor=## Get started]`. +- Target: `README.md:43 [UTF8-LF sha256=a83ac5347ba1090b21c3cd3d65e4dcf1fc201a2d78e733220994a70bdf2dadb4; anchor=## Get started]`. - Target: `docs/README.md:7 [UTF8-LF sha256=006973cc50167b64df88e80d539604df763b3edffac561a9ada86fcc7b69683b; anchor=## Operate and recover]`. - Retained: Task-oriented quick start, distinct surfaces, engineering-download provenance, maintained guide hub and truthful source/physical verification boundary adapted to actual Pakar contracts. - Omitted/replaced code: `PCController hardware map, media/seat operations, Go/C ABI examples`. Disposition: **not-applicable**. Reason: Different product hardware/runtime; copying would misdirect wiring or invent Pakar commands. @@ -2267,7 +2267,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `desktop/src/ui/preferences.rs:262 [UTF8-LF sha256=38bda5597ef69c27761de2bfc820e2d507c8fe29353d3e1f95c118a477d22448; anchor=fn board_controls(]`. - Target: `mobile/lib/api.dart:2109 [UTF8-LF sha256=bbb407cc65ccd54e10d7a21328d07831ce5fa3eff70eebe99a6a10b3815257e8; anchor=Future boardSound(]`. - Target: `mobile/lib/board_sound_preferences.dart:10 [UTF8-LF sha256=888e518c1a85ff594b6c4c778f2eb770a4cbcad3a1d53d3defea19b5e226dc5d; anchor=class BoardSoundPreferences]`. -- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=async function boardSoundTransaction(]`. +- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=async function boardSoundTransaction(]`. - Retained: Reread complete donor source through EOF. Adapt MCU-owned persistent Silent bit independent of host/Windows notification audio, capability-acknowledged controls, explicit unknown/pending/verified states and full-record preservation. Native Preferences Board page uses existing PCController GET/SET/GET with real AVR ACK and persistent readback over the selected fenced HTTP or USB owner only; Web and Flutter Preferences use the same living contract. No unsupported buzzer is invented, no automatic uncertain mutation replay, and unchanged persisted flags skip EEPROM writes. - Omitted/replaced code: `Full board/host/both/none mirroring routes, runtime overrides, OS backend/executable resolution and watched app configuration`. Disposition: **pending**. Reason: Reuse the known/unknown/pending/verified board-setting ownership, not an unimplemented host audio backend. Actual host routing parity needs independent implementation and acoustic acceptance; this change must not mute Windows notifications by accident. - Test-code evidence: `tests/tone_player_test.cpp:46 [UTF8-LF sha256=d1d890f6ead81d22702eb685ae710935bc7c007af5f97236454b851a3f5adc42; anchor=const auto beforeMute]`. @@ -2536,7 +2536,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `desktop/src/firmware_progress.rs:211 [UTF8-LF sha256=11188ec3c9bc7b89e76b94e5412f0e689fa656e5a636d4964136c2236aabbe31; anchor=pub fn observed(]`. - Target: `mobile/lib/firmware_progress.dart:9 [UTF8-LF sha256=c384ea707aee45a2c6e8faa7bfdaadadfc3d8b3a0b92f46ddce4d085edded464; anchor=class FirmwareProgress]`. -- Target: `firmware/esp/src/WebUi.h:2718 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function firmwareUpdateObservation(s)]`. +- Target: `firmware/esp/src/WebUi.h:2718 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function firmwareUpdateObservation(s)]`. - Retained: Adapt actual explicit measured stage counters, indeterminate non-transfer stages, separate verification/completion and terminal state handling. Rust retains external board update/local OTA state in HTTP/WS/USB DTOs; Flutter consumes the existing status stream, and Web renders that same source. No transfer 100 percent is treated as completed flashing. - Retained: 2026-10-29: reread the complete current donor and tests. Redesign the actual Flutter progress consumer using the imported Workspace semantic icon/card/badge surfaces. Show exact stage-local bytes/percentage, distinguish Sending from Programming and explicit verified completion from pending recovery. Unmeasured verification/reboot remains indeterminate; no fabricated ETA or stage history. Add compact/wide, light/dark, RTL and large-text bounds fixtures; installed/device progress evidence remains a separate gate. - Omitted/replaced code: `Remaining donor mechanisms outside this delivery slice`. Disposition: **pending**. Reason: This slice does not port the donor's per-operation milestone toast tracker, Windows taskbar COM ordering or terminal OSC progress presenter. Existing native notifications remain, but complete progress-notification/OS presentation parity is pending. @@ -3003,7 +3003,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O - Target: `mobile/lib/main.dart:1052 [UTF8-LF sha256=814e5944b0f27d21f2005ff4bfa8e391dc5721435e25f9c40ccf2c934090a7db; anchor=Future _command]`. - Target: `libraries/BoardCore/src/DeviceContext.h:25 [UTF8-LF sha256=d1fe9e5a3663b13017ea61d251b6bc314ce91b2cb43b8c8b9c5308fe5fa73f1c; anchor=inline uint16_t features(]`. - Target: `firmware/esp/application.ino:2471 [UTF8-LF sha256=a607abb53d7834663853f2adb45286361d9d5b1cf82edb0d18ee11c9d9a74c41; anchor=if(BoardCore::Context::pixelEvents(available))]`. -- Target: `firmware/esp/src/WebUi.h:2529 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function peerAvailability(]`. +- Target: `firmware/esp/src/WebUi.h:2529 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function peerAvailability(]`. - Retained: Actual connected AND have_status AND advertised-capability conjunction adapted to selected-peer fresh manifests. No feature inference from hostname, pixel count, catalog, defaults or online alone. - Retained: Reread the complete unchanged availability donor and tests for the table live-preview regression. Shared Context::pixelEvents now requires actual Network plus Leds service availability for both compiled roles, without requiring AVR acknowledgement. The same predicate owns feature advertisement, subscription admission and publication; no-driver and network-disabled builds cannot advertise or start pixel events. Existing authorized-listener-only latest-frame coalescing and backpressure remain unchanged. Both role host fixtures and source integration guards passed; live device subscription and optical acceptance remain separate. - Retained: Reread the complete unchanged donor and actual Flutter peer parser/menu/tab consumers for missing Pixel corrections: the known-feature allowlist now retains the explicit pixel-corrections advertisement. Unsupported or mismatched-owner manifests still cannot expose it; existing linked Diagnostics/Corrections tabs are reused rather than duplicated. Actual overflow navigation fixtures assert supported/unsupported visibility and zero board writes. @@ -3038,7 +3038,7 @@ Verdict: **equivalent-behavior**. Revision: `b0111ae0c80dc34149ea1044de7dd548892 Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. Original-byte SHA-256: `7a3e955ddc771cf27f9e545c11ea992a1342a7ed5eaeba9d9a5b95d00dacd2bc`. -- Target: `firmware/esp/src/WebUi.h:2490 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function workspaceSettingsRecord]`. +- Target: `firmware/esp/src/WebUi.h:2490 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function workspaceSettingsRecord]`. - Retained: Completely read actual allowlisted normalized local-preferences and unavailable-storage behavior; adapt bounds/type validation and storage-disabled retention to passive board/application Web workspaces. - Omitted/replaced code: `Full donor quick-header action/catalog UI`. Disposition: **pending**. Reason: This reuses normalization/persistence, not every quick-header control; individual capability-gated donor controls need separate mapping. - Test-code evidence: `tests/web_workspace_test.mjs:115 [UTF8-LF sha256=e35df2215cf2802e9e58896204d4c44dbb12225411a7c511808f47af9679d7cf; anchor=Disabled browser storage still retains this session workspace]`. @@ -3062,7 +3062,7 @@ Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. O Verdict: **parity-gap**. Revision: `b0111ae0c80dc34149ea1044de7dd5488920301b`. Original-byte SHA-256: `f600267bf09d925eaf9e5cc3d752574a0a3fbc46350782c614440300c08799e4`. - Target: `assets/web/frame-stream.js:9 [UTF8-LF sha256=3d0ab90616b173570e5618be76aded339754caa92961868a1d9b43a02e3c6d90; anchor=function createFrameStream]`. -- Target: `firmware/esp/src/WebUi.h:3811 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function readStreamPolicy]`. +- Target: `firmware/esp/src/WebUi.h:3811 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function readStreamPolicy]`. - Retained: Full source read through EOF. Actual injected clock, generation admission, one scheduled callback, cancellation and disposal structure adapted to the mechanically embedded latest-frame Web stream. - Retained: Stale callbacks check generation before clearing the timer handle, strengthening the donor against disarming a replacement owner. Observed board/boot and exact socket ownership replace build/name-only identity for this bounded slice. - Omitted/replaced code: `pendingStatus history queue and applyStatusFrameBatch ordered metrics/error reducer`. Disposition: **pending**. Reason: All status arrivals are useful for telemetry/history, but stale LED actuations must not be replayed. This latest-only send scheduler does not implement the donor telemetry reducer; retain it as separate useful work. @@ -3124,17 +3124,17 @@ Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f - Target: `.github/dependabot.yml:1 [UTF8-LF sha256=136887ba77b56544d0bcd367a31d2daaa7637ecdb8b997d63df6cb552d6f08e8; anchor=version: 2]`. - Retained: Actual donor weekly grouped github-actions and Cargo updates, with Cargo path adapted to the existing desktop workspace. - Omitted/replaced code: `npm updates at /web_ui`. Disposition: **not-applicable**. Reason: Pakar has no /web_ui/package.json or Vite runtime. Embedded Web/tests use Node built-ins; Flutter's actual /mobile Pub dependency contract is covered instead. -- Test-code evidence: `tests/repository_governance_test.mjs:105 [UTF8-LF sha256=2c8393bbd1463ce367cff24d72110a96e53e664824d780f2e66a2c8f8930bda1; anchor=console.log('Repository governance]`. +- Test-code evidence: `tests/repository_governance_test.mjs:107 [UTF8-LF sha256=95ddf3c77735d2693bc7d7cd8f37db7637d6ebe6923c7ae84281c6f9819ac56c; anchor=console.log('Repository governance]`. - Scoped advantage: Adds grouped Pub updates for the actual Android client and label routing while retaining weekly grouped Actions/Cargo updates. ### Pealayer: `.github/workflows/ci-cd.yml` Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `2e5c933b7c1646d5cb26ddd8a10f88529de15bd205b525295858755d5044988b`. -- Target: `.github/workflows/build.yml:2 [UTF8-LF sha256=88ae50be55cc684e1e23658d13f0f443e945cac7a38ad87948709681260b4861; anchor=name: "🚀 Build · Test · Release"]`. +- Target: `.github/workflows/build.yml:2 [UTF8-LF sha256=83924ae2ac89730473e32007eda800ad03ccbfb8267d61ff7ee52f984d586a8a; anchor=name: "🚀 Build · Test · Release"]`. - Target: `tools/build-desktop.ps1:49 [UTF8-LF sha256=720dad8eeffa5fb7da1e5460b582478d2a7c7f4b8645ca5695cc336884d8b410; anchor=--test-threads=1]`. - Target: `tools/ci-checks.mjs:280 [UTF8-LF sha256=c33954b785a09f8bf3b469fdf9a8b12133c75bf1198fa76ac050678c5ceaa64c; anchor=export function runChecks]`. -- Target: `tools/prepare-release.mjs:18 [UTF8-LF sha256=820cefc9698d46f95cf39b4cd667494a05cd03d119a1c54f9892b2a35d8b824b; anchor=export function firmwareManifest]`. +- Target: `tools/prepare-release.mjs:19 [UTF8-LF sha256=b31fc1117c192807cb01642ec932ee8ffcb1dd9fe3acabf837002ee6bf29a2e1; anchor=export function firmwareManifest]`. - Retained: Actual donor branch/PR/tag/dispatch/merge-group triggers, concurrency policy, pinned actions without checkout credentials, health-before-build jobs, timeouts, Rust cache reuse, locked tests/builds, packaging, curated notes, manifest/checksums/provenance and aggregate results adapted to current Windows/ESP/AVR/Android targets. - Retained: Release content is gated on all supported-target builds, created as an immutable draft prerelease, with the matched S3/AVR buffered pair and raw HTTPS update manifests. Explicit legacy packaging is preserved but the overflowing ESP8266 image is not promised as a release output. Untrusted PRs do not execute publishing code with a write token. - Retained: Actual donor serial native test execution, isolated test configuration and RUST_BACKTRACE=1 restored. Runtime harness flags are separated from compile jobs; immediate panic output remains available even if a later test aborts before its summary. @@ -3144,7 +3144,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O - Omitted/replaced code: `UPX checksum-locked packing and packed native package smoke/resource checks`. Disposition: **pending**. Reason: Existing Windows wrappers preserve donor resource/donor/cache gates and CLI runtime tests, but Pakar has no accepted compressed native package probe. Do not call a source or CLI test full packed GUI runtime acceptance. - Omitted/replaced code: `branch-tag and archive suffix creation, softprops update-existing release`. Disposition: **replaced**. Reason: User requests stable names without random/time suffixes. Version releases keep stable package names; release enumeration must succeed and an existing release is not overwritten. - Test-code evidence: `tests/build_storage_test.ps1:17 [UTF8-LF sha256=6bfae8dbd4e71ee19a6d760fe69898d3f057354877c3182dff73ee9240f1dbbd; anchor=Actual donor serial test contract]`. -- Test-code evidence: `tests/repository_governance_test.mjs:105 [UTF8-LF sha256=2c8393bbd1463ce367cff24d72110a96e53e664824d780f2e66a2c8f8930bda1; anchor=console.log('Repository governance]`. +- Test-code evidence: `tests/repository_governance_test.mjs:107 [UTF8-LF sha256=95ddf3c77735d2693bc7d7cd8f37db7637d6ebe6923c7ae84281c6f9819ac56c; anchor=console.log('Repository governance]`. - Remaining: The historical 8849ab8 menu failure was subsequently fixed; 5d02b07 Build 38141677102 and CodeQL 38141677110 pass. This is not production/deployment proof. Validate the unexecuted draft publisher, useful additional native targets, donor macOS diagnostics and optional compressed package/runtime verification. ### Pealayer: `.github/workflows/codeql.yml` @@ -3154,11 +3154,11 @@ Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238 - Target: `.github/workflows/codeql.yml:2 [UTF8-LF sha256=0ced3b7ee236102d9322f20ee0e4a37347aae41d791d48c38731f96daf4bdfba; anchor=name: "🛡️ Security · CodeQL"]`. - Retained: Actual donor Actions and JavaScript matrix, no-build security-extended queries, pinned checkout/CodeQL actions, no persisted checkout credentials, PR/main/schedule/dispatch/merge-group triggers, cancellation, timeouts and fail-closed aggregate summary. - Omitted/replaced code: `Pealayer React/Vite names, packages:read permission and branded prose`. Disposition: **replaced**. Reason: Pakar analyzes embedded Web/scripts and Actions, not Pealayer React. Package read permission is unnecessary for these none-build scans; Rust/C++ coverage is explicitly not invented. -- Test-code evidence: `tests/repository_governance_test.mjs:105 [UTF8-LF sha256=2c8393bbd1463ce367cff24d72110a96e53e664824d780f2e66a2c8f8930bda1; anchor=console.log('Repository governance]`. +- Test-code evidence: `tests/repository_governance_test.mjs:107 [UTF8-LF sha256=95ddf3c77735d2693bc7d7cd8f37db7637d6ebe6923c7ae84281c6f9819ac56c; anchor=console.log('Repository governance]`. ### Pealayer: `assets/themes/palettes.json` -Verdict: **equivalent-file**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `11990ef4b31ba6eb1275c6e76b9156e0f05bacb2f59a8fa0372b778c6caf1501`. +Verdict: **equivalent-file**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `11990ef4b31ba6eb1275c6e76b9156e0f05bacb2f59a8fa0372b778c6caf1501`. - Target: `assets/themes/palettes.json:2 [UTF8-LF sha256=11990ef4b31ba6eb1275c6e76b9156e0f05bacb2f59a8fa0372b778c6caf1501; anchor="studio"]`. - Retained: Byte-identical Studio/Native light/dark JSON catalog, all fourteen semantic roles. @@ -3169,28 +3169,28 @@ Verdict: **equivalent-file**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c ### Pealayer: `build.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `68fb1bdd9e7c7523ab303e37001d3a5252dcb03abe85e489432fe913be7b2e0f`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `68fb1bdd9e7c7523ab303e37001d3a5252dcb03abe85e489432fe913be7b2e0f`. -- Target: `desktop/build.rs:16 [UTF8-LF sha256=a7c694cdd2cfd17e3359db8970ce9ffd7db699110145543dde7c73703ca017ef; anchor=brand_image::native_icon_bytes(brand_image::icon_bytes())]`. -- Target: `docs/BRANDING-PARITY.md:60 [UTF8-LF sha256=0bfa8122dc9d6034551304f2fed472ddebcff170e14a23f63011177aab75d2d3; anchor=## Explicit unfinished useful code and reasons]`. +- Target: `desktop/build.rs:16 [UTF8-LF sha256=4a33b09a2c6bacd11f3dbe48832a6d3a6edf26449aec23f651cba28fd54a62f4; anchor=brand_image::native_icon_bytes(brand_image::icon_bytes())]`. +- Target: `docs/BRANDING-PARITY.md:81 [UTF8-LF sha256=a24fad79482885e11f72fca8ec34b41d7b8bac8d268a4fb19c42b0b493e6d7ed; anchor=## Explicit unfinished useful code and reasons]`. - Retained: Application PE/window/tray master derivatives are separated from actual semantic quick-action resource generation; master/helper changes trigger rebuild. - Omitted/replaced code: `emit_build_metadata; APPLICATION_BRAND JSON/APP_* precedence/filename validation; version/InternalName/OriginalFilename/copyright/provenance fields`. Disposition: **pending**. Reason: Fixed current identity exists; validated external branding and full generic metadata/provenance remain useful imports. - Omitted/replaced code: `macOS brew/mpv probing and rpath flags`. Disposition: **not-applicable**. Reason: Pakar is explicitly mpv-free; media linker dependencies violate that scope. -- Test-code evidence: `tests/branding_test.mjs:12 [UTF8-LF sha256=c39528379a8b6e97561e0e0deb5e435a182f75bce2b385780c7b9ee853455fbb; anchor=actual Pealayer icon_data_from_bytes import]`. +- Test-code evidence: `tests/branding_test.mjs:11 [UTF8-LF sha256=b333d65233f94c4e0e88a6ef2d6e2f360f5a5ff8a81b71728d8a2af53f3a1199; anchor=actual Pealayer icon_data_from_bytes import]`. - Remaining: Complete named generic omissions with preference/endpoint/runtime tests; source checks are not deployed acceptance. See BRANDING-PARITY.md. ### Pealayer: `docs/releases/next.md` -Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `71f81fa503d0494a85dd700e16cabdb23e1a6dcd6abbb0abc1af47000584b3f7`. +Verdict: **equivalent-behavior**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `71f81fa503d0494a85dd700e16cabdb23e1a6dcd6abbb0abc1af47000584b3f7`. - Target: `docs/releases/next.md:1 [UTF8-LF sha256=9e83c4d1a348af3bc275a5ec924abea7317ba22d1f0e66eac63d6f5499efbeec; anchor=# PakarController development packages]`. - Retained: Actual donor curated preview notes explicitly distinguish a development milestone from stable-release, physical and platform acceptance. - Omitted/replaced code: `Pealayer media/audio/timeline milestone inventory and archived media screenshot evolution links`. Disposition: **replaced**. Reason: These are donor-specific release facts, not transferable Pakar features. Record actual controller/interface packages and link Pakar issue #2 instead. -- Test-code evidence: `tests/repository_governance_test.mjs:105 [UTF8-LF sha256=2c8393bbd1463ce367cff24d72110a96e53e664824d780f2e66a2c8f8930bda1; anchor=console.log('Repository governance]`. +- Test-code evidence: `tests/repository_governance_test.mjs:107 [UTF8-LF sha256=95ddf3c77735d2693bc7d7cd8f37db7637d6ebe6923c7ae84281c6f9819ac56c; anchor=console.log('Repository governance]`. ### Pealayer: `docs/REVIEW-COMMENT-AUDIT.md` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `7a91d9fa8778383ee37e33d861ceebc5ab210e46bedab6af8be82d56c27523cc`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `7a91d9fa8778383ee37e33d861ceebc5ab210e46bedab6af8be82d56c27523cc`. - Target: `tools/audit-github-conversations.mjs:59 [UTF8-LF sha256=0bd597414af4e28668d2da96e250a27a99550fff9b86e5d58136b7de583a1dcf; anchor=export function collect]`. - Target: `docs/GITHUB-COORDINATION.md:1 [UTF8-LF sha256=64a078407d296db907e8645e07dc25a6392168cb1cb2e39cc8bb18a9bce01f0d; anchor=# Conversation-aware integration]`. @@ -3202,7 +3202,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `docs/superpowers/plans/2026-09-28-windows-taskbar-and-tray-suite.md` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `033a82778e4ed8258bbbf99600d16039f523043386e302032d6df8849624ea9f`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `033a82778e4ed8258bbbf99600d16039f523043386e302032d6df8849624ea9f`. - Target: `desktop/src/platform/windows_tray.rs:17 [UTF8-LF sha256=94bd79acba0dd4d572222cb064e451a274ee38579a392c95c56d997779cc35bf; anchor=struct TooltipSync]`. - Target: `desktop/src/platform/windows_notifications.rs:158 [UTF8-LF sha256=71f2254825ba2b16d83696ce0e0cf74ec7c95eedda5f60e1c3d167826693ec1a; anchor=fn tooltip_data(]`. @@ -3218,7 +3218,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `docs/verification/LOCAL-WORKSPACE-HYGIENE.md` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `c024125307f6e466c924e1b8874f869a575b085b2a05bb4493bfd1d1e9f38975`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `c024125307f6e466c924e1b8874f869a575b085b2a05bb4493bfd1d1e9f38975`. - Target: `docs/REUSE-PREFLIGHT.md:42 [UTF8-LF sha256=13521024e5b18f314abcc71af4e9c722262a7cb04c17f03155b1e88d0cf0972e; anchor=Mandatory sequence on every task]`. - Retained: Actual canonical-cache/stable-staging/preservation/blocked-operation and separate runtime-acceptance guidance read and adopted in mandatory continuation policy and tooling. @@ -3231,7 +3231,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `docs/WINDOWS-SHELL-RECOVERY.md` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `57fbd904e18d8f0036dd67e2c866d357ab282075689a1cbf6b38a64270875492`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `57fbd904e18d8f0036dd67e2c866d357ab282075689a1cbf6b38a64270875492`. - Target: `desktop/src/platform/windows_tray.rs:14 [UTF8-LF sha256=94bd79acba0dd4d572222cb064e451a274ee38579a392c95c56d997779cc35bf; anchor=Shell acceptance, not object presence]`. - Target: `desktop/src/ui/shell.rs:1332 [UTF8-LF sha256=015877d9b262b596d4e27fdddcbd03a42c8c1e1cbe2b15f46632a88bce7ccce8; anchor=value["tray_shell"]]`. @@ -3247,19 +3247,19 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `README.md` -Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `4e78a6c486bfc7d78adc6d34552bddfd67c89997edb8d2bae0b46e70c705dcb6`. +Verdict: **scoped-improvement**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `4e78a6c486bfc7d78adc6d34552bddfd67c89997edb8d2bae0b46e70c705dcb6`. -- Target: `README.md:7 [UTF8-LF sha256=6ef2bde812ca8aaf889f5ad1c8313ae6e4e5ac079b93424ef4be6e2cdd007da5; anchor=Connected boards. One contextual control workspace.]`. -- Target: `tools/generate-readme-artwork.mjs:1 [UTF8-LF sha256=2162d1ad3760618260eb9d659dfebb6651ad1e5f5b4eb2c37c12cde1ef7ff8d2; anchor=README uses the same bytes]`. +- Target: `README.md:7 [UTF8-LF sha256=a83ac5347ba1090b21c3cd3d65e4dcf1fc201a2d78e733220994a70bdf2dadb4; anchor=Connected boards. One contextual control workspace.]`. +- Target: `tools/generate-readme-artwork.mjs:1 [UTF8-LF sha256=83ac3f09a45dace80865eda69d7f69cb22a3af8042edf69a3ae12cf8022c6580; anchor=README uses the same bytes]`. - Retained: Pealayer's actual centered logo/title/tagline, badge row, visual preview, section navigation, architecture, build, docs, contribution and license structure adapted to Pakar. - Omitted/replaced code: `Media engine, NLE cue/timeline walkthroughs, playback APIs/shortcuts and libmpv installation sections`. Disposition: **not-applicable**. Reason: These describe Pealayer media business/runtime rather than Pakar board control. README links actual controller APIs, wiring and release/acceptance instead; no mpv is linked. - Omitted/replaced code: `Donor platform and latest-release badges, cinema-grade completion language and media screenshots`. Disposition: **replaced**. Reason: Unsupported OS/release claims and unrelated images would misrepresent this repo. Use the shared application logo and real embedded Web screenshot labeled simulated, explicit PR/source and physical acceptance boundaries. -- Test-code evidence: `tests/repository_governance_test.mjs:105 [UTF8-LF sha256=2c8393bbd1463ce367cff24d72110a96e53e664824d780f2e66a2c8f8930bda1; anchor=console.log('Repository governance]`. +- Test-code evidence: `tests/repository_governance_test.mjs:107 [UTF8-LF sha256=95ddf3c77735d2693bc7d7cd8f37db7637d6ebe6923c7ae84281c6f9819ac56c; anchor=console.log('Repository governance]`. - Scoped advantage: Canonical cross-interface icon bytes and explicit proof/acceptance boundaries prevent a polished landing page from claiming an unaccepted release. ### Pealayer: `scripts/capture-visible-window-windows.ps1` -Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `94bc5aed91407818905412d50dde72ea669f3c799ef56a043dd0a81befdce47f`. +Verdict: **scoped-improvement**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `94bc5aed91407818905412d50dde72ea669f3c799ef56a043dd0a81befdce47f`. - Target: `tools/capture-window-windows.ps1:75 [UTF8-LF sha256=c9f48604a224599ea0252638558e80f4025beb4b53834112af9e48af03ae73d0; anchor=public static extern bool PrintWindow]`. - Retained: Actual donor PrintWindow P/Invoke, minimized/window-bounds validation, DPI awareness, System.Drawing PNG lifecycle and read-only behavior. @@ -3270,7 +3270,7 @@ Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f ### Pealayer: `scripts/check-crate-boundary.mjs` -Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `da9b469ac596e6eb1999e4d499742a51ebf289335285549569116c1124963e38`. +Verdict: **scoped-improvement**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `da9b469ac596e6eb1999e4d499742a51ebf289335285549569116c1124963e38`. - Target: `tools/check-crate-boundary.mjs:10 [UTF8-LF sha256=4a8fbcecaf424460c051de61d5e44658532ec64527460ce21d4d86ec95c0550e; anchor=export function checkCrateBoundary]`. - Retained: Actual donor module extraction/intersection, thin executable and MSVC duplicate resource linkage guards imported/adapted. Native build wrapper and CI execute this read-only guard before compiling. @@ -3281,7 +3281,7 @@ Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f ### Pealayer: `scripts/libmpv-windows.ps1` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `ab6e48f3e0a55a2d86ad1dbb19c01a23c751891cb5a7ed61875a21b1e52645e5`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `ab6e48f3e0a55a2d86ad1dbb19c01a23c751891cb5a7ed61875a21b1e52645e5`. - Target: `tools/windows-build-host.ps1:16 [UTF8-LF sha256=7da123594866f591b490db084496b4bef75b2db3f6e0ac5b425b8d86e9401e9b; anchor=function Get-PakarCargoTargetDirectory]`. - Target: `tools/windows-build-host.ps1:46 [UTF8-LF sha256=7da123594866f591b490db084496b4bef75b2db3f6e0ac5b425b8d86e9401e9b; anchor=function Test-PakarFileContentEqual]`. @@ -3298,7 +3298,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `scripts/package-probe-windows.ps1` -Verdict: **equivalent-file**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `f4516884990ad76c020fbc6534d902c4949abae0b48da8ea40c008afa44dfd4f`. +Verdict: **equivalent-file**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `f4516884990ad76c020fbc6534d902c4949abae0b48da8ea40c008afa44dfd4f`. - Target: `tools/package-probe-windows.ps1:27 [UTF8-LF sha256=71604ab464776891dbc95db7123218c22b3ede09ce2835fe4659d75c6d0b9d5e; anchor=function Invoke-PackageProbe]`. - Target: `tools/replace-desktop.ps1:71 [UTF8-LF sha256=95a7f84383869622426e97d7c21d579ce93fd5c55d2bd4607697b6b352bbe525; anchor=$reply=Invoke-PackageProbe]`. @@ -3310,7 +3310,7 @@ Verdict: **equivalent-file**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c ### Pealayer: `scripts/package-windows.ps1` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `5651709cfb58c2f1e0d7052b3ca604df154563ce552498a066c6e67b8f9baedf`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `5651709cfb58c2f1e0d7052b3ca604df154563ce552498a066c6e67b8f9baedf`. - Target: `tools/windows-build-host.ps1:62 [UTF8-LF sha256=7da123594866f591b490db084496b4bef75b2db3f6e0ac5b425b8d86e9401e9b; anchor=function Assert-PakarPackageSourceStable]`. - Target: `tools/stage-desktop.ps1:38 [UTF8-LF sha256=1bbfe87fe8c9e6936e140c7911c5493f5937eceac1402ca386661dcabb40c4bd; anchor=Invoke-PackageProbe]`. @@ -3326,7 +3326,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `scripts/run-windows.ps1` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `013e5c67e227ed851f8a3d26b27654e38c8816edca2965381bbb1b48d10a750d`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `013e5c67e227ed851f8a3d26b27654e38c8816edca2965381bbb1b48d10a750d`. - Target: `tools/build-desktop.ps1:35 [UTF8-LF sha256=720dad8eeffa5fb7da1e5460b582478d2a7c7f4b8645ca5695cc336884d8b410; anchor=Get-PakarCargoTargetDirectory]`. - Retained: Shared resolver call and locked native build flow mapped to Pakar wrapper. Existing canonical cache is reused; explicit Check/Test/Release and storage/reuse gates avoid unnecessary links. @@ -3339,7 +3339,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `scripts/storage-hygiene.ps1` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `0d8fdeb3e15fb52b917784d4cb3875c68bc12c6c6ed78cd16f2ff8ee3561d89c`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `0d8fdeb3e15fb52b917784d4cb3875c68bc12c6c6ed78cd16f2ff8ee3561d89c`. - Target: `tools/storage-hygiene.ps1:11 [UTF8-LF sha256=3d1091c2761add106a5104f671bf12793c9621803f38bd898b193f597eabb329; anchor=function Get-DirectorySummary]`. - Target: `tools/build-mobile.ps1:87 [UTF8-LF sha256=0c5eee09b25ad17fc062555da65024fc84a9d8cc7c4a057d6d2e8a53d2ed8fb4; anchor=$taskCache=Get-DirectorySummary]`. @@ -3355,7 +3355,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `scripts/update-screenshots-windows.ps1` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `48507f6e9395c8c312c5557db729d05ed8d6a83e980d57a9b01e77ea525db287`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `48507f6e9395c8c312c5557db729d05ed8d6a83e980d57a9b01e77ea525db287`. - Target: `tools/capture-window-windows.ps1:75 [UTF8-LF sha256=c9f48604a224599ea0252638558e80f4025beb4b53834112af9e48af03ae73d0; anchor=public static extern bool PrintWindow]`. - Retained: Actual PrintWindow(PW_RENDERFULLCONTENT), near-uniform-black sampler, GetWindowDC/BitBlt/screen fallback and PID/dimension validation imported. Pakar fixture supplies isolated profile/selected surfaces; app-owned framebuffer capture does not depend on WGC. @@ -3385,14 +3385,14 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/branding.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `ee6ef94e685a86e72258e4609692a9fefa516d5935d75d15a5abe0ee42ada3c1`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `ee6ef94e685a86e72258e4609692a9fefa516d5935d75d15a5abe0ee42ada3c1`. -- Target: `desktop/src/branding.rs:75 [UTF8-LF sha256=13a85d887a09acb79aed6acb7b8c0e38f9ea1ba2e35e9306c8bf7558211bc211; anchor=pub fn icon_data_from_bytes]`. -- Target: `desktop/src/brand_image.rs:25 [UTF8-LF sha256=ab71607dcde16d7af14b0a292982f902186dacf6b5b78b3f4c983e37464428e9; anchor=pub fn native_icon_bytes]`. -- Target: `docs/BRANDING-PARITY.md:60 [UTF8-LF sha256=0bfa8122dc9d6034551304f2fed472ddebcff170e14a23f63011177aab75d2d3; anchor=## Explicit unfinished useful code and reasons]`. -- Target: `desktop/src/branding.rs:9 [UTF8-LF sha256=13a85d887a09acb79aed6acb7b8c0e38f9ea1ba2e35e9306c8bf7558211bc211; anchor=pub fn sync_peer]`. +- Target: `desktop/src/branding.rs:75 [UTF8-LF sha256=501550b1f21d7f165fb9de4c0c693a504f90e38b50a82c9add2637e9783377a9; anchor=pub fn icon_data_from_bytes]`. +- Target: `desktop/src/brand_image.rs:30 [UTF8-LF sha256=a286fb4a54cbc3c916343df1630bf0d0a1e9835b2bd644072b5d4ae18b8836b9; anchor=pub fn native_icon_bytes]`. +- Target: `docs/BRANDING-PARITY.md:81 [UTF8-LF sha256=a24fad79482885e11f72fca8ec34b41d7b8bac8d268a4fb19c42b0b493e6d7ed; anchor=## Explicit unfinished useful code and reasons]`. +- Target: `desktop/src/branding.rs:9 [UTF8-LF sha256=501550b1f21d7f165fb9de4c0c693a504f90e38b50a82c9add2637e9783377a9; anchor=pub fn sync_peer]`. - Target: `mobile/lib/main.dart:1670 [UTF8-LF sha256=814e5944b0f27d21f2005ff4bfa8e391dc5721435e25f9c40ccf2c934090a7db; anchor=peer.application?.icon ?? bundledApplicationArtwork]`. -- Target: `mobile/lib/application_artwork.dart:2 [UTF8-LF sha256=a1ee8fc15b0aa9111a5c416fcf74b3d05093b22e47b76d7744837f175f7b5ef4; anchor=const applicationArtworkBase64]`. +- Target: `mobile/lib/application_artwork.dart:2 [UTF8-LF sha256=2a55523277ac368f98b85018fd5713dfa5554094eb1dc3576b552954cb7a01b2; anchor=const applicationArtworkBase64]`. - Retained: Actual icon_data_from_bytes imported unchanged; one embedded PNG supplies native/Web artwork without disk caches. - Retained: Actual native_icon_bytes seven-frame ICO encoding/master preservation/Lanczos3 resampling and shell derivative test adapted to shared supplied bytes and PNG-only decoder. - Retained: Actual sync_native_window_icon source-signature cache, multi-viewport icon publication and tray refresh lifecycle adapted to fresh selected-peer Application metadata; no per-frame decode or disk cache. @@ -3402,13 +3402,13 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O - Omitted/replaced code: `sync_native_window_icon, icon_source_signature/revision metadata/multi-viewport/tray sync and tests`. Disposition: **replaced**. Reason: sync_peer now adapts the cache/multi-viewport lifecycle to peer Application metadata, shared header/About and tray artwork/Show label. Native runtime acceptance is still blocked by the cache guard; full icon preferences/tests remain open. - Omitted/replaced code: `PlaybackIconState/from_player/playback_state_is_unambiguous`. Disposition: **not-applicable**. Reason: Video state business expressly removed; hardware state icons require a separate validated state contract. - Omitted/replaced code: `Current apply_native_window_icon shared Preferences/main HWND path, native window_icons::apply fallback, (state,revision,HWND) sync stamp and file-metadata change detection`. Disposition: **pending**. Reason: Pakar currently caches selected peer Application metadata and emits viewport icon commands; it does not implement donor native HWND registration/replacement lifecycle, file override metadata or preset precedence. Preserve bounded inline peer artwork and import applicable native lifecycle only after Windows tests; playback business remains excluded separately. -- Test-code evidence: `tests/branding_test.mjs:12 [UTF8-LF sha256=c39528379a8b6e97561e0e0deb5e435a182f75bce2b385780c7b9ee853455fbb; anchor=actual Pealayer icon_data_from_bytes import]`. +- Test-code evidence: `tests/branding_test.mjs:11 [UTF8-LF sha256=b333d65233f94c4e0e88a6ef2d6e2f360f5a5ff8a81b71728d8a2af53f3a1199; anchor=actual Pealayer icon_data_from_bytes import]`. - Test-code evidence: `tests/web_identity_test.mjs:40 [UTF8-LF sha256=c4824a7923009f8698e0cde21c1d693609d1af98f55c47dbc20a140293a576be; anchor=Actual Web application identity]`. - Remaining: Complete named generic omissions with preference/endpoint/runtime tests; source checks are not deployed acceptance. See BRANDING-PARITY.md. ### Pealayer: `src/cli.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `412b553fcdcd4436075af6bc93c956a4b7d9ac93a552a3458f2afabb8aa1448f`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `412b553fcdcd4436075af6bc93c956a4b7d9ac93a552a3458f2afabb8aa1448f`. - Target: `desktop/src/cli_output.rs:28 [UTF8-LF sha256=135bdb2862fb8e1946164e685059aadbb12e19db096056224a16632e8333bc89; anchor=pub fn parse_cli_output(]`. - Retained: Actual format_help_message and PrintHelp/PrintVersion flag branches adapted with native short/long help/version assertions; terminate before config, network, GUI ownership and windows. Share device command help with existing TUI instead of duplicate stale strings. @@ -3420,7 +3420,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/diagnostics.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `92b065a4d8ff01ae3b4a81fa11fb6e5b671f85bb1f667be6af389e692fef9f71`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `92b065a4d8ff01ae3b4a81fa11fb6e5b671f85bb1f667be6af389e692fef9f71`. - Target: `desktop/src/cli_console.rs:26 [UTF8-LF sha256=bdf70294c5d4a40007baaf637a8ee26a8576f6dfd03604274fdd9a7d3de2a4ac; anchor=fn write_output(]`. - Target: `desktop/src/main.rs:5817 [UTF8-LF sha256=919d2a1ebeaae2e2694270a8251b93cf4fc56ba882be87a3cdce5297227cff32; anchor=cli_println!("{reply}")]`. @@ -3437,13 +3437,13 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/main.rs` -Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `452eb004c52bdcff6936de5602cfdddf5c925d58db9e1e48220fc9a21075b696`. +Verdict: **equivalent-behavior**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `452eb004c52bdcff6936de5602cfdddf5c925d58db9e1e48220fc9a21075b696`. - Target: `desktop/src/main.rs:2 [UTF8-LF sha256=919d2a1ebeaae2e2694270a8251b93cf4fc56ba882be87a3cdce5297227cff32; anchor=#![cfg_attr(windows, windows_subsystem = "windows")]]`. - Target: `desktop/src/cli_console.rs:69 [UTF8-LF sha256=bdf70294c5d4a40007baaf637a8ee26a8576f6dfd03604274fdd9a7d3de2a4ac; anchor=pub fn prepare(]`. - Target: `desktop/src/application_identity.rs:3 [UTF8-LF sha256=c37a32df5c00a1cc559c58d226b87d6e9756e7d837b56488646bd0ecc54f26bb; anchor=pub const WINDOWS_APP_ID]`. - Target: `desktop/src/platform/windows_jump_list.rs:13 [UTF8-LF sha256=847796332bd1ba7dd3c51a38a1699b0881ae7efe29249d8129de00d2a481d841; anchor=wide_null(crate::application_identity::WINDOWS_APP_ID)]`. -- Target: `desktop/build.rs:40 [UTF8-LF sha256=a7c694cdd2cfd17e3359db8970ce9ffd7db699110145543dde7c73703ca017ef; anchor=.set("CompanyName", application_identity::APP_NAME)]`. +- Target: `desktop/build.rs:40 [UTF8-LF sha256=4a33b09a2c6bacd11f3dbe48832a6d3a6edf26449aec23f651cba28fd54a62f4; anchor=.set("CompanyName", application_identity::APP_NAME)]`. - Retained: Lamp-background checkpoint: reread complete donor main.rs and current CLI preparation/early control-only dispatch. New --cell-backgrounds on|off uses existing owner IPC and fallible CLI output; it never starts another GUI, allocates a console, focuses the existing window or sends board traffic. Scoped consumer hashes are rebound; not new full startup/platform acceptance. - Retained: Actual complete six-line entrypoint read through EOF at5a6961ce. Import windows_subsystem=windows into the Pakar executable, preventing the OS from creating an empty console on ordinary GUI launches. GUI, shortcuts and updater helpers never allocate or attach a console. Explicit CLI/TUI commands may attach only to an existing parent console; inherited file/pipe handles are preserved. - Retained: Use one prefix-free PakarController native identity for window startup, process AppUserModelID, Jump List and executable FileDescription/ProductName/CompanyName/InternalName. Existing updater child CREATE_NO_WINDOW flags remain. This row certifies the tiny entrypoint adaptation, not whole-file Windows Shell parity. @@ -3469,7 +3469,7 @@ Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f ### Pealayer: `src/network.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `22abaf1ca05c64d7e694b7b1d8216904df23cb84f47a0d23c6e91e78d40b86f2`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `22abaf1ca05c64d7e694b7b1d8216904df23cb84f47a0d23c6e91e78d40b86f2`. - Target: `desktop/src/platform/lan_discovery.rs:27 [UTF8-LF sha256=870da3158a7edbf09572ff28eb7878ca4fc4d91d72b3c321a342abff6ee8bfe1; anchor=pub struct Advertiser]`. - Target: `desktop/src/ui/preferences.rs:500 [UTF8-LF sha256=38bda5597ef69c27761de2bfc820e2d507c8fe29353d3e1f95c118a477d22448; anchor=Enable API bridge / repeater]`. @@ -3480,7 +3480,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/platform/window_icons.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `63bbaa244728a2fb4bd53ad5c35f7ff4b95790e70358d47c34ae704ea79d4a4e`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `63bbaa244728a2fb4bd53ad5c35f7ff4b95790e70358d47c34ae704ea79d4a4e`. - Target: `desktop/src/platform/windows_window_icons.rs:138 [UTF8-LF sha256=bc430351f14d15d6559e6f1dd8a593329c1e05cf7661278856d959b9ab539f6b; anchor=pub fn apply(]`. - Target: `desktop/src/ui/shell.rs:1167 [UTF8-LF sha256=015877d9b262b596d4e27fdddcbd03a42c8c1e1cbe2b15f46632a88bce7ccce8; anchor=desktop.set_icon(&icon)]`. @@ -3493,7 +3493,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/platform/windows_quick_actions.rs` -Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `35f6de708a0e402f6958a4d8feeead5037b42174286050ddc98c494d4173e4cb`. +Verdict: **equivalent-behavior**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `35f6de708a0e402f6958a4d8feeead5037b42174286050ddc98c494d4173e4cb`. - Target: `desktop/src/platform/windows_quick_actions.rs:15 [UTF8-LF sha256=432e49b73bdd263fd21de74cdded3de2115605f203f4f3a455e1e2d8553cc0a3; anchor=pub const WINDOWS_QUICK_ACTIONS]`. - Retained: Actual typed action/resource catalog, equality traits, explicit negative resource-index selection, Preferences, Exit and generic Toggle fullscreen. Controller actions share the launch/IPC dispatcher and resource compiler. @@ -3503,7 +3503,7 @@ Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238 ### Pealayer: `src/platform/windows_shell_icons.rs` -Verdict: **equivalent-file**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `e1d8793f8f1697f2030bc407f51e48cab4063964c051f2e21d1f60ae3349732a`. +Verdict: **equivalent-file**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `e1d8793f8f1697f2030bc407f51e48cab4063964c051f2e21d1f60ae3349732a`. - Target: `desktop/src/platform/windows_shell_icons.rs:45 [UTF8-LF sha256=e1d8793f8f1697f2030bc407f51e48cab4063964c051f2e21d1f60ae3349732a; anchor=pub fn shell_icon_ico]`. - Retained: Byte-identical actual Phosphor rasterizer, centered glyph coverage, all seven ICO resolutions, bottom-up BGRA, DWORD-aligned AND masks and explicit directory offsets. Pakar build.rs keeps it for semantic quick-action assets; application PE/window/tray artwork now uses the shared master and actual Pealayer branding conversion. @@ -3512,7 +3512,7 @@ Verdict: **equivalent-file**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c ### Pealayer: `src/server/discovery.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `a707a76b8424353a304ec28e344e467e89823b81c1f4dca321ec3b7060069c6c`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `a707a76b8424353a304ec28e344e467e89823b81c1f4dca321ec3b7060069c6c`. - Target: `desktop/src/platform/lan_discovery.rs:27 [UTF8-LF sha256=870da3158a7edbf09572ff28eb7878ca4fc4d91d72b3c321a342abff6ee8bfe1; anchor=pub struct Advertiser]`. - Target: `desktop/src/platform/discovery.rs:174 [UTF8-LF sha256=126098720cf4b0d91a74e7147b41954f2361960f4ae7d210896f8c762ae24fd3; anchor=pub fn ssdp_locations]`. @@ -3524,7 +3524,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/ui/board_info.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `ab1c99e674e902e37626963e2dd5cf7d993965334411d5e33dafd1ea2bf79e51`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `ab1c99e674e902e37626963e2dd5cf7d993965334411d5e33dafd1ea2bf79e51`. - Target: `desktop/src/capabilities.rs:7 [UTF8-LF sha256=fe68fb6d4d5262079bae60446dd4dfbfc8f69ecce59cd7b12084f7d2cf6eb2a7; anchor=pub struct Manifest]`. - Target: `desktop/src/ui/shell.rs:1062 [UTF8-LF sha256=015877d9b262b596d4e27fdddcbd03a42c8c1e1cbe2b15f46632a88bce7ccce8; anchor=fn synchronize_context(]`. @@ -3534,7 +3534,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O - Target: `desktop/src/ui/preferences.rs:262 [UTF8-LF sha256=38bda5597ef69c27761de2bfc820e2d507c8fe29353d3e1f95c118a477d22448; anchor=fn board_controls(]`. - Target: `mobile/lib/api.dart:2109 [UTF8-LF sha256=bbb407cc65ccd54e10d7a21328d07831ce5fa3eff70eebe99a6a10b3815257e8; anchor=Future boardSound(]`. - Target: `mobile/lib/board_sound_preferences.dart:10 [UTF8-LF sha256=888e518c1a85ff594b6c4c778f2eb770a4cbcad3a1d53d3defea19b5e226dc5d; anchor=class BoardSoundPreferences]`. -- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=async function boardSoundTransaction(]`. +- Target: `firmware/esp/src/WebUi.h:3568 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=async function boardSoundTransaction(]`. - Retained: Reread all 1280 lines through EOF. Prior authoritative overview/capability/front-panel adaptation remains; shared dropdown dependency is now imported, but full typed board settings and ACK consumers remain pending. - Retained: Numeric display controls are independent of Text; peer title follows acknowledged name and lost capabilities cancel Table work. - Retained: Reread complete donor source through EOF. Adapt MCU-owned persistent Silent bit independent of host/Windows notification audio, capability-acknowledged controls, explicit unknown/pending/verified states and full-record preservation. Native Preferences Board page uses existing PCController GET/SET/GET with real AVR ACK and persistent readback over the selected fenced HTTP or USB owner only; Web and Flutter Preferences use the same living contract. No unsupported buzzer is invented, no automatic uncertain mutation replay, and unchanged persisted flags skip EEPROM writes. @@ -3558,7 +3558,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/ui/color_picker.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `fe2bf96c968d83874903f5d06085775f5787cf24467fb0c7be3fcf53077c1aa4`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `fe2bf96c968d83874903f5d06085775f5787cf24467fb0c7be3fcf53077c1aa4`. - Target: `desktop/src/ui/color_picker.rs:25 [UTF8-LF sha256=3a42e1d960fab77e1496899d7c708882f5db1ece1e92c01bd3192bc3e9eef0d5; anchor=pub fn remember_color(]`. - Target: `desktop/src/ui/color_picker.rs:243 [UTF8-LF sha256=3a42e1d960fab77e1496899d7c708882f5db1ece1e92c01bd3192bc3e9eef0d5; anchor=pub fn accent_picker(]`. @@ -3577,7 +3577,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/ui/control_density.rs` -Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `690a964825638da4272550f389a948ad62b5947bad03df8aaee60de49c1325ed`. +Verdict: **equivalent-behavior**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `690a964825638da4272550f389a948ad62b5947bad03df8aaee60de49c1325ed`. - Target: `desktop/src/ui/control_density.rs:7 [UTF8-LF sha256=d5e8b6ae76c101f6473297f4305061ca8b5d83a7e1f4137850383a66b9b1ff6c; anchor=pub fn configure(style: &mut egui::Style, density: UiControlDensity)]`. - Target: `desktop/src/config.rs:38 [UTF8-LF sha256=b84801a85e31a44b2691bd5f6ccefea0106d799952b0fb61e2d6162ee11b9414; anchor=pub enum UiControlDensity]`. @@ -3595,7 +3595,7 @@ Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238 ### Pealayer: `src/ui/controls.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `f5211d73c38438f9cff2543ac234965a8dabd26f4a532fb8b8ecf51248fc0a56`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `f5211d73c38438f9cff2543ac234965a8dabd26f4a532fb8b8ecf51248fc0a56`. - Target: `desktop/src/ui/cell_table.rs:368 [UTF8-LF sha256=a895f275243c9079783aa7f0165bac1d21f692e84b30f8aaeed4fbcc52cf8a19; anchor=fn find_field(]`. - Target: `desktop/src/ui/cell_table.rs:394 [UTF8-LF sha256=a895f275243c9079783aa7f0165bac1d21f692e84b30f8aaeed4fbcc52cf8a19; anchor=fn table_helper(]`. @@ -3621,7 +3621,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O - Target: `desktop/src/ui/preferences.rs:364 [UTF8-LF sha256=38bda5597ef69c27761de2bfc820e2d507c8fe29353d3e1f95c118a477d22448; anchor=let action_height = super::control_density::height(ui).max(dialog::ACTION_HEIGHT);]`. - Target: `desktop/src/ui/cell_table.rs:725 [UTF8-LF sha256=a895f275243c9079783aa7f0165bac1d21f692e84b30f8aaeed4fbcc52cf8a19; anchor=fn manager_selector(]`. -- Target: `firmware/esp/src/WebUi.h:183 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=/* Fixed manager slots:]`. +- Target: `firmware/esp/src/WebUi.h:183 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=/* Fixed manager slots:]`. - Target: `desktop/src/ui/effect_controls.rs:66 [UTF8-LF sha256=da148d2876de05674cc876ed167df5518bb294698090ec5d3fd5a6ad39587dfc; anchor=pub fn mode_picker(]`. - Target: `desktop/src/ui/panel_details.rs:161 [UTF8-LF sha256=d52b713fbf32ae3f9cf0c550f0ff172d2bc5450eeb985ab8a0ce1e0a7edd2d0d; anchor=pub fn correction_rules(]`. - Target: `desktop/src/ui/panel_details.rs:348 [UTF8-LF sha256=d52b713fbf32ae3f9cf0c550f0ff172d2bc5450eeb985ab8a0ce1e0a7edd2d0d; anchor=pub fn network(]`. @@ -3701,7 +3701,7 @@ Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f ### Pealayer: `src/ui/elegance_theme.rs` -Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `8d11f915ccf56e5ab67232ceac7432051437484d1faecacabab62ec5403d63bd`. +Verdict: **equivalent-behavior**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `8d11f915ccf56e5ab67232ceac7432051437484d1faecacabab62ec5403d63bd`. - Target: `desktop/src/ui/elegance_theme.rs:23 [UTF8-LF sha256=a494def22553b0c21b4bb9b2f786f9d117b26ed163b2a254f0ec43f3f979556f; anchor=pub fn sync_elegance_theme(ctx: &Context)]`. - Retained: Read all 321 donor lines through EOF. Pakar retains the actual host-style-preserving Elegance adapter: palette caching, opacity, WCAG 4.5:1 filled-action correction, typography, radius and spacing derivation are unchanged. All three donor tests are now imported and execute against Pakar's real configuration owner. @@ -3735,7 +3735,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/ui/icons.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `cd56a5849a0be621d8472b440c9cbac8b91bcaf603d228cb6148bba1eb554fc9`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `cd56a5849a0be621d8472b440c9cbac8b91bcaf603d228cb6148bba1eb554fc9`. - Target: `desktop/src/ui/icons.rs:581 [UTF8-LF sha256=cd5fe34a628b22220e9be47bf4de262e5e8eeec8e7c045f6dde76414c511a40b; anchor=pub fn searchable_workspace_icon_picker(]`. - Target: `desktop/src/ui/shell.rs:4404 [UTF8-LF sha256=015877d9b262b596d4e27fdddcbd03a42c8c1e1cbe2b15f46632a88bce7ccce8; anchor=icons::searchable_workspace_icon_picker]`. @@ -3784,7 +3784,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/ui/palette.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `c169db6a61b79ebb2ce00f0ca442305eefeea7b34740720a2cdf6424d6fef85d`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `c169db6a61b79ebb2ce00f0ca442305eefeea7b34740720a2cdf6424d6fef85d`. - Target: `desktop/src/ui/palette.rs:36 [UTF8-LF sha256=3d04f723252650661f9fdacd2e1929f3ad28fac4cd3dc40720bca32eac4f3a7c; anchor=pub fn apply(]`. - Retained: Native semantic visual-role mapping and actual palette JSON; appearance geometry is not overwritten. @@ -3839,7 +3839,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O - Target: `desktop/src/ui/shell.rs:1653 [UTF8-LF sha256=015877d9b262b596d4e27fdddcbd03a42c8c1e1cbe2b15f46632a88bce7ccce8; anchor=let firmware_progress = self.firmware_observation().filter(|p| p.active);]`. - Target: `desktop/src/ui/connection_controls.rs:90 [UTF8-LF sha256=02bbb46d280c606868f0f18220cb092c0dca2e07f9b06aa31bee1e4f4625ec65; anchor=pub fn draw(]`. - Target: `docs/CONNECTION-CONTROLS.md:1 [UTF8-LF sha256=002ee046e9c206a4cc241ad2b9033971b4933959d8e14f43958848403879f21d; anchor=# Front-panel transport dropdowns]`. -- Target: `firmware/esp/src/WebUi.h:2566 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function statusRgbOutput]`. +- Target: `firmware/esp/src/WebUi.h:2566 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function statusRgbOutput]`. - Target: `desktop/src/status_rgb.rs:46 [UTF8-LF sha256=3dbe61cf121e44b14fe047427fbe9d0b8e60735baa445ad3116310560631965e; anchor=pub fn retain(]`. - Target: `mobile/lib/status_rgb.dart:52 [UTF8-LF sha256=458f867c97d38107b37fc399dfc55f1ad2f786ce5e236a9a9b2c048d0b4fbfd0; anchor=class StatusRgbPreview]`. - Retained: Current complete source read through EOF independently by the status/front-panel and network/UI agents; selected target changes reviewed again during evidence integration. Actual per-item hide context menus, persistent visibility choices, bar-level restore menu and small truncating message labels remain adapted. Transport controls remain usable offline without claiming hardware readiness. @@ -3888,11 +3888,11 @@ Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f ### Pealayer: `src/ui/workspace_profiles.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `410d274f51e5e7db7ce81582d36166a97240b097e993cec5fee8707a95183e2f`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `410d274f51e5e7db7ce81582d36166a97240b097e993cec5fee8707a95183e2f`. - Target: `mobile/lib/output_panel.dart:27 [UTF8-LF sha256=3cf8895bbbdfc82cb7f4c12ed8e1895623099975722753d5dc722d3eb7ebe9c3; anchor=class OutputPanel]`. - Target: `assets/web/feature-workspaces.js:108 [UTF8-LF sha256=13a51897342b90e6d328d84da0c7272fd6f909fb84996de23a164bb48feb88fa; anchor=function diagnosticWorkspace(value)]`. -- Target: `web/index.html:2489 [UTF8-LF sha256=aa518a96eea2dd7d787cb0a31d5191c78886e2e31605eda64458a0cea728835d; anchor=function workspaceDiagnosticDraft()]`. +- Target: `web/index.html:2489 [UTF8-LF sha256=bc05318e412594e7508b401d2758c719084bf4e1169902bd64795dbfd0a3b4d0; anchor=function workspaceDiagnosticDraft()]`. - Target: `mobile/test/output_panel_test.dart:411 [UTF8-LF sha256=b75b25f46b391a84c0400f08361c4c520e2fda547e95f8b9030078f7f281e317; anchor=Output order is bounded, durable and independent of table selection]`. - Target: `mobile/lib/table_workspace.dart:13 [UTF8-LF sha256=02445683146ff2b3bdca50bfa8d1aa1dedb94261c361613fdb545e7ca4f7c83e; anchor=class TableWorkspace]`. - Target: `mobile/lib/main.dart:897 [UTF8-LF sha256=814e5944b0f27d21f2005ff4bfa8e391dc5721435e25f9c40ccf2c934090a7db; anchor=Future _saveWorkspaces()]`. @@ -3933,7 +3933,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `src/update.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `909e8aa4f903d1a8a63589fd2e371d77ff7b8c6c6bcb3fc9949609ab55440652`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `909e8aa4f903d1a8a63589fd2e371d77ff7b8c6c6bcb3fc9949609ab55440652`. - Target: `desktop/src/client_management.rs:278 [UTF8-LF sha256=29d4d38c2785187fe4ec71ba04dd8d297d4f3ec4a8161cf84fcd6b16336d87d1; anchor=pub fn newer(]`. - Target: `desktop/src/client_install.rs:273 [UTF8-LF sha256=d6088c3223ee29219a4b1048d7aa5d35d03f1906e371039dd7032145e9f87186; anchor=pub fn helper(]`. @@ -3947,7 +3947,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `tests/config_persistence_test.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `e06205e3e023e47e8a8c646e881044ce967e793628f7d52159fbbdf589a6f0d7`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `e06205e3e023e47e8a8c646e881044ce967e793628f7d52159fbbdf589a6f0d7`. - Target: `desktop/src/native_workspace.rs:48 [UTF8-LF sha256=15688543f8999613f064f17e60d453f50d59a05c564e927379fb86d50bc4f0d8; anchor=pub struct Snapshot]`. - Retained: Completely reread actual test. Adapt fresh-session serde roundtrip and persisted layout/state assertions to the actual native board/application workspace store, using actual egui ScrollArea state and DockState. No media dependencies or per-test temporary-directory cleanup copied. @@ -3957,7 +3957,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `tests/i18n_surface_audit_test.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `504768bc9cf2fda32a8dab8b0f50d573c74e45001734f45c7ff3120f36333f63`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `504768bc9cf2fda32a8dab8b0f50d573c74e45001734f45c7ff3120f36333f63`. - Target: `tests/localization_test.mjs:86 [UTF8-LF sha256=da500a29e5ebdb93f52cf275ec1e77f34881d5a66e729f99b67d3e29e1472249; anchor=Adapt Pealayer tests/i18n_surface_audit_test.rs]`. - Retained: Actual donor known-raw-caption prohibition and required localized-boundary audit pattern adapted to real shell menu captions, not renamed timeline/media files. Added peer text exclusion and reversible placeholder/language tests. @@ -3968,7 +3968,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `tests/windows_shell_suite_test.rs` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `3f1f8f7709dd7b0e9dad2c58d1b345e9a7b054bb1bcfbcff9c6aede6598791c6`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `3f1f8f7709dd7b0e9dad2c58d1b345e9a7b054bb1bcfbcff9c6aede6598791c6`. - Target: `desktop/src/platform/windows_notifications.rs:201 [UTF8-LF sha256=71f2254825ba2b16d83696ce0e0cf74ec7c95eedda5f60e1c3d167826693ec1a; anchor=assert!(Hook::new(42).is_err())]`. - Retained: Actual Preferences action/resource catalog is validated; invalid HWND registration rejects rather than claiming success; owner exclusion is tested. Live notification acceptance and shown-callback evidence are recorded independently. @@ -3980,7 +3980,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/scripts/appearance.test.mjs` -Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `35f269e9463e49dbc41572683ca374be8674a93e0e97c84240838d34dc950ddc`. +Verdict: **equivalent-behavior**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `35f269e9463e49dbc41572683ca374be8674a93e0e97c84240838d34dc950ddc`. - Target: `tests/web_appearance_test.mjs:1 [UTF8-LF sha256=f755365a55727e1f0ad3e3e57fdf9f93e990f16d4445840694e264b88710aa7f; anchor=First four tests port the actual Pealayer]`. - Retained: All four actual donor contract tests ported: Neutral helper default, preference merge without unrelated-field loss/resolution leakage, host/offline theme/accent and repeated native event/explicit-theme handling. Additional shipped-code tests cover all palette roles, cancel/apply, contrast, identical-write skip, media events, malformed storage, cross-tab updates and session-only storage failure. @@ -3993,7 +3993,7 @@ Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238 Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `ba2d7a35e2f887ec556b681cca24aaa6f263295208cbc80678bc248b61949845`. -- Target: `firmware/esp/src/WebUi.h:2475 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function createWorkspaceStorage]`. +- Target: `firmware/esp/src/WebUi.h:2475 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function createWorkspaceStorage]`. - Target: `assets/web/device-settings.js:93 [UTF8-LF sha256=28b490c94a63c0b55df4cac22405b02d9ef43725ee08d5e9e3cc418ae8df5492; anchor=function settingsObserve]`. - Target: `assets/web/workspace-studio.js:9 [UTF8-LF sha256=c5c4b999f9fb7ca6011b9193a1ded10ed293bba8b53d9c861ad1ea4c108a15f4; anchor=function studioRoute(]`. - Retained: Completely reread matching actual donor. Import/adapt readStoredJson/persistJson pending-map/timer/pagehide and per-surface scroll patterns into immutable board_id+application.id workspace storage. Selection/find/focus, presentation/panels, public drafts, settings navigation and scroll restore passively; equal writes skip, blocked storage retains in-memory state, and changed fresh settings keep their conflict baseline. @@ -4006,11 +4006,11 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/appearance.ts` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `b521c20a1f10e6f818978bcb09948c689b74caaf72df18bdec56f2f566f8db58`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `b521c20a1f10e6f818978bcb09948c689b74caaf72df18bdec56f2f566f8db58`. - Target: `assets/themes/appearance.js:4 [UTF8-LF sha256=62a7ebba994ad44f4e2d647bb97684aac9b563104f3f707b43573289e514ecdd; anchor=export function mergeAppearance]`. - Target: `tools/generate-web-appearance.mjs:33 [UTF8-LF sha256=e57a615bf5134b718d6df7b644e56faced0c0ef73e8662cf8cb06c05e23e59b4; anchor=replaceBlock('// BEGIN SHARED APPEARANCE']`. -- Target: `firmware/esp/src/WebUi.h:10 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=// BEGIN SHARED APPEARANCE]`. +- Target: `firmware/esp/src/WebUi.h:10 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=// BEGIN SHARED APPEARANCE]`. - Retained: Fully reread current source through EOF. The five previously adapted helpers remain in the target: mergeAppearance, resolvedAccent, resolvedAppearanceTheme, accentForeground and paletteName. Existing theme/palette/accent host resolution and luminance semantics remain; newer animation/density/font preference fields and font CSS helpers are explicitly pending, not claimed imported. - Retained: Generated into the shipped WebUi.h with the shared palette asset; --check rejects stale embedding. Browser preferences dialog validates theme/palette/accent, protects drafts, handles storage failure and cross-tab/System events without device writes or repetitive identical storage writes. - Omitted/replaced code: `ui_animation_mode, ui_control_density, ui_font_family, monospace_font_family merge fields; ControlDensity/controlDensityHeight 24/28/32/36 geometry; uiFontCss and monoFontCss`. Disposition: **pending**. Reason: New current donor behavior was fully read during mobile-network build preflight. Existing embedded target does not consume these client preferences and does not bundle PealayerUbuntu/PealayerHack; copying their font names would imply unavailable assets. Add actual shared settings/asset support and cross-client tests before claiming parity. @@ -4022,7 +4022,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/components/ColorDropdown.tsx` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `49d37654faab5033df04954456d0fe980571ccbc66478caaab7007dae1b8c151`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `49d37654faab5033df04954456d0fe980571ccbc66478caaab7007dae1b8c151`. - Target: `mobile/lib/color_picker.dart:50 [UTF8-LF sha256=8d1b4206d9b99bf4067df432e0147fdfc7fe67f60c6dab83ceb04478de2560c2; anchor=class _ColorPicker]`. - Retained: Read the full donor. Retained a single focused picker, bounded scrollable content, named presets and keyboard-focusable controls, with session recents shared across callers. Flutter dialog owns Cancel/Apply and returns a color rather than inventing another state or transport owner. @@ -4033,7 +4033,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/components/ColorPicker.tsx` -Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `024fdabb482a714c38a91d0dde5d0be11486b20859a019f4fbc2d3dd34295022`. +Verdict: **scoped-improvement**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `024fdabb482a714c38a91d0dde5d0be11486b20859a019f4fbc2d3dd34295022`. - Target: `mobile/lib/color_picker.dart:33 [UTF8-LF sha256=8d1b4206d9b99bf4067df432e0147fdfc7fe67f60c6dab83ceb04478de2560c2; anchor=Future showLedColorPicker]`. - Retained: Read the complete actual donor before implementation. Adapted preset selection, uppercase RGB representation and twelve deduplicated session recent colors into the shared Flutter picker used by semantic state appearance, temporary test color and game group overrides. An explicit Apply commits the local picker choice; Cancel makes no command or recent-color write. @@ -4046,7 +4046,7 @@ Verdict: **scoped-improvement**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f ### Pealayer: `web_ui/src/components/ControlBar.tsx` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `cbd6ebc09cbf23e4958c4d1979974d3e856f2096bcc2dcfd1556c5ef4c45cafd`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `cbd6ebc09cbf23e4958c4d1979974d3e856f2096bcc2dcfd1556c5ef4c45cafd`. - Target: `web/modules/components.js:98 [UTF8-LF sha256=200e38d3a70594f6f2463b03bc74df53cc10e17e8d2264c7851c200d9beff7d4; anchor=const actionIcons=]`. - Target: `assets/web/application-utilities.js:47 [UTF8-LF sha256=20744bfcfc0968df0205a46aeb3bdd513b205f0f91796b168dd99dcb16fdbbf1; anchor=function refreshLabels(]`. @@ -4060,7 +4060,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/components/DesignerFieldLabel.tsx` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `ed527ea04c4dc8e9f51e755c0dc92b8cd9a71a414b2fbcfbaba96e97cd7916a7`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `ed527ea04c4dc8e9f51e755c0dc92b8cd9a71a414b2fbcfbaba96e97cd7916a7`. - Target: `web/modules/components.js:99 [UTF8-LF sha256=200e38d3a70594f6f2463b03bc74df53cc10e17e8d2264c7851c200d9beff7d4; anchor=const controlIcons=]`. - Target: `assets/web/localization.js:43 [UTF8-LF sha256=fc7a39cae41e490fba858a8c7129abf0a7064811c486ddf9ba1b115b79e7c0fb; anchor=function renderUiText(]`. @@ -4073,7 +4073,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/components/EffectGroupDialog.tsx` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `8c90f7a85286efada6d5a1e24212a03dd1ae14e51bea1767f8d195a538ec8f80`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `8c90f7a85286efada6d5a1e24212a03dd1ae14e51bea1767f8d195a538ec8f80`. - Target: `assets/web/feature-workspaces.js:383 [UTF8-LF sha256=13a51897342b90e6d328d84da0c7272fd6f909fb84996de23a164bb48feb88fa; anchor=async function reloadCorrections(]`. - Target: `web/modules/components.js:135 [UTF8-LF sha256=200e38d3a70594f6f2463b03bc74df53cc10e17e8d2264c7851c200d9beff7d4; anchor=function dialog(]`. @@ -4093,14 +4093,14 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/components/HeaderBar.tsx` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `ad53ee284d969054f69b65e8447a313498b5928eae0aed2564e95f8c71e70d04`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `ad53ee284d969054f69b65e8447a313498b5928eae0aed2564e95f8c71e70d04`. -- Target: `tools/generate-branding.mjs:3 [UTF8-LF sha256=816544b2525d3c9210a586b8c2c5d59ed6c51fab8ca4bda27fbf2edbdd451367; anchor=Pakar embeds it for the standalone ESP surface]`. +- Target: `tools/generate-branding.mjs:3 [UTF8-LF sha256=945b5f80e23bb020634b794ea4f866ab8a293506c064cdf79319876db156ad73; anchor=Pakar embeds it for the standalone ESP surface]`. - Target: `mobile/lib/header_controls.dart:17 [UTF8-LF sha256=fdbae404068b75de261d1add7d5768e1b6844272ddfe4edb1b92b338f6cf4f87; anchor=class HeaderLayout]`. - Target: `mobile/lib/main.dart:767 [UTF8-LF sha256=814e5944b0f27d21f2005ff4bfa8e391dc5721435e25f9c40ccf2c934090a7db; anchor=Future _openConnection()]`. -- Target: `firmware/esp/src/WebUi.h:399 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=]`. -- Target: `docs/BRANDING-PARITY.md:60 [UTF8-LF sha256=0bfa8122dc9d6034551304f2fed472ddebcff170e14a23f63011177aab75d2d3; anchor=## Explicit unfinished useful code and reasons]`. -- Target: `firmware/esp/src/WebUi.h:3078 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function renderApplicationIdentity]`. +- Target: `firmware/esp/src/WebUi.h:399 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=]`. +- Target: `docs/BRANDING-PARITY.md:81 [UTF8-LF sha256=a24fad79482885e11f72fca8ec34b41d7b8bac8d268a4fb19c42b0b493e6d7ed; anchor=## Explicit unfinished useful code and reasons]`. +- Target: `firmware/esp/src/WebUi.h:3078 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function renderApplicationIdentity]`. - Target: `assets/web/device-settings.js:120 [UTF8-LF sha256=28b490c94a63c0b55df4cac22405b02d9ef43725ee08d5e9e3cc418ae8df5492; anchor=function settingsCanClose()]`. - Target: `docs/INTERFACE-CONTRACT.md:8 [UTF8-LF sha256=37a0aec859267e0fd62b546ffc044eaa02ae04d2f9a298c5d94a5c24c803cb1b; anchor=## One catalog, distinct transport and platform adapters]`. - Retained: Actual resolved-artwork img/alt binding adapted to standalone header/login, replacing diamond and font fallback. @@ -4113,14 +4113,14 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O - Omitted/replaced code: `Current keyboard-activatable connection-pill, collapsible action overflow parity and capability-aware web-feature preference switches`. Disposition: **pending**. Reason: Pakar must adapt actual endpoint lifecycle, capability/permission detection and keyboard semantics rather than presenting nonfunctional shortcuts. Shared static artwork and device-settings drafts do not provide these generic browser/header behaviors. - Test-code evidence: `mobile/test/header_controls_test.dart:100 [UTF8-LF sha256=db7a6c884949c426561569544a4a17e1be668e6f599a920ffe56f0f3a65539d9; anchor=Header customization saves and restores without changing board state]`. - Test-code evidence: `mobile/test/status_bar_layout_test.dart:93 [UTF8-LF sha256=52cb9e5aef5b21cb81477077b515c21c5108b075168eb410ce5617ba9614e447; anchor=Entire connection status icon and text open connection, errors stay inspectable]`. -- Test-code evidence: `tests/branding_test.mjs:12 [UTF8-LF sha256=c39528379a8b6e97561e0e0deb5e435a182f75bce2b385780c7b9ee853455fbb; anchor=actual Pealayer icon_data_from_bytes import]`. +- Test-code evidence: `tests/branding_test.mjs:11 [UTF8-LF sha256=b333d65233f94c4e0e88a6ef2d6e2f360f5a5ff8a81b71728d8a2af53f3a1199; anchor=actual Pealayer icon_data_from_bytes import]`. - Test-code evidence: `tests/web_identity_test.mjs:40 [UTF8-LF sha256=c4824a7923009f8698e0cde21c1d693609d1af98f55c47dbc20a140293a576be; anchor=Actual Web application identity]`. - Test-code evidence: `tests/interface_settings_test.mjs:33 [UTF8-LF sha256=102d6c411b732bad8106dd09358da3df3989d1140aa77c87a884c8072c66c6f3; anchor=Failed saves preserve the draft]`. - Remaining: Complete generic omissions and missing editors named in INTERFACE-CONTRACT.md; native/mobile/deployed acceptance remains open. ### Pealayer: `web_ui/src/components/NumericValueControl.tsx` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `6f1e99cd5ae8ef0bae30d43a86f22a22371c6543498c5d8938e486cff151d218`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `6f1e99cd5ae8ef0bae30d43a86f22a22371c6543498c5d8938e486cff151d218`. - Target: `mobile/lib/pixel_corrections_editor.dart:115 [UTF8-LF sha256=7b307453c53c084f22bb5e3845b43ba56e34a83633447b36041c4b1facad64c5; anchor=class PixelCorrectionNumberControl]`. - Target: `assets/web/pixel-groups.js:44 [UTF8-LF sha256=24abe18fbf1f11fe248f2f1ac5fe6b7149014be1290fae0f8b3bef59c256e617; anchor=function create(options)]`. @@ -4151,10 +4151,10 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/components/PlaybackButton.tsx` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `10b2c97e2b85d1f5390790992b53a8250dc49847ce0c4b1679f5928e30b9fe5a`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `10b2c97e2b85d1f5390790992b53a8250dc49847ce0c4b1679f5928e30b9fe5a`. - Target: `assets/web/application-utilities.js:37 [UTF8-LF sha256=20744bfcfc0968df0205a46aeb3bdd513b205f0f91796b168dd99dcb16fdbbf1; anchor=function setControlCaption(]`. -- Target: `web/index.html:3274 [UTF8-LF sha256=aa518a96eea2dd7d787cb0a31d5191c78886e2e31605eda64458a0cea728835d; anchor=function renderAssignmentTools(]`. +- Target: `web/index.html:3274 [UTF8-LF sha256=bc05318e412594e7508b401d2758c719084bf4e1169902bd64795dbfd0a3b4d0; anchor=function renderAssignmentTools(]`. - Retained: The Web owner fully read the actual canonical Pealayer component. Preserve its authoritative-snapshot action meaning, disabled unknown/unavailable state and matching icon/label/accessibility rather than optimistic click-state toggling. Existing cell ACK/capability gates remain authoritative; state-caption refresh uses the existing semantic state model and stable label slot. Selection by lost/won identity remains correct even when a user changes the configured RGB color. - Retained: Only canonical Pealayer web_ui/src/styles.css lines 77-102 and 521-552 were inspected as styling dependencies, SHA256 2d08f0129a28e29b55a137c708b9296d5282bd0aaffb6c2fdba6b9d5cf16462d. Fixed borders, optical glyph alignment and restrained tonal states were adapted; the whole stylesheet is not certified read. - Omitted/replaced code: `Play/Pause media command and React/Ant component runtime`. Disposition: **not-applicable**. Reason: The board application has no media player; only authoritative state and visual/action identity are adapted into its existing DOM model. @@ -4165,14 +4165,14 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/components/PreferencesTab.tsx` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `30a63cc1db61a46346c2d4c30ce011dc74081a8a6da2e29853e56d39811a0de1`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `30a63cc1db61a46346c2d4c30ce011dc74081a8a6da2e29853e56d39811a0de1`. - Target: `mobile/lib/device_settings_page.dart:18 [UTF8-LF sha256=b187bcc1ed640dc8b7052ce03c4f36a840289396f8908dbc77b967190eb9e9ee; anchor=class DeviceSettingsPage]`. - Target: `mobile/lib/device_settings.dart:413 [UTF8-LF sha256=0c10e5c712bae2b4fe2f706326115ee703f07e426a64a50728c09575efb71e9a; anchor=class DeviceSettingsSession]`. - Target: `mobile/lib/led_backend_control.dart:9 [UTF8-LF sha256=4769c24f714e241c5acb41987f5cbefef35681a86fbcda40c92ffb7db934c33a; anchor=class LedBackendControl]`. - Target: `mobile/lib/led_backend.dart:5 [UTF8-LF sha256=ccea33fd885d514027e622061bf55daf4d0c3564f977529b9956c6df42d57491; anchor=class LedBackendState]`. -- Target: `web/index.html:2641 [UTF8-LF sha256=aa518a96eea2dd7d787cb0a31d5191c78886e2e31605eda64458a0cea728835d; anchor=function renderLedBackendControl(anchor){]`. -- Target: `web/index.html:2612 [UTF8-LF sha256=aa518a96eea2dd7d787cb0a31d5191c78886e2e31605eda64458a0cea728835d; anchor=function waitForLedBackend(]`. +- Target: `web/index.html:2641 [UTF8-LF sha256=bc05318e412594e7508b401d2758c719084bf4e1169902bd64795dbfd0a3b4d0; anchor=function renderLedBackendControl(anchor){]`. +- Target: `web/index.html:2612 [UTF8-LF sha256=bc05318e412594e7508b401d2758c719084bf4e1169902bd64795dbfd0a3b4d0; anchor=function waitForLedBackend(]`. - Retained: Actual contract-driven sections/selected-section navigation, grouped labeled typed controls, contextual options, retained draft on section changes, descriptions, load/save status and reload adapted to Flutter DeviceSettingsPage using the existing shared Pakar catalog. Tablet uses a searchable navigation rail; phone uses wrapping section chips. Actual Phosphor repertoire supplies verified icon codepoints. - Retained: Actual valueAtPath/updatePaths structured settings ownership adapted to separate public drafts and secret actions. DeviceSettingsSession uses the fully read canonical Pakar native/Web validation, observe/conflict and positive acknowledgment/exact public readback workflow rather than generic optimistic UI success. In-memory secrets never enter saved client preferences; one POST body per explicit operation, no mutation replay. - Retained: Runtime LED transmitter checkpoint reread all563 donor lines and verified SHA30a63cc1. Adapt actual contract-derived select options, field-scoped saving state and external-observation refresh to Flutter LedBackendControl/LedBackendState and the single canonical Web selector. Only the intersection of advertised compiled choices is offered; selection reflects actual driver telemetry and renderer mode stays independent. Replace updatePaths optimistic save with one correlated mutation and same-peer requested/active/readiness/error/persistence observation. WebSocket events settle the result; configured bounded HTTP fallback reads never replay the mutation. This is a scoped mechanism adaptation, not a direct TSX component import or full PreferencesTab parity. @@ -4194,7 +4194,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/components/ServerFilePicker.tsx` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `df5b59007e0b726c815bed0eafcce87e4f5a6e4a59e8c79a1414f2cc7be89316`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `df5b59007e0b726c815bed0eafcce87e4f5a6e4a59e8c79a1414f2cc7be89316`. - Target: `assets/web/user-files.js:35 [UTF8-LF sha256=8b25d6925e5a604b95769d844c1c1d7d06ae9e49a33a9e2307bae5c75d77ec5f; anchor=function create(o)]`. - Target: `mobile/lib/documents.dart:19 [UTF8-LF sha256=9b447b248f21e855c2481e28c6c31e66969af5ab837fd32e4d57eb76164b9ff5; anchor=class AndroidDocuments]`. @@ -4218,11 +4218,11 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/i18n.ts` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `331d2545379e36ea717fcf2876508315437bc5abe49923170f50a4f1bb1b47fc`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `331d2545379e36ea717fcf2876508315437bc5abe49923170f50a4f1bb1b47fc`. - Target: `assets/web/localization.js:19 [UTF8-LF sha256=fc7a39cae41e490fba858a8c7129abf0a7064811c486ddf9ba1b115b79e7c0fb; anchor=function uiTr(text,values)]`. - Target: `tools/generate-font-assets.mjs:62 [UTF8-LF sha256=fdf6b75dac5afebad8598abbe408cd44bbf09cb306d4db91ee515add5ebb1412; anchor=const dictionary={}]`. -- Target: `firmware/esp/src/WebUi.h:795 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=// BEGIN SHARED LOCALIZATION]`. +- Target: `firmware/esp/src/WebUi.h:795 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=// BEGIN SHARED LOCALIZATION]`. - Retained: Fully reread all 630 current donor lines through EOF. Actual fa-dictionary fallback semantics remain reused for application copy, rather than translating arbitrary runtime data. Applicable native dictionary subset generates into the canonical Web module and actual firmware HTML; the new generic hardware/status/font/control vocabulary is useful pending consumer work, not an automatic dictionary import. - Retained: Added system/explicit language and Auto/LTR/RTL preferences, owned-template text/placeholder/accessibility snapshots, per-browser low-write persistence, shared font route and immutable peer-name boundary. - Retained: Persian Web regression slice: controller captions now include preferences, network/cloud/access/firmware and cell dialogs; capability mode labels participate in dictionary generation. Live telemetry and dynamic accessibility labels refresh in the selected language, real addresses release stale caption ownership, option values remain protocol-stable, and Persian text omits Latin letter spacing. Read-only actual HTML browser inspection verified mobile-width preferences/settings and reversible persistent locale switching; this is not live board acceptance. @@ -4235,7 +4235,7 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/preferenceFiles.ts` -Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `4580d1396b36f5a907cad6cf2f33a38486c3a7e6948a3bb222974e1b8a2a4af4`. +Verdict: **equivalent-behavior**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `4580d1396b36f5a907cad6cf2f33a38486c3a7e6948a3bb222974e1b8a2a4af4`. - Target: `mobile/lib/documents.dart:6 [UTF8-LF sha256=9b447b248f21e855c2481e28c6c31e66969af5ab837fd32e4d57eb76164b9ff5; anchor=bool preferenceFileAllowed]`. - Target: `assets/web/cell-assignments.js:3 [UTF8-LF sha256=510c03217f05a1938a27466a4dd571446d8db96cdffeb204109c5865632391d2; anchor=function cellAssignmentFileAllowed]`. @@ -4248,7 +4248,7 @@ Verdict: **equivalent-behavior**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238 ### Pealayer: `web_ui/src/timelineWheel.ts` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `1910311a3acba2f1d22d9d4fb57d43e08bcf6ee91f3ea567e381ae90e8a487cd`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `1910311a3acba2f1d22d9d4fb57d43e08bcf6ee91f3ea567e381ae90e8a487cd`. - Target: `web/modules/table-layout.js:7 [UTF8-LF sha256=30162a2894f72d2467b34fc2cb3e682e09b4da0a1b252ccf6579a25273b53542; anchor=function zoomAt]`. - Target: `mobile/lib/table_viewport.dart:158 [UTF8-LF sha256=d7fe024ea911c1610e36e88a8a1fc412e0b95c615584ebb30322d5870ee032a7; anchor=void zoomAt]`. @@ -4264,18 +4264,18 @@ Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. O ### Pealayer: `web_ui/src/webPlatform.ts` -Verdict: **parity-gap**. Revision: `10fc6604a9d6068eb57da2f00d7d9404238f00c8`. Original-byte SHA-256: `d6ee8217c05e96be2e20f9a40ab4c46249d57f58871c661a31c33e2310a92f0e`. +Verdict: **parity-gap**. Revision: `a878768875b0c5da7fd899fda475074fa90f3e35`. Original-byte SHA-256: `d6ee8217c05e96be2e20f9a40ab4c46249d57f58871c661a31c33e2310a92f0e`. -- Target: `tools/generate-branding.mjs:18 [UTF8-LF sha256=816544b2525d3c9210a586b8c2c5d59ed6c51fab8ca4bda27fbf2edbdd451367; anchor='FAVICON':]`. -- Target: `firmware/esp/src/WebUi.h:142 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=]`. -- Target: `docs/BRANDING-PARITY.md:60 [UTF8-LF sha256=0bfa8122dc9d6034551304f2fed472ddebcff170e14a23f63011177aab75d2d3; anchor=## Explicit unfinished useful code and reasons]`. +- Target: `tools/generate-branding.mjs:19 [UTF8-LF sha256=945b5f80e23bb020634b794ea4f866ab8a293506c064cdf79319876db156ad73; anchor='FAVICON':]`. +- Target: `firmware/esp/src/WebUi.h:142 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=]`. +- Target: `docs/BRANDING-PARITY.md:81 [UTF8-LF sha256=a24fad79482885e11f72fca8ec34b41d7b8bac8d268a4fb19c42b0b493e6d7ed; anchor=## Explicit unfinished useful code and reasons]`. - Retained: Same resolved artwork binds favicon/touch/header before login; ESP embeds data instead of requesting a protected host filesystem icon. - Retained: Current 383-line donor was completely reread. Existing favicon/header/touch artwork mapping remains valid; this is not browser-platform parity. - Omitted/replaced code: `storedBoolean/supportsStandaloneMode/useWebPlatform capabilities/events; install/share/toggleFullscreen/enableNotifications/applyUpdate; settings setters/signalInteraction`. Disposition: **pending**. Reason: Generic browser capabilities/lifecycle/preferences need controller-specific integration and tests; static branding does not certify them. - Omitted/replaced code: `registerPealayerServiceWorker/update/controllerchange, wake-lock cancellation/visibility and offline badge`. Disposition: **pending**. Reason: PWA manifest/high-resolution artwork/cache ownership and streaming-specific wake-lock state remain open. - Omitted/replaced code: `mediaTitle/current_video state icon resolution, MediaSession video metadata/play/pause/seek/chapter handlers`. Disposition: **not-applicable**. Reason: Video title/track/session business is excluded; generic browser capabilities are still pending. - Omitted/replaced code: `Current app_icon_revision-qualified touch/manifest URL refresh, dynamic application-title metadata and explicit media-action callback retirement/position clearing`. Disposition: **pending**. Reason: Generic artwork revision/title refresh must be adapted to board-owned application identity and actual PWA resources. Retained stale media callbacks and position cleanup illustrate useful lifecycle patterns, not permission to expose playback actions on a controller. Generic event ownership must be tested in Pakar's real contexts. -- Test-code evidence: `tests/branding_test.mjs:12 [UTF8-LF sha256=c39528379a8b6e97561e0e0deb5e435a182f75bce2b385780c7b9ee853455fbb; anchor=actual Pealayer icon_data_from_bytes import]`. +- Test-code evidence: `tests/branding_test.mjs:11 [UTF8-LF sha256=b333d65233f94c4e0e88a6ef2d6e2f360f5a5ff8a81b71728d8a2af53f3a1199; anchor=actual Pealayer icon_data_from_bytes import]`. - Remaining: Complete named generic omissions with preference/endpoint/runtime tests; source checks are not deployed acceptance. See BRANDING-PARITY.md. ### portable-shell: `_codeql_detected_source_root` @@ -4570,7 +4570,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `.github/dependabot.yml:3 [UTF8-LF sha256=136887ba77b56544d0bcd367a31d2daaa7637ecdb8b997d63df6cb552d6f08e8; anchor=package-ecosystem: github-actions]`. - Retained: Read exact ecosystem/schedule/group settings and retain Pakar's existing pinned Action/Cargo/pub maintenance. Firmware registry pins use the new dedicated checker instead of pretending Dependabot understands Arduino board/library indices. - Omitted/replaced code: `Unconditional latest-success/first-binary auto-flash and donor-specific test/product packaging`. Disposition: **replaced**. Reason: Use exact successful main source/run/artifact identity and existing Pakar jobs. Automatic writes require an explicitly authorized runner/environment and repository opt-in. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Execute actual new GitHub jobs; verify bot policy and authorized runner/environment before activation. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -4579,11 +4579,11 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `49d608184ca52242cc845026d05384081669eec57007733f43ede09539c79cb6`. -- Target: `.github/workflows/build.yml:108 [UTF8-LF sha256=88ae50be55cc684e1e23658d13f0f443e945cac7a38ad87948709681260b4861; anchor=name: "đź”§ ESP32-S3 + AVR"]`. -- Target: `tools/firmware-report.mjs:57 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=export function artifactMarkdown]`. +- Target: `.github/workflows/build.yml:108 [UTF8-LF sha256=83924ae2ac89730473e32007eda800ad03ccbfb8267d61ff7ee52f984d586a8a; anchor=name: "đź”§ ESP32-S3 + AVR"]`. +- Target: `tools/firmware-report.mjs:70 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=export function artifactMarkdown]`. - Retained: Adapt actual artifact size/checksum/download summary and staged build workflow mechanisms into existing Pealayer-derived build.yml plus firmware-report.mjs. Retain separate matched firmware outputs and draft-release provenance; no external progress image or rewritten timestamp header. - Omitted/replaced code: `Unconditional latest-success/first-binary auto-flash and donor-specific test/product packaging`. Disposition: **replaced**. Reason: Use exact successful main source/run/artifact identity and existing Pakar jobs. Automatic writes require an explicitly authorized runner/environment and repository opt-in. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Execute actual new GitHub jobs; verify bot policy and authorized runner/environment before activation. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -4592,11 +4592,11 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `06b31df1731e5ab45fb0f1c714f95c46470cf1006f6c50150dc9a461d95a52d0`. -- Target: `.github/workflows/build.yml:76 [UTF8-LF sha256=88ae50be55cc684e1e23658d13f0f443e945cac7a38ad87948709681260b4861; anchor=name: "đź§° Scripts · ${{ matrix.os }}"]`. +- Target: `.github/workflows/build.yml:76 [UTF8-LF sha256=83924ae2ac89730473e32007eda800ad03ccbfb8267d61ff7ee52f984d586a8a; anchor=name: "đź§° Scripts · ${{ matrix.os }}"]`. - Target: `.github/actionlint.yaml:3 [UTF8-LF sha256=5b3c6b07ca38aaadb14a1d6eb2d35ac83b705f065901fdafba8210afc9be4960; anchor=pakar-deploy]`. - Retained: Adapt actual tooling verification intent into Windows/Linux/macOS fixture/plan matrix before product jobs. Use one Node/PowerShell owner with explicit Windows-only utility boundaries; no donor-client build/test execution is falsely certified. - Omitted/replaced code: `Unconditional latest-success/first-binary auto-flash and donor-specific test/product packaging`. Disposition: **replaced**. Reason: Use exact successful main source/run/artifact identity and existing Pakar jobs. Automatic writes require an explicitly authorized runner/environment and repository opt-in. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Execute actual new GitHub jobs; verify bot policy and authorized runner/environment before activation. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -4609,7 +4609,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `tools/firmware-dependencies.mjs:77 [UTF8-LF sha256=903bd1fdd6e50218cab22db4fc21fb64aee44da2b025faf329fcee4703506ab1; anchor=export function applyUpdates]`. - Retained: Adapt scheduled registry check and guarded pin-change PR proposal into update-dependencies.yml. Report-only default, exact locked pin file, draft/no-auto-merge, pinned Actions and no device or SDK writes. - Omitted/replaced code: `Unconditional latest-success/first-binary auto-flash and donor-specific test/product packaging`. Disposition: **replaced**. Reason: Use exact successful main source/run/artifact identity and existing Pakar jobs. Automatic writes require an explicitly authorized runner/environment and repository opt-in. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Execute actual new GitHub jobs; verify bot policy and authorized runner/environment before activation. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -4622,7 +4622,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `tools/deploy-artifact.mjs:8 [UTF8-LF sha256=0710b78d5359b0d6ece4dd48f9129acebe1809c370ed4bb6b6767fd4917bf55d; anchor=export function trustedBuild]`. - Retained: Adapt completed-build artifact-to-device flow into opt-in upload.yml/deploy-artifact.mjs. Verify exact repository/head/event/main workflow/run/SHA plus clean artifact report/hash before invoking the same current updater; no guessed latest/first binary. - Omitted/replaced code: `Unconditional latest-success/first-binary auto-flash and donor-specific test/product packaging`. Disposition: **replaced**. Reason: Use exact successful main source/run/artifact identity and existing Pakar jobs. Automatic writes require an explicitly authorized runner/environment and repository opt-in. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Execute actual new GitHub jobs; verify bot policy and authorized runner/environment before activation. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -4645,7 +4645,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `tools/firmware-dependencies.mjs:34 [UTF8-LF sha256=903bd1fdd6e50218cab22db4fc21fb64aee44da2b025faf329fcee4703506ab1; anchor=export function installationPlan]`. - Retained: Retain official ESP8266 registry URL and extend it in one central pin file for ESP32-S3/MiniCore. Explicit install adds only missing configured registry URLs, never initializes/replaces operator SDK configuration. - Omitted/replaced code: `PU-specific board/profile and separate dependency/config write paths`. Disposition: **replaced**. Reason: Reuse applicable exact versions/official registries in one reviewed pin owner. Preserve operator config and Pakar hardware flags; no silent downgrade, duplicate Arduino_JSON API, unsupported library additions or automatic SDK initialization. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Run live registry check and review any candidate version changes with full build/hardware acceptance; pins were not upgraded by this slice. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -4675,10 +4675,10 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `c4473c19a749ee6e70d5f321959524162806e7a2456175966ccf3ae918a14afc`. -- Target: `tools/firmware-report.mjs:67 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=const source_sha=execFileSync]`. +- Target: `tools/firmware-report.mjs:80 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=const source_sha=execFileSync]`. - Retained: Adapt actual editor preflight entrypoint to the shared Windows launcher and build wrapper. The same target/link flags and generated-file checks now apply to editor, local CLI and CI calls. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -4687,10 +4687,10 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `d2c1857bd842c3219b50a858b4a6331afdc9018eadc7c610c7bf1e87f9ae076a`. -- Target: `tools/firmware-report.mjs:67 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=const source_sha=execFileSync]`. +- Target: `tools/firmware-report.mjs:80 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=const source_sha=execFileSync]`. - Retained: Adapt actual shell preflight/delegation into pakar.sh/build.sh and the same generated-asset/donor build guards used on Windows. No second editor-only compiler path. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -4760,7 +4760,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `pakar.cmd:8 [UTF8-LF sha256=d09fcf080f3134ef52b4d286427b1dfe42897ca28ea18595cb89405829c7fa1d; anchor=tools\pakar.mjs]`. - Retained: Retain actual PU argument/help/preflight/build-stage semantics behind a small Windows launcher. Firmware mode/target validation and diagnostics now share tools/pakar.mjs with Bash instead of maintaining a second compiler implementation. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -4776,7 +4776,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Retained: Retain PU mode/target preflight and explicit build stages through the same portable dispatcher and guarded compiler wrapper. Artifact size/hash and optional gzip reporting live in firmware-report.mjs instead of shell parsing. - Retained: Resource reporting extends the existing PU size/hash adaptation with real OTA-slot and AVR ELF/static budgets, retained CI baselines and separate timestamped read-only live observations. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Test-code evidence: `tests/resource_report_test.mjs:43 [UTF8-LF sha256=90947f5b882e8204f3609d0d29d12068bfc0de8d1b5ce09e57a0bef6e26de376; anchor=Resource reports:]`. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. @@ -4926,7 +4926,7 @@ Verdict: **scoped-improvement**. Revision: `431104072952f694a35b3a83c19f13fbb098 - Target: `firmware/esp/src/WebAccess.h:31 [UTF8-LF sha256=774b524f4cd81c003e4139d0bb6cf3353d987674bbfb49d7a1b989ee2a232294; anchor=class WebAccess]`. - Target: `firmware/esp/src/AccessConfig.cpp:67 [UTF8-LF sha256=aba76ed621e1e107ecea9a44ab32cb077fa7d08c0422b3631b3afeadc4e8d198; anchor=bool AccessConfig::configure(]`. - Target: `desktop/src/ui/connection_controls.rs:213 [UTF8-LF sha256=02bbb46d280c606868f0f18220cb092c0dca2e07f9b06aa31bee1e4f4625ec65; anchor=if authentication == Some(true)]`. -- Target: `firmware/esp/src/WebUi.h:3652 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function presentDeviceAccess(info)]`. +- Target: `firmware/esp/src/WebUi.h:3652 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function presentDeviceAccess(info)]`. - Retained: Complete exact donor source read and live SHA-256 matched the inventoried revision. Retained middleware authorization, public login, credential validation and cookie/session admission concepts in the actual shared WebAccess implementation. Added saved explicit authentication opt-in, default-off Web/native behavior, verified atomic storage migration, bounded session/WS ownership, rate limiting, origin and peer/boot fencing. - Omitted/replaced code: `complexAuth hardcoded user/password; doLogin password/token response and diagnostic dump; /pass PU access-level commands`. Disposition: **replaced**. Reason: Factory authentication is not an opt-in. Password/token dumps disclose secrets, and the PU access-level business commands do not describe this LED board. Use explicit saved access settings and non-disclosing session routes instead. - Omitted/replaced code: `Duplicated run implementation, placeholder AuthenticationHandler/getAuthToken/session access-level skeleton and role=staff sample`. Disposition: **replaced**. Reason: The donor skeleton has unresolved identifiers and no complete role-based authorization contract. Imported the applicable route/session behavior into compiling middleware rather than enabling an incomplete authorization example. No implemented Pakar role support is claimed. @@ -4943,7 +4943,7 @@ Verdict: **scoped-improvement**. Revision: `431104072952f694a35b3a83c19f13fbb098 - Target: `firmware/esp/src/WebAccess.h:31 [UTF8-LF sha256=774b524f4cd81c003e4139d0bb6cf3353d987674bbfb49d7a1b989ee2a232294; anchor=class WebAccess]`. - Target: `firmware/esp/src/AccessConfig.cpp:67 [UTF8-LF sha256=aba76ed621e1e107ecea9a44ab32cb077fa7d08c0422b3631b3afeadc4e8d198; anchor=bool AccessConfig::configure(]`. - Target: `desktop/src/ui/connection_controls.rs:213 [UTF8-LF sha256=02bbb46d280c606868f0f18220cb092c0dca2e07f9b06aa31bee1e4f4625ec65; anchor=if authentication == Some(true)]`. -- Target: `firmware/esp/src/WebUi.h:3652 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor=function presentDeviceAccess(info)]`. +- Target: `firmware/esp/src/WebUi.h:3652 [UTF8-LF sha256=93ccbdb337359b9bc4c3b7dd5bdef9df484ebe7f1da2c910f004c2495d11f196; anchor=function presentDeviceAccess(info)]`. - Retained: Complete exact donor source read and live SHA-256 matched the inventoried revision. Retained middleware authorization, public login, credential validation and cookie/session admission concepts in the actual shared WebAccess implementation. Added saved explicit authentication opt-in, default-off Web/native behavior, verified atomic storage migration, bounded session/WS ownership, rate limiting, origin and peer/boot fencing. - Omitted/replaced code: `complexAuth hardcoded user/password; doLogin password/token response and diagnostic dump; /pass PU access-level commands`. Disposition: **replaced**. Reason: Factory authentication is not an opt-in. Password/token dumps disclose secrets, and the PU access-level business commands do not describe this LED board. Use explicit saved access settings and non-disclosing session routes instead. - Omitted/replaced code: `Duplicated run implementation, placeholder AuthenticationHandler/getAuthToken/session access-level skeleton and role=staff sample`. Disposition: **replaced**. Reason: The donor skeleton has unresolved identifiers and no complete role-based authorization contract. Imported the applicable route/session behavior into compiling middleware rather than enabling an incomplete authorization example. No implemented Pakar role support is claimed. @@ -5333,7 +5333,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `firmware/esp32s3/src/SsdpDevice.cpp:255 [UTF8-LF sha256=25ffe3de9548501ec275174edbff3d9295ec1733fbea6f0fd288e4b284dc357c; anchor=void SsdpDevice::post(]`. - Target: `firmware/esp32s3/src/SsdpDevice.cpp:546 [UTF8-LF sha256=25ffe3de9548501ec275174edbff3d9295ec1733fbea6f0fd288e4b284dc357c; anchor=void SsdpDevice::schema(Print &client) const]`. - Target: `firmware/esp/src/UpnpDescription.h:19 [UTF8-LF sha256=c037418dca2cc7631c04f06d9dc51b4267d86aabe25d61bde4422a5430234639; anchor=template void description(]`. -- Target: `firmware/esp/src/BoardIconAsset.h:6 [UTF8-LF sha256=38856c8b4f954c2cbd9043ea2c66e311ad4736984d95ee4dde9d6bf7a8d13000; anchor=static const uint8_t kBoardIconPng[] PROGMEM]`. +- Target: `firmware/esp/src/BoardIconAsset.h:6 [UTF8-LF sha256=2f0fd62282276aef2bc8223e3a54698e99e77f1bc6559a94fb2527c8f2240973; anchor=static const uint8_t kBoardIconPng[] PROGMEM]`. - Target: `tools/generate-board-icon-asset.mjs:7 [UTF8-LF sha256=fa6093635fbbc333fe87fb1b6733453147950bc2bc2e23c10d9c7b39d9b9f078; anchor=const variants=[];]`. - Target: `firmware/esp32s3/src/SsdpUdp.h:70 [UTF8-LF sha256=e25782c43552d9a2fb570b2dd18446c99907a9b58d0d1ec6f5f190b9fee84f98; anchor=bool beginPacketMulticast(]`. - Target: `firmware/esp32s3/src/DiscoveryInterfaces.h:17 [UTF8-LF sha256=f6c87195a581b098486e533d44192b3fa728145977888caf46676f780c9a50b6; anchor=inline DiscoveryInterfaces activeDiscoveryInterfaces()]`. @@ -5505,7 +5505,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `tools/build-firmware.ps1:210 [UTF8-LF sha256=10cc9bd60e9ea7cbedf418e1d4c002a8eb484556bbd77df156b2d4e40283e067; anchor=esp32:esp32:esp32s3:CDCOnBoot]`. - Retained: Read complete donor board profile/platform/library locks. Retain exact ESP8266 core/ArduinoJson/ESP Async TCP pins where applicable, preserve existing reviewed Pakar dependency pins, and keep actual S3/AVR FQBN/flags in the canonical wrapper. - Omitted/replaced code: `PU-specific board/profile and separate dependency/config write paths`. Disposition: **replaced**. Reason: Reuse applicable exact versions/official registries in one reviewed pin owner. Preserve operator config and Pakar hardware flags; no silent downgrade, duplicate Arduino_JSON API, unsupported library additions or automatic SDK initialization. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Run live registry check and review any candidate version changes with full build/hardware acceptance; pins were not upgraded by this slice. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -5559,7 +5559,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `tools/build-all.ps1:6 [UTF8-LF sha256=8175e248b0a79227467dc334dac932454df4b59d48588673f8b9446b086f31a3; anchor=$taskSelected=[Collections.Generic.HashSet[string]]]`. - Retained: Import actual case-insensitive HashSet selection, Write-Step, Assert-Executable, Invoke-Native, scoped working directory and elapsed result. Typed hashtable splatting selects Firmware/Desktop/Mobile, defaults to plans and stops on failure. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -5569,11 +5569,11 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `f3e6a8ed2eae52c8ab7f1f178b85c3a1fe4ad2a85bce2a27a67a0b1c07a24d6c`. - Target: `tools/build-desktop.ps1:83 [UTF8-LF sha256=720dad8eeffa5fb7da1e5460b582478d2a7c7f4b8645ca5695cc336884d8b410; anchor=Invoke-PakarNative -WorkingDirectory]`. -- Target: `tools/firmware-report.mjs:40 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=export function collectArtifacts]`. +- Target: `tools/firmware-report.mjs:51 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=export function collectArtifacts]`. - Retained: Adapt actual native-command failure preservation and build/test/publish stage dispatch into script-runtime.ps1 and build-all.ps1. Existing Rust/Flutter owners remain responsible for Pakar client outputs, with an explicit Release/preview choice. - Omitted/replaced code: `Build and distribute parallel .NET/WinHTTP/Go ASA clients`. Disposition: **replaced**. Reason: Pakar already owns Rust and Flutter applications and the standard-library Node updater. Avoid three duplicate client stacks/SDK caches; reusable command/preflight/transfer contracts are mapped separately. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Verify full native distributable/platform parity; Windows cross-build output is not Linux-native execution. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. @@ -5589,7 +5589,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Omitted/replaced code: `ASA gzip/two-record manifest, legacy plain-info fallback and exact ok! reply; verification bypass`. Disposition: **replaced**. Reason: Current Pakar S3 uses raw application validation and structured JSON/update endpoints with board/boot fences. Mandatory auth-off/new-boot/full-SHA checks must not be weakened to preserve an incompatible donor wire protocol. - Omitted/replaced code: `Content-stable auto-upload watch, resumable atomic CLI download and verified pre-update CLI backup`. Disposition: **pending**. Reason: One-shot updater and readback are not complete watch/resume/backup parity. Import these only with peer identity, stable snapshot and no ambiguous-write replay guards; keep useful donor cases open. - Omitted/replaced code: `Build and distribute parallel .NET/WinHTTP/Go ASA clients`. Disposition: **replaced**. Reason: Pakar already owns Rust and Flutter applications and the standard-library Node updater. Avoid three duplicate client stacks/SDK caches; reusable command/preflight/transfer contracts are mapped separately. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Implement and exercise watch/resume/export/pre-update-backup contracts and remaining donor negative cases. - Remaining: Verify full native distributable/platform parity; Windows cross-build output is not Linux-native execution. @@ -5604,7 +5604,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Retained: Entire file/sections read through EOF: All fields/constructors and heading/info/success/warning/error/detail/upload/download/transfer/poll/clear/verbose/write/sanitize/byte/color methods - Retained: Exact function dispositions are in the C# manifest/deflate slice of docs/PU850-PARITY.md. - Omitted/replaced code: `TransferProgress independent streams/redirected10percent/bar; PollProgress spinner`. Disposition: **pending**. Reason: Redirected progress buckets/bar/spinner remain useful pending. Actual C# independent stdout/stderr color policy is now imported into current Node logger with both redirection directions and NO_COLOR/TERM=dumb/JSON fixtures; stronger control/OSC sanitation retained. -- Test-code evidence: `tests/script_tooling_test.mjs:22 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=const independent=createLogger(]`. +- Test-code evidence: `tests/script_tooling_test.mjs:23 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=const independent=createLogger(]`. - Remaining: Redirected progress buckets/bar/spinner remain useful pending. Actual C# independent stdout/stderr color policy is now imported into current Node logger with both redirection directions and NO_COLOR/TERM=dumb/JSON fixtures; stronger control/OSC sanitation retained. ### PU850-ESP: `Tool/C#/Uploader/DownloadApp.cs` @@ -5651,7 +5651,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `ea82a43da0bb2f5f98687b4cbd1a9b343faa636ccd8b536cd31e687dbcdd5b91`. -- Target: `tools/firmware-report.mjs:51 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=const gz=portableGzip(bytes),manifest=createFirmwareManifest(]`. +- Target: `tools/firmware-report.mjs:64 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=const gz=portableGzip(bytes),manifest=createFirmwareManifest(]`. - Target: `tools/firmware-manifest.mjs:14 [UTF8-LF sha256=fd8a77a38ee5f1b6ca8fc3df3f77cb2790bf4fc747fc22dd85315b5da113ac7c; anchor=export function parseFirmwareManifest(]`. - Target: `docs/PU850-PARITY.md:196 [UTF8-LF sha256=90fd0fcaa4c6bfab14639db6e6fa479a2f70729100ed5800edd73020f494d1a3; anchor=## Exhaustive continuation: C# manifest and deflate slice, 2026-10-19]`. - Retained: Entire file/sections read through EOF: All LoadAsync/SelectFor/ComputeMd5Async/ComputeFirmwareHashesAsync/PortableFileName/generated regex methods, entries/hash/limit records and exceptions @@ -5686,7 +5686,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `2429a0837fab902db2d834fc513ee41dd21418722067c67fc46cb478c459677b`. -- Target: `tools/firmware-report.mjs:51 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=const gz=portableGzip(bytes),manifest=createFirmwareManifest(]`. +- Target: `tools/firmware-report.mjs:64 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=const gz=portableGzip(bytes),manifest=createFirmwareManifest(]`. - Target: `tests/firmware_manifest_test.mjs:10 [UTF8-LF sha256=0e23edb29deede8a2c9aade93fc8d997d59813ea4fc5781a643d9cc42dc68776; anchor=const content=hash(raw).toUpperCase()]`. - Target: `docs/PU850-PARITY.md:196 [UTF8-LF sha256=90fd0fcaa4c6bfab14639db6e6fa479a2f70729100ed5800edd73020f494d1a3; anchor=## Exhaustive continuation: C# manifest and deflate slice, 2026-10-19]`. - Retained: Entire file/sections read through EOF: All20top-level tests; every helper/assertion; both FakeFirmwareServer/FakeDownloadServer constructors/routes/request/response/read/write/dispose/properties and TestHttpRequest @@ -5768,11 +5768,11 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `7379ae908f01676ed3db145f11579bb2bf07b79a7b5da2bdfe3cc8baa172e297`. - Target: `tools/build-desktop.ps1:83 [UTF8-LF sha256=720dad8eeffa5fb7da1e5460b582478d2a7c7f4b8645ca5695cc336884d8b410; anchor=Invoke-PakarNative -WorkingDirectory]`. -- Target: `tools/firmware-report.mjs:40 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=export function collectArtifacts]`. +- Target: `tools/firmware-report.mjs:51 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=export function collectArtifacts]`. - Retained: Retain executable preflight, bounded native failure handling and explicit selected component dispatch in shared PowerShell helpers. Windows package/capture utilities remain explicitly platform-specific, not advertised as Unix binaries. - Omitted/replaced code: `Build and distribute parallel .NET/WinHTTP/Go ASA clients`. Disposition: **replaced**. Reason: Pakar already owns Rust and Flutter applications and the standard-library Node updater. Avoid three duplicate client stacks/SDK caches; reusable command/preflight/transfer contracts are mapped separately. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Verify full native distributable/platform parity; Windows cross-build output is not Linux-native execution. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. @@ -5783,11 +5783,11 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `0af1f4b0ba2a7014d7f0938f69885b7d7a46763513408058cffeab4772d5827d`. - Target: `tools/build-desktop.ps1:83 [UTF8-LF sha256=720dad8eeffa5fb7da1e5460b582478d2a7c7f4b8645ca5695cc336884d8b410; anchor=Invoke-PakarNative -WorkingDirectory]`. -- Target: `tools/firmware-report.mjs:40 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=export function collectArtifacts]`. +- Target: `tools/firmware-report.mjs:51 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=export function collectArtifacts]`. - Retained: Retain Bash preflight/delegation to an explicit component owner. pakar.sh shares dispatch with Windows and CI; a MinGW cross-build of WinHTTP is not represented as a Linux-native Pakar application. - Omitted/replaced code: `Build and distribute parallel .NET/WinHTTP/Go ASA clients`. Disposition: **replaced**. Reason: Pakar already owns Rust and Flutter applications and the standard-library Node updater. Avoid three duplicate client stacks/SDK caches; reusable command/preflight/transfer contracts are mapped separately. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Verify full native distributable/platform parity; Windows cross-build output is not Linux-native execution. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. @@ -5857,7 +5857,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Omitted/replaced code: `ASA gzip/two-record manifest, legacy plain-info fallback and exact ok! reply; verification bypass`. Disposition: **replaced**. Reason: Current Pakar S3 uses raw application validation and structured JSON/update endpoints with board/boot fences. Mandatory auth-off/new-boot/full-SHA checks must not be weakened to preserve an incompatible donor wire protocol. - Omitted/replaced code: `Content-stable auto-upload watch, resumable atomic CLI download and verified pre-update CLI backup`. Disposition: **pending**. Reason: One-shot updater and readback are not complete watch/resume/backup parity. Import these only with peer identity, stable snapshot and no ambiguous-write replay guards; keep useful donor cases open. - Omitted/replaced code: `Build and distribute parallel .NET/WinHTTP/Go ASA clients`. Disposition: **replaced**. Reason: Pakar already owns Rust and Flutter applications and the standard-library Node updater. Avoid three duplicate client stacks/SDK caches; reusable command/preflight/transfer contracts are mapped separately. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Implement and exercise watch/resume/export/pre-update-backup contracts and remaining donor negative cases. - Remaining: Verify full native distributable/platform parity; Windows cross-build output is not Linux-native execution. @@ -5867,13 +5867,13 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `176dabcb53d4b1db79c4493b08958e1d1b0546151f6046603e589bd534308bb9`. -- Target: `tests/script_tooling_test.mjs:74 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=const cliPlan=]`. +- Target: `tests/script_tooling_test.mjs:75 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=const cliPlan=]`. - Target: `tests/update_tool_test.mjs:237 [UTF8-LF sha256=f77db2458acdf69bc16d9e187911d2856e8b4990027371bd7ed85d4efc192889; anchor=await uploadImage(origin,peer,image,identity)]`. - Retained: Adapt loopback/subprocess fixture structure and fail-before-contact/integrity assertions without requiring a WinHTTP executable or Python test server. Existing updater fixtures exercise actual multipart bytes and fragmented WS; new CLI subprocess fixtures exercise offline/invalid argument behavior. - Omitted/replaced code: `ASA gzip/two-record manifest, legacy plain-info fallback and exact ok! reply; verification bypass`. Disposition: **replaced**. Reason: Current Pakar S3 uses raw application validation and structured JSON/update endpoints with board/boot fences. Mandatory auth-off/new-boot/full-SHA checks must not be weakened to preserve an incompatible donor wire protocol. - Omitted/replaced code: `Content-stable auto-upload watch, resumable atomic CLI download and verified pre-update CLI backup`. Disposition: **pending**. Reason: One-shot updater and readback are not complete watch/resume/backup parity. Import these only with peer identity, stable snapshot and no ambiguous-write replay guards; keep useful donor cases open. - Omitted/replaced code: `Build and distribute parallel .NET/WinHTTP/Go ASA clients`. Disposition: **replaced**. Reason: Pakar already owns Rust and Flutter applications and the standard-library Node updater. Avoid three duplicate client stacks/SDK caches; reusable command/preflight/transfer contracts are mapped separately. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Test-code evidence: `tests/update_tool_test.mjs:291 [UTF8-LF sha256=f77db2458acdf69bc16d9e187911d2856e8b4990027371bd7ed85d4efc192889; anchor=Automatic updater plan/preflight]`. - Remaining: Implement and exercise watch/resume/export/pre-update-backup contracts and remaining donor negative cases. @@ -5905,11 +5905,11 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `7a7d58167051cdfa2bab660a4128d0b29400c17a653bdf751226f86607da246a`. - Target: `tools/build-desktop.ps1:83 [UTF8-LF sha256=720dad8eeffa5fb7da1e5460b582478d2a7c7f4b8645ca5695cc336884d8b410; anchor=Invoke-PakarNative -WorkingDirectory]`. -- Target: `tools/firmware-report.mjs:40 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=export function collectArtifacts]`. +- Target: `tools/firmware-report.mjs:51 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=export function collectArtifacts]`. - Retained: Adapt actual selected-target orchestration, tool preflight and raw native exit preservation without installing a duplicate Go application stack. Existing Rust checks/tests/Release and Flutter preview remain explicit. - Omitted/replaced code: `Build and distribute parallel .NET/WinHTTP/Go ASA clients`. Disposition: **replaced**. Reason: Pakar already owns Rust and Flutter applications and the standard-library Node updater. Avoid three duplicate client stacks/SDK caches; reusable command/preflight/transfer contracts are mapped separately. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Verify full native distributable/platform parity; Windows cross-build output is not Linux-native execution. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. @@ -5920,11 +5920,11 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `746e6667fba804bce07d90acf6bf370e0f7b62100c83d806cf057ef77f600ff7`. - Target: `tools/build-desktop.ps1:83 [UTF8-LF sha256=720dad8eeffa5fb7da1e5460b582478d2a7c7f4b8645ca5695cc336884d8b410; anchor=Invoke-PakarNative -WorkingDirectory]`. -- Target: `tools/firmware-report.mjs:40 [UTF8-LF sha256=a374a5172a8e9d366e1bbe124311004e2f093ab648e94a54cd8c4a1ca18b4423; anchor=export function collectArtifacts]`. +- Target: `tools/firmware-report.mjs:51 [UTF8-LF sha256=8eef0c52a110d86abf1278193dc6405807814d824944779d06f1d03d577e8283; anchor=export function collectArtifacts]`. - Retained: Retain shell launcher preflight and one delegated owner with explicit testing/build selection. Pakar Bash and Windows now reach identical guarded component wrappers rather than separate drifting build recipes. - Omitted/replaced code: `Build and distribute parallel .NET/WinHTTP/Go ASA clients`. Disposition: **replaced**. Reason: Pakar already owns Rust and Flutter applications and the standard-library Node updater. Avoid three duplicate client stacks/SDK caches; reusable command/preflight/transfer contracts are mapped separately. - Omitted/replaced code: `Forced cleans/no-cache recompiles, PU profile/name, timestamp/personal build headers and audible failure side effects`. Disposition: **replaced**. Reason: Use existing Pakar board/link flags and generated-file checks, stable warm output/cache paths and quiet explicit actions. Do not wear SSDs, alter identity or start devices as an implicit build action. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Verify full native distributable/platform parity; Windows cross-build output is not Linux-native execution. - Remaining: Run configured OS-matrix command plans and affected real SDK builds on their matching hosts. @@ -6029,7 +6029,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Omitted/replaced code: `ASA gzip/two-record manifest, legacy plain-info fallback and exact ok! reply; verification bypass`. Disposition: **replaced**. Reason: Current Pakar S3 uses raw application validation and structured JSON/update endpoints with board/boot fences. Mandatory auth-off/new-boot/full-SHA checks must not be weakened to preserve an incompatible donor wire protocol. - Omitted/replaced code: `Content-stable auto-upload watch, resumable atomic CLI download and verified pre-update CLI backup`. Disposition: **pending**. Reason: One-shot updater and readback are not complete watch/resume/backup parity. Import these only with peer identity, stable snapshot and no ambiguous-write replay guards; keep useful donor cases open. - Omitted/replaced code: `Build and distribute parallel .NET/WinHTTP/Go ASA clients`. Disposition: **replaced**. Reason: Pakar already owns Rust and Flutter applications and the standard-library Node updater. Avoid three duplicate client stacks/SDK caches; reusable command/preflight/transfer contracts are mapped separately. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Implement and exercise watch/resume/export/pre-update-backup contracts and remaining donor negative cases. - Remaining: Verify full native distributable/platform parity; Windows cross-build output is not Linux-native execution. @@ -6090,7 +6090,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Retained: Retain stable help/exit, quiet output, explicit validation and safe transfer intent. Document the Pakar updater's current contract and guarded entrypoints; do not claim documented donor watch/resume/backup behavior is already implemented. - Omitted/replaced code: `ASA gzip/two-record manifest, legacy plain-info fallback and exact ok! reply; verification bypass`. Disposition: **replaced**. Reason: Current Pakar S3 uses raw application validation and structured JSON/update endpoints with board/boot fences. Mandatory auth-off/new-boot/full-SHA checks must not be weakened to preserve an incompatible donor wire protocol. - Omitted/replaced code: `Content-stable auto-upload watch, resumable atomic CLI download and verified pre-update CLI backup`. Disposition: **pending**. Reason: One-shot updater and readback are not complete watch/resume/backup parity. Import these only with peer identity, stable snapshot and no ambiguous-write replay guards; keep useful donor cases open. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Implement and exercise watch/resume/export/pre-update-backup contracts and remaining donor negative cases. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -6103,7 +6103,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `tools/pakar.mjs:65 [UTF8-LF sha256=0875bb298a832a275d62e3595c2e2691c38eef442ac5246a85fb4445c3715bd3; anchor=Node.js20.19]`. - Retained: Read exact chalk/chokidar/readdirp locked graph. Shared console implements required logger/color/terminal sanitation with Node standard libraries; no new node_modules or lockfile is needed for currently implemented one-shot commands. - Omitted/replaced code: `New chalk/chokidar/readdirp npm installation for one-shot tools`. Disposition: **replaced**. Reason: Currently required console/argv behavior uses Node standard libraries and no file watcher is advertised. Preserve zero additional npm tree; advanced watcher parity remains explicit. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Complete guarded content-stable watch behavior before claiming uploader dependency/feature parity. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -6113,10 +6113,10 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `60754d1116254eeac6b10e626c2e2b4506e60ad3ecd0296ce59645d63858e540`. - Target: `tools/script-console.mjs:5 [UTF8-LF sha256=2243be58e4dce21a7592865121e94ebdb64f21286f3333358c8259bb2bdedafb; anchor=export const EXIT]`. -- Target: `.github/workflows/build.yml:92 [UTF8-LF sha256=88ae50be55cc684e1e23658d13f0f443e945cac7a38ad87948709681260b4861; anchor=node tests/script_tooling_test.mjs]`. +- Target: `.github/workflows/build.yml:92 [UTF8-LF sha256=83924ae2ac89730473e32007eda800ad03ccbfb8267d61ff7ee52f984d586a8a; anchor=node tests/script_tooling_test.mjs]`. - Retained: Retain explicit Node20.19 minimum and direct Node entrypoints, tests and help without an additional npm install. Shared logger/CLI use Node standard libraries; unavailable watch mode is recorded as a gap. - Omitted/replaced code: `New chalk/chokidar/readdirp npm installation for one-shot tools`. Disposition: **replaced**. Reason: Currently required console/argv behavior uses Node standard libraries and no file watcher is advertised. Preserve zero additional npm tree; advanced watcher parity remains explicit. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Complete guarded content-stable watch behavior before claiming uploader dependency/feature parity. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -6130,7 +6130,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Retained: Map actual uploader/build/CLI usage to the shared Pakar command reference and tools. Clearly separate raw S3/JSON verification from ASA gzip/ok!, plans from execution and current one-shot support from pending advanced transfer modes. - Omitted/replaced code: `ASA gzip/two-record manifest, legacy plain-info fallback and exact ok! reply; verification bypass`. Disposition: **replaced**. Reason: Current Pakar S3 uses raw application validation and structured JSON/update endpoints with board/boot fences. Mandatory auth-off/new-boot/full-SHA checks must not be weakened to preserve an incompatible donor wire protocol. - Omitted/replaced code: `Content-stable auto-upload watch, resumable atomic CLI download and verified pre-update CLI backup`. Disposition: **pending**. Reason: One-shot updater and readback are not complete watch/resume/backup parity. Import these only with peer identity, stable snapshot and no ambiguous-write replay guards; keep useful donor cases open. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Implement and exercise watch/resume/export/pre-update-backup contracts and remaining donor negative cases. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -6152,7 +6152,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Retained: After the same live post-upload readback timeout recurred beyond about 1 MiB, reread the donor verifyAfterReboot/verifiedDownload functions and existing updater/verifier owners. Both post-reboot verification paths now import one 16 KiB range constant from download-firmware, without circular imports or changing that module's successful 64 KiB backup transfers. Updater progress records only verified bytes. The actual updater fixture crosses 1 MiB, tests the final short range, one same-range pinned read retry, second timeout and invalid late range without replaying any upload. This is source/fixture evidence; no new board mutation was used to test this tool change. - Omitted/replaced code: `ASA gzip/two-record manifest, legacy plain-info fallback and exact ok! reply; verification bypass`. Disposition: **replaced**. Reason: Current Pakar S3 uses raw application validation and structured JSON/update endpoints with board/boot fences. Mandatory auth-off/new-boot/full-SHA checks must not be weakened to preserve an incompatible donor wire protocol. - Omitted/replaced code: `Stable watcher/coalescing/graceful-stop/progress and remaining negative cases`. Disposition: **pending**. Reason: Actual verified pre-update backup and ranged/resumable export now implemented through existing owners with same-peer/release/auth/job/boot/latch and no-overwrite checks. Watch/coalescing/graceful stop/skip-identical/progress, remaining gzip consumer/platform/filesystem/transport and exact unported negative scenarios remain pending as applicable. No donor tests, SDK builds, live update/restore or physical proof claimed. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Test-code evidence: `tests/update_backup_test.mjs:53 [UTF8-LF sha256=9fad7b056864a821193c642fbc8739ca60f6b490fc358853906564fd242b75cc; anchor=Backup must precede even remote staging]`. - Test-code evidence: `tests/verify_running_firmware_test.mjs:115 [UTF8-LF sha256=77f9d8389d7668b39cdfb57b71a9ec9acba3da9b439bf7feefdb284d98a04058; anchor=Read-only running firmware verifier:]`. @@ -6164,7 +6164,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. Original-byte SHA-256: `02842871c7f5c1285b57c1cc2392d655df848ef993c138f6a6c11b9779bf0778`. -- Target: `tests/script_tooling_test.mjs:74 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=const cliPlan=]`. +- Target: `tests/script_tooling_test.mjs:75 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=const cliPlan=]`. - Target: `tests/update_tool_test.mjs:173 [UTF8-LF sha256=f77db2458acdf69bc16d9e187911d2856e8b4990027371bd7ed85d4efc192889; anchor=const server=createServer]`. - Target: `tools/update-firmware.mjs:216 [UTF8-LF sha256=f1661663563a2dcd4eaed9d1a054cc986cf03d8e3b0806bc93d6bf07560ad068; anchor=export async function updateFirmware(]`. - Target: `tools/peer-identity.mjs:54 [UTF8-LF sha256=869e9ea5db1887dde58b170c66d4c2b379aa6fb7d3c123adc5c023e1b8db1ce7; anchor=export function boardPeer(]`. @@ -6173,7 +6173,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Retained: Actual Node performUpload and C# BackupInstalledFirmwareAsync backup-before-write sequencing now serves existing updater with explicit --backup/--resume-backup, first-read expected-peer fencing, metadata match and fresh auth/job/boot/latch admission before local upload or remote stage/apply. - Omitted/replaced code: `ASA gzip/two-record manifest, legacy plain-info fallback and exact ok! reply; verification bypass`. Disposition: **replaced**. Reason: Current Pakar S3 uses raw application validation and structured JSON/update endpoints with board/boot fences. Mandatory auth-off/new-boot/full-SHA checks must not be weakened to preserve an incompatible donor wire protocol. - Omitted/replaced code: `Stable watcher/coalescing/graceful-stop/progress and remaining negative cases`. Disposition: **pending**. Reason: Actual verified pre-update backup and ranged/resumable export now implemented through existing owners with same-peer/release/auth/job/boot/latch and no-overwrite checks. Watch/coalescing/graceful stop/skip-identical/progress, remaining gzip consumer/platform/filesystem/transport and exact unported negative scenarios remain pending as applicable. No donor tests, SDK builds, live update/restore or physical proof claimed. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Test-code evidence: `tests/update_tool_test.mjs:291 [UTF8-LF sha256=f77db2458acdf69bc16d9e187911d2856e8b4990027371bd7ed85d4efc192889; anchor=Automatic updater plan/preflight]`. - Test-code evidence: `tests/update_backup_test.mjs:53 [UTF8-LF sha256=9fad7b056864a821193c642fbc8739ca60f6b490fc358853906564fd242b75cc; anchor=Backup must precede even remote staging]`. @@ -6200,7 +6200,7 @@ Verdict: **parity-gap**. Revision: `431104072952f694a35b3a83c19f13fbb098ca5b`. O - Target: `upgrade.cmd:3 [UTF8-LF sha256=8e8614d6dc26192f66ef8e842a3dd53a3a5b66272a53d7d3bff7c275ea454dcb; anchor=dependencies]`. - Retained: Adapt exact-name registry indexing, check/apply operation and one cached index into firmware-dependencies.mjs. Improve lexical version selection to numeric stable comparison, retain pinned-ahead versions, detect concurrent edits and install only explicitly locked versions. - Omitted/replaced code: `PU-specific board/profile and separate dependency/config write paths`. Disposition: **replaced**. Reason: Reuse applicable exact versions/official registries in one reviewed pin owner. Preserve operator config and Pakar hardware flags; no silent downgrade, duplicate Arduino_JSON API, unsupported library additions or automatic SDK initialization. -- Test-code evidence: `tests/script_tooling_test.mjs:133 [UTF8-LF sha256=8cecc892a9f416c7fd4d7df6aae64cef7792b557e73213bc77d9e6a4a53c1380; anchor=Script tooling:]`. +- Test-code evidence: `tests/script_tooling_test.mjs:141 [UTF8-LF sha256=4b8743c890eb724f2d6ae27d6b0593b2ac482578da0330d382d91f040d91c305; anchor=Script tooling:]`. - Test-code evidence: `tests/script_tooling_test.ps1:26 [UTF8-LF sha256=d3c679d8caa22177e7a5590564cd1141b84e1b194b3c3ee0bb825c26a4d46305; anchor=PowerShell utilities parse]`. - Remaining: Run live registry check and review any candidate version changes with full build/hardware acceptance; pins were not upgraded by this slice. - Remaining: No physical deployment, full client distribution or donor-wide completion is inferred from source or fixtures. @@ -6676,7 +6676,7 @@ Verdict: **equivalent-behavior**. Revision: `filesystem-snapshot-no-git`. Origin - Target: `assets/themes/browser-appearance.js:70 [UTF8-LF sha256=056ef41691b92dacbcd7c75b11ff38a2e492093e769aab26dc2577785994de54; anchor=function applyPrepaintLocale()]`. - Target: `tools/generate-web-appearance.mjs:35 [UTF8-LF sha256=e57a615bf5134b718d6df7b644e56faced0c0ef73e8662cf8cb06c05e23e59b4; anchor=replaceBlock('// BEGIN BROWSER CONTROLLER']`. -- Target: `firmware/esp/src/WebUi.h:9 [UTF8-LF sha256=dcd9e175d488ecbcb4c824fa7c7fd2004c5da9411c67851831940a4ba8881a73; anchor= -PakarController
    - +

    Connecting to device…