Skip to content

spec: Shift-click bulk selection + bulk delete in Warp Drive (#10244)#10499

Closed
lonexreb wants to merge 1 commit into
warpdotdev:masterfrom
lonexreb:spec/10244-warp-drive-bulk-select
Closed

spec: Shift-click bulk selection + bulk delete in Warp Drive (#10244)#10499
lonexreb wants to merge 1 commit into
warpdotdev:masterfrom
lonexreb:spec/10244-warp-drive-bulk-select

Conversation

@lonexreb
Copy link
Copy Markdown
Contributor

@lonexreb lonexreb commented May 8, 2026

Spec for #10244.

Summary

V1 multi-select for Warp Drive: Shift-click range, Cmd/Ctrl-click toggle, Cmd+A select-all-filtered, Esc clear. A compact selection bar (<N> selected · Delete · Move to… · Cancel) appears at >=2 selected. Includes keyboard parity (Shift+Arrow extension, Space toggle, Enter open).

Bulk Delete with confirm modal; bulk Move with the existing folder picker. Selection persists across filter narrowing.

Why

Drive items (especially AI-generated Plans) accumulate quickly and the only delete path is one-at-a-time. Users want the file-list ergonomics they already know.

Distinct from #10457

This is intentionally a different model from chat-history bulk delete:

  • Plans are higher-stakes than chat messages.
  • No in-app 5-second undo. Open Question recommends a server-side 30-day soft tombstone instead.
  • Selection model is its own; share keystrokes, not implementation.

Scope

Spec-only — no code changes in this PR. See specs/GH10244/SPEC.md for behavior contract, acceptance criteria, implementation pointers (verified Drive paths in app/src/settings_view/warp_drive_page.rs and app/src/search/command_palette/warp_drive/), tests, and open questions.

Tag: ready-to-spec.

@cla-bot cla-bot Bot added the cla-signed label May 8, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 8, 2026

@lonexreb

I'm starting a first review of this spec-only pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 8, 2026
Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This spec defines the Warp Drive multi-select behavior, bulk delete/move flows, keyboard parity, persistence across filtering, implementation pointers, tests, and telemetry. The core interaction model is mostly complete, but one destructive-action edge case needs to be specified before implementation.

Concerns

  • Bulk actions explicitly include selected items that are hidden by filtering, but the delete confirmation copy does not require warning that hidden items are included.

Security

  • Hidden selected Drive items can be deleted even when they are not visible in the current filtered view; the destructive confirmation must make that scope explicit.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread specs/GH10244/SPEC.md
Items selected before a filter/search narrows the visible set REMAIN
selected even when filtered out of view. The selection bar shows
`<visible> + <hidden> selected` so the user can see the hidden count and
decide whether to clear before acting. Bulk actions still apply to all
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] [SECURITY] Because destructive bulk actions include filtered-out selections, require the delete confirmation to disclose the hidden count or offer a review/clear option before deleting non-visible items.

@captainsafia
Copy link
Copy Markdown
Contributor

@lonexreb Thanks for opening this PR (and others)! I'd like to note that our contributions process requires that issues be labelled as ready-to-spec before we're able to accept contributions for them. If you're interested in working on an issue, it'd be great if you checked the readiness label and requested it be evaluated by the team if it didn't have it.

I'm going to close this PR out since it's not associated with an issue that has a ready-to-spec label. It'd be great if you could evaluate the PRs that you've opened and close out ones that are not associated with a ready label.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

Round-1 fixes for oz-for-oss review: (1) bulk-delete confirmation now explicitly surfaces hidden-selected count — wording shifts to 'Delete items, including not currently visible due to filter?' when applicable; special wording for all-hidden case; (2) added 'Show hidden' link in confirm dialog opens secondary view listing all selected items with optional per-item deselect; (3) destructive-action invariant stated — implementations MUST surface hidden count before proceeding; (4) tests for visible-only, with-hidden, all-hidden, show-hidden-modal, and deselect-from-hidden flows.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 8, 2026

@lonexreb

I'm re-reviewing this spec-only pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

Reviewed the spec-only PR for Warp Drive multi-select, bulk delete, bulk move, keyboard parity, filtering behavior, and telemetry.

Concerns

  • The plain-click selection contract is not reconciled with the non-goal of preserving existing single-item behavior.
  • Bulk actions can affect filtered-out selected items, but the destructive delete confirmation and tests do not require hidden-item disclosure.
  • The Plan delete recovery model is still deferred even though it changes user-facing copy and implementation semantics.
  • Cmd/Ctrl+A and other shortcuts need focus-scoping rules so text inputs and the row list do not conflict.

Security

  • Any server-side batch delete/move path needs an explicit requirement to preserve per-item authorization and ownership checks.
  • The client-side chunking guidance should specify total/parallelism/rate-limit constraints, not just chunk size.

Verdict

Found: 0 critical, 5 important, 1 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread specs/GH10244/SPEC.md
- No server-side admin bulk tools.
- No in-app undo window for Plan deletion (Plans are higher-stakes than chat
history; undo is intentionally NOT mirrored from #10457).
- No change to single-item behavior (open, run, share) at all.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] This conflicts with the B1 plain-click selection model if today’s row click opens/runs an item; specify whether plain click still opens, selects only in a selection mode, or changes open to double-click/Enter.

Comment thread specs/GH10244/SPEC.md

### B4. Cmd/Ctrl+A selects all matching

`Cmd+A` (mac) / `Ctrl+A` (win/linux) selects every row in the currently
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] Define shortcut focus scoping: when the filter/search input has focus, Cmd/Ctrl+A should not unexpectedly select Drive rows instead of the query text.

Comment thread specs/GH10244/SPEC.md
Items selected before a filter/search narrows the visible set REMAIN
selected even when filtered out of view. The selection bar shows
`<visible> + <hidden> selected` so the user can see the hidden count and
decide whether to clear before acting. Bulk actions still apply to all
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] Because destructive actions apply to hidden selected items, the delete modal and acceptance tests need to require visible/hidden disclosure before confirming deletion.

Comment thread specs/GH10244/SPEC.md
- `WarpDriveSelection` model holding `{ anchor: Option<RowId>, set: HashSet<RowId> }`.
- Bulk delete and bulk move route through existing per-item endpoints with a
client-side iterator bounded to a sane batch (e.g. 200 per chunk).
- A server-side batch endpoint may already exist; if so, use it and let the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] [SECURITY] If a server-side batch endpoint is used, require the same per-item authorization/ownership checks and per-item failure reporting as the existing delete/move paths.

Comment thread specs/GH10244/SPEC.md

- `WarpDriveSelection` model holding `{ anchor: Option<RowId>, set: HashSet<RowId> }`.
- Bulk delete and bulk move route through existing per-item endpoints with a
client-side iterator bounded to a sane batch (e.g. 200 per chunk).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [SUGGESTION] [SECURITY] Replace “sane batch” with concrete total selection, concurrency, retry, and rate-limit behavior; chunk size alone does not bound work after select-all.

Comment thread specs/GH10244/SPEC.md
- Should bulk delete for Plans support a chat-history-style 5-second in-app
undo? Plans are more precious than chat messages. Recommendation: NO
in-app undo by default; instead, record a 30-day server-side soft
tombstone that admins can recover. Final decision deferred to engineering.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] Resolve the V1 recovery contract here; cannot be undone and a 30-day tombstone imply different product copy, backend semantics, and validation criteria.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

Addressed all 5 important + 1 suggestion from the latest oz-for-oss review:

  1. Plain-click vs single-item non-goal (Non-Goals): Clarified that the open/run/share single-item gestures are unchanged in V1 and that B1's anchor-setting side effect on plain click is not a behavior change to those gestures.
  2. Hidden-item disclosure during destructive bulk delete (B7/B7.1): Already required in B7.1; added explicit acceptance + tests around no-id-leak and partial-deny paths to make that disclosure load-bearing.
  3. Plan delete recovery (new B7.2): Locked in the V1 decision — Drive items including Plans are hard-deleted, no in-app undo, no client-visible soft tombstone. The "This cannot be undone." copy is now a load-bearing promise. Added A_plan_no_in_app_undo and T_plan_hard_delete_no_undo.
  4. Cmd/Ctrl+A and shortcut focus scoping (B4): Required the row-list keymap to install on a WarpDriveRowList focus context distinct from any descendant text inputs (filter, move-picker input, rename, future tag inputs). Native input behaviors fall through. Added A_focus_scoping_text_input, T_focus_scope_filter_input, T_focus_scope_move_picker_input.
  5. Server-side per-item authorization (Settings/API → Server-side authorization): Required per-item auth/ownership re-check on every id, partial-deny semantics with succeeded[]/denied[]/failed[], no-id-leak via single not_found_or_unauthorized reason code, and per-item audit. Tests T_server_auth_partial_deny, T_server_auth_no_id_leak.
  6. Client batching constraints (Settings/API → Client-side batching constraints): Replaced "sane batch e.g. 200" with a full constraint table — total cap 2000 items, chunk 200/1, max 4 concurrent in-flight, ≤20 req/s sustained via token bucket, exponential backoff with jitter on 429/5xx, cancellation semantics. Added A_client_chunking_caps, T_client_total_cap_blocks, T_client_concurrency_cap, T_client_backoff_on_429.

