8.7 KiB
created, status, requirements, system_design, legacy_specs
| created | status | requirements | system_design | legacy_specs | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 2026-09-02 | done |
|
|
|
Implementation Plan: Deduplicate Empty Workflow Prompts
Overview
The backend uses an atomically claimed session prompt boundary before it applies the task-description fallback. The frontend uses the canonical plan-tool names.
The follow-up work makes immediate agent-start placement independent of agent mode. This keeps the task in the workflow step that owns automatic starts.
Scope
In scope
- Stop repeated task-description prompts on empty automatic-start steps.
- Apply one fallback rule to automatic step entry and explicit workflow-step launch.
- Preserve non-empty step prompts for prompted sessions.
- Preserve the first task-description prompt for unprompted sessions.
- Correct
plan_getandplan_updatein the active-plan context. - Add focused Go, TypeScript, and Playwright regressions.
- Route an immediate plan-mode agent start to the first automatic-start step.
- Prove the routing through desktop and mobile task creation.
- Update the public workflow guidance.
Out of scope
- Do not change the first-step placement of plan-only prepared sessions when
start_agent=false. - Do not change the configured start-step behavior for no-agent task creation.
- Do not change workflow prompts that contain text.
- Do not add a database column or migration.
- Do not change MCP tool registration or transport names.
Technical approach
Durable prompt history
Add a bounded repository query for task_session_prompt_seq.last_seq and an atomic initial-fallback claim. The claim and direct user-message creation use the same per-session persistence boundary, so concurrent automatic and explicit admissions cannot both qualify as the first prompt. The claim uses a zero-valued counter row as its reservation marker, so the first visible message still receives prompt ordinal 1.
Expose this query and claim through the repository contract that the orchestrator uses. Keep message deletion behavior unchanged because the counter never decreases.
Shared workflow prompt decision
Add an orchestrator helper that composes a workflow-entry prompt for one session. For an empty WorkflowStep.Prompt only, use the task description only when the atomic initial-fallback claim succeeds. Non-empty step prompts, including {{task_prompt}} expansion, retain their existing semantics.
Call the helper from launchAfterOnEnterDispatch before its ACP or passthrough split. Call the same helper from StartSessionForWorkflowStep.
Keep buildWorkflowPromptWithTrustedContext as the string composer. Keep non-empty WorkflowStep.Prompt behavior unchanged.
Apply plan-mode and session-config transforms before deciding whether the composed prompt is empty. If the composed ACP prompt is empty, let autoStartStepPrompt inspect any queued handoff first. Return without message creation or dispatch only when the merged prompt and attachments are empty. Attachment-only handoffs are admitted and persisted with their metadata.
Plan-tool names
Change the active-plan context in apps/web/hooks/use-message-handler.ts. Use get_task_plan_kandev and update_task_plan_kandev.
Export the pure context helper for focused unit coverage. Do not localize this model-facing instruction.
Immediate-launch placement
Change task.Service.resolveWorkflowStep so StartAgent is evaluated before
PlanMode. A request with both values uses ResolveAutoStartStep. A request
with only PlanMode continues to use ResolveFirstStep.
Keep explicit workflow_step_id precedence and the existing automatic-start
fallback chain. No transport, API, persistence, or frontend production change
is required.
Update the existing desktop workflow E2E scenario. Add a mobile scenario that uses the visible plan-mode action. Update the public task-creation reference and troubleshooting text.
Tests
AC-TASKS-WORKFLOW-STEP-AGENT-START-OWNERSHIP-003.1: add a Go test for an unprompted session on an empty automatic-start step.AC-TASKS-WORKFLOW-STEP-AGENT-START-OWNERSHIP-003.2: add a Go test for a prompted plan-mode session that later enters an empty automatic-start step.AC-TASKS-WORKFLOW-STEP-AGENT-START-OWNERSHIP-003.3: add a Go test that a non-empty step prompt still dispatches after earlier prompts.AC-TASKS-WORKFLOW-STEP-AGENT-START-OWNERSHIP-003.4: assert that an empty result creates no user row and no runtime prompt, while an attachment-only handoff remains durable input.AC-TASKS-WORKFLOW-STEP-AGENT-START-OWNERSHIP-003.5: add a focusedStartSessionForWorkflowStepregression.AC-TASKS-WORKFLOW-STEP-AGENT-START-OWNERSHIP-003.6: cover the shared decision before the transport split.AC-TASKS-MCP-TOOL-NAMES-001.3: add a TypeScript test for canonical plan-tool names.AC-TASKS-WORKFLOW-STEP-AGENT-START-OWNERSHIP-004.1: update service and transport routing tests forstart_agent=truewithplan_mode=true.AC-TASKS-WORKFLOW-STEP-AGENT-START-OWNERSHIP-004.2: retain the existing automatic-start fallback test.AC-TASKS-WORKFLOW-STEP-AGENT-START-OWNERSHIP-004.3: retain the explicit-step precedence test.
E2E tests
Update apps/web/e2e/tests/workflow/start-step-vs-auto-start-step.spec.ts.
Start a plan-mode agent through the desktop task dialog. Assert that the task
lands in the first automatic-start step.
Keep the duplicate-prompt scenario by making Plan the first automatic-start destination. Move the idle task into a second empty automatic-start step. Assert that the description appears once and that no extra turn exists.
Add apps/web/e2e/tests/workflow/mobile-start-step-vs-auto-start-step.spec.ts.
Use the mobile plan-mode button and assert the same destination. These tests
change behavior only. The current task dialog layout and mobile composition
remain unchanged.
The current mobile task-create footer is the nearest mobile exemplar. It keeps the plan-mode action visible as a touch-sized button. The desktop split menu and the mobile button continue to use one submission handler.
Work orders
- Task 01: Deduplicate empty workflow prompts
- Task 02: Correct plan-tool names
- Task 03: Prove the plan-mode workflow flow
- Task 04: Route immediate plan-mode starts
Verification results
- Backend focused race suite: 18 tests passed after the PR fixup, including prompt-admission races, plan-only and attachment-only inputs, passthrough draining, and session-ID reuse cleanup.
- Backend full suite: all packages passed with the task-session internal
configuration handoff variables cleared. The plain command was blocked by
the inherited launcher-selected
/root/.kandev/config.yaml, which made isolated config-discovery tests select the operator config. - Backend
make lint: 0 issues. - Backend new-from-
origin/maingolangci-lint: no issues. - Frontend focused hook suite: 27 tests passed.
- Frontend typecheck, targeted ESLint, i18n check, and i18n ratchet: passed.
- Frontend production build and targeted Playwright regression: passed.
- Task 04 focused backend suite: 14 tests passed in 2 packages.
- Task 04 desktop Playwright suite: 3 tests passed, including the retained duplicate-prompt regression.
- Task 04 mobile Chrome Playwright suite: 1 test passed through the phone-only Plan mode action and phone board navigation.
- Public documentation validation: 61 tests passed and 41 published pages validated.
Risks
- A transcript scan can grow with session size. The implementation must use the bounded prompt counter.
- Suppression before queued-message merge can lose a handoff. The ACP path must merge first.
- A broad guard can suppress non-empty step prompts. The claim applies only to the empty
WorkflowStep.Promptfallback; non-empty prompts, including{{task_prompt}}, retain their existing semantics. - A session-ID reuse can leak a prompt claim if the counter is not removed with the session. Delete the counter explicitly because the replay-safe table has no foreign key.
- The explicit workflow-step path also manages resume state. Prompt suppression must not change its existing lifecycle behavior.
- The current desktop E2E scenario encodes the old plan-mode destination. Task 04 must replace that assertion without removing duplicate-prompt coverage.