workflow_sink's mention parser never masks code regions — @name inside a code span wakes the agent
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
Research direction
Start in crates/buzz-relay/src/workflow_sink.rs at resolve_mention_pubkeys and compare the existing CLI handling in crates/buzz-cli/src/commands/messages.rs with buzz_sdk::mentions::strip_code_regions. Add workflow-parser test cases in the file's existing tests module for inline and fenced code, surrounding prose, and the listed positive and negative controls. Done means code-contained @mentions do not wake agents while ordinary mentions still resolve.
Written by the indexing model from the issue text.
Description
Split from the parser-divergence cluster (#2526, #2686). This is a different failure direction from those: they are silent non-notification, this is a silent false notification, in the same function.
Problem
resolve_mention_pubkeys in crates/buzz-relay/src/workflow_sink.rs never masks code regions. So a workflow-rendered message containing an @name inside an inline code span or a fenced block emits a real p tag, and those p tags gate ACP agent wake (event_mentions_agent, crates/buzz-acp/src/lib.rs).
Workflow text is machine-generated markdown, and agents emit code constantly — a code sample naming an agent is documentation, not an address.
This is the mirror of the CLI issue noted as item 3 of #2526. That one was fixed on the CLI side: resolve_content_mentions now strips code regions before @name extraction (crates/buzz-cli/src/commands/messages.rs:166 feeding :226). The relay path never got the equivalent, exactly as #2526 describes the TS/Rust drift pattern — one surface moves, the other does not.
Measured on pristine main
A probe test appended to the tests module in crates/buzz-relay/src/workflow_sink.rs, one member ("Robby", <pubkey>), calling resolve_mention_pubkeys directly:
let got = resolve_mention_pubkeys("see `ping @Robby` for syntax", &members);
// PROBE inline-code-span result: ["aaaa…aaaa"] <- the code span resolved a real pubkey
The assertion got.is_empty() fails: the mention inside the backtick span wakes Robby.
Verified against crates/buzz-relay/src/workflow_sink.rs as it stands on main today: is_left_boundary is still at line 102 and the file contains zero references to strip_code_regions. git log <earlier-sha>..main -- crates/buzz-relay/src/workflow_sink.rs is empty, so #6953 ("fix(acp): wake agents from workflow messages") did not touch this file.
Note this is independent of the left-boundary widening in #2686 / #2691. Whitespace was always an opener, so `see @Robby` resolved before any boundary change and still will after one. Widening the opener set slightly extends the surface (`(@Robby)` also matches) but is not the cause.
Suggested direction
buzz-relay already depends on buzz-sdk (crates/buzz-relay/Cargo.toml), and buzz_sdk::mentions::strip_code_regions is already pub and already used on the CLI path. Calling it in resolve_mention_pubkeys before scanning is a two-line change.
One implementation note that is easy to get wrong: strip_code_regions is not length-preserving. Measured — "a code @x b" (13 chars) returns "a b" (5 chars). Any caller that maps positions back onto the original string will corrupt them.
That happens to be safe in resolve_mention_pubkeys specifically, because at and consumed are internal to the scanned copy and nothing position-derived escapes the function — it returns pubkeys ordered by first appearance, and masking does not reorder surviving prose. Worth stating explicitly in a comment so a future refactor that does surface offsets does not silently break.
A second, narrower limitation worth a test vector either way: a fence that does not begin at a line start is not masked at all. Measured — "pre ```\nblk @y\n``` post" returns "pre \nblk @y\n ", leaving the mention intact, because is_fence_start` requires the fence to follow a newline or only whitespace. Mid-line fences are unusual in prose but not in machine-rendered text.
Test vectors
Suggested cases for the workflow parser, the first three being the actual fix:
| body | expected |
|---|---|
see `ping @Robby` for syntax |
no wake |
```\nping @Robby\n``` |
no wake |
`code` then @Robby please |
wake (masking must not swallow surrounding prose) |
heads up @Robby (positive control) |
wake |
alice@Robby (negative control, already passing) |
no wake |
#2526 notes that none of the existing 69 mention tests place an emphasis character next to an @; similarly there is currently no workflow-parser test involving code at all.
- Dominant language
- Rust
- Stars
- 33.7k
- Forks
- 4.4k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 239
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from block/buzz
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
Difficulty 2/5 Half a day Newbie friendliness 88/100
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 · 1 comment ·
-
bug triage:deciding
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/otel-arrow#4132 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
bitcoindevkit/bdk-ffi#1125 ·