decisions/v1-app-acceptance-checklist.md
V1 app acceptance checklist
Status: checks derived from Sam's accepted design decisions on 14 October 2026. A check passes only with a recorded result for the build under test. Implementation status lives in PROGRESS.md, and results live in the acceptance ledger. This checklist adds no new product choices and does not alter the multi-monitor release checklist.
Prerequisites and evidence
The Accessibility attribution prototype required by ADR 0009 ran on 14 October 2026 with an ad-hoc bundle that used the release identifiers. Run permission and lifecycle checks on the actual Miri app bundle and helper identities. Use the development signing identity, or ad-hoc signing without it, for development checks, and the Developer ID signed, notarized bundle for public-release checks. Record the app build, pinned engine revision, macOS version, display setup, and observed result for each check. An unavailable or unverified check remains pending rather than passing.
Permission and setup behavior
- Launch Miri without Accessibility permission. Miri explains why it needs permission and links to the relevant System Settings page. Window management starts only after permission is available.
- Grant permission to the identity established by the prototype. Miri reports the actual engine state and starts management unless the user previously selected Stop.
- Test the documented recovery procedure after replacing or moving the installed bundle. The verified Accessibility entry restores management after the engine restarts.
- Run a competing window manager, including standalone Paneru. Miri refuses to start management and names the competing tool. The other tool's configuration stays unchanged.
- Turn off Displays have separate Spaces. Miri refuses to start management and explains the logout requirement.
- Exercise the setup checker for Stage Manager, macOS tiling, and supported macOS gesture conflicts. The checker reports the condition, links to System Settings, and never changes macOS settings itself. Automatic detection remains pending where the engineering investigation has not established a reliable check.
- Exercise a non-gesture setup check whose setting cannot be inspected. The checker shows Not checked with manual instructions. The unavailable check is never presented as passed.
App lifecycle and recovery
- Close and reopen Settings through the menu bar or Dock entry. Window management continues while Settings is closed.
- Select Stop and relaunch Miri. Management remains stopped until the user starts it.
- Start management and select Quit Miri. Both the app and helper stop.
- Check the launch-at-login setting on a new installation. The setting is enabled by default and can be changed through Settings.
- Crash the engine once while Settings remains open. The app stays available, restarts the engine, and restores its layout.
- Cause three engine crashes within five minutes. Miri stops automatic retries and presents the failure, logs, and manual restart control.
- Perform a successful manual restart. The crash count resets, and the app reconciles its displayed state with the engine.
Window accessibility after management ends
All managed windows must remain accessible after Miri stops, quits, or experiences an unrecoverable engine failure. Never leave windows stranded off-screen.
- Prepare managed windows beyond both visible ends of a scrolling strip.
- Select Stop and verify access to every previously managed window while management remains stopped. No window is stranded off-screen.
- Prepare off-screen managed windows again and select Quit Miri. Every previously managed window remains accessible after the app and helper stop.
- Prepare off-screen managed windows again and cause an unrecoverable engine failure. Every previously managed window remains accessible without a successful engine restart.
- Repeat the failure check when the engine cannot execute its clean-shutdown handler. Window access does not depend on the failed engine completing cleanup.
- Repeat these checks across the native Spaces and display arrangements in the multi-monitor checklist. Verify that each previously managed window can be focused and interacted with.
Configuration behavior
- Change gaps and width presets through Settings. Valid changes apply immediately, persist, and require no Save action or engine restart.
- Relaunch Miri. The selected settings remain in effect.
- Edit
~/Library/Application Support/Miri/config.tomlexternally with valid settings. The app detects the edit and applies the valid settings. - Introduce invalid TOML. The engine retains the last valid settings. Settings and the menu bar show the error and its line. Miri does not overwrite the file it could not read correctly.
- Make the configuration file unwritable and attempt a setting change. Miri reports the write failure and retains the last valid settings.
- Check standalone Paneru configuration before and after these operations. Miri never reads it as a fallback or modifies its files.
- Check a new installation's layout defaults.
Width presets are
[0.25, 0.33, 0.5, 0.66, 0.75], and both gaps are 8 points. - Upgrade an installation whose configuration needs migration. Miri creates a backup before migration and preserves user values in the migrated file.
- Exercise a migration that cannot preserve user values. Miri leaves the original file unchanged and reports an error.
Shortcuts and layout behavior
- Record several shortcuts for one action. Each recorded binding performs the selected action.
- Test supported non-US keyboard layouts, including AZERTY, QWERTZ, and Dvorak. The recorder and configured actions work with the active layout.
- Upgrade an installation with custom bindings. Existing bindings remain unchanged, and new defaults fill only unused keys. The explicit reset action selects the current default set.
- Exercise the v1 bindings in Keybinding reference. Numbered jumps select columns and restore the selected stack's last-focused window. Dedicated monitor commands follow physical monitor directions.
- Open a new resizable window. Its initial width is 50% of display width, and existing windows retain their widths.
- Adjust column width and window height. Each press changes size by five percentage points of the corresponding display dimension, subject to window size constraints.
- Open fixed-size windows and Miri's settings. Those windows float automatically. Clicking and macOS window switching provide access to floating windows. Open a Picture-in-Picture video from Chrome while another app is focused. The video window floats above ordinary windows on every Space, takes keyboard focus once, and closing it leaves the layout unchanged.
- Focus different columns in a strip that fits, then in a strip that overflows. The strip moves only as far as needed to show the focused column fully, and a fully visible column does not move. After a trackpad swipe, the strip settles on a column and that column takes focus. A width change keeps the column around its own center, and cycling back to the starting width returns it to the same place.
- Check the layout with a visible Dock. The layout reserves Dock space without a separate Miri setting.
- Enable macOS Reduce Motion with Miri's disable-animation setting off. Strip movement is instant.
- Turn off Reduce Motion and enable Miri's disable-animation setting. Strip movement remains instant.
- Check v1 controls and bindings for deferred work. Virtual-workspace commands and their indicator remain hidden, and tabbed-column commands are unavailable in v1.
- Record a shortcut already assigned to a different Miri action. Miri rejects the conflicting assignment and leaves the existing binding unchanged.
- Record a shortcut with a known macOS conflict. Miri warns about the conflict and never silently replaces another binding.
- Maximize a tiled window with ⌃⌥F, then move focus to the left and right past it, and swipe the strip past it. The window stays maximized and fills the usable area whenever it is in view, and no neighbor shows on top of it. A title-bar double-click restores it, the column returns to its earlier width, and the neighbors keep their sizes. ⌃⌥F and the double-click do the same on a floating window, and no action creates a native full-screen Space.
- Set Maximized stacked window opens to Left of its stack, then to Right of its stack, and maximize a stacked window each time. The window leaves its stack for a column of its own on the chosen side. On restore it returns to its old position in the stack when the stack still exists and has room.
- Start Miri with a configuration that binds
window_fullwidthto a shortcut. The shortcut toggles maximize, Settings lists it under Maximize or restore window, and Miri adds no second binding.
Strip gestures and conflict handling
- Inspect the strip gesture controls. The supported selections are three fingers, four fingers, and Off. Five-finger support is unavailable in v1.
- Run initial setup without verified gesture usability. Miri recommends four fingers, but strip gestures default to Off. Keyboard window management remains available when its startup prerequisites are satisfied.
- Run initial setup with four-finger usability verified and no macOS conflict. Four-finger strip gestures can be enabled.
- Exercise the supported three-finger and four-finger strip gestures on real hardware. The strip follows finger movement by default. The actual supported gesture and macOS setting combinations have recorded hardware evidence.
- Reverse swipe direction through Settings and relaunch Miri. The selected reverse preference persists, but the gesture remains Off pending retesting. After a successful retest and explicit user confirmation, the selected reverse direction controls strip movement.
- Select Off. Miri does not intercept the strip gesture, and keyboard window management remains available.
- Confirm a known macOS conflict with the selected strip gesture. Miri disables its conflicting strip gesture, preserves keyboard window management, and shows manual setup instructions. Miri never modifies macOS settings automatically.
- Make gesture conflict detection unavailable. Miri shows Unable to verify and offers a gesture test. Unavailable detection by itself is neither a confirmed conflict nor a passed verification.
- Complete a real gesture test with consistent strip movement and no unintended macOS actions. Without explicit user confirmation, Miri does not mark usability as verified by the user test. After explicit user confirmation, Miri shows Verified by user test. The underlying macOS gesture configuration is not presented as automatically verified.
- Relaunch Miri after selecting and persisting a gesture preference. The preference remains stored, and an option to retest is available. Ordinary restarts do not invalidate the user-test result.
- Fail or leave a gesture test inconclusive. The gesture remains Off, and keyboard window management remains available when its startup prerequisites are satisfied.
- Confirm a known macOS conflict despite a user test or user confirmation. The known conflict still prevents the conflicting strip gesture from being enabled.
- Change the finger count, then separately change the direction. Each change invalidates the prior user-test result. The selected preference remains saved, but the gesture stays Off until another successful test and explicit user confirmation.
- Upgrade macOS, then separately upgrade the bundled engine. Each upgrade invalidates the prior user-test result and requires retesting before gesture enablement.
- Detect a change to relevant macOS gestures, then separately report such a change through Miri. Each case invalidates the prior user-test result and requires retesting. Miri does not claim to detect changes when automatic detection is unavailable.
- Check keyboard window management while a gesture is Off pending retesting. Keyboard window management continues when its startup prerequisites are satisfied.
Updates and diagnostics
- Check the default update policy on a new installation. Miri checks daily and asks before installing an update.
- Enable automatic updates and start Miri with an update available. Miri installs the update in the background without an installation prompt. The app update carries its pinned engine upgrade.
- Open logs and use Copy Diagnostics. Logs remain local, and Miri provides a preview before copying. Diagnostics include versions, monitor setup, permission status, engine status, and redacted logs. Window titles, document paths, usernames, and raw configuration are excluded by default.
- Observe network activity during management, update checks, and update downloads. Miri sends no telemetry or window-management data. Update checks and downloads can use the network.
- Exercise diagnostics with known window titles, document paths, usernames, and raw configuration values in the test data. Inspect both the preview and the clipboard contents. Neither contains those fields under the default diagnostics policy.
Public-release delivery
- Validate the release disk image on the target Mac. The app has Developer ID signing and Apple notarization.
- Install the release through its Homebrew cask. The installed app follows the same permission and setup behavior.
- Check the distributed source and license notices. The release follows the accepted GPL-3.0-or-later direction and preserves Paneru's required MIT notices.
Remaining limits
The intended gesture defaults and conflict policy are accepted. Gesture-test pass criteria and result invalidation are accepted. Supported gesture combinations still need engine and hardware verification. Configuration keys, validation ranges, and private API fallbacks require review against the actual pinned dependency. This checklist does not supply a memory-stability threshold or settle Q6 about release duration, which Sam decides at the final check before publishing v1. The design tree status retains those open items.