# Composer Stop and task controls The empty composer shows **Stop** while this task has a live execution and the viewer can manage task controls. Stop creates the same manual pause hold as **Pause work** / **Pause subtree** in the task menu. A parent pause includes its descendants. Cancellation remains a separate menu action. Text (after trimming) or attachments switch the button back to Send. Uploading and failed attachments retain their existing restrictions. Keyboard submission never invokes Stop. Queued-message editing and structured interactions keep their existing actions, and text entered while stopping remains in the draft. Pause dispatches without a preview dialog or reason. The button stays pending while affected run state is checked; native cancellation must be acknowledged. A saved hold with unconfirmed termination produces an error rather than a success claim. The cancellation dialog requires a valid preview and excludes terminal tasks. Resume/restore retain the optional wake-agents checkbox. ## Resume and execution recovery Resume releases a hold. Waking agents is optional and only applies to tasks in `todo`, `in_progress`, or `in_review`; parked and terminal tasks stay untouched. The current execution-recovery policy requires verified outcomes before a stopped provider can restart. If any affected task still needs that reconciliation, Resume with wake enabled returns an inline error and preserves the pause. The operator can release the pause without waking agents, then use the existing execution-reconciliation flow after reviewing the stopped run. Resume does not claim that unknown provider actions completed or were never performed. A completed release remains successful if a best-effort wake fails. Its response includes optional `wakeFailures`, the page reports them inline, and remaining eligible tasks still receive their wake requests. No new endpoint is introduced. The deterministic E2E fixtures prove interruption, then record their known lack of external effects through the existing reconciliation API before continuing. ## Quiet task feedback The visible task/subtree does not produce duplicate state toasts. Its live notifications are suppressed while foregrounded, including descendant runs; unrelated and background work retains notifications. Tree-control results use inline state, and failures stay in the composer, page, or confirmation dialog. The pause row contains only “Subtree is paused.” (or “Task is paused.”) and Resume. Expected cancellation uses a muted gray disclosure with optional details. This is recorded as a product rule in `DESIGN.md`. The follow-up passed 213 focused tests, both isolated runner E2E journeys (including no-toast assertions), UI typecheck/build, token gates, and Storybook build. Paused, expanded cancellation, Stop without toasts, mobile, and light stories were inspected in the browser. ## Storybook Run from the worktree: ```sh pnpm --filter @paperclipai/ui exec storybook dev -p 6016 -c storybook/.storybook --no-open ``` Open `http://localhost:6016/?path=/story/tasks-execution-controls--running-empty`. The `Tasks / Execution Controls` stories compose the production composer and menu/dialog controls together. They cover text switching, attachment-only, idle, stopping, paused, errors, cancellation preview/loading, and mobile/light presentations. The Storybook state transitions simulate requests; runner verification belongs to the isolated browser suite below. ## Automated verification ```sh pnpm exec vitest run --project @paperclipai/ui ui/src/components/task-chat/TaskChatComposer.test.tsx ui/src/components/TaskChatThread.test.tsx ui/src/pages/IssueDetail.test.tsx ui/src/lib/wait-for-stopped-runs.test.ts pnpm exec vitest run --project @paperclipai/server server/src/__tests__/issue-tree-control-routes.test.ts pnpm check:token-gates pnpm build-storybook pnpm -r typecheck pnpm test:run pnpm build ``` The component/page tests cover whitespace, attachments and upload restrictions, permissions, keyboard submission, queue edits, duplicate clicks, draft preservation, shared pause requests, compact cancellation, and visible errors. Stop verification tests include continued execution, native acknowledgment, network failures, and hung status requests. Route tests cover pause dispatch, authorization, cancellation, and opt-in resume wakeups with terminal/company exclusions. ## Isolated browser acceptance Legacy process coverage needs no provider credentials: ```sh pnpm exec playwright test --config tests/e2e/playwright-composer-stop.config.ts ``` To include native execution, build the real runner and deterministic Codex protocol fixture from this checkout, then point the suite at their absolute paths: ```sh cargo build --manifest-path packages/paperclip-runner/runner/Cargo.toml --bin paperclip-runnerd --bin fake-codex-app-server PAPERCLIP_STOP_FAKE_CODEX="$PWD/packages/paperclip-runner/runner/target/debug/fake-codex-app-server" \ PAPERCLIP_RUNNER_BINARY="$PWD/packages/paperclip-runner/runner/target/debug/paperclip-runnerd" \ pnpm exec playwright test --config tests/e2e/playwright-composer-stop.config.ts ``` The suite boots a disposable local-trusted instance on port 3199 (override with `PAPERCLIP_E2E_PORT`). It never attaches to an existing server. Native coverage is explicitly skipped without the fixture; it must not use a logged-in provider as a fallback. Test companies are archived during cleanup. For each runner, the journey starts a parent, child, and unrelated task, plus a terminal child. It sends while running and verifies the durable queue, clicks Stop, verifies interruption and the persisted hold, and observes three ten-second scheduler intervals without continuation. It resumes with wakeups, pauses from the menu, dismisses and then confirms cancellation, and verifies terminal-task exclusions and unrelated execution. Timing attachments distinguish click-to-request from request-to-observed-stop. Native proof requires provider `turn/start` before the click, `turn/interrupt` after it, and durable cancellation acknowledgment. Legacy proof checks the actual parent and child PIDs have exited with a one-second configured grace period. HTTP success alone is insufficient. For a release with real providers, repeat while an actual long-running tool is active, confirm the tool's own process/output stops, and verify a queued message is consumed on continuation. The deterministic provider exercises the native transport and cancellation protocol, not external provider behavior or every tool's process cleanup. Preserve these limits in any test report. ## Recorded acceptance run (2026-09-09) Both isolated browser journeys passed. Legacy Stop dispatched after 214 ms and observed both runs stopped 155 ms after dispatch; native dispatched after 212 ms and observed stop 320 ms later. These are single local observations including browser automation overhead, not latency guarantees. Native used the real runnerd and the repository's deterministic Codex protocol fixture. Real hosted provider/tool cleanup remains a release acceptance check. Repository typecheck, production build, Storybook build, token gates, targeted UI tests, and tree-control route tests passed. The broad UI run passed 5,491 tests with one five-second timeout in an unchanged `IssuesList` test; rerunning that file passed all 46 tests. The repository test run encountered 17 failures in unchanged suites, all reproduced in the original checkout: - `server/src/__tests__/workspace-runtime.test.ts`: 2 failures. - `server/src/services/workspace-runtime-exposure.test.ts`: 7 failures. - `server/src/__tests__/execution-workspace-runtime-control-conflict.test.ts`: 4 failures. - `server/src/__tests__/workspace-instance-cleanup.test.ts`: 1 failure. - `server/src/__tests__/company-skills.test.ts`: 2 failures. - `server/src/__tests__/worktree-seed-server-spawn.test.ts`: 1 failure. These baseline failures prevent a green repository-wide test result. The broad run was stopped after more than 30 minutes in its serial server lane once these failures were independently reproduced. Later full-suite groups did not run. The full UI suite and the feature's server route suite were run separately as described above.