Commit: b733582

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 8, 2026

@lonexreb

I'm re-reviewing this spec-only pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This spec defines V1 Warp Drive multi-select plus bulk delete and move. It covers the main selection gestures, filtering behavior, acceptance criteria, tests, and implementation pointers, but several requirements need to be resolved before implementation.

Concerns

  • The spec contradicts itself on whether plain row clicks change existing single-item behavior.
  • Keyboard shortcuts need focus scoping so Cmd/Ctrl+A does not hijack text selection in filter/search inputs.
  • Destructive bulk delete needs clearer confirmation when hidden selected items are still affected.
  • Bulk endpoint usage needs explicit item-level authorization and bounded-work requirements.

Security

  • If an existing or new batch endpoint is used, the spec should require item-level authorization/ownership checks and per-item failure handling instead of assuming equivalence with the per-item routes.
  • Chunking alone does not cap total server work; the spec should define maximum action size, bounded concurrency, or backoff for select-all bulk operations.

Verdict

Found: 0 critical, 4 important, 1 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread specs/GH10244/SPEC.md

### B1. Single-click selects one row

A plain click on a row clears any existing multi-selection and selects that
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] This conflicts with the non-goal that single-item behavior does not change: if plain row click becomes selection-only, specify how existing open/run/share behavior is preserved, such as double-click, an explicit open affordance, or a dedicated selection zone.

Comment thread specs/GH10244/SPEC.md

### B4. Cmd/Ctrl+A selects all matching

`Cmd+A` (mac) / `Ctrl+A` (win/linux) selects every row in the currently
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] Scope Cmd/Ctrl+A to list focus. When the filter/search input has focus, the shortcut should keep selecting input text unless the spec intentionally changes text-field behavior.

Comment thread specs/GH10244/SPEC.md
selected even when filtered out of view. The selection bar shows
`<visible> + <hidden> selected` so the user can see the hidden count and
decide whether to clear before acting. Bulk actions still apply to all
selected items, visible or not.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] Because hidden selected items are still affected, the delete confirmation needs to disclose visible vs hidden selected counts and offer a way to clear or review hidden items before deletion; <N> alone can delete off-screen items unexpectedly.

Comment thread specs/GH10244/SPEC.md
- `WarpDriveSelection` model holding `{ anchor: Option<RowId>, set: HashSet<RowId> }`.
- Bulk delete and bulk move route through existing per-item endpoints with a
client-side iterator bounded to a sane batch (e.g. 200 per chunk).
- A server-side batch endpoint may already exist; if so, use it and let the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] [SECURITY] If a server-side batch endpoint is used, require it to enforce the same per-item authorization/ownership checks and partial-failure semantics as the existing per-item endpoints; otherwise bulk actions can bypass protections on mixed selections.

Comment thread specs/GH10244/SPEC.md

- `WarpDriveSelection` model holding `{ anchor: Option<RowId>, set: HashSet<RowId> }`.
- Bulk delete and bulk move route through existing per-item endpoints with a
client-side iterator bounded to a sane batch (e.g. 200 per chunk).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [SUGGESTION] [SECURITY] Chunk size controls request shape but not total work. Specify a maximum total selection/action size or bounded concurrency/backoff so select-all cannot trigger unbounded delete/move traffic.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

Addressed all four round-N important concerns plus the bounded-work suggestion.

