Harden author-coloring PUA sentinels against intra-emphasis markdown #33
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Harden author-coloring PUA sentinels against intra-emphasis markdown
Summary
Make the F9/F10 author-coloring technique (Private-Use-Area sentinels injected
into prose, then mapped to
cw-by-*spans after markdown render) robust when anauthor span starts/ends inside a markdown emphasis run (e.g. mid-
**bold**ormid-
_italic_), so the injected sentinels don't perturb markdown-it's inlineparsing.
Problem / pain
colorByAuthor(salvaged into F10'srenderReview) injects paired PUA sentinelsat a span's char offsets, lets markdown-it render, then replaces the sentinels with
<span class="cw-by-*">tags. When a span boundary falls inside an emphasisdelimiter run (e.g. between the
*s, or splitting**), the inserted sentinel canbreak markdown-it's emphasis matching — the emphasis fails to render or the span
nests incorrectly. F9 flagged this as a known edge and deferred hardening; F10
inherits it. Today it's mitigated only by the per-block
try/catch→ error chip,which degrades that block rather than rendering it correctly.
Who feels it
The human coauthor (PP-1) reviewing prose where an attributed span boundary
coincides with emphasis markup — uncommon, but it produces a visibly wrong or
error-chipped block when it happens.
Desired outcome / value
Author-coloring renders correctly even when span boundaries land inside emphasis
runs — the colored
<span>wraps the intended text and the emphasis still renders,with no error chip and no broken markup.
Acceptance — "done right"
**bold**/_italic_/`code`renders with both the emphasis AND the correctcw-by-*coloring.colorByAuthorcases (the F9-salvaged unit testsstay green).
renderReview/colorByAuthorremain pure and deterministic (INV-33).Scope / non-goals
In scope: the sentinel injection/extraction robustness in
trackChangesModel.ts(
injectSentinels/sentinelsToSpans/colorByAuthor).Non-goals: changing the visual language or the attribution data model; atomic
fences (already handled whole); broadening beyond emphasis edge cases that actually
reproduce.
Assumptions · constraints · dependencies
rendered HTML rather than the source — to be decided at implementation.
Source / signal
Self-originated — capture session vscode-cowriting-plugin-0031 (2026-06-12),
from the F9 deferred refinement carried into F10. Spec:
specs/coauthoring-interactive-review.md§1.7 / §9 ("intra-emphasis sentinel-safetyhardening"); origin in the F9 authorship-preview design. Relates to F10
#29.Priority (WSJF)
Provisional: Value low (correctness on an uncommon edge; today degrades
gracefully to an error chip) · Time-criticality low · Opportunity low ÷
Size small → provisional priority/P3. (Decision aid, not auto-scored.)
Decomposition
Task (no independent business value — a robustness fix). Checklist:
colorByAuthorcases; determinism holds.Solution notes (optional — NOT a design)
Non-binding: the cleanest fix may be to apply author coloring as an HTML
post-process keyed on character ranges of the rendered text, rather than injecting
sentinels into the markdown source — but that is a larger change; clamping span
boundaries to safe token edges may suffice for the common case.
Investigation (session 0032) — failure characterized; deferred to its own session.
Reproduced via
renderReviewwith the real markdown-it renderer (unchanged emphasis block + an author span whose boundary lands in/near emphasis markup). Two distinct failure modes:a**b**c, span0..2ending between the two opening*): the injected sentinel splits**, breaking emphasis parsing entirely →<p><span class="cw-by-human">a<em></span></em>b**c</p>(stray<em></em>,b**cleft raw). This is the parse-break the issue describes.**bold**, span covers**bo): emphasis renders, but the author<span>and<strong>misnest →<strong>bo</span>ld</strong>(the</span>closes inside<strong>). Invalid/overlapping HTML, browser-tolerated — so it doesn't error-chip, it silently emits malformed markup.**bold**fully covered): correct (<span class="cw-by-human"><strong>bold</strong></span>).Design fork for the fix:
<span>segment per text run): fixes both correctly, but is a meaningful rewrite ofcolorByAuthor— andcolorByAuthoris shared by F9/F10, so it needs care + full regression coverage.The full token-aware approach is the genuinely-correct one (CASE3 misnesting is inherent to wrapping arbitrary char ranges across element boundaries with source-injected sentinels). Recommend implementing it in a dedicated session. No code changed for #33 in 0032 — only this characterization.
Shipped (#53, session 0047) via the token-aware approach.
injectSentinelsclamps any sentinel off a delimiter run (CASE1 parse-break fixed);sentinelsToSpansis now a walker that emits the cw-by-* span only around text runs, splitting at every<tag>boundary so spans never misnest with<strong>/<em>/<code>(CASE3 fixed) and no PUA char leaks. Pure/deterministic (INV-33); no regression. 222 unit + 74/5 host E2E green.