Skip to content

fix(planreview): anchor comments reliably and highlight what they point at - #114

Merged
tusharbhardwaj-bk merged 1 commit into
expbkmainfrom
t3code/brest
Aug 18, 2026
Merged

tusharbhardwaj-bk merged 1 commit into
expbkmainfrom
t3code/brest

Conversation

@tusharbhardwaj-bk

@tusharbhardwaj-bk tusharbhardwaj-bk commented Aug 17, 2026 •

Copy link
Copy Markdown
Collaborator

Why

Anchored plan feedback reached the agent as raw <review_comment> XML instead of a card:

raw XML in the transcript

Three links, each reproduced end to end against the real functions before changing anything:

  1. locateQuotedLineRange compared the reviewer's quote against raw markdown with String.includes. The quote comes from window.getSelection().toString() over rendered Plate output, so ** and backticks are already gone — '1. **Outbound email context**'.includes('1. Outbound email context') is false. Comments on formatted lines are the common case, not an edge case.
  2. With no range located, formatPlanReviewComment omitted startIndex/endIndex.
  3. parseReviewCommentContext required both indices, returned null, and the transcript fell back to printing the block verbatim — so the XML rendered as prose and the ```markdown fence became a monospace code block. apps/mobile had the identical gate.

Separately, CommentLeaf was registered but nothing ever applied a comment mark — a comment was real on the server and invisible in the document.

What changed

The prompt path

  • planReviewAnchorText projects both sides onto the text a reader would select (strips block syntax, emphasis, code spans, links/images) before comparing. Only the comparison changes; quotedText still travels verbatim.
  • The range is now optional in both parsers, so a future locate miss degrades to a card without a line range rather than to raw XML.
  • A plan comment renders as its own card — plan title and a blockquote, not a workspace-relative path and a code block. The byline moved from the body into an author attribute.

The review surface

  • Two-tier highlight: bright while composing, persistent amber once saved, hairline once resolved. Restored on reopen by re-locating the stored quote, so teammates' comments are highlighted too.
  • Inline comment popover beside the selection (quote in the header, ⌘/Ctrl+Enter, Esc), replacing the box at the foot of the panel.
  • One-click 👍 / remove quick labels.
  • Two-way rail ↔ document linking.
  • Width-gated Contents outline with per-section comment counts, via container query — no ResizeObserver.
  • Send feedback only claims the primary slot once there is feedback to send.

Verification

123 tests passed across 8 scoped files; tsgo --noEmit clean for apps/web and packages/shared; apps/mobile is byte-identical to its pre-existing 76-error navigation baseline; lint and check-fork-markers.ts pass.

Two traps are pinned by tests against a real Plate editor, because either would make commenting look like a reviewer edit and send the agent a spurious edited-plan document:

  • serialized markdown is byte-identical after applying a comment mark and after a draft mark;
  • cancelling a draft restores the tree exactly.

Reviewer check on bkt3-dev: open a plan, select a bold list item, comment — the text should highlight and the transcript card should show the plan title and a quotation, with no <review_comment> text and no monospace block.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…nt at

Anchored plan feedback reached the agent as raw `<review_comment>` XML. Three
links, each verified: `locateQuotedLineRange` compared the reviewer's quote —
captured from rendered Plate output, so already stripped of markdown — against
raw source with `String.includes`, so any bold or code-spanned line missed;
`formatPlanReviewComment` then omitted the range; and the transcript parser
required that range, rejected the block, and fell back to printing it verbatim.
Comments on formatted lines are the common case, not an edge case.

Fix all three. `planReviewAnchorText` projects both sides onto the text a reader
would select before comparing, the parser treats the range as optional in web and
mobile alike, and a plan comment now renders as its own card — plan title and a
blockquote, not a workspace-relative path and a monospace code block.

Separately, `CommentLeaf` existed but nothing ever applied a mark, so a comment
was real on the server and invisible in the document. Selecting now highlights
immediately, saving turns that into a persistent amber anchor, and reopening the
panel restores highlights by re-locating the stored quote. Comment marks are
proven not to reach the serialized markdown, so commenting never dirties the
draft.

Rounds out the review surface with the UX worth taking from Plannotator: an
inline comment popover beside the selection, one-click 👍/remove labels,
two-way rail-to-document linking, and a width-gated Contents outline carrying
per-section comment counts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Aug 17, 2026
@tusharbhardwaj-bk
tusharbhardwaj-bk changed the base branch from main to expbkmain August 17, 2026 19:16
@github-actions github-actions Bot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 17, 2026
@github-actions

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 11.4 KiB — 15.1 KiB ✅
Codex Thread snapshot wire — 5.7 KiB — 7.3 KiB ✅
Codex Live turn WebSocket wire — 5.7 KiB — 7.8 KiB ✅
Codex Live turn WebSocket decoded — 50.4 KiB — 66.4 KiB ✅
Codex Live turn messages — 11 — 21 ✅
Claude Total thread wire — 11.5 KiB — 15.1 KiB ✅
Claude Thread snapshot wire — 5.7 KiB — 7.3 KiB ✅
Claude Live turn WebSocket wire — 5.7 KiB — 7.8 KiB ✅
Claude Live turn WebSocket decoded — 51.2 KiB — 66.4 KiB ✅
Claude Live turn messages — 11 — 21 ✅

Baseline: unavailable · PR result: 57ef413 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 95.6 KiB
  • Claude decoded thread snapshot: 96.3 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@tusharbhardwaj-bk
tusharbhardwaj-bk merged commit 6c6e83d into expbkmain Aug 18, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant