Files
kandev/docs/plans/task-create-executor-default/plan.md
T
2026-08-23 17:34:52 +00:00

7.0 KiB

spec, created, status
spec created status
docs/specs/tasks/requirements/task-create-executor-default.md 2026-08-01 complete

Implementation Plan: Task Create Executor Default

Overview

Change the task-create selection order so source/workspace policy resolves the executor before a portable last-used profile is considered. Lock the behavior down first with focused Vitest regressions, then prove the backend-settings/cross-browser path through the existing Create Task Playwright flow. No backend, schema, API, or rendered-layout change is required.

Confirmed root cause

pickDefaultExecutorProfileId accepts any eligible lastUsedExecutorProfileId before calling pickDefaultExecutorId. For an ordinary repository-backed task, a valid saved Local profile is therefore returned before the no-workspace-default Worktree fallback is resolved. The executor-ID effect also waits for any valid saved profile and then derives the executor from that profile, making the Local selection portable across browsers and updates by design.

Frontend

Executor policy and profile restoration

  • Update apps/web/components/task-create-dialog-effects.ts so pickDefaultExecutorProfileId first obtains the executor selected by pickDefaultExecutorId.
  • Restore lastUsedExecutorProfileId only when its flattened profile candidate belongs to that resolved executor.
  • Prefer the resolved executor's first profile when the saved profile belongs to another executor. Preserve the current first-eligible fallback if the resolved executor has no usable profile.
  • Update shouldWaitForLastUsedExecutorProfile so executor-ID auto-pick waits only for a saved profile compatible with the resolved executor. A saved Local profile must not suppress the Worktree executor-ID fallback for an ordinary repository-backed task.
  • Preserve the current task-source rules in pickDefaultExecutorId: explicit unmanaged local paths and repository-less tasks prefer direct Local; a valid workspace default wins; otherwise DEFAULT_LOCAL_EXECUTOR_TYPE (worktree) is preferred.
  • Keep task-create persistence and submit handlers unchanged. A manual selection still applies to the current task and is still recorded by the backend.

Mobile design contract

  • Desktop and mobile outcome: the existing Executor Profile selector shows the same policy-resolved profile for the same task source and workspace settings.
  • Nearest shipped mobile exemplar: the existing mobile Create Task dialog remains the composition and interaction baseline.
  • Presentation and hierarchy: no markup, overlay, scrolling, safe-area, focus, or touch target changes; only the shared selection state changes.
  • Shared logic: desktop and mobile already call the same task-create effects, so the fix stays in that shared hook.
  • Mobile proof: focused unit coverage is sufficient because this is state normalization inside the unchanged dialog. Existing mobile task-create E2E remains the layout/touch coverage; no new mobile-only interaction is introduced.

Tests

  • What: a saved Local profile cannot override the Worktree fallback for an ordinary repository-backed task with no workspace default.
    • File: apps/web/components/task-create-dialog-effects-executor.test.ts
    • How: render useDefaultSelectionsEffect with Local and Worktree executors, loaded backend settings, and lastUsedExecutorProfileId set to Local; assert Worktree profile and executor ID.
  • What: an explicit Local workspace default remains authoritative.
    • File: apps/web/components/task-create-dialog-effects-executor.test.ts
    • How: use the same executor set with default_executor_id set to Local and a saved Worktree profile; assert Local profile and executor ID.
  • What: source constraints remain authoritative for an explicit local path and repository-less task.
    • File: apps/web/components/task-create-dialog-effects-executor.test.ts
    • How: extend the existing local-path/no-repository cases with a saved Worktree profile and assert a direct Local profile.
  • What: a saved alternative Worktree profile is still restored when Worktree is the resolved executor, and missing-profile fallback behavior remains unchanged.
    • File: apps/web/components/task-create-dialog-effects-executor.test.ts
    • How: retain the existing restoration case and add/adjust table cases around resolved executor membership.

E2E Tests

  • Scenario: GIVEN backend user settings contain a last-used Local profile and the workspace has no executor default, WHEN Create Task opens for the seeded repository in a browser context, THEN the Executor Profile selector shows Worktree.
    • File: apps/web/e2e/tests/task/create-task-executor-default.spec.ts
    • What to verify: seed the Local profile through saveUserSettings, navigate through the regular Kanban UI, open the dialog, and assert the visible Worktree selection.
  • Scenario: GIVEN the workspace explicitly defaults to Local, WHEN Create Task opens for the seeded repository, THEN the selector shows Local even when the saved profile is Worktree.
    • File: apps/web/e2e/tests/task/create-task-executor-default.spec.ts
    • What to verify: set and later restore default_executor_id, assert the visible Local profile, and restore the backend last-used profile to Worktree so the worker-scoped fixture does not leak state.

Implementation Tasks

Execution is sequential in the primary conversation. No subagent delegation is planned or authorized.

Validation

Run from the repository root unless noted otherwise:

  • cd apps/web && pnpm test -- --run components/task-create-dialog-effects-executor.test.ts components/task-create-dialog-executor-wait.test.ts
  • cd apps/web && pnpm run typecheck
  • cd apps/web && pnpm e2e:run --project chromium tests/task/create-task-executor-default.spec.ts

Completed validation: 14 focused Vitest tests passed, the web typecheck passed, targeted ESLint and Prettier checks passed, and the managed Chromium run passed both Create Task scenarios.

The managed E2E runner performs the required production build before Playwright. This worktree ran cd apps && pnpm install --frozen-lockfile before the recorded validation; fresh worktrees must run that prerequisite if frontend dependencies are missing.

Risks

  • The executor-ID and executor-profile effects run independently and settle through microtasks. Tests must assert the final paired selection, not only one setter call, so a transient mismatch cannot become a regression.
  • Existing E2E fixtures preserve task-create last-used fields on partial settings writes. New tests must restore a Worktree profile, and tests that set a workspace default must clear it in cleanup.
  • The single stored last-used profile cannot retain a preferred profile for multiple executor types; adding per-executor history remains explicitly out of scope.