feat(desktop): real-use Desktop product path (D1-D6 complete on Windows) - #37
Open
AllureCurtain wants to merge 7 commits into
Open
feat(desktop): real-use Desktop product path (D1-D6 complete on Windows)#37AllureCurtain wants to merge 7 commits into
AllureCurtain wants to merge 7 commits into
Conversation
…use-final # Conflicts: # docs/runtime/implementation-status.md
Pre-existing clippy::drain_collect failure on origin/main blocked cargo clippy --workspace --all-targets -- -D warnings, which the A1 deterministic gate requires. std::mem::take is semantically identical for Vec<StreamEvent>: the source is left empty and the elements move into the new binding without a second allocation. Not Desktop-scope work; applied only to unblock the workspace gate.
Desktop D2 previously stopped at a safe keyring receipt boundary because the shared onboarding contract was not yet on main. That contract landed in cc9799f, so Desktop now consumes it instead of maintaining a private credential path. Shared-service integration: - add apps/api/src/product/provider_onboarding.rs, an in-process facade over rove_app_bootstrap::ProviderOnboardingService that keeps keyring storage, real inventory probing, Catalog CAS publication, and failure compensation owned by the shared service; - expose ApiState::onboard_product_provider / probe_product_provider / use_product_provider. The credential is a separate non-serializable &str argument, so it cannot become an HTTP or WebView payload. There is no HTTP route that accepts a provider secret; - project the published profile into ProductStore as an identity stub only. A projection failure after a successful publication returns the typed provider_product_projection code and requests reconciliation rather than diverging from the shared Catalog. Desktop host: - the Tauri host holds the embedded ApiState and reuses it for the new provider_credential_prompt, provider_profile_probe, and provider_profile_use commands; - the Windows native prompt collects the secret, sets CREDUI_FLAGS_DO_NOT_PERSIST so the dialog cannot persist credentials on its own, hands the value straight to the shared service, and zeroizes both the wide buffers and the decoded String on every path; - remove the Desktop-private com.rove.agent.provider keyring receipt and drop the now-unused keyring dependency; - no new Desktop event type, emit, or listener: canonical events remain the only projection source. Web surface: - desktop-commands.ts validates and normalizes profile id, label, API base, model, and revision, and rejects non-remote provider types and browser use before invoking; - Settings splits by host. Desktop renders native onboarding, probe, Catalog publication, refresh, and selection with a SiliconFlow preset; the browser keeps the existing env/file/reference CRUD and never gets a secret path; - add refreshProviderProfiles and typed keyring/reconciliation/ model-unavailable error copy. Verification (real exit codes): cargo fmt --all --check 0 cargo clippy --workspace --all-targets -- -D warnings 0 cargo test --workspace 0 (1567 passed, 0 failed) cargo test -p rove-api 0 (137) cargo test -p rove-desktop --all-targets 0 (13 lib + 3 integration) pnpm test 0 (37 files / 255 tests) pnpm typecheck 0 pnpm build:desktop 0 Negative coverage asserts the secret never appears in a serialized receipt, that failures are typed and redacted, and that probe/use metadata stays bounded and secret-free. D6 is NOT met. Installation, Start menu launch, the credentialed SiliconFlow two-turn run, and restart restoration remain unverified: the NSIS package is perMachine and installation needs UAC, which this session did not have. The implementation plan stays Partially Implemented and no document claims Desktop real-use completion.
Update Desktop status to match the code now on this branch, without overclaiming. - desktop-real-use.md: the Shared Dependency section is resolved (cc9799f is contained in origin/main at 8a4e141, which this branch merged), the contract section describes the in-process facade and the Desktop/browser Settings split, and the verified-checks block records real exit codes including the deterministic A1 gate; - split Open Gates into what closed on this branch and what still blocks a real-use claim, and state the UAC/perMachine reason installation was not run; - implementation-status.md, acceptance-matrix.md, release-readiness.md: replace the "waiting for the shared contract" wording with the integrated state plus the named test evidence, and keep installation, the credentialed SiliconFlow run, restart restoration, and D6 unverified; - implementation plan: mark the D6 items that deterministic evidence supports, keep every installed-state item unchecked, and record the blocking reason. Status stays Partially Implemented; - README: document the Desktop native provider onboarding path and point at the unverified-installation caveat. Playwright pnpm test:e2e was not run on this branch and remains part of the final A1 gate on main.
D6 now passes all nine items against the installed Desktop, launched from the Start menu, using the real SiliconFlow provider (openai / https://api.siliconflow.cn/v1 / deepseek-ai/DeepSeek-V3.2) with the key read only from the Windows keyring. No Fake provider, no temporary environment variable. Newly verified this pass: - uninstall/reinstall round trip, 10/10. Both NSIS packages are perMachine, so each direction runs as an elevated child; an unelevated session driving uninstall.exe fails with WinError 740. %APPDATA%\Rove stayed at 146 files / 11204219 bytes across all three stages, so uninstall preserves user data. - reinstall plus Start-menu relaunch restores workspace, all four sessions with their statuses, the provider profile as a keyring reference, and the terminal run binding of the successful real run. - SSE disconnect/reconnect, 5/5. after=40 resumed at exactly seq 41 and drained to 1148: no duplicate seqs, one run_completed, no gaps, one run per job. - restart recovery, 10/10, including artifact sha256 digests. /jobs/{id}/state returns 404 by design; terminal state comes from the durable report. Replaces the stale blocking note that claimed installation was impossible without an administrator session, and corrects the bundle-output path: the build redirected CARGO_TARGET_DIR to C: for disk space, so artifacts landed outside the in-repo target/release/bundle/. Records four product defects found while running the gate (needs_attention deadlock, project config never loaded on the API path, unreachable max_model_turns_per_step, product UI cannot select an agent profile). None are fixed here: section 6 forbids this branch from unilaterally changing the Core Agent loop, Provider wire protocol, or Tool Registry permissions. Remaining gaps stated honestly: the section 10.1 A gate still must run on merged main, Playwright e2e was not run here, and no screenshots were captured.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Delivers the D package of
docs/plans/2026-08-18-tui-desktop-real-use-final-implementation.md: the Windows Desktop product path, from install to a real Agent task equivalent to the TUI's.Desktop stays a thin Tauri host over the shared
rove-api, Runtime, ProductStore, Tool Registry, provider catalog, canonical events, and durable run state. No Agent loop, no Desktop-private event protocol, no unilateral change to the Core Agent loop, Provider wire protocol, or Tool Registry permissions.D1-D6 are complete on Windows. The final section 10.1 A gate is still outstanding and must run on merged
main.What's in the code
provider_credential_prompt: accepts only non-secret profile metadata, opens the native credential UI withCREDUI_FLAGS_DO_NOT_PERSIST, hands the raw credential straight to the shared onboarding service. The secret never reaches WebView state, ordinary config, logs, or traces.ProviderOnboardingService, so a Start-menu launch can configure and enable a provider with no terminal and no TOML.secure_onboarding_projects_catalog_identity_without_serializing_the_secret,probe_and_use_metadata_are_bounded_and_secret_free.D6 installed-state gate: 9/9 pass
Run 2026-08-26 against the real SiliconFlow provider —
openai,https://api.siliconflow.cn/v1,deepseek-ai/DeepSeek-V3.2— with the key read only from the Windows keyring. No Fake provider was used anywhere in this gate, and no temporary PowerShell environment variable was involved. Desktop was launched from the Start-menu shortcut every time.Details worth pulling out:
tool_use_id— not JSON embedded in assistant text. 6 approval events.after=40, resumed at exactly seq 41 and drained to 1148. No duplicate seqs, exactly onerun_completed, no gaps, one run id per job./jobs/{id}/statereturns 404 — the job registry is ephemeral by design, so terminal state is recovered from the durable report (status: success,termination_reason: final).%APPDATA%\Roveheld 146 files / 11204219 bytes at installed, uninstalled, and reinstalled states alike.perMachine. Install and uninstall must run as an elevated child; drivinguninstall.exefrom an unelevated session fails withWinError 740. The earlier claim that installation was impossible in a non-administrator session is now corrected in the docs.Evidence package at
C:\rove-evidence\d6-desktop\—manifest.jsonindexes every artifact with a sha256 digest, alongsidereport.json,tool-events.jsonl,transcript.md,session-diff.json,uninstall-round-trip.{json,md},provider-safe-identity.json,git-status.txt,checks.json. Generated, and deliberately not committed. Every file passed a leak scan (sk-,SILICONFLOW_API_KEY=,Bearer ey,api_key":") before being written.Deterministic checks
CARGO_TARGET_DIRwas redirected toC:\rove-build\desktop-real-use-finalbecause the D: volume was short on space, so bundles landed there rather than in the in-repotarget/release/bundle/. The docs previously stated the in-repo path unconditionally; that is now corrected.Product defects found, not fixed
Confirmed by observation while running the gate, each recorded in the manifest. Left unfixed on purpose — section 6 forbids this branch from unilaterally changing Core Agent loop, Provider wire protocol, or Tool Registry permission behaviour, and none of these are Desktop-owned:
needs_attentionis a terminal deadlock. A run ending without a final answer strands the session; there is no recovery endpoint.erroraccepts new turns,needs_attentiondoes not.project_config_loadedis hardcoded false even when theproject_configurationtrust capability has been granted.max_model_turns_per_step = 4is unreachable from Desktop. Hardcoded asDEFAULT_MAX_MODEL_TURNS_PER_STEPinruntime/src/planning/execution.rs.POST /jobshonours anagentfield, butCreateProductMessageRequestsetsdeny_unknown_fields, so the Desktop and Web product path cannot send one. Identical onmain; this branch adds no agent-selection frontend code.Test plan
pnpm test:e2e(Playwright) — not run here, part of the final A1 gate onmainmainafter both branches merge; this Windows-only, single-machine evidence does not substitute for it, nor for the A3 installed-state TUI gateScope notes
Windows-only. No release claim is made for unverified platforms. No existing tests were deleted; new tests are limited to the §8.2 golden path plus the security regressions above.