Skip to content

fix(transcript): keep steer frame promptIds and arrival order across cold rebuilds - #3426

Open
liruifengv wants to merge 6 commits into
mainfrom
fix/steer-frame-prompt-ids
Open

fix(transcript): keep steer frame promptIds and arrival order across cold rebuilds#3426
liruifengv wants to merge 6 commits into
mainfrom
fix/steer-frame-prompt-ids

Conversation

@liruifengv

Copy link
Copy Markdown
Collaborator

Related Issue

Companion to the code-app PR fixing stale steer echoes (MoonshotAI/kimi-code-app#490); no standalone issue.

Problem

A steered user message can reappear as a ghost bubble at the bottom of the chat after the client refreshes its transcript page, and the per-turn diff panel renders before the turn ends. The client-side root cause (paginated turns vs. unpaginated prompts) is fixed in the companion PR. On the server side, two latent inconsistencies in the transcript rebuild paths can destroy the same promptIds pairing the fix relies on:

  1. Cold rebuild drops promptIds on steer frames. groupMessagesIntoSnapshot folds a steered user message into its turn as a user text frame but never stamps it with the prompt ids, even though prompt.steered records carry them. When the post-turn heal (healEndedTurns, 250ms after every terminal turn) patches the live store with cold-rebuilt frames, a live frame that carried promptIds can be replaced by a cold frame without them — breaking echo pairing for fresh steers, which the client-side age rule cannot suppress.
  2. Live and cold paths order queued frames differently. The live projector flushes pendingTaskNotifications before pendingSteers at step start, while the cold path keeps a single arrival-ordered queue. When a steer and a task notification land in the same inter-step gap, frameIds misalign between the two paths, so heal compares the wrong frames and can clobber or duplicate them.

What changed

  • packages/kap-server/src/services/transcript/transcriptService.ts: readColdSnapshot now records prompt.steered records into per-content promptId queues and pairs them into turn.steer entries (FIFO, so identical contents steered repeatedly pair in order; unmatched entries degrade to undefined, same as before).
  • packages/transcript/src/history/groupTurns.ts: steeredContents values changed from counts to promptId queues; a folded steer frame is stamped with the queued promptIds.
  • packages/kap-server/src/services/transcript/coreEventMap.ts: pendingTaskNotifications and pendingSteers merged into one arrival-ordered pendingUserFrames queue, flushed in arrival order at step start; turn-end semantics unchanged (steers flushed, notifications dropped).

Tests

  • packages/transcript/test/layers.test.ts: 9 existing steer-map usages migrated to the queue shape; 2 new cases (promptIds stamped on the folded frame, repeated identical contents pair in order).
  • packages/kap-server/test/services/transcript.test.ts: new cold-path case (readColdSnapshot stamps promptIds from prompt.steered) and new live-path case (queued steer + notification flush in arrival order).
  • pnpm --filter @moonshot-ai/transcript test — 111 passed; pnpm --filter @moonshot-ai/kap-server test — 1318 passed (one unrelated heartbeat timing flake in instanceRegistry.test.ts, passes in isolation); pnpm lint — 0 errors.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: the issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c43a73c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@moonshot-ai/kap-server Patch
@moonshot-ai/transcript Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Sep 1, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@c43a73c
npx https://pkg.pr.new/@moonshot-ai/kimi-code@c43a73c

commit: c43a73c

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a16b97081c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/kap-server/src/services/transcript/transcriptService.ts Outdated
@liruifengv

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c5a6057b8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/kap-server/src/services/transcript/transcriptService.ts Outdated
Comment thread packages/kap-server/src/services/transcript/transcriptService.ts Outdated
@liruifengv

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7768880273

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/kap-server/src/services/transcript/transcriptService.ts Outdated
Comment thread packages/kap-server/src/services/transcript/transcriptService.ts
@liruifengv

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88b19841c7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/transcript/src/history/groupTurns.ts Outdated
Comment thread packages/kap-server/src/services/transcript/transcriptService.ts Outdated
Comment thread .changeset/steer-frame-prompt-ids.md
@liruifengv

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c43a73c947

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

const steeredByKind = steeredContents.get(contentKey);
const steeredRemaining = steeredByKind?.get(steerKind) ?? 0;
const matchedSteer = steeredByKind !== undefined && steeredRemaining > 0;
const steeredPromptId = matchedSteer ? steeredPromptIds[steeredPromptIdIndex] : undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pair IDs with the actual steer occurrence

When an ordinary user prompt has the same content and origin as a later steer, steeredContents already contains the later record while messages are folded from the beginning, so this line assigns the later steer’s promptIds to the earlier prompt and exhausts the count before reaching the actual steer. The cold snapshot then omits the IDs from the real steer frame and may reconcile the wrong prompt entity during post-turn healing; pairing must preserve each surviving turn.steer record’s position rather than treating content matches as an unordered count.

AGENTS.md reference: packages/transcript/AGENTS.md:L9-L11

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant