docs(openspec): define phase 3d native macos client
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: P3D-016 complete MVP input
|
||||
Input SHALL support keyboard, absolute and relative mouse, high-resolution scroll, and one standard controller with a pressed-state ledger and release-all on every authority/interruption boundary.
|
||||
|
||||
#### Scenario: Authority loss with pressed input
|
||||
- **WHEN** focus, network, session authority, sleep, cancellation, or termination changes while input is pressed
|
||||
- **THEN** release-all is sent/recorded once and no pressed state remains
|
||||
|
||||
### Requirement: P3D-017 Windows password is ordinary input
|
||||
Windows lock-screen credentials SHALL travel only as normal encrypted input events and SHALL never be collected, stored, autofilled, or separately injected.
|
||||
|
||||
#### Scenario: Lock-screen typing
|
||||
- **WHEN** the user types into a remote Windows credential field
|
||||
- **THEN** the client handles the keys like any remote input and retains no credential value
|
||||
|
||||
### Requirement: P3D-028 controller layouts
|
||||
Controller input SHALL support user-selectable Xbox, PlayStation, and Nintendo/Switch-style normalized layouts with explicit unsupported-capability behavior.
|
||||
|
||||
#### Scenario: Layout selection
|
||||
- **WHEN** the user changes controller layout
|
||||
- **THEN** subsequent normalized events use the selected mapping and unsupported controls are surfaced explicitly
|
||||
|
||||
### Requirement: P3D-029 bounded text clipboard
|
||||
The client SHALL expose clipboard enablement/direction and visible failure behavior, permit only bounded text, and reject files, file URLs, folders, binary data, and oversized content.
|
||||
|
||||
#### Scenario: File clipboard attempt
|
||||
- **WHEN** a local or remote clipboard advertises a file or file URL
|
||||
- **THEN** transfer is rejected without reading or persisting file content
|
||||
|
||||
### Requirement: P3D-035 native pointer modes and escape safety
|
||||
The client SHALL aspect-fit video, emit absolute pointer events only inside the rendered viewport, default to macOS-owned absolute cursor behavior, and provide session-only relative capture with reserved local control chords.
|
||||
|
||||
#### Scenario: Letterbox pointer
|
||||
- **WHEN** the absolute pointer is in a letterbox bar
|
||||
- **THEN** no remote absolute-pointer event is emitted
|
||||
|
||||
#### Scenario: Toggle relative mode
|
||||
- **WHEN** `Control-Option-Shift-M` is pressed during a session
|
||||
- **THEN** pressed input is released, the chord is not forwarded, capture switches, and the saved/restored cursor point is clamped inside the rendered viewport
|
||||
|
||||
#### Scenario: Emergency release
|
||||
- **WHEN** `Control-Option-Shift-Escape` is pressed in any input mode
|
||||
- **THEN** pressed input is released, absolute/local cursor ownership and controls return, and the chord is not forwarded
|
||||
|
||||
### Requirement: P3D-036 scoped keyboard mappings
|
||||
Keyboard mapping SHALL support physical/logical keys and simultaneous chords with Mac-to-Windows and language defaults, deterministic global/resource precedence and modifier order, conflicts, enablement, add/remove, and Restore Defaults; macros and reserved-chord remapping are prohibited.
|
||||
|
||||
#### Scenario: Conflicting resource mapping
|
||||
- **WHEN** an enabled resource mapping conflicts with a global mapping
|
||||
- **THEN** deterministic resource precedence applies and the conflict is visible/editable
|
||||
|
||||
#### Scenario: Reserved mapping attempt
|
||||
- **WHEN** a mapping targets either local reserved escape chord
|
||||
- **THEN** the mapping is rejected and the local chord remains intercepted
|
||||
@@ -0,0 +1,43 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: P3D-018 explicit recovery states
|
||||
The client SHALL distinguish network interruption, reconnectable session, draining, provider cleanup failure, assignment unavailable, capacity queue, entitlement loss, and terminal end with safe actions.
|
||||
|
||||
#### Scenario: Reconnectable interruption
|
||||
- **WHEN** the control authority reports a reconnectable session after network loss
|
||||
- **THEN** the UI offers only a fresh authorized reconnect path and does not replay the old grant
|
||||
|
||||
### Requirement: P3D-019 deterministic lifecycle changes
|
||||
Sleep/wake, foreground/background, display/audio/controller/network changes, server/gateway restart, and core cancellation SHALL have deterministic tested behavior.
|
||||
|
||||
#### Scenario: Sleep during active stream
|
||||
- **WHEN** the Mac sleeps during an active stream
|
||||
- **THEN** input is released, owned tasks/resources stop, and wake reconciles authority before reconnect
|
||||
|
||||
### Requirement: P3D-021 accessible critical paths
|
||||
Authentication, resources, brokerage, session, errors, and settings SHALL support VoiceOver, keyboard navigation, visible focus, contrast, reduced motion, dynamic type where applicable, and non-color status cues.
|
||||
|
||||
#### Scenario: Keyboard-only connection
|
||||
- **WHEN** a user navigates the workspace without a pointer
|
||||
- **THEN** every critical action is reachable with visible focus and meaningful accessibility labels
|
||||
|
||||
### Requirement: P3D-022 redacted diagnostics
|
||||
Errors, telemetry, logs, crashes, and support artifacts SHALL exclude credentials, grants, provider endpoints, raw media/input, clipboard content, and Windows secrets while retaining bounded correlation identifiers.
|
||||
|
||||
#### Scenario: Synthetic secret canary
|
||||
- **WHEN** all diagnostics and support outputs are generated after injecting secret canaries
|
||||
- **THEN** the scanner finds no secret, media, input, clipboard, or provider-endpoint value
|
||||
|
||||
### Requirement: P3D-023 release platform safety
|
||||
Any distributed release SHALL be signed, notarized, hardened-runtime compatible, signature-verified for update, and rollback-tested.
|
||||
|
||||
#### Scenario: Tampered update
|
||||
- **WHEN** update metadata or the application artifact is modified after signing
|
||||
- **THEN** update verification fails before installation or execution
|
||||
|
||||
### Requirement: P3D-024 explicit uninstall policy
|
||||
Uninstall SHALL remove documented local application state according to explicit Keychain/cache policy and SHALL NOT silently delete server-side device authority.
|
||||
|
||||
#### Scenario: Offline uninstall
|
||||
- **WHEN** the app is removed while the Server is unreachable
|
||||
- **THEN** local state follows policy and server-side revocation is not falsely claimed
|
||||
@@ -0,0 +1,15 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: P3D-014 hardware video presentation
|
||||
Video SHALL use negotiated registered media identifiers, VideoToolbox hardware decode, and Metal presentation without unnecessary copies or persistence.
|
||||
|
||||
#### Scenario: Unsupported hardware decode
|
||||
- **WHEN** the negotiated profile cannot be decoded by supported VideoToolbox hardware
|
||||
- **THEN** the session fails explicitly without software fallback, remote transcode, or pixel logging
|
||||
|
||||
### Requirement: P3D-015 bounded audio playback
|
||||
Audio SHALL use a proven CoreAudio abstraction with bounded buffering, negotiated channel layout, drift handling, and measurable A/V synchronization.
|
||||
|
||||
#### Scenario: Audio device replacement
|
||||
- **WHEN** the default audio device changes or disappears during an active session
|
||||
- **THEN** bounded playback state is recreated or fails visibly without persisting streamed audio
|
||||
@@ -0,0 +1,134 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: P3D-001 Apple Silicon platform baseline
|
||||
The client SHALL target Apple Silicon with macOS 26 primary, macOS 15/14 supported, and a non-release macOS 27 compatibility lane when its SDK/runtime exists.
|
||||
|
||||
#### Scenario: Supported platform matrix
|
||||
- **WHEN** the frozen candidate is qualified
|
||||
- **THEN** exact native evidence exists for macOS 26, 15, and 14, while Intel is not claimed
|
||||
|
||||
### Requirement: P3D-002 isolated SwiftUI state
|
||||
The shell SHALL use SwiftUI with structured concurrency and isolated authentication, resource, broker, stream, and settings state.
|
||||
|
||||
#### Scenario: Concurrent state update
|
||||
- **WHEN** control and stream events arrive concurrently
|
||||
- **THEN** owning actors serialize mutation and views receive immutable main-actor projections
|
||||
|
||||
### Requirement: P3D-003 no former C++ core
|
||||
The implementation SHALL NOT restore the superseded C++ core packaging design.
|
||||
|
||||
#### Scenario: Core dependency audit
|
||||
- **WHEN** the native client dependency graph is inspected
|
||||
- **THEN** no VerseVDI C++ streaming core or wrapper is linked
|
||||
|
||||
### Requirement: P3D-004 stable C ABI
|
||||
The C ABI SHALL use sized versioned tables and define pointer ownership, lifetime, callback thread, cancellation, error, reentrancy, and destroy behavior.
|
||||
|
||||
#### Scenario: Older caller table
|
||||
- **WHEN** a caller supplies a supported older structure size
|
||||
- **THEN** the core reads only available fields and returns a deterministic compatibility result
|
||||
|
||||
### Requirement: P3D-005 Rust core
|
||||
The platform-neutral streaming core SHALL be Rust, not the superseded C++ implementation.
|
||||
|
||||
#### Scenario: Core artifact inspection
|
||||
- **WHEN** the XCFramework artifact is inventoried
|
||||
- **THEN** its exported VerseVDI surface is the reviewed C ABI backed by the pinned Rust core
|
||||
|
||||
### Requirement: P3D-006 Swift platform ownership
|
||||
Swift SHALL own HTTPS/WebSocket control, Keychain, navigation, accessibility, Apple decode/render/audio/input objects, signing, and update integration.
|
||||
|
||||
#### Scenario: Platform operation routing
|
||||
- **WHEN** a platform credential, window, decoder, audio device, or input operation occurs
|
||||
- **THEN** it is owned by Swift/AppKit/Apple frameworks and not by the Rust core
|
||||
|
||||
### Requirement: P3D-007 narrow credential storage
|
||||
Refresh credentials and device private keys SHALL use the narrowest practical Keychain accessibility; access tokens and gateway grants SHALL remain memory-only.
|
||||
|
||||
#### Scenario: Relaunch storage audit
|
||||
- **WHEN** the app terminates and relaunches
|
||||
- **THEN** no access token or gateway grant is recoverable from persistent client storage
|
||||
|
||||
### Requirement: P3D-008 authenticated device enrollment
|
||||
First use SHALL authenticate before device-key generation/registration and SHALL complete server challenge proof before launch authority.
|
||||
|
||||
#### Scenario: Unauthenticated enrollment attempt
|
||||
- **WHEN** device enrollment is requested without a current authenticated user session
|
||||
- **THEN** no key is registered and no launch authority is issued
|
||||
|
||||
### Requirement: P3D-009 no active LDAP mode
|
||||
The Phase 3D client SHALL NOT expose an active LDAP login mode before Phase 6.
|
||||
|
||||
#### Scenario: Login surface inspection
|
||||
- **WHEN** the Phase 3D login UI and control requests are exercised
|
||||
- **THEN** only local login is offered and no LDAP request is made
|
||||
|
||||
### Requirement: P3D-010 authorized resources only
|
||||
The UI SHALL show only assigned desktops and entitled pools, including unavailable assignment, `awaiting_desktop`, and capacity queue state.
|
||||
|
||||
#### Scenario: Cross-subject cached resource
|
||||
- **WHEN** stale local data references another subject's resource
|
||||
- **THEN** reconciliation removes or withholds it and no action is available
|
||||
|
||||
### Requirement: P3D-011 idempotent broker reconciliation
|
||||
The client SHALL request/cancel idempotently, apply events by sequence, resync gaps through REST, and reconcile current authority after relaunch.
|
||||
|
||||
#### Scenario: Event sequence gap
|
||||
- **WHEN** the next event sequence is not contiguous
|
||||
- **THEN** incremental application stops and REST reconciliation completes before further action
|
||||
|
||||
### Requirement: P3D-012 gateway-only manifest
|
||||
The client SHALL accept only a gateway-only manifest matching authenticated server, device, session, audience, expiry, and supported tunnel range.
|
||||
|
||||
#### Scenario: Wrong manifest context
|
||||
- **WHEN** any manifest binding or required tunnel capability is wrong
|
||||
- **THEN** the core rejects it before opening a media/input session
|
||||
|
||||
### Requirement: P3D-013 forbidden provider details
|
||||
The client SHALL reject and safely report any manifest containing a provider/VM endpoint or credential-like field.
|
||||
|
||||
#### Scenario: Provider field injection
|
||||
- **WHEN** a manifest contains a provider address or credential-shaped field
|
||||
- **THEN** launch fails closed and diagnostics contain no injected value
|
||||
|
||||
### Requirement: P3D-020 callback isolation
|
||||
Core callbacks SHALL transfer bounded immutable values to their owning actor and SHALL NOT mutate SwiftUI state directly.
|
||||
|
||||
#### Scenario: Callback storm
|
||||
- **WHEN** callbacks arrive rapidly from a non-main core thread
|
||||
- **THEN** bounded bridge delivery preserves order/ownership without direct view-state mutation
|
||||
|
||||
### Requirement: P3D-025 fake-core-first candidate
|
||||
The client SHALL pass fake-core UI behavior before real-core fixture integration and SHALL freeze a platform-qualified candidate before owner live Apollo acceptance.
|
||||
|
||||
#### Scenario: Live provider unavailable
|
||||
- **WHEN** deterministic implementation gates pass without owner Apollo access
|
||||
- **THEN** the candidate can reach engineering review with live interoperability recorded `deferred-owner-e2e`
|
||||
|
||||
### Requirement: P3D-026 XCFramework packaging
|
||||
The Rust core SHALL be packaged as a static library within an XCFramework behind one stable C ABI and thin Swift wrapper.
|
||||
|
||||
#### Scenario: Unsafe-call audit
|
||||
- **WHEN** Swift source is inspected
|
||||
- **THEN** only the designated bridge owns direct C ABI pointer and callback translation
|
||||
|
||||
### Requirement: P3D-027 core responsibility boundary
|
||||
The Rust core SHALL own tunnel negotiation, cryptography, reconstruction, encoded delivery, input encoding, policy updates, statistics, and core errors without owning product authorization or Apple UI/media devices.
|
||||
|
||||
#### Scenario: Responsibility audit
|
||||
- **WHEN** the core dependency/module graph is inspected
|
||||
- **THEN** no SwiftUI, Apple decoder/renderer/audio device, or product-auth implementation is linked into it
|
||||
|
||||
### Requirement: P3D-030 registered media dispatch
|
||||
Core and client SHALL dispatch framing, reconstruction, decode, and render from registered negotiated identifiers and SHALL fail stably on unsupported/stale combinations.
|
||||
|
||||
#### Scenario: Unsupported profile combination
|
||||
- **WHEN** framing and media identifiers have no supported explicit intersection
|
||||
- **THEN** the session fails before decoder allocation without guessing, fallback, or transcode
|
||||
|
||||
### Requirement: P3D-031 local authentication lifecycle
|
||||
The MVP SHALL support local login, rotating refresh, logout, device-revocation response, and generic anti-enumeration errors.
|
||||
|
||||
#### Scenario: Refresh-family revocation
|
||||
- **WHEN** the Server reports refresh reuse or device revocation
|
||||
- **THEN** local authority and active input/stream state are cleared and generic reauthentication is shown
|
||||
@@ -0,0 +1,23 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: P3D-032 native desktop workspace
|
||||
The app SHALL expose Favorites, Desktops, Pools, and Settings in a native split workspace without Apps, Add PC, manual endpoint, or direct-provider surfaces. Desktop cards SHALL remain `328 x 205 pt`, use full-bleed previews and subtle readable metadata treatment, and adapt only the grid column count.
|
||||
|
||||
#### Scenario: Narrow and wide resize
|
||||
- **WHEN** the workspace moves between narrow, medium, and wide widths
|
||||
- **THEN** card geometry remains fixed, the column count changes, and text/actions do not overflow
|
||||
|
||||
#### Scenario: Accessible card actions
|
||||
- **WHEN** a card receives hover or keyboard focus
|
||||
- **THEN** Favorite and settings controls become available without adding a connect button; double-click or Return connects
|
||||
|
||||
### Requirement: P3D-037 private favorites and previews
|
||||
Favorites, search, sort, filters, diagnostics, and previews SHALL reveal only current authorized resources. A stable desktop MAY retain one `656 x 410` mode-`0600` preview only after an active session ends cleanly; pool art is generic and preview bytes are excluded from backup/telemetry/log/crash/support data.
|
||||
|
||||
#### Scenario: Failed launch and clean end
|
||||
- **WHEN** a launch fails and a later active session ends cleanly
|
||||
- **THEN** the failed launch preserves the old preview and only the clean end atomically replaces it
|
||||
|
||||
#### Scenario: Entitlement loss
|
||||
- **WHEN** logout or reconciliation removes a desktop entitlement
|
||||
- **THEN** its preview is cleared and cannot appear through Favorites, search, cache, or diagnostics
|
||||
@@ -0,0 +1,27 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: P3D-033 requested and effective display mode
|
||||
The client SHALL offer global and desktop/pool overrides for Automatic, detected/common preset, Custom, and Full Native width/height/FPS. A display-aware request SHALL be feature-gated; the Server SHALL validate, include it in idempotency identity, resolve immutable policy, proportionally clamp to even dimensions and maximum FPS, persist requested/effective values atomically, and disclose both without provider details.
|
||||
|
||||
#### Scenario: Oversized custom request
|
||||
- **WHEN** a requested mode exceeds either policy dimension or FPS
|
||||
- **THEN** the Server applies one proportional scale, floors both dimensions to even pixels, caps FPS, persists the result, and returns the requested and accepted modes
|
||||
|
||||
#### Scenario: Legacy request
|
||||
- **WHEN** a client omits the feature and requested display object
|
||||
- **THEN** the Server preserves the legacy response shape and provider work uses the existing exact policy mode
|
||||
|
||||
#### Scenario: Same idempotency key with different mode
|
||||
- **WHEN** two requests reuse an idempotency key but contain different requested display modes
|
||||
- **THEN** the Server rejects the mismatch rather than returning or mutating the earlier session
|
||||
|
||||
### Requirement: P3D-034 native detection and reconnect semantics
|
||||
Automatic mode SHALL derive physical pixels and maximum FPS from the screen where the session window opens, prefer a defensible notch-safe built-in mode, otherwise disclose Full Native, and SHALL NOT mutate an active mode after a display move. Reconnect to match the new display SHALL end the prior session and use a new request/idempotency key. Owner E2E SHALL prove accepted values on Apollo/SudoMaker IDD through the gateway-only route.
|
||||
|
||||
#### Scenario: Move active session to another display
|
||||
- **WHEN** an Automatic session window moves to a display with different native capability
|
||||
- **THEN** the active mode remains unchanged and the user may explicitly reconnect with a newly detected request
|
||||
|
||||
#### Scenario: Exact owner virtual-display acceptance
|
||||
- **WHEN** the owner runs the frozen client, Server, gateway, and Apollo candidate
|
||||
- **THEN** retained evidence binds requested and accepted width/height/FPS to the actual SudoMaker virtual display without a direct client-provider route
|
||||
Reference in New Issue
Block a user