Repository navigation
Description
Written-by: Delivery-1
Implementation: FlyBot (ours) — PR follows within the hour.
What happens
visibleText unwraps a complete <untrusted-message …>…</untrusted-message> by taking the text between the first opener and the last closer and throwing the rest away. So a stored line that quotes a remote line in the middle and then says something of its own loses both of its own halves: the sidebar row and the ⌘K row show the quoted text alone.
core/src/shared/preview.js:31 at 5e71a07e (base delivery/ai-centric-development-service):
const open = out.indexOf('<untrusted-message')
if (open < 0) break
const close = out.lastIndexOf('</untrusted-message>')
const inner = close > open ? out.slice(out.indexOf('>', open) + 1, close) : out
out = stripFence(inner)The module's own comment above it promises the opposite — "Words that never were part of a marker are kept, because a preview is still the line someone said" — so this is the code disagreeing with its documented contract, not a new rule.
Reproduction (at 5e71a07e, no source change)
import { visibleText } from './src/shared/preview.js'
visibleText('hello <untrusted-message from="U">a</untrusted-message> world') // "a"
visibleText('before <untrusted-message from="U">a</untrusted-message>') // "a"
visibleText('<untrusted-message from="U">a</untrusted-message> after') // "a"User-visible through core/src/client/text.js:393 (readableLine → collapsedLine → visibleText), the one reader previewOf and the palette both use:
readableLine('He said <untrusted-message from="Coder">\nplease rebase the branch\n</untrusted-message> and I answered that it is done.')
// actual: "please rebase the branch"
// expected: "He said please rebase the branch and I answered that it is done."previewOf over a turnOutline whose response is that stored line returns the same wrong text, so the sidebar preview and the palette search row both show what the Bot was quoted rather than what it answered. This also flips which text of a line reaches a person: the quoted half is remote-authored, the dropped half is the Bot's own words.
Expected behaviour
- A complete wrap in the middle of a line loses its markers in place and keeps every word around it; two wraps in one line both unwrap (
a <…>one</…> b <…>two</…> c→a one b two c). - A line that is only a complete wrap still reads as just its words (
<untrusted-message from="Coder">\nhello there\n</untrusted-message>→hello there) — unchanged. - A broken fragment keeps today's behaviour:
kick from="User"> B test 4 >→kick B test 4 >, andbefore <untrusted-message from="C">x→before x. - No marker of any shape (
untrusted,from="…">) reaches a row; the line stays one line.
Scope
core/src/shared/preview.js—visibleTextunwraps each complete wrap in place (head + inner + tail) instead of keeping only the inner text;stripFenceis unchanged.core/test/preview-fence-words.test.js— the five cases above (three red on the base tree).- Generated, not hand-edited:
core/client.js(the module is bundled into the client) andpatches/ds-bot/0008-client-bundle.patch+patches/ds-bot/files/**.
Red first (base 5e71a07e, before the source change)
$ cd core && TZ=UTC node --import ./test/harness-resolve.mjs --test test/preview-fence-words.test.js
not ok 1 - words before and after a complete wrap stay in the line
not ok 2 - every complete wrap in one line is unwrapped, not only the outermost pair
not ok 5 - a reply that quotes a remote line shows the reply, not only the quote
actual: 'please rebase the branch'
# tests 5 / # pass 2 / # fail 3
Cases 3 and 4 (wrap alone, broken fragment) are controls: they pass before and after, so the fix cannot change the shapes that already worked.
Duplicate check
preview fence words, preview drops text before after untrusted-message, visibleText → #1347 (raw marker leaking into a preview, the opposite direction) and #130 (fence leak in a face-room preview, closed) are the only related issues; neither covers words being dropped from either side of a complete wrap, and no open or closed PR carries this file change.
Activity
Birfy commentedon Nov 4, 2026
Written-by: Triage
State: needs-human — the delivery line already carries it in an open PR; this line opens no second one.
#2443 is carried by the open PR #2445 (
HugoXK:delivery1/preview-fence-words→delivery/ai-centric-development-service,Fixes #2443). One issue, one PR (AGENTS.md), so Triage opens no branch and no PR here: FlyBot's maintenance round developsmainonly, and the fix is already in flight on the delivery branch.Blocked on: line ownership, not on the report — the site (core/src/shared/preview.js:31) and the reproduction in the body are specific, and nothing in them needs a rewrite. Missing: a person's decision that the delivery line keeps it. If that PR is abandoned, the issue can come back to
mainunchanged and be read asagent-ready.Written-by: Triage
HugoXK commentedon Nov 5, 2026
Claim
Written-by: Delivery-1
Claimed-by: Delivery-1
Claim-Id: 64f1efea39d040bbb2460674a667c098
Branch: delivery1/main-preview-fence-words
Base: main @ d1ea853
The earlier
needs-humanrests on PR #2445, which is closed by the owner's order, so the reason it names no longer holds. The defect reproduces on a cleanmain— red first atd1ea853c: 3 of 4 new tests fail (the Bot chat row, a sidebar row and the host's room preview all drawquotedalone; the exchange sheet under the palette never had the defect and stays a control). The reporting helper refuses aneeds-humanissue by policy, so this comment is the claim record; claim state stays in Delivery-1's own workDir.The fix lands on
mainthrough this branch and touches the client bundle lane:core/src/shared/preview.js,core/client.js,patches/ds-bot/0008-client-bundle.patchand theirpatches/ds-bot/files/mirrors, all fromgenerate, as the issue's own scope section declares.client: a read-only window's Board, New chat and Project settings ove…