Files
kandev/docs/specs/tasks/system-design/initial-task-brief.md
T
2026-09-13 12:06:50 +01:00

127 lines
6.5 KiB
Markdown

---
status: current
system: tasks
requirements:
- REQ-TASKS-INITIAL-TASK-BRIEF-001
created: 2026-09-12
updated: 2026-09-12
owners:
- kandev
---
# Initial task brief system design
## Boundary and mapping
The task service owns accepted prompt content. The repository selects initial
content inside its existing session write transaction. The handler dispatches
the committed result. This extends the existing first-prompt boundary.
| Requirement | Design sections |
| --- | --- |
| `REQ-TASKS-INITIAL-TASK-BRIEF-001` | Admission, Composition and delivery, Transcript, Failure and compatibility |
## Admission
`MessageHandlers.wsAddMessage` already resolves session changes after
`ProcessOnTurnStart`. Eligibility belongs to that resolved session, including
a CREATED source redirected to a fresh workflow session. The service verifies
task/session ownership and excludes Office, ephemeral, and configuration contexts.
Use a server-only admission option on `CreateMessageRequest`. It carries a
prepared initial-content candidate and its corresponding trusted prompt context.
This option is not a public request field and is never accepted from client metadata.
Existing callers without the option keep their current behavior.
Select between ordinary and initial candidates inside the existing repository
user-message transaction, before `assignUserMessageBoundary` allocates an ordinal.
Read `task_session_prompt_seq` with the same transaction and session write lock.
An existing row, including `last_seq = 0`, means that another prompt owns the
first boundary. Do not use CREATED state, transcript length, title ownership,
or the eventual ordinal alone as proof of eligibility.
Extend the shared boundary used by ordinary, idempotent, plan-comment, and
queued plan-comment message writes. Keep candidate selection, message insertion,
ordinal allocation, comment consumption, and queue insertion atomic where those
operations are already atomic. Preserve SQLite writer serialization and the
PostgreSQL session advisory lock. A new counter table or migration is unnecessary.
The candidate uses a task-description snapshot read from authorized task data.
Validate that snapshot against the task row during final admission. A concurrent
description edit rejects stale admission for recomposition, rather than saving
an unintended stale brief. Do not run saved-prompt lookups inside the write transaction.
Return the selected content and selected trusted-context identity to the service.
The same selection determines persistence, queue content, and agent dispatch.
On rollback, restore caller-visible content and metadata as well as timestamps
and prompt ordinal. Otherwise retries can retain a failed selection.
## Composition and delivery
For an eligible candidate, put the trimmed brief before the additional
instruction, separated by two newlines. Exact equality after outer trimming
produces one copy. Empty descriptions use the ordinary candidate.
Prepare both candidates through the existing server-owned saved-prompt and
system-context pipeline before admission. Resolve title ownership, canvas
capabilities, and session transitions once, then reuse their canonical snapshots. Keep each candidate paired with its
trusted expansion. Fingerprint the original request before either transform.
An idempotent replay returns the saved winner even after the description changes.
`wsAddMessage` already assigns `req.Content = message.Content` before dispatch.
Extend that handoff to use the selected trusted context. Do not independently
prepend the brief inside `StartCreatedSession`, `startTask`, or the browser.
The real created-session launch must preserve both visible sections through
workflow composition. Compose the applicable workflow instructions once and
retain the accepted direct content as user input. If a replacing step template
would discard this content, append the direct content after that template and
use the existing composed-prompt launch option to prevent a second replacement.
Keep automatic workflow-entry composition unchanged. Test empty step prompts,
`{{task_prompt}}`, and nonempty templates without that placeholder.
The saved user row and final dispatch must contain the same visible brief and
instruction. Existing canonical system-context additions retain their authority.
Passthrough delivery retains visible text without hidden saved-prompt expansion.
Keep submitted attachments, entity references, and plan-comment claims intact.
`initial_prompt_preview` remains display-only and cannot supply prompt authority.
## Transcript
Keep `useProcessedMessages` and `shouldShowTaskDescriptionFallback` eligibility
unchanged. Before admission, the synthetic description row represents the brief.
After admission, prompt #1 replaces it and contains the brief plus instruction.
No synthetic historical prompt, extra ordinal, or permanently pinned banner is needed.
Reuse the existing transcript and Prompt History renderers. The nearest mobile
exemplar is `components/task/task-layout.tsx` and its `SessionMobileLayout`.
Phone Chat remains a full-height destination with one transcript scroll owner.
Composer position, safe-area handling, touch targets, and navigation remain unchanged.
Long first prompts remain reachable through existing prompt expansion/history controls.
## Failure and compatibility
A history, snapshot, or persistence error stops admission before dispatch.
Existing launch-error behavior handles failures after message acceptance. This
package does not promise provider-level exactly-once delivery after a process crash.
Race tests must include a direct request competing with
`ClaimInitialPromptFallback`, two distinct direct messages, and a same-ID retry.
A zero-valued fallback reservation suppresses direct brief insertion.
Deleted user rows cannot make an existing prompt-counter row eligible again.
Existing launch, workflow-entry, and Office callers do not opt into this direct
admission option. No public API field, database migration, or new UI control is needed.
This design records a local extension of existing ownership, so no separate ADR is required.
## Related contracts
- [Workflow first-prompt ownership](workflow-step-agent-start-ownership.md#prompt-history-contract)
- [Saved-prompt delivery](saved-prompt-delivery.md)
- [Transcript history visibility](../../ui/system-design/task-prompt-transcript-visibility.md)
- [Server-owned saved-prompt expansion](../../../decisions/2026-09-01-server-owned-saved-prompt-expansion.md)
## Implementation plans
[Initial task brief fix package](../../../plans/initial-task-brief/plan.md)