Files
makelore/.project-docs/30-worklog/tasks/20260904-design-summary-separation-9c4e7a21.md
brother7 403236115b
Some checks failed
Electron E2E / Electron E2E (macos-latest) (push) Has been cancelled
Electron E2E / Electron E2E (ubuntu-latest) (push) Has been cancelled
Electron E2E / Electron E2E (windows-latest) (push) Has been cancelled
fix(design): show submitted messages immediately
2026-09-04 08:38:13 +08:00

9.2 KiB

Task: Separate AI Design summary from chat messages

Identity

  • Task ID: 20260904-design-summary-separation-9c4e7a21
  • Mode: Feature
  • Branch: codex/20260904-design-summary-separation-9c4e7a21-design-summary-separation
  • Worktree: D:\Datas\OthersProjects.codex-worktrees\makelore\20260904-design-summary-separation-9c4e7a21
  • Base commit: 945b40de11
  • Owner: codex-root
  • Status: Ready for Integration

Scope

  • Separate in-progress AI Design reasoning from committed conversation messages in the ImageCanvas Renderer. Raw assistant stream text must not appear as a finished chat bubble; the UI should show an explicit, non-content progress state until the canonical turn arrives.
  • Close the supported duplicate-stream path caused by overlapping event-source opens and repeated/out-of-order chunkIndex delivery.
  • Project a newly submitted chat command into the conversation immediately, before the server returns the canonical turn. Keep the provisional message visually honest, replace it with the canonical turn without duplication, and restore the draft after a definitive failure.
  • Add focused Renderer and Store regression tests. Do not change Works Square server, Electron Main DTO/API, Current Specification authority, Quote/generation, Plugin navigation, packaging, publication, or the three foreign root task records.

Intent And Constraints

  • The screenshot proves that transient stream content is visually indistinguishable from an assistant reply and that chunks are duplicated. A progress draft is not a semantic turn and must not be presented as one.
  • Keep the final persisted assistant question visible in the conversation after the command settles. Do not parse model prose to guess where a summary ends or a question begins.
  • Preserve stable operation identity and transport-unknown state. A temporarily uncertain accepted command may retain its internal stream state, but unfinished prose remains hidden behind an honest status label.
  • Preserve ADR-007: Current Specification remains the semantic authority and the right-side “AI 听懂的想法” remains its secondary projection.
  • Keep Chinese-only copy, reduced-motion behavior, at least 40 px interactive targets, and the current responsive single-mount behavior.
  • Do not create a second chat state machine: the existing pending operation is the provisional message identity, while only the returned Workspace turn is canonical.

Project Context Loaded

  • Concurrent Task Gate: passed in an isolated managed worktree because root main remains owned by integration task 20260904-integrate-guided-design-6a3f9c82 and contains three explicitly preserved foreign untracked task records.
  • Planning Gate: passed after reading the active task, startup memory set, integrated state, ADR-007, system overview, business rules, success criteria, evidence index, and relevant peer scopes.
  • Relevant peers: the old Enter-only E2E task owns only one historical test path; the undefined August assessment task has no implementation scope. Neither semantically conflicts with this isolated current-frontier ImageCanvas change. Plugin-navigation tasks are in separate worktrees and outside scope.
  • project-positioning.md and top-level project success remain placeholders; concrete authority comes from ADR-007 and populated current-state, architecture, domain, and prior Design task records.
  • Likely files: src/pages/ImageCanvas/DesignConversationPane.tsx, src/stores/image-workspace.ts, tests/unit/image-canvas-page.test.tsx, and tests/unit/image-workspace-store.test.ts.
  • Gate result: Passed.

Outcome

  • A chat command now appears in the conversation immediately from its existing PendingDesignOperation, before the server returns the canonical Workspace turn. The provisional user bubble carries a small 发送中 state, changes to 正在确认 for an unknown accepted outcome, and is filtered to the active Workspace.
  • While that exact draft is projected as a provisional bubble, the composer looks cleared without deleting the stored draft. Canonical success atomically replaces the provisional bubble with the persisted turn; definitive failure removes the pending projection and naturally restores the original draft for correction/retry.
  • First-use guidance is hidden as soon as the first provisional user message exists. Other in-flight Design input commands retain the existing composer lock, so the UX change does not introduce concurrent reducer writes.
  • DesignConversationPane no longer renders raw assistantStreams prose as an assistant chat bubble. It renders one compact role=status surface that explicitly says the AI is organizing the idea and that the content is not a new reply. A transport-unknown operation instead says the existing result is being confirmed and must not be resent.
  • Final canonical turn.assistantMessage content remains in the ordinary conversation; the implementation does not parse or classify model prose.
  • Event connection startup now has a generation fence. An open that resolves after a disconnect/replacement closes itself, so React remounts cannot leave two live sources consuming the same stream. A failed open releases the pending connection identity so a later retry remains possible.
  • Assistant chunkIndex is now consumed as the ordering/deduplication contract; replayed or older chunks do not append duplicate text. Chunk progress is cleared with successful/definitive settlement and Workspace reset/switch/delete.
  • The root main worktree and its three foreign untracked task records were not modified.

Verification

  • New optimistic-message red baseline: Store publication passed, while the Renderer regression failed because no 发送中 message existed, the first-use prompt remained, and the composer still showed the submitted draft. After the fix, the two focused files pass 27/27, including submitting → unknown → canonical replacement.
  • Adjacent ImageCanvas, Store, Fine Tune, youth summary/projection/copy tests now pass 6 files / 51 tests.
  • Follow-up TypeScript tsc --noEmit, changed-file ESLint, and production Renderer/Main/Preload/utility Vite build pass. Build output contains only the existing browserslist, dynamic-import, and large-chunk warnings.
  • Electron/Playwright AI Design checks both pass individually: Prompt Museum media isolation passed in the two-test run; the conversation/adjustment/Quote/Task flow initially timed out at the pre-Design auth-fixture readiness gate, then passed 1/1 in isolation in 1.8 seconds. The timeout occurred before this feature path and is not recorded as product success evidence for the new provisional state.
  • Red baseline: three new regressions failed against the original implementation—raw unfinished prose had no progress role, an obsolete concurrent EventSource was not closed, and replaying chunk index 0 produced duplicated text. A fourth targeted red test caught and prevented a retry regression introduced by the first connection fence implementation.
  • Focused conversation/store tests: 25 passed.
  • Adjacent ImageCanvas, Store, Fine Tune, youth summary/projection/copy tests: 6 files / 49 passed.
  • TypeScript tsc --noEmit: passed.
  • Changed-file ESLint: passed.
  • Production Renderer/Main/Preload/utility Vite build: passed; only existing browserslist, dynamic-import, and chunk-size warnings were emitted.
  • Electron/Playwright AI Design V2 flow: 2 passed, covering desktop/mobile layout, conversation, optional adjustments, Quote, and generation confirmation.
  • git diff --check: passed before task-document completion.

Follow-ups

  • Integrate the completed source commit onto client main after the existing root integration owner is safely released or explicitly recovered. Do not force-release it or modify its three adopted foreign task records without separate authority.

Promotion Candidates

  • Target: .project-docs/30-worklog/current-state.md, canonical AI Design UX wording, and the AI Design stream reconciliation rule in architecture/domain memory.
  • Proposal: record that design.assistant.delta is unfinished progress, never a committed conversation turn. Renderer may show an explicit progress/uncertainty status but must not render its raw prose as a chat reply; only canonical persisted turns enter the timeline. A locally submitted chat command may appear immediately as a clearly provisional user bubble by projecting its existing pending operation; it must disappear when the canonical turn arrives and must not become a second semantic message store. Concurrent/replayed stream delivery must converge by connection generation and chunkIndex.
  • Evidence: the user screenshot, four red-before/green-after regressions, 49 adjacent tests, typecheck, scoped lint, production build, and 2/2 Electron E2E.
  • Future impact: later streaming polish must preserve the distinction between transient reasoning/progress, authoritative Specification projection, and committed dialogue.
  • Semantic conflicts: none; this sharpens the conversation-primary behavior already integrated while preserving ADR-007.
  • Human confirmation: the user explicitly identified the chat-bubble presentation as misleading; no additional product-direction decision is required.