fix: preserve inherited workspace delete copy (#3864)

This commit is contained in:
Carlos Florêncio
2026-09-22 23:31:49 +01:00
committed by GitHub
parent 2e600341f4
commit 151c8bb526
22 changed files with 466 additions and 11 deletions
@@ -0,0 +1,151 @@
---
created: 2026-09-22
status: complete
requirements:
- REQ-UI-TASK-CLEANUP-CONFIRMATION-001
- REQ-TASKS-RUNTIME-CLEANUP-001
system_design:
- ../../specs/ui/system-design/confirmation-warning-hierarchy.md
- ../../specs/tasks/system-design/runtime-cleanup.md
legacy_specs: []
---
# Implementation Plan: Preserve inherited parent workspace copy
## Overview
Correct single-task delete confirmation copy when a subtask uses
`workspaceMode: "inherit_parent"`. The existing cleanup model keys only on the
executor and therefore tells users that the child's worktree and branch will be
deleted, even though task cleanup preserves the borrowed parent environment.
The implementation updates the shared summary model, the delete dialog's
explicit and task-store-derived context, all specified task-aware callers, and
the supported locale catalogs.
The work is one sequential vertical slice. The existing backend cleanup
contract remains unchanged; this package makes the confirmation reflect it.
## Scope
### In scope
- Add the inherited-parent cleanup summary branch and localized note.
- Resolve inherited-parent state explicitly at task-aware call sites and through
the dialog's task-id fallback.
- Preserve the existing bulk cleanup model, deletion callbacks, layout, focus,
and consent behavior.
- Update English, Portuguese, Simplified Chinese, Traditional Chinese, and
Japanese task catalogs.
- Add summary and rendered-dialog regression coverage.
### Out of scope
- Backend cleanup ownership, reference counting, or worktree deletion logic.
- Bulk delete copy or bulk workspace-mode inference.
- A new confirmation surface or responsive layout change.
- Public documentation.
## Technical approach
1. Extend `getCleanupSummary` with an optional `CleanupSummaryOptions` object.
The inherited-parent branch returns the existing session-stop translation
and a new parent-workspace note before the executor-specific branch runs.
2. Add `sharesParentWorkspace` to `TaskDeleteConfirmDialogProps`. For single
deletes, use the prop when present and otherwise resolve the task with
`findTaskInSnapshots(taskId, state.kanbanMulti.snapshots, state.kanban.tasks)`
through `useAppStore`. Bulk deletes continue using grouped executor copy.
3. Pass the task's workspace mode from the five specified callers. Other
callers remain protected by the dialog fallback when they provide a task ID.
4. Add the new key to all six task catalogs. Run the existing Traditional
Chinese generator after updating `zh-cn` and verify catalog parity.
5. Add failing summary and dialog tests, then implement the smallest production
change and rerun the focused tests before the full task checks.
## ASCII UI preview
### UI-01: Inherited-parent workspace delete confirmation
Entry point: delete action for a child task with a worktree executor and
`workspaceMode = inherit_parent`. Desktop and phone use the existing centered
`AlertDialog`; on phones the existing body scrolls while the footer remains
reachable. The copy hierarchy is the same at both sizes.
Current behavior:
```text
+----------------------------------------------+
| Delete task |
| Delete "Child task". This action cannot be |
| undone. |
| |
| Cleanup |
| * The task's git worktree and its branch |
| will be deleted. |
| Your main repo and other branches are not |
| affected. |
| * Any running agent sessions will be stopped.|
| Cancel Delete |
+----------------------------------------------+
```
Corrected behavior:
```text
+----------------------------------------------+
| Delete task |
| Delete "Child task". This action cannot be |
| undone. |
| |
| Cleanup |
| * Any running agent sessions will be stopped.|
| This task shares its parent's workspace. The |
| parent task's worktree, branch, and files |
| are not touched. |
| Cancel Delete |
+----------------------------------------------+
```
Structural requirements: keep the named delete outcome, one effects list, one
supporting note, existing focus and consent behavior, and existing action
reachability. ASCII spacing is illustrative, not a pixel contract. The
corrected view covers `AC-UI-TASK-CLEANUP-CONFIRMATION-001.15`.
## Tests
| Acceptance criterion | Evidence |
| --- | --- |
| `AC-UI-TASK-CLEANUP-CONFIRMATION-001.15` | `apps/web/components/task/task-cleanup-summary.test.ts` verifies the exact structured branch; `apps/web/components/task/task-delete-confirm-dialog.test.tsx` verifies rendered parent-worktree preservation and task-id fallback. |
| `AC-TASKS-RUNTIME-CLEANUP-001.3` | The same rendered copy regression reflects the existing shared-environment cleanup contract. |
## E2E tests
No new Playwright test is required. This is a content and state-normalization
change inside the existing confirmation surface. The mobile composition,
interaction, and geometry remain unchanged; the focused rendered component
test covers the new branch, and the existing mobile confirmation contract
continues to apply.
## Work orders
- [x] [Task 01: Correct inherited workspace delete confirmation](task-01-inherited-workspace-delete-copy.md)
## Verification results
- Focused summary, dialog, and task-menu tests passed: 56 tests across 3 files.
- `pnpm run typecheck`, `pnpm run lint`, `pnpm run build:vite`, and `git diff --check` passed.
- The scoped Traditional Chinese task catalog generator passed.
- `pnpm run i18n:check` remains blocked by 32 pre-existing missing Japanese keys
in `executors` and `task`; the new inherited-workspace key is present in all
six supported catalogs.
- The full Traditional Chinese generator remains blocked by two pre-existing
simplified Chinese values in `zh-hk/workflows` and `zh-tw/workflows`.
## Risks
- A missing task in the store must keep the current executor-based fallback so
unrelated dialogs do not lose cleanup information.
- Bulk delete must continue using executor grouping and must not infer one
workspace mode for several tasks.
- The repository currently reports unrelated missing Japanese catalog keys in
`pnpm run i18n:check`; the final result must distinguish that baseline issue
from any key introduced by this change.
@@ -0,0 +1,130 @@
---
id: "01-inherited-workspace-delete-copy"
title: "Correct inherited workspace delete confirmation"
status: complete
wave: 1
depends_on: []
plan: "plan.md"
requirements:
- REQ-UI-TASK-CLEANUP-CONFIRMATION-001
- REQ-TASKS-RUNTIME-CLEANUP-001
acceptance_criteria:
- AC-UI-TASK-CLEANUP-CONFIRMATION-001.15
- AC-TASKS-RUNTIME-CLEANUP-001.3
system_design:
- ../../specs/ui/system-design/confirmation-warning-hierarchy.md
- ../../specs/tasks/system-design/runtime-cleanup.md
---
# Task 01: Correct inherited workspace delete confirmation
## Summary
Make single-task delete confirmation accurately describe a child task that
shares its parent's materialized workspace. The summary will show only the
agent-session stop effect plus the parent-workspace preservation note, with
explicit caller context and a task-store fallback for callers that provide only
the task ID.
## In scope
- Extend the single-task cleanup summary options and inherited-parent branch.
- Add the dialog prop, store lookup fallback, and five specified call-site
values.
- Add the English and five translated catalog values.
- Add summary and dialog regressions, including explicit prop and fallback
behavior.
## Out of scope
- Backend task cleanup or worktree lifecycle behavior.
- Bulk cleanup summary changes.
- Confirmation layout, touch sizing, focus, or callback changes.
- New Playwright coverage for an unchanged mobile composition.
## Acceptance
- `getCleanupSummary(_, { sharesParentWorkspace: true })` returns exactly one
agent-session effect and exactly one inherited-parent workspace note, with no
worktree or branch deletion copy.
- A rendered delete dialog shows the preserved parent worktree, branch, and
files when the explicit prop is true or when the task ID resolves to
`inherit_parent` in the app store.
- Existing executor-specific single and bulk copy, deletion callbacks, and
consent behavior remain unchanged for all other tasks.
## ASCII UI preview
See [UI-01 in the plan](plan.md#ui-01-inherited-parent-workspace-delete-confirmation).
The dialog keeps the existing desktop and phone composition; only the cleanup
effects and supporting note change for inherited-parent tasks.
```text
Cleanup
* Any running agent sessions will be stopped.
This task shares its parent's workspace. The parent task's worktree,
branch, and files are not touched.
Cancel Delete
```
## Verification
```bash
(cd apps/web && pnpm run i18n:zh-hant)
(cd apps/web && pnpm test components/task/task-cleanup-summary.test.ts components/task/task-delete-confirm-dialog.test.tsx)
(cd apps/web && pnpm run typecheck)
(cd apps/web && pnpm run i18n:check)
(cd apps/web && pnpm run lint)
```
## Files likely touched
- `apps/web/components/task/task-cleanup-summary.ts`
- `apps/web/components/task/task-cleanup-summary.test.ts`
- `apps/web/components/task/task-delete-confirm-dialog.tsx`
- `apps/web/components/task/task-delete-confirm-dialog.test.tsx`
- `apps/web/components/task/task-actions-menu-dialogs.tsx`
- `apps/web/components/kanban-card-menu.tsx`
- `apps/web/components/task/task-management-surface.tsx`
- `apps/web/app/tasks/columns.tsx`
- `apps/web/app/tasks/tasks-list-view.tsx`
- `apps/web/src/locales/{en,pt-pt,zh-cn,zh-hk,zh-tw,ja}/task.json`
## Dependencies
None.
## Risks
- Callers with stale or missing task projections must retain the generic or
executor-based summary through the dialog fallback.
- Traditional Chinese catalogs are generator-managed and must be updated with
`pnpm run i18n:zh-hant`.
- The repository's existing Japanese catalog gaps may keep the full i18n check
red after this task; report the exact pre-existing failures.
## Parallelism
`sequential`
## Inputs
- `docs/specs/ui/requirements/confirmation-warning-hierarchy.md`, especially
`AC-UI-TASK-CLEANUP-CONFIRMATION-001.15`.
- `docs/specs/ui/system-design/confirmation-warning-hierarchy.md`.
- `docs/specs/tasks/requirements/runtime-cleanup.md`,
`AC-TASKS-RUNTIME-CLEANUP-001.3`.
- `docs/specs/tasks/system-design/runtime-cleanup.md`.
- `apps/web/AGENTS.md`.
- `.agents/skills/tdd/SKILL.md` and `.agents/skills/mobile-parity/SKILL.md`.
## Results
Implemented the inherited-parent cleanup branch, explicit task-aware caller
context, task-store fallback, supported locale values, and regression coverage.
The focused test files pass with 56 tests. Typecheck, lint, Vite build, and
diff validation pass. The scoped Traditional Chinese task catalog generation
passes. The full i18n check still reports the 32 pre-existing Japanese missing
keys, and the full Traditional Chinese generator still reports two pre-existing
simplified Chinese values in `zh-hk/workflows` and `zh-tw/workflows`.
@@ -163,6 +163,11 @@ repository resources, so that I can understand the consequence before acting.
- **AC-UI-TASK-CLEANUP-CONFIRMATION-001.14:** At phone widths, the discard
selection shall remain inside the existing centered dialog and its scrolling
body. Its label shall provide a touch target of at least 44 CSS px.
- **AC-UI-TASK-CLEANUP-CONFIRMATION-001.15:** When a task uses an inherited
parent workspace, its delete confirmation shall state that any running agent
sessions for the task will be stopped and that the parent task's worktree,
branch, and files remain untouched. It shall omit statements that the task's
worktree or branch will be deleted.
Consent inspection, clean-workspace suppression, and failure recovery follow
[task runtime cleanup](../../tasks/requirements/runtime-cleanup.md),
@@ -68,6 +68,16 @@ archive popover and inline confirmation use the same ordered model with their
established compact spacing. This removes copy drift without moving cleanup
policy into a visual component.
Single-task delete also accepts an inherited-parent workspace context. When
that context is true, `getCleanupSummary` returns only the generic agent-session
effect and the localized note that the parent task's worktree, branch, and files
remain untouched. It does not return the worktree deletion effect or its
single-worktree reassurance. `TaskDeleteConfirmDialog` receives this context
from task-aware callers and, when a caller provides only `taskId`, resolves
`workspaceMode` from `kanbanMulti.snapshots` with `kanban.tasks` as the fallback.
If the task cannot be resolved, the existing executor-based summary remains the
safe fallback.
### Full-dialog composition
`TaskDeleteConfirmDialog` keeps Radix `AlertDialog` and the existing centered
@@ -253,6 +263,8 @@ disabled actions, single and bulk callback values, cascade behavior, and typed
conflict feedback. Dialog and compact-surface tests assert equivalent structured
content, semantic action variants, unchanged callbacks, and that a deferred
positive descendant result does not expose a provisional fine-pointer popover.
The inherited-parent cleanup path is covered at both the summary and rendered
dialog boundaries, including the task-id resolution fallback.
Pending-dismissal component cases cover Escape, trigger focus restoration, and
outside pointer intent.
Rendered desktop and phone checks cover viewport bounds, scroll ownership,