docs(openspec): define phase 3d native macos client
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-10
|
||||
@@ -0,0 +1,176 @@
|
||||
## Context
|
||||
|
||||
Phase 3C freezes a gateway-only control/media baseline, but the Data Plane macOS target is
|
||||
still a template and the shared Protocol has no requested display mode, absolute pointer, or
|
||||
high-resolution scroll contract. The closed Server already owns broker persistence,
|
||||
allocation policy, manifest disclosure, and provider-work. The GPLv3 Data Plane owns the
|
||||
pure-Go gateway/Apollo translation plus the future Rust core and native client. The Protocol
|
||||
repository remains the only wire authority.
|
||||
|
||||
The implementation must preserve strict legacy JSON decoding, exact immutable Protocol pins,
|
||||
no direct client-to-provider path, encoded-media relay without gateway decode/transcode, and
|
||||
bounded release-all behavior. UI references are retained in the Planning repository as
|
||||
review evidence only.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Deliver one native Apple-Silicon SwiftUI/AppKit client for macOS 26 with macOS 15/14
|
||||
compatibility, built against a deterministic fake core before real streaming integration.
|
||||
- Carry a client-requested display mode through Server allocation to provider work, while the
|
||||
Server remains the only policy/clamp authority and both requested/effective values remain
|
||||
visible to the client.
|
||||
- Add provider-neutral absolute pointer and high-resolution scroll events without changing
|
||||
the gateway-only route or coupling the public contract to Apollo packet shapes.
|
||||
- Keep lifecycle, input release, local preview storage, secrets, media, and diagnostics
|
||||
bounded and testable at their trust boundaries.
|
||||
- Preserve a small, sized/versioned Rust C ABI and a single Swift unsafe bridge.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Remote apps, manual PC/direct provider connections, live display renegotiation,
|
||||
multi-monitor remote topology, HDR, microphone, file/folder redirection, image clipboard,
|
||||
macros/timed sequences, Intel, provider-specific UI, or a plugin framework.
|
||||
- Gateway decode, encode, transcode, render, cgo, native sidecar, insecure retry, or silent
|
||||
capability fallback.
|
||||
- Public release, signing credentials, deployment, promotion, or agent access to the owner's
|
||||
Apollo host. Live Apollo/SudoMaker evidence remains owner E2E.
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Repository and compatibility ownership
|
||||
|
||||
- Protocol adds a reusable `DisplayMode` object and optional request/response fields while
|
||||
retaining control wire version 1. Generated Go represents optional referenced objects as
|
||||
pointers so `nil` is omitted; Rust/Swift use optionals. A legacy request receives the
|
||||
legacy response shape, while a display-aware request requires `display.request.v1` and a
|
||||
display-aware manifest contains the accepted value.
|
||||
- Protocol registers `display.request.v1`, `input.absolute.v1`, and `input.scroll.v1` and
|
||||
extends VGI1 only behind those negotiated features. Old gateways continue to reject
|
||||
unknown kinds; clients therefore never send an unadvertised kind.
|
||||
- Protobuf remains unchanged unless an observed consumer or verification gate proves that
|
||||
the JSON control route actually depends on it. This avoids an unrelated second contract.
|
||||
- A verified-unused immutable Phase 3D Protocol RC is frozen before Server/Data pins advance
|
||||
together. No sibling `replace` or local wire fork is committed.
|
||||
|
||||
### 2. Server-owned display decision
|
||||
|
||||
- Broker sessions gain nullable requested/effective width, height, and FPS columns plus the
|
||||
immutable policy-version identity needed to replay allocation/reconnect. Dedicated columns
|
||||
keep the decision queryable and avoid overloading the existing bandwidth policy JSON.
|
||||
- Request validation accepts width 320..16384, height 200..8640, and FPS 1..240. Requested
|
||||
mode participates in every idempotency identity, including waiting sessions.
|
||||
- Allocation selects the machine, resolves the immutable machine/pool/global policy, computes
|
||||
the accepted mode, and atomically persists the allocation and accepted values. Reconnect
|
||||
reuses the persisted result; it does not re-clamp against later policy.
|
||||
- Clamp is proportional and deterministic:
|
||||
`scale = min(policyWidth/requestWidth, policyHeight/requestHeight, 1)`;
|
||||
`effectiveWidth = floorToEven(requestWidth * scale)`;
|
||||
`effectiveHeight = floorToEven(requestHeight * scale)`;
|
||||
`effectiveFPS = min(requestedFPS, policyFPS)`.
|
||||
- Provider work uses the persisted effective dimensions/FPS and the selected immutable
|
||||
policy's codec/bitrate/audio. Legacy sessions retain today's exact policy dimensions.
|
||||
|
||||
### 3. Provider-neutral input
|
||||
|
||||
- VGI1 kind `0x06` has exactly eight body bytes: big-endian unsigned `x`, `y`, viewport
|
||||
width, and viewport height. Width/height must be nonzero; x < width and y < height.
|
||||
- VGI1 kind `0x07` has exactly four body bytes: big-endian signed 16-bit vertical and
|
||||
horizontal high-resolution scroll deltas.
|
||||
- Protocol docs, fixtures, Go/Rust/Swift classifiers, Data encode/decode, fuzzing, transport,
|
||||
and Apollo translation share the same vectors. Apollo packet details remain private to the
|
||||
adapter and must be justified by pinned reference source before implementation.
|
||||
- Absolute/scroll events do not enter the pressed-state ledger. Keys, buttons, and controllers
|
||||
continue to release through the existing ledger on every authority/lifecycle exit.
|
||||
|
||||
### 4. Native workspace, display discovery, and input ownership
|
||||
|
||||
- The client uses `NavigationSplitView`, native controls/materials, and standard macOS 26
|
||||
Liquid Glass APIs conditionally. macOS 15/14 retain identical hierarchy with native
|
||||
materials; no custom glass framework is introduced.
|
||||
- Desktop cards remain `328 x 205 pt`; an adaptive grid only changes column count. Card
|
||||
actions remain accessible without hover, and no direct-connect button or endpoint entry is
|
||||
added.
|
||||
- Automatic mode reads physical pixels for the screen where the session window opens and
|
||||
uses its maximum FPS. A defensible notch-safe built-in mode is preferred; otherwise Full
|
||||
Native is disclosed. A display move offers a new-session reconnect and never mutates the
|
||||
active stream.
|
||||
- The renderer aspect-fits. Absolute coordinates originate only inside the rendered viewport;
|
||||
letterbox bars produce no pointer event.
|
||||
- Native `NSWindow` fullscreen preserves top-edge system UI in absolute mode. Relative mode
|
||||
hides/captures the cursor. Reserved mode-toggle and emergency-release chords are handled
|
||||
before mapping and never cross the core boundary. Mode switches release pressed input and
|
||||
clamp cursor restoration to the rendered viewport.
|
||||
|
||||
### 5. State, Rust core, and platform boundaries
|
||||
|
||||
- Swift actors own authentication, resources, brokerage, streaming, and settings; immutable
|
||||
projections reach `MainActor` views. One bridge owns every C pointer/callback/lifetime.
|
||||
- The Rust core owns tunnel negotiation, authenticated framing, packet reconstruction,
|
||||
encoded media delivery, input encoding, statistics, cancellation, and structured errors.
|
||||
Apple frameworks own decode/render/audio/device/input capture and product state.
|
||||
- The C ABI uses fixed-width values, explicit lengths, opaque handles, sized/versioned tables,
|
||||
a declared callback queue, caught panics, cancellation, and late-callback/destroy rules.
|
||||
- Fakes cover every external boundary before real core/media integration. No speculative
|
||||
adapter/factory/plugin layer is added beyond interfaces already needed for deterministic
|
||||
tests.
|
||||
|
||||
### 6. Preview and diagnostic privacy
|
||||
|
||||
- Stable desktop previews are downscaled to `656 x 410`, stored in the sandbox cache as mode
|
||||
`0600`, and written only after an active session ends cleanly. Failed launch retains the
|
||||
prior preview. Pool cards use generic art.
|
||||
- Logout or entitlement loss clears affected previews. Hide/Clear settings are explicit.
|
||||
Backup, telemetry, OSLog, crashes, support bundles, and default diagnostics exclude preview
|
||||
and raw media bytes.
|
||||
- Diagnostics are allowlisted structured state/correlation/performance summaries; tokens,
|
||||
grants, provider endpoints, media, input, clipboard, and Windows secrets never enter them.
|
||||
|
||||
### 7. Delivery and evidence
|
||||
|
||||
- Land capability-sized commits in order: Planning/OpenSpec, Protocol, Server, gateway input,
|
||||
fake-core native shell, Rust/core integration, platform media, then full qualification.
|
||||
- Every nontrivial boundary starts with a focused failing test/vector and ends with the
|
||||
narrow affected gate; one complete clean-source gate runs only after freeze.
|
||||
- macOS 26/15/14 native behavior, accessibility, lifecycle, privacy, and platform media require
|
||||
real target evidence. The owner later runs the only live Apollo/SudoMaker acceptance.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Strict legacy decoders reject additive response fields] -> Emit display fields only for a
|
||||
negotiated display-aware request; retain legacy shapes and cross-version fixtures.
|
||||
- [Requested dimensions exceed policy or change aspect] -> Apply one Server-owned
|
||||
proportional/even clamp, persist it atomically, and disclose both values.
|
||||
- [Absolute coordinates mismatch presentation] -> Normalize against the rendered viewport,
|
||||
reject letterbox coordinates, and test edge/scale/display cases.
|
||||
- [Relative capture strands local input] -> Keep an unremappable emergency release, release
|
||||
before every mode/authority transition, and test focus/sleep/cancel/revocation paths.
|
||||
- [Preview bytes leak user media] -> Minimize one local file, mode `0600`, clean-session-only
|
||||
writes, lifecycle clearing, and explicit exclusion/secret-canary tests.
|
||||
- [Apollo input semantics are guessed] -> Stop until the pinned provider source establishes
|
||||
the exact packet; do not encode provider assumptions into VGI.
|
||||
- [macOS API rendering differs by release/accessibility setting] -> Test deterministic
|
||||
geometry and state automatically; use bounded manual material review without snapshots of
|
||||
OS-owned pixels as the sole gate.
|
||||
- [The full client scope is large] -> Keep serial capability commits and stop at the first
|
||||
failed contract/environment gate rather than introducing fallbacks or partial claims.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Freeze Planning/OpenSpec and visual references.
|
||||
2. Implement/freeze an immutable Protocol RC with legacy and new feature fixtures.
|
||||
3. Apply the forward-only Server migration and update Server/Data Protocol pins together.
|
||||
4. Deploy no schema or runtime automatically; validate clean install/upgrade/legacy rows and
|
||||
gateway fixtures locally/private CI first.
|
||||
5. Build the native shell against fakes, then integrate the frozen core/gateway surfaces.
|
||||
6. Roll back application binaries only while schema compatibility permits; nullable additive
|
||||
fields preserve legacy row behavior. Never down-migrate or rewrite applied migrations.
|
||||
7. Keep signing, publication, deployment, promotion, and live owner E2E under separate
|
||||
authorization.
|
||||
|
||||
## Open Questions
|
||||
|
||||
None at proposal time. Exact Apollo absolute-pointer/scroll packet vectors must be established
|
||||
from the approved pinned source before the adapter step; absence of that evidence is an
|
||||
implementation hard stop, not a design choice to guess.
|
||||
@@ -0,0 +1,65 @@
|
||||
## Why
|
||||
|
||||
Phase 3C has frozen the gateway and Connection Server image-engineering baseline, so the first
|
||||
native VerseVDI endpoint can now be built against an immutable gateway-only authority model.
|
||||
Phase 3D must add the user-facing macOS workspace, exact display negotiation, safe native
|
||||
input, and streaming core without exposing Apollo/provider details or weakening the existing
|
||||
control and transport boundaries.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Build the Apple-Silicon SwiftUI/AppKit client and platform-neutral Rust Streaming Core
|
||||
behind one sized/versioned C ABI (`P3D-001`–`P3D-031`).
|
||||
- Implement the reviewed native workspace, fixed preview cards, Favorites, search/sort,
|
||||
settings, accessibility, and privacy-bounded desktop previews (`P3D-032`, `P3D-037`).
|
||||
- Add feature-gated requested/effective display modes, Server-owned policy clamping,
|
||||
client display detection/disclosure, and explicit reconnect-on-display-change behavior
|
||||
(`P3D-033`–`P3D-034`).
|
||||
- Add provider-neutral absolute pointer and high-resolution scroll input while preserving
|
||||
relative input, release-all, reserved local escape chords, letterbox exclusion, and scoped
|
||||
keyboard mapping (`P3D-035`–`P3D-036`).
|
||||
- Keep authentication, manifests, media, input, and clipboard on the authenticated
|
||||
gateway-only route. The client receives no provider endpoint, provider credential, or
|
||||
Windows credential outside normal encrypted input.
|
||||
- Defer remote apps, manual PC/direct-provider connections, live display renegotiation,
|
||||
multi-monitor remote topology, HDR, microphone, file/folder redirection, image clipboard,
|
||||
macros, Intel, public release, and provider-specific client UI.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `macos-native-foundation`: Platform baseline, Swift/Rust/C ABI ownership, authentication,
|
||||
resource/broker authority, gateway-only manifest validation, and fake-core-first delivery.
|
||||
- `macos-media-presentation`: Registered media dispatch, hardware video presentation, audio,
|
||||
bounded queues, and observable quality without media persistence.
|
||||
- `macos-input-control`: Provider-neutral keyboard, pointer, scroll, controller, text
|
||||
clipboard, mappings, reserved local chords, and release-all behavior.
|
||||
- `macos-lifecycle-quality`: Interruption, reconnect, accessibility, privacy, diagnostics,
|
||||
packaging, rollback, uninstall, and candidate qualification behavior.
|
||||
- `macos-workspace`: Screenshot-backed workspace/card/settings interactions, Favorites,
|
||||
search/sort, and privacy-bounded previews.
|
||||
- `session-display-mode`: Feature-gated requested/effective display mode, Server policy
|
||||
clamping, client detection/disclosure, and owner Apollo IDD acceptance.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
None. Existing Phase 3C gateway capabilities remain unchanged; this change consumes and
|
||||
extends their separately owned Protocol surfaces without redefining their requirements.
|
||||
|
||||
## Impact
|
||||
|
||||
- **Protocol repository:** additive strict JSON display objects, feature identifiers, VGI1
|
||||
absolute/scroll grammar, cross-language bindings, fixtures, and compatibility tests.
|
||||
- **Connection Server:** additive broker-session migration/query fields, request identity,
|
||||
allocation transaction/clamp, manifest disclosure, and provider-work projection.
|
||||
- **Data Plane:** Protocol pin update, Go gateway input validation/Apollo translation, Rust
|
||||
core/C ABI/XCFramework, SwiftUI/AppKit client, tests, documentation, and private build
|
||||
configuration.
|
||||
- **Provenance and license boundary:** Apollo, Moonlight, Microsoft Windows App, and Omnissa
|
||||
material remains reference evidence only. No proprietary Server or Planning content is
|
||||
copied into the GPLv3 Data Plane.
|
||||
- **Hard stops:** unknown provider packet semantics, incompatible legacy response behavior,
|
||||
direct-provider routing, secret/media/input persistence, unsupported platform safety, or
|
||||
a failed deterministic gate blocks the affected capability. Live Apollo/macOS/firewall
|
||||
interoperability remains `deferred-owner-e2e` until the owner runs the frozen candidate.
|
||||
@@ -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
|
||||
@@ -0,0 +1,69 @@
|
||||
## 1. Contract Freeze
|
||||
|
||||
- [ ] 1.1 Add Protocol `DisplayMode`, negotiated display fields/features, VGI1 absolute/scroll grammar, strict valid/invalid cross-language fixtures, and optional-field omission regressions
|
||||
- [ ] 1.2 Regenerate Go/Rust/Swift outputs twice, pass Protocol `make verify`, freeze a verified-unused immutable Phase 3D RC, and record its fixture/generated hashes
|
||||
- [ ] 1.3 Update Server and Data Plane to the exact Protocol RC without a filesystem replacement and prove clean-cache module resolution before consumer implementation
|
||||
|
||||
## 2. Server Display Authority
|
||||
|
||||
- [ ] 2.1 Add the forward-only nullable requested/effective display and policy-version migration plus clean-install/upgrade/schema/grant tests
|
||||
- [ ] 2.2 Add strict request validation and requested-mode idempotency identity, including waiting-session mismatch regressions
|
||||
- [ ] 2.3 Implement one proportional even-pixel/FPS clamp at allocation and atomically persist the immutable requested/effective decision
|
||||
- [ ] 2.4 Disclose display-aware broker/manifest values only to negotiated clients, preserve legacy response shapes, and reuse the persisted mode on reconnect
|
||||
- [ ] 2.5 Project persisted effective width/height/FPS through existing provider work with selected immutable codec/bitrate/audio and pass focused repository/E2E tests
|
||||
|
||||
## 3. Gateway Input Translation
|
||||
|
||||
- [ ] 3.1 Add red VGI absolute/scroll encode/decode/bounds/fuzz/transport tests and prove unadvertised kinds fail before provider translation
|
||||
- [ ] 3.2 Establish exact Apollo absolute-pointer and scroll vectors from the approved pinned source; hard-stop without that evidence
|
||||
- [ ] 3.3 Implement the smallest provider-neutral VGI validation and Apollo adapter translation without adding pressed-state or direct-provider surfaces
|
||||
- [ ] 3.4 Pass focused input vectors/fuzz/transport/fake-provider tests, then one affected Data Plane `make verify`
|
||||
|
||||
## 4. Rust Core and Stable ABI
|
||||
|
||||
- [ ] 4.1 Pin Rust toolchain/dependencies and add minimal core modules with bounded fake transport, Protocol fixtures, cancellation, errors, queues, and redaction
|
||||
- [ ] 4.2 Specify and test the sized/versioned C ABI ownership, callback thread, panic, reentrancy, cancellation, late-callback, and destroy contracts before implementation
|
||||
- [ ] 4.3 Implement gateway-only manifest/QUIC/framing/media/input behavior against fixtures with no provider endpoint, decoder, renderer, transcode, or product-auth path
|
||||
- [ ] 4.4 Package deterministic Apple-Silicon static XCFramework output and one Swift bridge; pass Cargo format/Clippy/tests plus applicable fuzz/Miri/sanitizer and ABI stress gates
|
||||
|
||||
## 5. Native Foundation Against Fakes
|
||||
|
||||
- [ ] 5.1 Reconcile the Xcode project to macOS 14 deployment, Xcode 26.6/Swift 6.3 Swift-6 mode, Apple Silicon, and conditional macOS 26 APIs
|
||||
- [ ] 5.2 Implement isolated auth/resource/broker/stream/settings owners and deterministic control/event/core/credential/platform fakes with unit tests before views
|
||||
- [ ] 5.3 Implement local login, device proof, serialized rotating refresh, Keychain/memory-only policy, logout/revocation, and anti-enumeration tests
|
||||
- [ ] 5.4 Implement resource/broker/event-gap/relaunch/idempotency reconciliation and cross-subject fixture negatives
|
||||
|
||||
## 6. Workspace and Display UX
|
||||
|
||||
- [ ] 6.1 Build the screenshot-backed Favorites/Desktops/Pools/Settings shell with fixed `328 x 205 pt` cards, adaptive columns, safe truncation, native focus/VoiceOver, and no Apps/Add-PC/direct endpoint surfaces
|
||||
- [ ] 6.2 Add global and resource Automatic/preset/Custom/Full Native settings, physical-pixel/FPS detection, notch-safe disclosure, and requested/accepted projections with deterministic display fakes
|
||||
- [ ] 6.3 Add aspect-fit viewport math, letterbox pointer exclusion, display-move reconnect offer, and new-session/idempotency behavior tests
|
||||
- [ ] 6.4 Pass geometry/hierarchy/visibility/responsive/accessibility automation and bounded macOS 26/15/14 native-material review
|
||||
|
||||
## 7. Native Input and Preview Privacy
|
||||
|
||||
- [ ] 7.1 Implement absolute and relative pointer capture with native fullscreen, top-edge local controls, pressed-state release, bounded cursor restore, HUD, and unremappable local toggle/emergency chords
|
||||
- [ ] 7.2 Implement physical/logical and language-aware global/resource keyboard mappings, deterministic conflicts/precedence/modifier order, add/remove/enable/restore, and no-macro/reserved-chord negatives
|
||||
- [ ] 7.3 Implement normalized controller layouts and bounded text-only clipboard with file/binary/oversize/loop/permission negatives
|
||||
- [ ] 7.4 Implement atomic clean-session-only mode-`0600` desktop previews, generic pool art, hide/clear/logout/entitlement behavior, and backup/log/crash/support exclusion tests
|
||||
|
||||
## 8. Platform Media and Lifecycle
|
||||
|
||||
- [ ] 8.1 Implement registered VideoToolbox decode and Metal aspect-fit presentation with bounded latency-first queues, configuration/IDR/discontinuity/device-loss tests, and no pixel persistence
|
||||
- [ ] 8.2 Implement bounded CoreAudio playback/synchronization with device/format/sleep/cancel tests and retained timing summaries without audio persistence
|
||||
- [ ] 8.3 Implement deterministic sleep/wake, foreground/background, display/audio/controller/network change, server/gateway restart, cancellation, reconnect, and release-all behavior
|
||||
- [ ] 8.4 Complete accessible errors/actions, allowlisted diagnostics, privacy manifest, secret-canary support-bundle tests, and 100-cycle ownership/leak stress
|
||||
|
||||
## 9. Real-Core Integration
|
||||
|
||||
- [ ] 9.1 Replace fake-core session transport only at the existing client seam and pass the same state/UI/lifecycle suites unchanged
|
||||
- [ ] 9.2 Run shared Protocol manifest/framing/media/input fixtures through Go, Rust, Swift, gateway transport, and fake Apollo without payload or provider-detail leakage
|
||||
- [ ] 9.3 Pass fixture-backed gateway-only video/audio/input/reconnect/cancel/revocation integration and reject every direct-route/provider-field/downgrade case
|
||||
|
||||
## 10. Freeze and Qualification
|
||||
|
||||
- [ ] 10.1 Freeze exact source, Protocol/core artifacts, locks, settings, Xcode/toolchain, fake/provider fixtures, and environment; any change invalidates only its affected evidence plus the final gate
|
||||
- [ ] 10.2 Run the single final clean-source Protocol `make verify`, Server generated-SQL/OpenSpec/full serial Go suite, Data `make verify`/race/resource gates, Cargo gates, and Swift/XCTest/XCUITest/accessibility suites
|
||||
- [ ] 10.3 Qualify macOS 26/15/14 Apple Silicon platform behavior, lifecycle, performance/energy, privacy, uninstall/rollback preparation, and clean checkout; keep signing/publication/deployment/promotion separately authorized
|
||||
- [ ] 10.4 Retain versions, hashes, logs, inventories, redacted metrics, failures, and exact requirement mapping; archive this change only when canonical specs match
|
||||
- [ ] 10.5 Package but do not execute the owner E2E that binds Automatic/Custom requested and accepted width/height/FPS to the Apollo/SudoMaker virtual display through the gateway-only route; retain it as `deferred-owner-e2e`
|
||||
Reference in New Issue
Block a user