Skip to content

[KS] Driver runs: make remaining host observers inert (#433) - #451

Merged
sethwebster merged 1 commit into
seth/kitchen-sink-gatefrom
seth/ks-433-driver-observers
Oct 13, 2026
Merged

sethwebster merged 1 commit into
seth/kitchen-sink-gatefrom
seth/ks-433-driver-observers

Conversation

@sethwebster

Copy link
Copy Markdown
Collaborator

Refs #433

What changed

Under SPARK_TEST_DRIVER (production unchanged):

  • Displays (SparkDisplayObserver): a driver run installs only the simulation observer. No screen-parameter, color-space or CGDisplayRegisterReconfigurationCallback source, so a real display change can't add a displayDetailsChanged entry.
  • Motion coordinator: a driven coordinator installs only the window-close observer. Power, screen-parameter, window-screen, occlusion and Reduce Motion observers are skipped. The driver also pins the frame rate at 60 Hz (maximumFramesPerSecond), next to Reduce Motion, Reduce Transparency and Low Power Mode. simulateDisplays restore now goes back to 60 Hz, not the real display's rate.
  • RNWindowManager: no screensChanged: observer in driver runs.
  • System getters: at driver start the system module seeds fixed values, and simulateSystemEvent overrides them as before:
    • getSystemInfo: onBattery: false, batteryLevel: null, idleSeconds: 0, timeZone: "UTC", lowPowerMode: false, thermalState: "nominal"
    • getNetworkStatus: online, ["wired"], not expensive or constrained, all proxies null. No path monitor runs.
    • getAppearancePreferences: invertColors and keyboardNavigation false
  • Launch arguments: -reduceMotion NO, -AppleInterfaceStyle Light and -AppleInterfaceStyleSwitchesAutomatically NO join PINNED_DEFAULTS. The other appearance fields were already pinned. preferences-real still overrides them.
  • Still real (documented): osVersion, architecture, translated, locale and dark. These are the process's own facts: the OS, the build, Rosetta, the launch locale and the app's effective appearance.
  • Docs: system.md, displays.md, motion.md and test-driver.md (pinned-host-settings table).
  • Flows:
    • system-integration/state now asserts exact driver values.
    • state-visual masks only the OS version row; it used to mask the whole info and network panels.
    • motion-system/visual no longer masks the accessibility-power environment readout.
    • preferences-real asserts that invert colors and keyboard navigation are false.

Native tests (both modes)

  • tests/system-events.native.mm: outside a driver run, the reads report the host (time zone, Low Power Mode, a real path, invert colors and keyboard navigation). In a driver run, after driver start, they report the fixed values, and simulations replace them (offline, thermal serious).
  • tests/displays.native.mm: in driver mode, screen-parameter and color-space notifications don't reach the handler, and simulation changes do.
  • tests/motion-coordinator.native.mm: the driven coordinator has 1 observer and no accessibility observer, and reports a pinned environment of 60 Hz. The app coordinator has 5 observers plus the accessibility one. Restore returns to 60 Hz.
  • tests/window-manager.native.mm: a screen-parameter notification reaches onDisplaysChanged only outside driver mode.
  • Mutation checks run in this session: removing the window-manager gate, the system seed or the displays driver check makes the matching test fail.

Other host sources a driver run can still see (not fixed here)

  • SparkFrameTimeline (assertFrames) measures the real display link. That's inherent: it fails with 0 frames while the display sleeps.
  • getDisplayDetails without a simulation reports the real displays (intended: displays-real).
  • Global shortcuts map keys through the current keyboard layout (TISCopyCurrentASCIICapableKeyboardLayoutInputSource), and so does keyboard navigation in AppKit.
  • RCTAccessibilityManager (react-native-macos) still observes accessibility display changes. The values it re-reads are pinned by launch arguments.
  • The Dock tile's progress view still refreshes on AppleInterfaceThemeChanged and system color changes. Its appearance read is pinned by -AppleInterfaceStyle Light.
  • The clipboard already uses a private pasteboard in driver mode.

Verification (run in this session)

  • bun run typecheck: pass.
  • bun run test: 1980 passed, 2 failed. Both are the accepted host failures: node-runtime (asdf shim) and the motion-native frames check (frames >= 5, display asleep). The frames check also fails on the base.
  • bun run e2e:lint: 0 problems.
  • Rebuilt the Kitchen Sink (rebuild:macos). Then, with --backend driver under ks-lock native, ran displays-graphics, system-integration, appearance-theming, motion-system and infra/catalog-driver: 75 passed, 9 skipped (Windows-only), 2 failed. Neither failure comes from this change:
    • appearance-theming/app-icon-build needs ${APP_PATH} (gate-only).
    • motion-system/js-block hit assertFrames: 0 display-link frames while the display sleeps.
  • Every golden in those flows matched with 0 different pixels, including system-integration-state and motion-system-accessibility-power with their masks reduced. No golden was re-approved.
  • multiwindow (display listener and simulated displays): 28 passed, 4 skipped. The 5 failures are flows that need focusWindow, which the driver backend doesn't support.
  • No system settings or displays were changed.

Under the test driver, the displays observer, motion's power, screen and
occlusion observers and the window manager's screen observer install no
host sources. getSystemInfo, getNetworkStatus and getAppearancePreferences
report fixed driver values for fields no simulation sets; launch arguments
pin Reduce Motion and the appearance setting. Motion pins 60 Hz. Native
tests cover both modes.
@sethwebster
sethwebster merged commit 54e7214 into seth/kitchen-sink-gate Oct 13, 2026
2 checks passed
@sethwebster
sethwebster deleted the seth/ks-433-driver-observers branch October 13, 2026 05:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant