From eafd15f0efebe8a236fb4aff0378418fc0d4e46e Mon Sep 17 00:00:00 2001 From: claude_code Date: Thu, 25 Jun 2026 23:44:49 +0300 Subject: [PATCH] docs(ai-chat): document load-bearing invariant of messageSignature memo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #182 review (post-fix pass) surfaced two latent correctness risks in the new MessageItem memo: the per-message signature tracks only [type, text length, state, error/output presence] + metadata, so a part kind whose VISIBLE content can change WITHOUT changing those fields would silently freeze a stale row. Neither is reachable with the current toolset (tool output is set once; streaming is append-only with a fixed id), so the correct fix is to harden the documented invariant rather than hash output content on every delta (getPage returns full page content — hashing it per-delta would tax the hot path this PR optimizes). Add a WARNING in messageSignature naming the two future triggers (a tool that streams `preliminary` output; a client-side regenerate/edit that mutates a finalized row in place) and the required action (extend the signature). No behavior change (comment only). vitest src/features/ai-chat 189/189 pass, tsc clean for the touched files. Co-Authored-By: Claude Opus 4.8 --- apps/client/src/features/ai-chat/utils/message-signature.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/client/src/features/ai-chat/utils/message-signature.ts b/apps/client/src/features/ai-chat/utils/message-signature.ts index 69c93eba..84c37919 100644 --- a/apps/client/src/features/ai-chat/utils/message-signature.ts +++ b/apps/client/src/features/ai-chat/utils/message-signature.ts @@ -5,7 +5,11 @@ import type { UIMessage } from "@ai-sdk/react"; * appended, a tool/text part flips state once), so a per-part [type, text * length, state, error/output presence] tuple + the persisted metadata * (error/finishReason) is a sufficient change signal without comparing full - * strings on every delta. */ + * strings on every delta. WARNING — load-bearing for the MessageItem memo: + * if a future part kind's VISIBLE content can change WITHOUT changing [type, + * text length, state, error/output presence] (e.g. a tool that streams + * `preliminary` output, or a client-side regenerate that edits a finalized + * row in place), extend this signature or the memo will freeze a stale row. */ export function messageSignature(message: UIMessage): string { const parts = message.parts .map((p) => {