Initial public release of Warp.
Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# PRODUCT.md — Linear deeplink must not silently auto-submit prompts into the agent
|
||||
|
||||
**GitHub Issue:** [warpdotdev/warp-external#703](https://github.com/warpdotdev/warp-external/issues/703)
|
||||
**Figma:** none provided
|
||||
|
||||
## Summary
|
||||
|
||||
`warp://linear/work?prompt=<PROMPT>` currently drops the URI-supplied prompt straight into the user's active agent conversation and, when the user is already in fullscreen agent view, submits it to the LLM with no visible confirmation. The feature must instead always treat a Linear deeplink prompt as untrusted input: it should populate the agent input buffer, make it visually obvious where that prompt came from, and require an explicit user gesture before anything is sent to the model.
|
||||
|
||||
## Problem
|
||||
|
||||
The Linear "work on issue" deeplink is a trusted URI surface: the handler accepts any `prompt=` query value and forwards it verbatim into `enter_agent_view_for_new_conversation(prompt, LinearDeepLink, ...)`. Inside `try_enter_agent_view`, an auto-submit branch fires when the terminal was already in fullscreen agent view, even though `LinearDeepLink` is intentionally excluded from `should_autotrigger_request`'s allowlist. Combined with any of Warp's `warp://` dispatch primitives (macOS URL handler, Linux D-Bus, Windows named pipe, third-party openers), an attacker-controlled URL can silently inject a prompt — and, transitively, trigger auto-executed AI tools — in the currently authenticated user's session with no UI indication.
|
||||
|
||||
Users of Warp's AI features need to be able to trust that nothing reaches the LLM without their explicit, conscious action, regardless of what state the app was in when a `warp://` URL was delivered.
|
||||
|
||||
## Goals
|
||||
|
||||
1. A Linear deeplink never sends a prompt to the model without an explicit user gesture from inside Warp.
|
||||
2. When a Linear deeplink is opened, the user can always see the full prompt before choosing whether to send it.
|
||||
3. The behavior is independent of whether the terminal was already in fullscreen agent view when the URL was handled.
|
||||
4. Telemetry correctly reflects that Linear-originated prompts are not auto-submitted.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Closing the underlying unauthenticated `warp://` dispatch primitives (tracked in #655, #666). This spec assumes the dispatch primitive may be reachable by an attacker and hardens the Linear handler defensively.
|
||||
- Redesigning the Linear deeplink feature itself (issue titles, branch names, richer metadata).
|
||||
- Changing auto-submit behavior for other `AgentViewEntryOrigin` variants (e.g. `SlashCommand`, `AcceptedPromptSuggestion`, `Cli`). Those have different trust models and are out of scope here.
|
||||
- Sanitizing or filtering the prompt string content. The mitigation relies on requiring a user gesture, not on content-based filtering.
|
||||
- Removing the `prompt` query parameter from the Linear URI schema. The parameter remains supported; only the auto-submit behavior changes.
|
||||
|
||||
## Behavior
|
||||
|
||||
1. **Deeplink dispatch opens a new tab in agent view.** When `warp://linear/work?prompt=<PROMPT>` is dispatched, Warp opens a new tab, enters agent view for a new conversation (as today), and places the decoded `<PROMPT>` string into the agent input buffer for that conversation.
|
||||
|
||||
2. **The prompt is never submitted to the LLM automatically.** No code path initiated by a Linear deeplink submits the prompt on the user's behalf. Specifically:
|
||||
- The prompt is not auto-sent when the user was previously in fullscreen agent view in the focused terminal.
|
||||
- The prompt is not auto-sent when the user was not previously in agent view.
|
||||
- The prompt is not auto-sent on any platform (macOS, Linux, Windows) or via any dispatch primitive (OS URL handler, D-Bus, named pipe, third-party app opener).
|
||||
- The prompt is not auto-sent if the user has other agent conversations open or active elsewhere in the window.
|
||||
|
||||
3. **The user sees the full prompt before sending.** The attacker-supplied prompt is visible in the agent input buffer, rendered normally. The user can edit, clear, or reorder it before submitting. If the prompt contains newlines or very long content, the input renders it the same way it renders any user-typed multi-line prompt.
|
||||
|
||||
4. **"Enter again to send" affordance is shown.** When the Linear deeplink lands a prompt in the input buffer, Warp displays the existing ephemeral "press enter again to send to agent" confirmation message, signaling clearly that the prompt is pending and requires a deliberate keypress to send. The confirmation window matches the existing `ENTER_OR_EXIT_CONFIRMATION_WINDOW` timing.
|
||||
|
||||
5. **Explicit send gesture.** The prompt is submitted to the LLM only when the user performs an explicit send gesture in the agent input. That gesture is one of: pressing `Enter` while the ephemeral "enter again to send to agent" message from invariant 4 is still showing (within `ENTER_OR_EXIT_CONFIRMATION_WINDOW`); clicking the Send button in the agent input UI; or invoking the existing `SendInput` action via its bound keybinding (Cmd+Enter on macOS, Ctrl+Enter on Linux/Windows, as configured in the user's keymap). The gesture must target the agent input that was populated by the deeplink — not some other focused surface.
|
||||
6. **Empty or missing prompt is a no-op for input.** If the URL has no `prompt` parameter, or the parameter decodes to an empty string, the agent input buffer is not overwritten. The tab still opens in agent view (matching current behavior for a prompt-less deeplink).
|
||||
7. **No agent tools are invoked as a side effect of the deeplink.** Because nothing is submitted to the LLM until the user sends, none of the auto-executed agent tools (read_files, StartAgent, SendMessageToAgent, FetchConversation, UseComputer, etc.) are triggered by the act of opening the URL.
|
||||
8. **Telemetry reflects non-auto-submission.** The `AgentViewEntered` telemetry event recorded for a Linear deeplink entry reports `did_auto_trigger_request = false`, regardless of prior agent view state. The `LinearIssueLinkOpened` event continues to fire on dispatch.
|
||||
9. **Fallback display title is preserved.** The conversation's fallback display title remains `"Linear Issue"` so history and conversation pickers continue to identify the conversation as originating from a Linear deeplink.
|
||||
10. **Regression guards for other origins.** Origins currently in `should_autotrigger_request`'s allowlist (e.g. `Input { was_prompt_autodetected: true }`, `SlashCommand` non-keybinding triggers, `Cli`, `AcceptedPromptSuggestion`) continue to auto-submit as before. The "already in fullscreen agent view" shortcut, which today promotes *any* origin to auto-submit, must no longer promote `LinearDeepLink` — and must not introduce regressions for other origins that previously relied on it.
|
||||
11. **Background-window dispatch.** When Warp is backgrounded (or not the frontmost app) at the time the URL is dispatched, the new tab and its draft prompt must remain pending until the user foregrounds Warp. Nothing is submitted to the LLM during the time the user is not looking at the app. When the user does foreground Warp, they see the prompt in the input buffer and the "enter again to send" affordance exactly as in invariant 1–4; the pending state does not expire or auto-send itself on focus change.
|
||||
12. **Logging and telemetry redaction.** The verbatim `prompt` query parameter from a Linear deeplink must not appear in log lines, telemetry payloads, error toasts, or conversation titles that escape the user's own machine. Specifically: the `AgentViewEntered` and `LinearIssueLinkOpened` telemetry events carry only the origin classifier and fixed schema fields — never the prompt body. Error logging (`log::error!`) emitted on a failed agent-view entry includes only the origin (`AgentViewEntryOrigin::LinearDeepLink`) and the structured error value, not the `initial_prompt`. Error toasts surface the error kind, not the attacker-supplied prompt. The input buffer is the only user-visible destination for the prompt content.
|
||||
13. **Error paths remain silent to the user.** If entering agent view fails for a Linear deeplink, the existing error toast/logging path is used, subject to invariant 12's redaction rules.
|
||||
|
||||
## Success Criteria
|
||||
1. Opening `warp://linear/work?prompt=<anything>` while the focused terminal is in fullscreen agent view results in the prompt appearing in the input buffer with an "enter again to send" confirmation — the prompt is not sent to the LLM.
|
||||
2. Opening the same URL while the focused terminal is not in agent view results in identical behavior: new tab, agent view for a new conversation, prompt populated in the input buffer, confirmation shown, nothing sent.
|
||||
3. Opening the same URL while Warp is backgrounded does not submit the prompt; on foregrounding, the user sees the draft and affordance and must act explicitly.
|
||||
4. No LLM request, agent tool invocation, or model-facing network call is triggered by the act of handling the Linear deeplink, on any supported platform.
|
||||
5. Telemetry for the Linear deeplink entry records `did_auto_trigger_request = false`, and no emitted telemetry, log line, toast, or conversation title contains the verbatim `prompt` body.
|
||||
6. Non-Linear origins that were previously auto-submitted continue to auto-submit with the same timing as before the fix.
|
||||
@@ -0,0 +1,100 @@
|
||||
# TECH.md — Linear deeplink must not silently auto-submit prompts into the agent
|
||||
|
||||
**GitHub Issue:** [warpdotdev/warp-external#703](https://github.com/warpdotdev/warp-external/issues/703)
|
||||
**Product Spec:** `specs/GH703/product.md`
|
||||
|
||||
## Context
|
||||
|
||||
`warp://linear/work?prompt=<PROMPT>` is a trusted `warp://` URI. The handler decodes the `prompt` query parameter and feeds it into a new agent conversation. A shortcut in `try_enter_agent_view` today promotes *any* origin with an `initial_prompt` to auto-submit when the focused terminal was already in fullscreen agent view, which causes the Linear-supplied prompt to be sent to the LLM without any user interaction. This is contrary to the intent encoded in `AgentViewEntryOrigin::should_autotrigger_request`, which deliberately excludes `LinearDeepLink`.
|
||||
|
||||
The relevant code paths today:
|
||||
|
||||
- `app/src/uri/mod.rs:429-443` — `UriHost::Linear` match arm parses `LinearAction::WorkOnIssue`, builds `LinearIssueWork`, and dispatches into the new-or-existing window action.
|
||||
- `app/src/linear.rs:30-38` — `LinearIssueWork::from_url` reads `prompt` from the URL with no validation beyond "non-empty".
|
||||
- `app/src/root_view.rs:1107-1119,2875-2891` — `open_linear_issue_work_in_{new,existing}_window` forwards `LinearIssueWork` to `workspace.open_linear_issue_work(...)`.
|
||||
- `app/src/workspace/view.rs:15888-15937` — `open_linear_issue_work` opens a new tab and calls `terminal_view.enter_agent_view_for_new_conversation(prompt, AgentViewEntryOrigin::LinearDeepLink, ctx)`.
|
||||
- `app/src/terminal/view/agent_view.rs:48-83` — `enter_agent_view_for_new_conversation` delegates to `try_enter_agent_view`.
|
||||
- `app/src/terminal/view/agent_view.rs:160-290` — `try_enter_agent_view` captures `was_in_agent_view_already` and runs `if origin.should_autotrigger_request() || was_in_agent_view_already { send_user_query_in_conversation(...) }`. This is where the auto-submit occurs for `LinearDeepLink`.
|
||||
- `app/src/ai/blocklist/agent_view/controller.rs:172-205` — `AgentViewEntryOrigin::LinearDeepLink` is defined and `should_autotrigger_request` intentionally returns `false` for it.
|
||||
- `app/src/uri/uri_test.rs:293-347` — existing unit tests covering the Linear URI parsing surface.
|
||||
|
||||
The ephemeral "enter again to send" path already exists in the `else` arm of `try_enter_agent_view` (`app/src/terminal/view/agent_view.rs:240-266`): it populates the agent input buffer via `self.input.update(...).replace_buffer_content(&initial_prompt, ctx)` and shows an ephemeral message tagged `ENTER_AGAIN_TO_SEND_MESSAGE_ID`. That is the desired user experience for Linear-originated prompts.
|
||||
|
||||
Product invariants 1–13 in `specs/GH703/product.md` define the required behavior.
|
||||
|
||||
## Proposed changes
|
||||
|
||||
### 1. Remove the implicit `was_in_agent_view_already` shortcut (committed decision)
|
||||
`try_enter_agent_view`'s auto-submit condition is the root cause. We make the auto-submit decision a function of the origin alone — the `was_in_agent_view_already` shortcut is deleted outright. This was evaluated against two options during spec review; we commit to **option (a)**:
|
||||
- **(a) chosen:** Only `origin.should_autotrigger_request()` governs auto-submit. The prior shortcut existed to preserve "typed a new prompt in agent view and pressed Cmd+Enter" ergonomics, but that flow already enters via `AgentViewEntryOrigin::Input { was_prompt_autodetected: true }` (in the allowlist) or `AgentViewEntryOrigin::Keybinding`/`SlashCommand` paths. Any origin that legitimately needs to auto-submit when the user is already in agent view must be added to `should_autotrigger_request` explicitly.
|
||||
- (b) rejected: gating the shortcut on a new `is_trusted_user_originated` predicate keeps the footgun. If a future `AgentViewEntryOrigin` gets added and forgets to opt out of the predicate, the URI-injection bug reopens. Option (a) removes the whole class of problem.
|
||||
The concrete change replaces:
|
||||
```rust path=null start=null
|
||||
if origin.should_autotrigger_request() || was_in_agent_view_already {
|
||||
// ...send to LLM
|
||||
}
|
||||
```
|
||||
with a single check whose result depends only on the origin and the caller's explicit `AutoSubmitPolicy` (see step 3).
|
||||
**Audit of other origins (in-scope, committed deliverable).** Every `AgentViewEntryOrigin` variant was enumerated against `should_autotrigger_request`'s allowlist. The allowlist intentionally contains only: `Input { was_prompt_autodetected: true }`, `SlashCommand { trigger: !is_keybinding() }`, `Cli`, `AcceptedPromptSuggestion`. Every other variant — including `CodexModal`, `CloudAgent`, `ChildAgent`, `ProjectEntry`, `OnboardingCallout`, `LinearDeepLink`, `AgentViewBlock`, `AgentRequestedNewConversation`, `SharedSessionSelection`, `RestoreExistingConversation`, `InlineCodeReview`, `ConversationSelector`, `AgentModeHomepage`, `AIDocument`, `AutoFollowUp`, `AcceptedUnitTestSuggestion`, `AcceptedPassiveCodeDiff`, `ImageAdded`, `SlashInit`, `CreateEnvironment`, `Keybinding`, `CodeReviewContext`, `InlineHistoryMenu`, `InlineConversationMenu`, `ConversationListView`, `DefaultSessionMode`, `LongRunningCommand`, `Onboarding`, `ClearBuffer`, `PromptChip`, plus the soon-to-be-removed `ContinueConversationButton`/`ViewPassiveCodeDiffDetails`/`ResumeConversationButton` — now receives the explicit "populate input buffer + show `ENTER_AGAIN_TO_SEND_MESSAGE_ID`" behavior for `initial_prompt`. None of them carry URI- or network-sourced prompt strings except `LinearDeepLink` today, but the shortcut removal future-proofs the decision.
|
||||
### 2. Keep the "populate buffer + enter again to send" path as the default for Linear
|
||||
With the shortcut removed, `LinearDeepLink` naturally falls into the existing `else` branch of `try_enter_agent_view` (input buffer replacement + ephemeral `ENTER_AGAIN_TO_SEND_MESSAGE_ID` message). No new UI surface is needed; this is already the behavior for non-auto-triggering origins that arrive with an `initial_prompt` when the user is not in fullscreen agent view.
|
||||
### 3. Defense-in-depth: opt `open_linear_issue_work` out of auto-submit at the call site (committed shape)
|
||||
We commit to the **"explicit parameter on `try_enter_agent_view` + thin wrapper method at the public API"** shape:
|
||||
1. Add a private `AutoSubmitPolicy` enum in `app/src/terminal/view/agent_view.rs` with two variants: `FromOrigin` (today's behavior after step 1) and `NeverAutoSubmit` (forced draft).
|
||||
2. Thread `auto_submit: AutoSubmitPolicy` as a new parameter on `try_enter_agent_view`. Inside `try_enter_agent_view`, the auto-submit decision becomes `match auto_submit { FromOrigin => origin.should_autotrigger_request(), NeverAutoSubmit => false }`.
|
||||
3. Expose two public entrypoints from `TerminalView`:
|
||||
- `enter_agent_view_for_new_conversation(prompt, origin, ctx)` — unchanged signature for existing callers; uses `AutoSubmitPolicy::FromOrigin`.
|
||||
- `enter_agent_view_for_new_conversation_with_prompt_draft(prompt, origin, ctx)` — new wrapper for call sites that handle prompts from URI-sourced, IPC, or otherwise untrusted input; uses `AutoSubmitPolicy::NeverAutoSubmit`.
|
||||
4. `open_linear_issue_work` in `app/src/workspace/view.rs` calls `enter_agent_view_for_new_conversation_with_prompt_draft` instead of `enter_agent_view_for_new_conversation`.
|
||||
The parameter-plus-wrapper shape was chosen over a pure wrapper because the wrapper alone cannot prevent a future internal refactor from re-introducing an implicit fullscreen promotion inside `try_enter_agent_view`; the explicit policy parameter makes the decision visible at every call site of `try_enter_agent_view` and forces a typed match.
|
||||
Any future origin that should behave the same way can call the draft entrypoint at its call site without needing to re-audit `try_enter_agent_view`.
|
||||
This is defense-in-depth: step 1 is sufficient on its own for correctness; step 3 ensures that even if `should_autotrigger_request` ever grows a buggy allowlist entry, Linear deeplinks remain safe.
|
||||
### 4. Leave `LinearAction`, `LinearIssueWork::from_url`, and the URI validation layer unchanged
|
||||
No parsing, validation, or sanitization of the `prompt` query parameter is added. The mitigation depends on user gesture, not on string filtering — content-based filters are trivially bypassable for prompt injection. `LinearIssueWork::from_url` continues to decode `prompt` verbatim (still filtering empty strings, matching product invariant 6).
|
||||
### 5. Telemetry and logging redaction
|
||||
No telemetry schema changes are required. `did_auto_trigger_request` in `TelemetryEvent::AgentViewEntered` naturally reports `false` for Linear deeplinks after the fix; no extra code is needed.
|
||||
To honor product invariant 12 (logging / telemetry redaction), the implementation commits to the following, and reviewers should verify:
|
||||
- `TelemetryEvent::AgentViewEntered` and `TelemetryEvent::LinearIssueLinkOpened` carry only origin classifiers and fixed schema fields. The `initial_prompt` value is never attached to a telemetry payload.
|
||||
- The `log::error!` call in `enter_agent_view_for_new_conversation_with_policy` interpolates only `origin` (a compile-time enum discriminant) and `e` (a structured `EnterAgentViewError` whose `Display` does not include the prompt body). The `initial_prompt: Option<String>` is explicitly not passed to any formatting macro in this file.
|
||||
- `self.show_error_toast(e.to_string(), ctx)` relies on `EnterAgentViewError: Display`; the error types enumerated in `EnterAgentViewError` do not carry user-prompt strings. New error variants added in the future must not include the prompt body.
|
||||
- Conversation title fallback remains `"Linear Issue"` (product invariant 9) so the prompt never becomes a title.
|
||||
|
||||
## End-to-end flow (after the fix)
|
||||
|
||||
1. OS/dispatch primitive hands `warp://linear/work?prompt=<ATTACKER>` to Warp.
|
||||
2. `validate_custom_uri` → `UriHost::Linear` → `LinearAction::WorkOnIssue` → `LinearIssueWork::from_url` → `open_linear_issue_work_in_{new,existing}_window`.
|
||||
3. `workspace.open_linear_issue_work` opens a new tab and invokes `enter_agent_view_for_new_conversation_with_prompt_draft(prompt, AgentViewEntryOrigin::LinearDeepLink, ctx)` (new entrypoint from step 3).
|
||||
4. `try_enter_agent_view` enters agent view for the new conversation. Because `should_autotrigger_request()` returns `false` for `LinearDeepLink` and the `was_in_agent_view_already` shortcut has been removed (step 1) — or, belt-and-suspenders, because the caller passed `NeverAutoSubmit` (step 3) — the code takes the "replace buffer + show ephemeral message" branch.
|
||||
5. The user sees the prompt in the input buffer and the "press enter again to send to agent" message. No LLM request has been made.
|
||||
6. The user either sends (explicit Enter inside the confirmation window) or edits/clears the prompt.
|
||||
|
||||
## Testing and validation
|
||||
Tests map back to the numbered product invariants in `specs/GH703/product.md`.
|
||||
1. **Unit tests in `app/src/terminal/view_test.rs` (invariants 1, 2, 3, 4, 6).** Three tests are implemented:
|
||||
- `linear_deeplink_populates_input_as_draft_when_not_in_agent_view` — enters via `enter_agent_view_for_new_conversation_with_prompt_draft` when agent view is inactive; asserts the input buffer contains the attacker prompt and the ephemeral message id is `ENTER_AGAIN_TO_SEND_MESSAGE_ID`.
|
||||
- `linear_deeplink_does_not_auto_submit_when_already_in_agent_view` — first enters fullscreen agent view via `Input { was_prompt_autodetected: false }`, then dispatches the Linear deeplink. Asserts a new conversation id is allocated, the prompt lands in the input buffer instead of being auto-submitted, and the ephemeral affordance is shown.
|
||||
- `linear_deeplink_via_default_entrypoint_does_not_auto_submit_in_fullscreen` — verifies the defense-in-depth layer: even if a caller forgets to use the draft entrypoint and goes through `enter_agent_view_for_new_conversation` directly, `LinearDeepLink` still does not auto-submit because the `was_in_agent_view_already` shortcut is gone.
|
||||
2. **Regression guard for other origins (invariant 10).** The existing `clear_buffer_action_in_fullscreen_agent_view_starts_new_conversation` test and the broader agent-view test suite cover `AgentViewEntryOrigin::Input { was_prompt_autodetected: true }` and keyboard-driven flows. The allowlist in `should_autotrigger_request` is unchanged, so origins that auto-submit today (`Cli`, `Input { was_prompt_autodetected: true }`, `SlashCommand { trigger: !is_keybinding() }`, `AcceptedPromptSuggestion`) continue to do so.
|
||||
3. **Unit test for URL parsing (already present, keep).** `app/src/uri/uri_test.rs` covers `validate_custom_uri_linear`, `test_linear_action_parse_*`, and `test_linear_issue_work_*`. No changes required; they continue to exercise the decoding path to ensure we don't regress the URI schema.
|
||||
4. **Manual verification (invariants 1–5, 7, 11).**
|
||||
- On macOS, Linux, and Windows, open `warp://linear/work?prompt=<attacker+payload>` while the focused terminal is already in fullscreen agent view. Confirm the prompt shows up in the input, the ephemeral "enter again to send" message is visible, and no LLM request is made until the user presses Enter.
|
||||
- Repeat with the focused terminal not in agent view.
|
||||
- Repeat with the app closed (cold start) to cover the dispatch path used by `open_linear_issue_work_in_new_window`.
|
||||
- Repeat with Warp backgrounded at dispatch time (invariant 11): foreground Warp afterward and confirm the prompt stays as a draft and the affordance is still shown.
|
||||
- Confirm that opening the URL does not cause any of `read_files`, `StartAgent`, `SendMessageToAgent`, `FetchConversation`, or `UseComputer` tool calls to be issued.
|
||||
5. **Telemetry and redaction spot check (invariants 8, 12).** Inspect the emitted `AgentViewEntered` event and confirm `did_auto_trigger_request = false`. Confirm `LinearIssueLinkOpened` still fires once per dispatch. Grep `log::` output from the agent-view entry path to confirm the verbatim prompt never appears in a log line.
|
||||
6. **`./script/presubmit`** passes (fmt, clippy, tests).
|
||||
|
||||
## Risks and mitigations
|
||||
|
||||
1. **Removing `was_in_agent_view_already` could regress other flows.** Some origins may rely on this shortcut today (e.g. entering a second conversation from agent view with a typed prompt). Mitigation: the agent-view unit tests in `app/src/terminal/view_test.rs` continue to exercise `Input { was_prompt_autodetected: false }`, `Input { was_prompt_autodetected: true }`, and keyboard-driven flows. Because any origin that legitimately needs to auto-submit is already in `should_autotrigger_request`'s allowlist, removing the fullscreen promotion does not change their behavior. If a regression does surface, the correct fix is to add the specific origin to the allowlist — not to re-introduce a generic fullscreen shortcut.
|
||||
2. **Other URI-originated origins could have the same bug.** `CodexModal`, `ProjectEntry`, `OnboardingCallout`, and future URI-sourced origins were audited in step 1 above and are not in the auto-submit allowlist; the shortcut removal already protects them. New URI- or IPC-sourced call sites should additionally use `enter_agent_view_for_new_conversation_with_prompt_draft` for defense-in-depth.
|
||||
|
||||
3. **User confusion from unexpected input content.** A user who did not intend to open a Linear deeplink will still see the URI-supplied prompt in their agent input. This is a strict improvement over silent submission: they can inspect, edit, or clear it. No mitigation needed; the ephemeral "enter again to send" message already signals that the prompt is pending.
|
||||
|
||||
4. **Attacker-supplied very long prompts.** Existing input buffer handling already supports arbitrarily long content. No change needed.
|
||||
|
||||
## Follow-ups
|
||||
- The audit of other `AgentViewEntryOrigin` variants (previously a follow-up) is now promoted into step 1 above and is a committed deliverable of this change. No follow-up issue is required; the grep-based audit is covered by the shortcut removal.
|
||||
- Coordinate with the owners of #655 (Windows named pipe) and #666 (Linux D-Bus) to gate `warp://` dispatch on a platform-trusted source. This spec is orthogonal defense; with that work landed the prompt-injection blast radius shrinks further. Tracked separately in those issues — this spec does not block on them.
|
||||
- Consider adding a dedicated UI indicator (banner or toast) identifying a prompt as "from a Linear deeplink" so the user knows its provenance at a glance. Not required for the fix but would improve trust; can be added iteratively once the safety invariant is in place.
|
||||
Reference in New Issue
Block a user