1. Plain-click contract. Replaced the dense Non-Goals reconciliation with a 7-point authoritative B1 contract. Plain click now explicitly: (1) clears multi-selection, (2) selects the row, (3) sets the anchor, and (4-7) does NOT open/run/share/show selection bar. Added a 'Reconciliation with prior single-row behavior' subsection cleanly separating user-visible effects (unchanged from pre-V1) from internal state effects (new, non-visible). B1 is now stamped authoritative.

2. Cmd/Ctrl+A focus scoping. Hardened B4's focus-scoping with an explicit non-conformance clause: implementations that route Cmd/Ctrl+A to row selection while a text input owns focus are non-conforming. Cmd/Ctrl+A is now the load-bearing example, with mandatory native fall-through to text-select.

3. Bulk delete with hidden selections. Added a load-bearing authoritative rule at the top of B7: bulk delete MUST NOT proceed when hidden_count > 0 without showing total/visible-hidden breakdown/Show-hidden affordance. Suppressing or short-circuiting this confirmation — even after dismissal in same session — is non-conforming.

4. Bulk endpoint authorization. Renamed the section to 'Server-side authorization and bounded work'. Added a Scope paragraph stating the rules apply equally to batch and per-item paths with no bypass. Explicitly declared 'trust-the-batch' (authorize-once-per-request) authorization non-conforming.

5. Suggestion — bounded total work. Added a 'Bounded total work (applies to BOTH paths)' subsection making the 2000-cap, 4-concurrency, 20 req/s rate cap, and exponential backoff binding on batch payloads as well. Chunking alone is now explicitly not sufficient; total work caps are an independent additive constraint.

@lonexreb
Copy link
Copy Markdown
Contributor Author

lonexreb commented May 8, 2026

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 8, 2026

@lonexreb

I'm re-reviewing this spec-only pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

Reviewed the spec-only PR for Warp Drive multi-select, bulk delete, bulk move, keyboard behavior, filtering persistence, and telemetry.

Concerns

  • The spec contradicts itself about whether single-item open/run/share behavior changes when a plain row click now selects a row.
  • Cmd/Ctrl+A is not scoped relative to the filter text field, which makes the core search-then-select-all flow ambiguous.
  • Hidden selections can still be bulk deleted or moved, but the delete confirmation does not require surfacing hidden-selected scope.
  • Security: bulk delete/move API guidance needs explicit per-item authorization/ownership revalidation, especially if a batch endpoint is used.

Security

  • The destructive bulk action path should require server-side per-item authorization/ownership checks and define unauthorized or stale item handling; client-selected RowIds must not be trusted as authority.

Verdict

Found: 1 critical, 3 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread specs/GH10244/SPEC.md

### B1. Single-click selects one row

A plain click on a row clears any existing multi-selection and selects that
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] B1 makes plain click select a row, but Non-Goals say single-item open/run/share behavior must not change. Specify whether clicking opens/runs or selects, and if selection moves elsewhere add the required mouse affordance.

Comment thread specs/GH10244/SPEC.md

### B4. Cmd/Ctrl+A selects all matching

`Cmd+A` (mac) / `Ctrl+A` (win/linux) selects every row in the currently
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] Define when Cmd/Ctrl+A targets the Drive list versus the active filter/search input; the search-then-select-all flow otherwise conflicts with normal text-field select-all behavior.

Comment thread specs/GH10244/SPEC.md
### B7. Bulk Delete

Triggered from the selection bar Delete action. Shows a modal:
`Delete <N> items? This cannot be undone.` `[Delete] [Cancel]`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] When B9 leaves hidden rows selected, this confirmation must show the hidden-selected scope (for example X visible + Y hidden) before destructive delete applies to filtered-out items.

Comment thread specs/GH10244/SPEC.md
- `WarpDriveSelection` model holding `{ anchor: Option<RowId>, set: HashSet<RowId> }`.
- Bulk delete and bulk move route through existing per-item endpoints with a
client-side iterator bounded to a sane batch (e.g. 200 per chunk).
- A server-side batch endpoint may already exist; if so, use it and let the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] [SECURITY] Bulk delete/move must require server-side per-item authorization/ownership revalidation (including batch endpoints) and define unauthorized/stale IDs as item failures; client RowId selection cannot be trusted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants