Parent tracking issue: #141. Phase 7 of 11.
Objective
Implement explicit visible/hidden requests with durable controller/connector reconciliation and per-target exclusivity.
Scope
Validate protocol/capabilities, current host/config/account binding, permissions and workspace before persisting and submitting immutable UUID/digest requests. Permission and visibility are independent. Visible is default; create a NEW app-visible durable thread or continue a specified app-owned one through the version-verified route from #146. Never resume a thread through a second writer to simulate app ownership. Existing app permissions are reported as inherited unless enforcement is proven.
Hidden uses ephemeral CLI execution with no app conversation/open request. Local --ephemeral help only guarantees no persisted session files; target-version absence from the app is a tested acceptance condition. Each hidden follow-up is a new explicit task, not a resumable invisible app chat. Hidden describes chat visibility, not absence of OS effects, logs or provider retention. Expose only capabilities compatible with hidden execution and refuse unavailable app-only tools; do not pretend arbitrary prompt intent can be fully classified in advance. No silent conversion to visible.
Acquire a durable per-target/account lock in the remote connector, including alias duplicates and multiple controllers. Serialize one desktop user resource; handle account/session collisions explicitly. Use atomic admission, persisted immutable receipts and process-instance identity. Never create a new UUID automatically after uncertain send. Cover the crash between receipt creation, process start, queue enqueue and acknowledgment: preserve uncertain state for reconciliation, not fabricated exactly-once guarantees. Nonterminal uncertainty does not free the slot. These locks govern connector submissions, not a person or another tool using the PC/app; detect app-owned active turns before enqueue and report interference rather than claiming exclusive desktop control.
Page or cursor through history to correlate request markers/turn IDs; the prototype's last-10-turn query is insufficient. Distinguish local wait expiry from remote timeout and cancellation requested from confirmed termination. Never kill the whole app or a reused PID. Protect status/cancel during controller audit outage. Keep provider completion and semantic outcome separate; exit 0 or prose alone does not prove task completion. Bound frame/log size and sanitize untrusted remote output.
Controller sleep/logout/disconnect may stop observation while the remote connector continues. On reconnect, reconcile durable request IDs and remote process/turn evidence before allowing new admission. Report stale last-observed status; lack of a heartbeat is not proof that remote execution ended. Cancellation capability is mode-specific: unavailable app interruption stays clearly unavailable/pending instead of promising an effective Cancel action.
Acceptance criteria
Validation and evidence level
Go and connector integration tests, controlled disconnect/crash fixtures, vet/lint/race and focused real Windows mode checks. #150 is the final two-PC release gate.
Dependencies and risks
Depends on #143, #144, #145, #146.
Out of scope
Exactly-once arbitrary side effects, automatic replay with a fresh ID or shell passthrough capability.
Delivery boundary
Parent #141 defines the shared product contract. This issue owns one reviewable change and its own validation; do not close the parent from its PR. Keep source implementation, automated checks, installation and observed client behavior distinct. No secrets, real prompts, account identifiers or unredacted device logs belong in GitHub evidence.
Parent tracking issue: #141. Phase 7 of 11.
Objective
Implement explicit visible/hidden requests with durable controller/connector reconciliation and per-target exclusivity.
Scope
Validate protocol/capabilities, current host/config/account binding, permissions and workspace before persisting and submitting immutable UUID/digest requests. Permission and visibility are independent. Visible is default; create a NEW app-visible durable thread or continue a specified app-owned one through the version-verified route from #146. Never resume a thread through a second writer to simulate app ownership. Existing app permissions are reported as inherited unless enforcement is proven.
Hidden uses ephemeral CLI execution with no app conversation/open request. Local --ephemeral help only guarantees no persisted session files; target-version absence from the app is a tested acceptance condition. Each hidden follow-up is a new explicit task, not a resumable invisible app chat. Hidden describes chat visibility, not absence of OS effects, logs or provider retention. Expose only capabilities compatible with hidden execution and refuse unavailable app-only tools; do not pretend arbitrary prompt intent can be fully classified in advance. No silent conversion to visible.
Acquire a durable per-target/account lock in the remote connector, including alias duplicates and multiple controllers. Serialize one desktop user resource; handle account/session collisions explicitly. Use atomic admission, persisted immutable receipts and process-instance identity. Never create a new UUID automatically after uncertain send. Cover the crash between receipt creation, process start, queue enqueue and acknowledgment: preserve uncertain state for reconciliation, not fabricated exactly-once guarantees. Nonterminal uncertainty does not free the slot. These locks govern connector submissions, not a person or another tool using the PC/app; detect app-owned active turns before enqueue and report interference rather than claiming exclusive desktop control.
Page or cursor through history to correlate request markers/turn IDs; the prototype's last-10-turn query is insufficient. Distinguish local wait expiry from remote timeout and cancellation requested from confirmed termination. Never kill the whole app or a reused PID. Protect status/cancel during controller audit outage. Keep provider completion and semantic outcome separate; exit 0 or prose alone does not prove task completion. Bound frame/log size and sanitize untrusted remote output.
Controller sleep/logout/disconnect may stop observation while the remote connector continues. On reconnect, reconcile durable request IDs and remote process/turn evidence before allowing new admission. Report stale last-observed status; lack of a heartbeat is not proof that remote execution ended. Cancellation capability is mode-specific: unavailable app interruption stays clearly unavailable/pending instead of promising an effective Cancel action.
Acceptance criteria
Validation and evidence level
Go and connector integration tests, controlled disconnect/crash fixtures, vet/lint/race and focused real Windows mode checks. #150 is the final two-PC release gate.
Dependencies and risks
Depends on #143, #144, #145, #146.
Out of scope
Exactly-once arbitrary side effects, automatic replay with a fresh ID or shell passthrough capability.
Delivery boundary
Parent #141 defines the shared product contract. This issue owns one reviewable change and its own validation; do not close the parent from its PR. Keep source implementation, automated checks, installation and observed client behavior distinct. No secrets, real prompts, account identifiers or unredacted device logs belong in GitHub evidence.