Skip to content

fix: restore ACP chat bindings and preserve pending canvas edits - #182

Merged
cxxxxxn (cxxxxxn) merged 5 commits into
microsoft:mainfrom
cxxxxxn:fix/acp-chat-refresh-state
Sep 14, 2026
Merged

cxxxxxn (cxxxxxn) merged 5 commits into
microsoft:mainfrom
cxxxxxn:fix/acp-chat-refresh-state

Conversation

@cxxxxxn

@cxxxxxn cxxxxxn (cxxxxxn) commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Resolve established Question conversations from their durable owner binding so ACP identity and follow-up routing survive refresh.
  • Apply non-content node updates without overwriting pending local content; compare JSON metadata by value using fast-deep-equal.
  • Preserve the original user baseline across sequential AI note edits, and remove pending modified markers when an AI rewrite restores that baseline without rewriting operation history.
  • Add regression coverage for JSON round trips, nested metadata changes, normalized Markdown restoration, duplicate blocks, and preservation of other pending provenance records.
  • Update the corresponding architecture documentation.

Validation

  • pnpm typecheck: passed across the repository.
  • pnpm format: completed; formatter changes included.
  • pnpm lint:fix: completed with warnings, no errors.
  • Shared package full suite: 383 tests passed.
  • Related web store, save queue, conversation-owner, and provenance suites: 71 tests passed.
  • git diff --check: passed.

Scope

Includes the three existing branch commits plus the review follow-up fixes. No real ACP service/browser end-to-end run was performed.

Related issues

Fixes #141.

Related to #172 and #98: this PR addresses false content-conflict detection for non-content updates, but does not resolve genuine label/content conflicts or the broader parallel-write/version-gap behavior. These issues should remain open.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Three unresolved moderate findings affect delta performance, binding precedence, and provenance restoration.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Restores durable ACP chat bindings, preserves pending canvas edits during sync, and improves AI note provenance handling.

Changes:

  • Restores durable Question-node bindings.
  • Prevents lifecycle deltas from overwriting pending local content.
  • Preserves provenance baselines across sequential AI edits.
  • Adds dependency updates, regression tests, and architecture documentation.
File summaries
File Reviewed change
pnpm-lock.yaml Locks the deep-equality dependency.
packages/shared/src/types/canvas/node.ts Updates provenance contracts.
packages/shared/src/canvas-engine/provenance/noteProvenance.ts Preserves and clears AI provenance. Moderate, 2 votes: Preserve the baseline canonical key or compare against full-document definitions to handle reference-style syntax correctly.
packages/shared/src/canvas-engine/__tests__/noteProvenance.executor.test.ts Adds provenance regression coverage.
docs/architecture/question-node.md Documents durable binding replay.
docs/architecture/note-node.md Documents provenance restoration behavior.
docs/architecture/canvas-realtime-sync.md Documents lifecycle delta merging.
apps/web/src/utils/__tests__/blockProvenance.test.ts Tests provenance edge cases.
apps/web/src/store/conversationOwner.ts Adds durable binding resolution. Moderate, 1 vote: Restrict binding precedence to established/fixed conversations so editable threads honor updated selections.
apps/web/src/store/conversationOwner.test.ts Tests binding resolution.
apps/web/src/store/canvasStore.ts Preserves pending content during delta application. Moderate, 1 vote: Construct localNodesById lazily to avoid unnecessary O(n) work on clean canvases.
apps/web/src/store/canvasStore.agentDeltaConflict.test.ts Tests delta conflict behavior.
apps/web/src/hooks/useAgentStream.ts Uses durable bindings for requests.
apps/web/src/components/Panels/ChatPanel/index.tsx Hydrates bindings synchronously.
apps/web/package.json Adds fast-deep-equal.
Review details

Files not reviewed (1)

  • pnpm-lock.yaml: Generated file

Suppressed comments (2)

apps/web/src/store/canvasStore.ts:1574

  • localNodesById is allocated by scanning every canvas node before the dirty.size === 0 fast path is selected, and it is never read for the usual clean-canvas case. Every incoming agent delta batch therefore pays O(number of nodes) work introduced by this change; make the lookup lazy or construct it only when dirty.size > 0.
      const preservedPendingNodeIds = new Set<string>();
      const localNodesById = new Map(
        get().nodes.map((node) => [node.id, node]),
      );

apps/web/src/store/conversationOwner.ts:127

  • This unconditionally treats any source.agentBinding as authoritative, but ChatPanel still exposes the selector for selectable Question nodes with no user messages. For a selectable/idle node that already has a binding, choosing another agent only updates the cache; this function keeps returning the old node binding, and the first send routes with it again. Restrict owner precedence to established/fixed conversations (or pass the compose state) so editable threads continue to use their cache binding.
export function resolveConversationAgentBinding(
  source: ConversationOwnerSource | undefined,
  cachedBinding: AgentBinding,
): AgentBinding {
  return source?.agentBinding ?? cachedBinding;
  • Files reviewed: 14/15 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +163 to +167
const baselineBlocks = fingerprintMarkdownBlocks(
existing.baselineMarkdown,
);
// Occurrence suffixes identify duplicate positions, not block content.
// Only a return to the original normalized block cancels a modification.
@cxxxxxn
cxxxxxn (cxxxxxn) merged commit c613f85 into microsoft:main Sep 14, 2026
2 checks passed
@cxxxxxn
cxxxxxn (cxxxxxn) deleted the fix/acp-chat-refresh-state branch September 14, 2026 07:00
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.

ChatPanel profile selector can mismatch the active external-agent thread

2 participants