Skip to content

feat(notify): Windows production boot clock, toast delivery, and none-setup - #187

Draft
777genius wants to merge 11 commits into
feat/agent-notify-e2efrom
cursor/uap-installer-windows-notify-6c84
Draft

777genius wants to merge 11 commits into
feat/agent-notify-e2efrom
cursor/uap-installer-windows-notify-6c84

Conversation

@777genius

@777genius 777genius commented Sep 14, 2026

Copy link
Copy Markdown
Owner

This is the R3/P7 Windows runtime slice on top of #177. It is independent of the wizard/SDK stack (#180/#182/#183), of the R0 configure PR (#185), and of the Linux P7 PR (#186).

What landed

  • journal.PlatformClock on Windows uses NtQuerySystemInformation(SystemBootEnvironmentInformation) plus QueryInterruptTime (suspend-inclusive, 100ns units) with GetTickCount64 fallback.
  • notifier.SystemBootClock uses that same sample so runtime and journal share one boot ID.
  • Windows stdio adapter duplicates the handle, classifies FILE_TYPE_PIPE vs disk vs FILE_TYPE_CHAR (NUL stays local if deadlines fail), and never claims pollable I/O it cannot cancel. Anonymous pipes stay pollable when SetDeadline is unsupported.
  • Windows journal storage uses NT relative opens, exclusive LockFileEx, private DACLs, and atomic replace of journal.json. RestrictPrivate sets the current-user owner so elevated runners (Administrators-owned new files) still initialize. RequirePrivate accepts SYSTEM/Administrators owners and inherit-only ACEs, matching the config store.
  • Directory os.File.Sync is a no-op on Windows (FlushFileBuffers does not support directory handles), matching installruntime.syncDir. File contents are flushed before rename. Leaf directories and files request FILE_GENERIC_WRITE/FILE_GENERIC_READ for NtCreateFileGENERIC_WRITE is outside an FA ACE and was ACCESS_DENIED on GitHub runners. RestrictPrivate uses SDDL FA because GENERIC_ALL ACEs make SetSecurityInfo return ERROR_INVALID_PARAMETER on GitHub Windows runners.
  • Setup treats installruntime.IdentityMode(0600) as the private policy mode (0666 on Windows, 0600 on Unix) so explicit policy CAS survives Windows identityMode.
  • Portable locator filesystem on Windows reuses confined NT opens, private DACLs, and identityMode primaries (0666/0444, no Unix execute bits).
  • Windows default delivery factory returns WindowsToastDelivery instead of the macOS native helper:
    • one go-toast submit for navigation=none
    • no beeep fallback after a possible toast effect
    • does not start the click-to-focus protocol handler
    • navigation=required stays navigation_unavailable
  • Windows Status is eligible for a managed non-recovery install without DecoderFloor native.
  • setup.Apply / Inspect accept Windows for navigation none, initialize the journal, and still reject local .app routing. Darwin still requires the native helper.
  • Existing-installer setup-notifications enable --navigation none works with Platform: windows without a native helper.
  • clientsetup now has a confined NT document reader. Windows identityMode stores 0666/0444 only, so ledger-owned regular commands are accepted without Unix execute bits.

Honest non-goals (still open)

Tests

  • TestWindowsPlatformClockAvailableAndStableWithinBoot / TestSystemBootClockMatchesJournal
  • TestWindowsToastNavigationNoneSubmitsWithoutBeeep and timeout → unknown/handoff_unconfirmed without beeep
  • TestWindowsNoneSetupProvisionsJournalWithoutNative / TestWindowsSetupNotificationsEnableNoneWithoutNative
  • TestWindowsInitializeOpenAdmit / TestWindowsAgentNotifyPipeIsPollable
  • TestWindowsRateLimitPersistsClockAcrossSyntheticReboot / TestWindowsUnavailableClockKeepsRateLimit
  • TestWindowsApplyAcceptsIdentityModeWithoutUnixExecute / TestWindowsReadConfinedDocumentAndDirectory
  • TestWindowsPublishAcquireRevoke / TestWindowsIdentityModePrimaryAccepted
  • Hosted Linux/macOS tests exercise the Platform: windows setup seam against unix journal storage; native Windows FS/DACL tests are GOOS=windows.
Open in Web Open in Cursor 

…setup

Windows MCP now has a kernel boot-environment clock, pollable stdio
adapter, crash-safe journal store, and a toast session backend that
never falls back to beeep after a possible toast effect. Existing
installer enable --navigation none provisions a journal without the
macOS native helper; local .app routing stays rejected.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 59.06040% with 122 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.25%. Comparing base (89d8524) to head (05d0c6d).

Files with missing lines Patch % Lines
internal/agentnotify/setup/state_provision.go 59.77% 38 Missing and 34 partials ⚠️
internal/notifier/delivery_toast.go 62.50% 17 Missing and 13 partials ⚠️
internal/agentnotify/setup/setup.go 33.33% 4 Missing and 4 partials ⚠️
internal/agentnotify/clientsetup/clientsetup.go 50.00% 1 Missing and 2 partials ⚠️
internal/agentnotify/portable/locator.go 40.00% 1 Missing and 2 partials ⚠️
internal/notifier/delivery.go 66.66% 1 Missing and 1 partial ⚠️
internal/notifier/delivery_toast_other.go 0.00% 2 Missing ⚠️
internal/agentnotify/runtime/policy.go 0.00% 0 Missing and 1 partial ⚠️
internal/installruntime/transaction.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                    Coverage Diff                    @@
##           feat/agent-notify-e2e     #187      +/-   ##
=========================================================
- Coverage                  65.27%   65.25%   -0.02%     
=========================================================
  Files                        168      172       +4     
  Lines                      17182    17287     +105     
=========================================================
+ Hits                       11215    11281      +66     
- Misses                      4360     4383      +23     
- Partials                    1607     1623      +16     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Windows CI go vet failed on setup_windows_test.go because
windowsContext used time.Second without importing time.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
cursoragent and others added 2 commits September 14, 2026 18:21
Elevated Windows runners own newly created files as Administrators.
RestrictPrivate now sets the current-user owner, and RequirePrivate
accepts SYSTEM/Administrators plus inherit-only ACEs like the config
store. Anonymous pipes stay pollable when SetDeadline is unsupported.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Windows identityMode stores 0666/0444 only, and clientsetup previously
always returned ErrConflict from the non-unix reader. Add confined NT
document reads and accept ledger-owned regular commands on Windows.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
cursoragent and others added 4 commits September 14, 2026 19:04
NT directory handles need READ_CONTROL before GetSecurityInfo, otherwise
Initialize/Apply report state_repair_required or unsafe setup directory.
GENERIC_ALL ACEs make SetSecurityInfo return ERROR_INVALID_PARAMETER on
GitHub runners; apply the same SDDL FA DACL the config store already uses.
Control-root checks now skip inherit-only ACEs and accept SYSTEM or
Administrators owners, matching journal/setup RequirePrivate.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
os.File.Sync maps to FlushFileBuffers, which rejects directory handles
opened list/traverse-only. Keep ancestor walks read-only; open the
private leaf (and setup children) with GENERIC_WRITE so journal
Initialize and none-setup provision can fsync on GitHub runners.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
FlushFileBuffers does not support directory handles, so os.File.Sync on
journal/setup dirs returns Access is denied even after GENERIC_WRITE.
File contents are already flushed before rename; match installruntime.syncDir.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Plan §13.4/§13.7 requires a confined portable/locator adapter. Reuse NT
relative opens, private FA DACLs, and identityMode primaries so Publish
and Acquire work without Unix execute bits.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
cursoragent and others added 3 commits September 14, 2026 19:45
…e files

NtCreateFile does not map GENERIC_WRITE, so FA DACLs on GitHub runners
denied journal Initialize. Request FILE_GENERIC_WRITE instead, and treat
identityMode(0600)=0666 as the private policy mode on Windows.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
§13.5 requires the new boot time base to persist when Admit is refused,
and unavailable clocks must not disable rate limits. These tests use the
Windows NT journal so GitHub runners prove the storage adapter, not only
the unix journal_test.go copies.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Lock create succeeded because it already requested FILE_GENERIC_READ.
Exclusive oWRONLY creates (namespace, journal.json) used FILE_GENERIC_WRITE
only, so RestrictPrivate's GetFileInformationByHandle returned Access is
denied. Match the lock/installruntime mask and name open vs restrict errors.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
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.

2 participants