You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is the v1 (PowerShell) catalog. It was intended to become the cross-version spec and
never did — it has no v2 coverage and no parity column, and has not been updated since
2026-05-20. For v2 behaviour use v2/README.md, v2/ATVTOOLS-PARITY.md and v2/CHANGELOG.md.
Line references into Shield-Optimizer.ps1 have drifted; re-check before trusting one.
This document is the source of truth for what Shield Optimizer does. It exists for two reasons:
Reference for the v2 (Tauri/Rust) rewrite — a language-agnostic spec of every behavior, every ADB command, and every edge case the current v1 PowerShell implementation handles, so v2 can reach behavioral parity without reverse-engineering.
Living changelog of capabilities — every PR that adds, removes, or changes a feature is expected to update this doc in the same commit. If a feature isn't here, it doesn't exist as far as the project is concerned.
Maintenance rule: when you add a feature to v1 or v2, you update this doc. When the two implementations diverge, that's a regression — flag it in the Parity column.
Source-of-truth precedence: if the script and this doc disagree, the script wins for v1 behavior; the doc wins for v2 specification. Resolve drift by updating whichever side is wrong.
Catalog tracks v1's current main. Function and line references point at Shield-Optimizer.ps1 at HEAD — re-verify them when touching this doc to catch drift.
Force re-download of platform-tools even if already present. Used to recover from corrupt ADB binary.
-LightMode
Force the light color theme regardless of system setting.
-DarkMode
Force the dark color theme regardless of system setting.
-Subnet (string)
Override auto-detected subnet for Scan Network (e.g. -Subnet "10.0.0"). Useful for multi-subnet networks or where gateway detection fails.
Stored as $Script:ForceAdbDownload, $Script:LightMode, $Script:DarkMode, $Script:Subnet for use throughout the script.
0.2 Platform detection
Purpose
Identify host OS for ADB binary download, color detection, and OS-specific shell quirks
Behavior
Sets $Script:Platform to Windows / macOS / Linux / Unknown via PowerShell 7's $IsWindows / $IsMacOS / $IsLinux. Sets $Script:IsUnix = $Platform -in @("macOS", "Linux")
0.3 Startup sequence
When the script is invoked:
Strict mode enabled (Set-StrictMode -Version Latest) and $ErrorActionPreference = "Stop".
Platform detection (§0.2).
Color theme initialized via Initialize-Colors honoring -LightMode / -DarkMode flags or auto-detecting (§15.1).
ADB lifecycle check via Check-Adb: locates or downloads platform-tools, validates binary version, may prompt user.
Optional window resize: if terminal width < 80 cols, attempts to resize to 100×35. Silently no-ops on terminals that don't support resize (Windows Terminal, VS Code).
Main menu loop entered (§2).
0.4 Strictness conventions
Functions exit on first uncaught error (-Stop) and strict mode rejects uninitialized variables. v2 should preserve this strictness for safety — quiet failures during privileged ops are how users brick devices.
1. Connection & discovery
1.1 Network scan
Purpose
Auto-discover Android TV devices on the local subnet
Determine host's local subnet from default gateway, parallel-ping the /24 range, ARP-resolve responders, attempt adb connect to each on port 5555, classify each as device / unauthorized / offline
ADB calls
adb connect <ip>:5555 per candidate; adb devices for state
Concurrency
Parallel via PowerShell jobs
Edge cases
Hosts behind firewall return as offline; multi-subnet networks need manual entry; macOS/Linux ARP table parsing differs from Windows
1.2 Connect by IP
Purpose
Manual connection when scan fails or device is on a different subnet
v1 source
Main menu flow, validated via Test-ValidIP (3392)
Behavior
Prompt for IP[:port], default port 5555, validate as IPv4, adb connect
ADB calls
adb connect <ip>:<port>
Edge cases
Invalid IP rejected with explanation; existing connection on that IP is overwritten
1.3 PIN pairing (Android 11+)
Purpose
Pair newer Chromecast w/ Google TV and Android 11+ devices that require the pairing-code flow
v1 source
Connect-PinPairing (943)
Behavior
Prompt user for IP, pair port, and 6-digit PIN from TV; invoke adb pair; on success, adb connect to the standard 5555 port
ADB calls
adb pair <ip>:<pair_port> <pin>, then adb connect <ip>:5555
Status
Marked experimental in v1; works on Google TV devices, not needed for Shield
1.4 Disconnect
Purpose
Drop a device's ADB connection without affecting others
v1 source
Disconnect-Device (931)
ADB calls
adb disconnect <serial>
1.5 ADB lifecycle management
Purpose
Ensure ADB binary is present, the right version, and the daemon is healthy
First run: downloads platform-tools for the host OS (Linux/macOS/Windows) and extracts to ./platform-tools/ (or alongside script). Detects ADB version mismatch and offers to redownload. Restarts the ADB server via the "Restart ADB" main-menu action (§2) or -ForceAdbDownload flag.
Download source
Google's official https://dl.google.com/android/repository/platform-tools-latest-<os>.zip per OS
Edge cases
Existing ADB process owned by another user blocks server start; ARM Macs need x86_64 ADB under Rosetta for some Google ADB builds; Stop-AdbProcess kills adb system-wide before redownload to release file locks on Windows
1.6 Device enumeration & friendly names
Purpose
Convert adb devices raw output into a structured list with friendly display names
v1 source
Get-Devices (1012)
Behavior
Runs adb devices, parses each line for serial+status, classifies connection type (Network if IP:port, else USB). For each connected (status=device) entry, batches a single ADB call to read: settings get global device_name; getprop ro.product.brand; getprop ro.product.model; getprop ro.product.device; getprop ro.product.manufacturer. Then classifies device type and maps codenames to friendly names.
Returned shape
PSCustomObject { ID; Serial; Name; Model; Type; Status; ConnectionType } per device. ID is the 1-based menu position used by the keyboard-shortcut layer.
Shield codename → friendly model
mdarcy → "Shield TV Pro (2019)", sif → "Shield TV (2019 Tube)", darcy → "Shield TV (2017)", foster → "Shield TV (2015)", default → "Shield TV (<model code>)"
Note
Device-type detection logic here (manufacturer/brand/device-based) differs slightly from the standalone Get-DeviceType (brand/model/device-based). v2 should consolidate into one canonical detection. See §13.1.
USB support status
Detected and tagged [USB], but Shield TV does not support USB debugging (host ports only). Marked experimental in README. Useful for phones/tablets used during development.
1.7 USB-debugging UNAUTHORIZED guidance
Purpose
Help user resolve an UNAUTHORIZED device entry instead of leaving them confused
Behavior
When user selects a device in unauthorized state from the main menu, displays detailed numbered steps: (1) look at TV, (2) accept "Allow USB debugging?" prompt, (3) check "Always allow", (4) tap Allow. Falls back to revoke+reconnect guidance if no prompt appears.
v1 source
Inline in main menu loop (~line 3946)
2. Main menu
The outermost menu (looped until Quit). Layout:
[Connected devices, one per row, with [NET]/[USB] tag and friendly name]
---
[Static actions below the separator]
Devices use numeric shortcuts (1-9 based on position), static actions use letter shortcuts.
2.1 Static main-menu actions
Action
Shortcut
Description
Scan Network
S
Trigger §1.1 auto-discovery
Connect IP
C
Prompt for IP[:port], validate via Test-ValidIP (line 3392), adb connect
Pair Device (PIN)
P
Trigger §1.3 PIN-pairing flow (experimental)
Report All
R
Run Run-Report against every device whose status is device
Refresh
F
No-op; falls through to top of loop which re-queries Get-Devices
Restart ADB
A
Kill and restart the ADB server (§1.5)
Help
H
Show keyboard/usage help (Show-Help at line 1530)
Quit
Q
Exit script
2.2 Device row selection
Selecting a device in device status drops into the action menu (§3).
Selecting a device in unauthorized state shows the §1.7 guidance.
Selecting a device in offline or other state shows "Cannot manage device in state: <status>" then returns to main menu.
3. Device action menu
Inner menu shown for a connected device. Shortcuts in parens.
Action
Shortcut
Description
v1 source
Optimize
O
Walk through the device-specific bloat + perf list and apply changes
Run-Task -Mode Optimize (3095)
Restore
R
Reverse of Optimize — re-enable disabled packages, reset tuned settings
Run-Task -Mode Restore (3095)
Report
E
Health report (temp/RAM/storage/display/bloat) + optional Live Monitor
Apply the device-specific app and performance changes in one guided pass
v1 source
Run-Task (3095)
Behavior
(1) Prompt whether to apply all defaults without per-item confirmation. (2) Query installed/all/disabled package lists. (3) Snapshot the per-app memory map once via Get-AppMemoryMap. (4) For each app in the device's list: skip if not installed / already disabled / already uninstalled (in Optimize mode), then prompt for DISABLE / SKIP / UNINSTALL / ABORT with default chosen per DefaultOptimize field, show "(using X MB RAM)" if currently running. (5) Apply the chosen action. (6) Run Performance Settings (animation triple). (7) Summarize. (8) Offer reboot.
Each app has Safe / Medium / High Risk shown as color-coded tag (green/yellow/red)
Defaults
Each app has DefaultOptimize (Y/N) and DefaultRestore (Y/N) that pre-select the prompt; respected in "apply all defaults" mode
Abort behavior
ESC or selecting ABORT halts the loop, shows partial summary, returns to action menu
Edge cases
Multi-process apps' RAM summed by base package via Get-AppMemoryMap; apps not in pm list packages but in pm list packages -u shown as [ALREADY UNINSTALLED]; uninstall failure causes Open-PlayStore prompt
4.2 Task summary
Purpose
Show counts after Optimize / Restore (full or aborted)
Single-shot snapshot of device vitals + bloat status
v1 source
Run-Report (2066)
Behavior
Batches multiple dumpsys calls into one shell invocation, parses sections delimited by per-section sentinels (::THERMAL::, ::MEMINFO::, ::STORAGE::, ::PROPS::, ::SETTINGS::, ::PACKAGES::), displays System Info, Vitals, Settings, Display (mode/refresh/HDR/audio), Top Memory Users, Bloat Check table
ADB call (batched)
One adb shell invocation joining: echo '::THERMAL::'; dumpsys thermalservice 2>/dev/null | head -50; echo '::MEMINFO::'; dumpsys meminfo 2>/dev/null; echo '::STORAGE::'; df -h /data 2>/dev/null; echo '::PROPS::'; getprop ro.board.platform; getprop ro.build.version.release; echo '::SETTINGS::'; settings get global window_animation_scale; echo '::PACKAGES::'; pm list packages -e 2>/dev/null
Display query (separate)
dumpsys display (resolution / refresh from supportedModes table matched to active modeId; HDR from HdrCapabilities mSupportedHdrTypes), dumpsys audio (current output device) — see §5.3
Vitals shown
Temperature (parsed from thermal zones), RAM (free/used/total/swap from meminfo), Storage (from df)
Filtered via Test-AppPackage (skips system processes); top 10 shown
Edge cases
Long-running session leaks ADB connections on Windows if not cleaned; PowerShell cursor positioning differs by terminal
5.3 Display & audio diagnostics
Purpose
Show actual negotiated display mode so users can verify 4K@60 vs lower fallback
v1 source
Get-DisplayMode (731), called from Run-Report
Behavior
Parse dumpsys display for active modeId, look up that id in the supportedModes table for width/height/fps; parse HdrCapabilities mSupportedHdrTypes=[...] and decode 1=Dolby Vision, 2=HDR10, 3=HLG, 4=HDR10+; parse dumpsys audio first Devices: line for output device
Outputs
Resolution, RefreshRate, HdrTypes (comma-joined or SDR only), AudioDevice (uppercased) — each may be $null
Edge cases
dumpsys format varies by Android version — current parser tested on Shield Android 11; audio device detection is best-effort, may be empty on some builds
6. Launcher management
6.1 Custom launcher catalog
Supported preset launchers ($Script:Launchers):
Display name
Package
Projectivy Launcher
com.spocky.projengmenu
FLauncher
me.efesser.flauncher
ATV Launcher
com.sweech.launcher
Wolf Launcher
com.wolf.firelauncher
AT4K Launcher
com.overdevs.at4k
Dispatch Launcher
com.spauldhaliwal.dispatch
A "Custom..." menu option lets the user type any package id (validated against package-name regex, must be installed).
Install, select, and activate a custom launcher; re-enable / disable stock launcher safely
v1 source
Setup-Launcher (2875)
Menu options
(a) Each preset launcher from $Script:Launchers (Projectivy, FLauncher, ATV, Wolf, AT4K, Dispatch), tagged [INSTALLED] / [MISSING]. (b) Stock Launcher — labeled with the detected stock package name and a status tag ([ACTIVE] / [DISABLED] / [NOT FOUND]). Re-enables and re-activates the stock launcher when picked. (c) Custom... — type any package id, validated against package-name regex, must be installed. (d) Back.
Behavior
(1) Run Test-ChannelDependencies against the just-fetched disabled-package list — covers every exit path. (2) Detect current launcher via cmd package resolve-activity. (3) Identify which stock launcher is on this device (from $Script:StockLaunchers) and whether it's currently disabled. (4) Show the menu (above). (5) For a preset / custom: if not installed, offer Play Store install. If already active, just offer to clean up other HOME handlers. Else prompt to disable other launchers (calls Disable-AllStockLaunchers), call Set-DefaultLauncher, report success/failure with captured ADB error. (6) For Stock Launcher: re-enable if disabled and set as default.
ADB calls
See Set-DefaultLauncher strategy in §6.3
6.3 Set default launcher (multi-strategy)
Purpose
Programmatically promote a package to the default HOME app across Android versions and customized builds
(1) pm enable <pkg> — unblock previously-disabled launchers. (2) Role API: cmd role add-role-holder android.app.role.HOME <pkg>, verify by read-back, skip immediately if "Unknown command". (3) For each activity candidate (dumpsys-discovered first via cmd package query-activities --components, then .MainActivity / .Main / .LauncherActivity / .HomeActivity guesses): try cmd package set-home-activity --user 0 <comp> then pm set-home-activity --user 0 <comp>, verify after each. (4) Last resort: am start -W -a android.intent.action.MAIN -c android.intent.category.HOME to kick the system selector when only one launcher remains enabled.
Error capture
$Script:LastSetHomeError captures the underlying ADB response so the UI can display why the set failed
Verified on
Real Shield running Android 11 — Projectivy .ui.home.MainActivity
Edge cases
cmd role doesn't exist on Shield's customized Android 11; activity may be deeply nested (.ui.home.MainActivity etc.) — dumpsys parser was unreliable, replaced by query-activities --components
6.4 Disable stock launchers
Purpose
Disable every HOME-capable app except the chosen custom launcher and safe fallbacks
Query all HOME-capable apps via cmd package query-activities -a android.intent.action.MAIN -c android.intent.category.HOME; add known-problematic handlers (setupwraith, droidlogic.launcher.provider); skip already-disabled and safe-fallback packages; prompt per-launcher YES/NO; disable accepted via pm disable-user --user 0. Sets the HOME role holder first (if role API works).
Friendly names
Resolves package → display name via custom-launcher list + hardcoded stock-launcher map
Edge cases
Refuses to proceed if no HOME handlers detected; never disables the package supplied as -CustomLauncherPkg; never disables com.android.tv.settings (emergency fallback)
6.5 Restore stock launchers
Purpose
Re-enable every HOME-capable app that was previously disabled
v1 source
Restore-AllStockLaunchers (2668)
ADB calls
pm enable <pkg> for each disabled stock launcher; sets HOME role back to com.google.android.tvlauncher on Shield / equivalent on Google TV if possible
6.6 Channel dependency warning
Purpose
Warn user if com.android.providers.tv is disabled — without it, no streaming app can publish Watch Next / Continue Watching channels
v1 source
Test-ChannelDependencies (called from Setup-Launcher)
Behavior
Check disabled-package list for com.android.providers.tv; if found, surface warning and offer to re-enable via pm enable
7. Display & input tuning
Purpose
Toggle individual display/input settings outside the Optimize flow
settings get global <key> / settings get secure <key>
ADB calls (write)
settings put <ns> <key> <value> / settings delete <ns> <key> for reset-to-default
UX
Sub-menu shows current values for all six settings; user picks one to change; per-setting prompts give ON/OFF/Reset/Cancel (for bools) or value list (for enums)
Verified
All key/namespace combinations tested against Shield Android 11
8. Display scaling
Purpose
Switch resolution and density between presets (4K, 1080p, default)
v1 source
Set-DisplayScaling (3461)
Presets
Shield TV 4K = 3840x2160 / density 540; Shield TV 1080p = 1920x1080 / density 320; Reset to Default
ADB calls
wm size <WxH> / wm density <DPI> / wm size reset / wm density reset
Edge cases
Applies to all device types but presets are Shield-tuned; non-Shield users may need manual density tuning
9. Snapshot / restore
9.1 Snapshot data model
JSON file at ./snapshots/<safe-device-name>_<timestamp>.json:
Enumerate disabled packages (pm list packages -d), capture current launcher, read all tracked settings (skip values that are null or empty), write JSON with timestamp
9.3 Apply
v1 source
Apply-Snapshot (3698)
Behavior
List snapshots sorted newest-first, preview the chosen one, confirm. (1) For each package in disabledPackages: if installed and not currently disabled, run pm disable-user --user 0 <pkg>. (2) Run Set-DefaultLauncher with saved launcher (works through full strategy chain). (3) For each setting: settings put <ns> <key> <value>. Summary with disabled / already-disabled / not-on-device / launcher result / settings-applied counts.
Safety property
Never re-enables a currently-enabled package not on the snapshot list. Apply is additive-only for disable state.
Cross-device warning
If snap.deviceType ≠ current device type, warns user before proceeding
9.4 Menu
v1 source
Show-SnapshotMenu (3778)
Options
Save current state / Apply a saved snapshot / Open snapshots folder / Back
Light and dark color schemes, auto-detected from system or forced via -LightMode / -DarkMode
v1 source
Initialize-Colors (58), Test-SystemLightMode (37)
Auto-detect
macOS: osascript running tell application "System Events" to tell appearance preferences to get dark mode (chosen over defaults read -g AppleInterfaceStyle because the defaults entry can be stale). Windows: registry HKCU:\…\Themes\Personalize\AppsUseLightTheme. Linux: no detection — falls through to dark default (a v2 improvement opportunity: gsettings get org.gnome.desktop.interface color-scheme or gtk-theme).
Color slots
Header / SubHeader / Success / Warning / Error / Info / Selected / Unselected / Bracket highlight / Separator / Label / Value / TextDim / Disabled / Shortcut (15 named colors per theme)
14.2 Read-Menu
Purpose
The keyboard-navigated list selector used everywhere
Renders options, supports arrow-key navigation, number/letter shortcuts, ESC to cancel; shows description of focused item below; redraws in-place using MoveTo cursor positioning. Highlighted shortcut character is bracketed inline for letter shortcuts and prefixed for digit shortcuts (digits-on-IPs ambiguity). Separators (---) render as visual dividers.
Returns
Integer index of selected option, or -1 on ESC
Edge cases
UNAUTHORIZED items rendered in error color; closing-arrow indicator on selected row; works under PowerShell on Windows Terminal / iTerm / GNOME Terminal
14.3 Read-Toggle
Purpose
YES/NO/ABORT-style horizontal toggle
v1 source
Read-Toggle (2002)
Inputs
Prompt, Options[] (2-3 entries), DefaultIndex
Behavior
Left/Right arrows to move; Enter confirms; first-letter shortcuts
Returns
Integer index or -1 on ESC
14.4 Help
Purpose
In-app keyboard shortcut reference
v1 source
Show-Help (1530)
Content
Arrow / number / letter / Enter / ESC bindings
15. Data catalogs
These are the structured arrays that drive Optimize behavior. In v2 they should be runtime-fetched JSON, not embedded code.
15.1 CommonAppList — universal Android TV bloat
Telemetry, defunct apps, streaming apps (UNINSTALL, DefaultOptimize=N — user choice), Canadian streaming apps, FAST apps, premium add-ons, medium-risk system shims, high-risk launcher/critical-service entries. Currently ~40 entries.
Defunct apps section: Google Play Movies, Google Play Music, Funimation, Stadia, Quibi, HBO Now (legacy).
Currently single entry: animation speed (window/transition/animator scales set together, Optimize=0.5, Restore=1.0).
15.6 Custom launchers — see §6.1
15.7 Snapshot setting keys — see §9.1
16. Cross-cutting concerns
16.1 ADB command invocation
v1 source
Invoke-AdbCommand (675)
Behavior
Wraps & $Script:AdbPath -s $Target shell <cmd> and returns @{ Success; Output; Error }. Catches exceptions, normalizes output to string.
v2 expectation
Single point for ADB calls; should add structured logging, optional dry-run mode, request/response tracing for debugging
16.2 Multi-device sessions
The script supports multiple connected devices simultaneously. The main menu (§2) shows all adb devices results with shortcuts (numeric for device rows, letter for static actions). Selecting a device drops into its action menu (§3).
16.3 Failure surfacing
ADB stderr captured into a LastSetHomeError-style scoped variable (currently only for launcher set-default; v2 should generalize this pattern)
Failed operations don't halt the loop — they're counted in the summary
Write-ErrorMsg / Write-Warn go to the user's terminal in distinct colors
16.4 Reversibility model
Disable (pm disable-user) — reversible via Restore / Recovery
Uninstall (pm uninstall --user 0) — semi-reversible via pm install-existing (works if APK is still on the system partition) or Play Store
Settings writes — reversible via Restore (resets to known values) or by writing null / deleting the key
Snapshot Apply — additive-only for disable state; safe to re-apply
16.5 Play Store deep-link
Purpose
Open the Play Store on the device to a specific package, used as a fallback path when reinstalling a previously-uninstalled app
v1 source
Open-PlayStore (1310)
ADB call
am start -a android.intent.action.VIEW -d 'market://details?id=<pkg>'
Used by
Optimize/Restore flow (when pm install-existing fails because the APK file is missing); Launcher Setup (when chosen custom launcher isn't installed)
16.6 Uninstall / install error decoding
Purpose
Translate Android's terse uninstall failure patterns into user-readable hints, surfaced after a pm uninstall returns non-success
v1 source
Get-UninstallErrorReason (662)
Recognized patterns
Broken pipe → "Protected system app - cannot be removed"; not installed for → "App not installed for this user"; DELETE_FAILED_INTERNAL_ERROR → "Internal error - app may be in use". Anything else → "Unknown error".
Note for v2
Install-side failures (INSTALL_FAILED_INSUFFICIENT_STORAGE, INSTALL_FAILED_VERSION_DOWNGRADE, etc.) are handled inline in Install-ApkFile (~lines 1364-1372), not in this helper. v2 should consolidate both decoders into one place.
16.7 Utility helpers
Function
Purpose
Test-PackageInList (555)
Boolean: is <pkg> present in the multiline output of pm list packages [-d/-e/-u]? Centralizes the parsing of package:<name> format
Test-AppPackage (564)
Boolean: is this package a user-installable app (vs. a system process)? Filters dumpsys meminfo rows down to apps.
Test-ValidIP (3392)
IPv4 + optional :port validator
Format-FileSize (1321)
Bytes → human-readable string (KB/MB/GB) for APK file listings
Get-ParsedTemperature (570)
Extracts CPU temp in °C from dumpsys thermalservice across multiple format variants
Get-ParsedRamInfo (594)
Extracts free/used/total/swap MB from dumpsys meminfo summary block
Get-VitalColor (625)
Maps a vital metric (Temperature / RAM / Storage / AppMemory) + value to a console color name based on threshold tiers
Get-VitalAnsiColor (640)
Same as above but returns an ANSI color code for cursor-positioned UIs
Open-PlayStore (1310)
Opens Play Store deep-link via am start … market://details?id=<pkg>; see §16.5
Get-UninstallErrorReason (662)
Decodes uninstall failure patterns; see §16.6
16.8 Code conventions used in v1 (not requirements for v2)
All PowerShell function names are Verb-Noun
$Script: scope for module-globals (theme, ADB path, summary counters)
ANSI escape sequences for cursor control (cross-platform via PowerShell's RawUI)
Inline error checking: every ADB call's result inspected for Exception|Error|denied patterns
All pm commands use --user 0 explicitly to avoid ambiguity on multi-user builds (Android TV rarely is, but the safety is cheap)
Maintenance checklist (for PR authors)
When opening a PR that affects user-visible behavior, at minimum:
Add or update the corresponding section here
If you added a new menu item, update §2 (main menu) or §3 (device action menu)
If you added a new ADB call, add it to the relevant feature's "ADB calls" row
If you added a new setting key, update §7 (Tweaks) and §9.1 (snapshot setting keys)
If you added a new app or list, update §15 (data catalogs)
If you fixed a previously-broken edge case, update the "Edge cases" row to reflect the fix
Cross-link from v1 implementation to this doc by referencing section numbers in commit messages where useful
If v2 (Rust/Tauri) work is in flight, also note which sections have parity vs. v1 in a status table here (to be added once v2 has structure).