Skip to content

fix(sdk): recognize CJK and Markdown-adjacent mentions - #3917

Open
Chessing234 wants to merge 6 commits into
block:mainfrom
Chessing234:fix/cjk-mention-boundary-3904
Open

Chessing234 wants to merge 6 commits into
block:mainfrom
Chessing234:fix/cjk-mention-boundary-3904

Conversation

@Chessing234

@Chessing234 Chessing234 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Open @mention extraction when @ is preceded by anything other than an ASCII letter/digit — so 交给@Scout处理 emits a p tag while user@example.com stays inert (Proposal: define CLI/SDK @mention behavior next to CJK text #3904).
  • Align extract_at_mentions_with_known with the same char-aware boundary (it previously inspected a single UTF-8 byte) and treat trailing CJK as a word boundary.
  • Document the rule in docs/mention-boundaries.md, AGENTS gotchas, CONTRIBUTING, and the CLI README.

Test plan

  • cargo test -p buzz-sdk extract_at_names
  • cargo test -p buzz-sdk extract_at_mentions_with_known_allows_cjk_adjacent
  • cargo test -p buzz-sdk email_address_not_matched
  • buzz messages send --content "交给@Scout处理" against a channel where Scout is a member → Scout receives a mention / agent wakes

Closes #3904

The same boundary rule also accepts Markdown-emphasis and parenthesized mentions, rather than maintaining a separate allowlist of leading delimiters. This covers the emphasis issue as well as CJK adjacency.

Closes #2526.

@Chessing234
Chessing234 requested a review from a team as a code owner July 31, 2026 12:19
CJK and other scripts often omit spaces around agent names. Treat any
non-alphanumeric ASCII predecessor as a mention boundary while still
rejecting email-like `user@host` (block#3904).

Signed-off-by: Taksh <takshkothari09@gmail.com>

Signed-off-by: Taksh <takshkothari09@gmail.com>
Give operators and agent authors a short table for block#3904 without reading
the Rust module docs.

Signed-off-by: Taksh <takshkothari09@gmail.com>

Signed-off-by: Taksh <takshkothari09@gmail.com>
Point agent authors at the boundary rule so handoffs without spaces still
wake harnesses (block#3904).

Signed-off-by: Taksh <takshkothari09@gmail.com>

Signed-off-by: Taksh <takshkothari09@gmail.com>
Keep the CJK vs email rule discoverable from the contributor guide (block#3904).

Signed-off-by: Taksh <takshkothari09@gmail.com>

Signed-off-by: Taksh <takshkothari09@gmail.com>
Demonstrate that messages send emits p-tags for spaced-less handoffs.

Signed-off-by: Taksh <takshkothari09@gmail.com>

Signed-off-by: Taksh <takshkothari09@gmail.com>
@Chessing234
Chessing234 force-pushed the fix/cjk-mention-boundary-3904 branch from 2edbe97 to 86a52d0 Compare August 2, 2026 03:58
@Chessing234

Copy link
Copy Markdown
Contributor Author

Rebased onto latest upstream/main with Signed-off-by on all commits and force-pushed. CI should re-run shortly — still ready for @block/buzz-oss-team review when you have bandwidth.

@Chessing234

Copy link
Copy Markdown
Contributor Author

@tlongwell-block @wesbillman @wpfleger96 mind taking a look when you get a chance?

@Chessing234
Chessing234 force-pushed the fix/cjk-mention-boundary-3904 branch from 86a52d0 to 3344196 Compare August 5, 2026 10:34
@Chessing234

Copy link
Copy Markdown
Contributor Author

@wesbillman sdk @mention fix for cjk-adjacent tokens without breaking emails. tip is rebased + dco. review/merge when you can?

…ndary-3904

Signed-off-by: Taksh <takshkothari09@gmail.com>

# Conflicts:
#	AGENTS.md
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is 59328d5ae38a51a618dd2fddd7faf1343d42096f...322611debb68c02011f2968ae29f96f9d45561cc.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review 322611debb68c02011f2968ae29f96f9d45561cc to authorize a new review.
Any previous review applies only to its recorded range.

@cristiansotogarciaxatech

Copy link
Copy Markdown

This branch is doing more than #3904 and the title hides it. It also fixes #2526, and on every case I can produce it is the only one of the four open branches editing this predicate that fixes all of them.

Five open PRs currently touch @mention boundary handling in crates/buzz-sdk/src/mentions.rs. #2547, #2684, #5932, this one, and #6079 (case folding rather than the boundary). None of the five reference each other, and #2526, the filed issue for the emphasis case, is linked from two of them and not from here.

So I measured rather than argued. One probe test appended to crates/buzz-sdk/src/mentions.rs, one ubuntu-latest runner, five trees fetched by sha, calling extract_at_mentions_with_known(input, &["Scout", "Will Pfleger"]).

Run: https://github.com/cristiansotogarciaxatech/buzz/actions/runs/34030702637

body main 3c7f288c #2547 0a39d45d #2684 3128593d #5932 32fcbd0f this PR 322611de
@Scout hi (positive control) scout scout scout scout scout
**@Scout** hi none scout scout scout scout
(@Scout) hi none scout scout scout scout
**@Will Pfleger** hi none will pfleger will pfleger will pfleger will pfleger
\u{a0}@Scout hi (NBSP) none none none scout scout
\u{feff}@Scout hi (BOM) none none none none scout
\u{200b}@Scout hi (ZWSP) none none none none scout
交给@Scout处理 none none none none scout
mail user@Scout.com here (negative control) none none none none none

"none" is an empty vec, which on the CLI path means the message publishes with zero p tags and exit 0. Nobody is notified and the text renders perfectly at the destination.

Two things fall out of that table.

Main drops (@Scout). Parentheses around a mention are more common in ordinary prose than ** is, and nobody has filed that one. Same four lines as everything else here.

The BOM row is the argument for your approach. !prev.is_ascii_alphanumeric() needs no list of characters. The other three branches carry an allowlist of leading characters, and every new character costs another PR. U+FEFF is the proof, because it is not whitespace under char::is_whitespace, measured on the same runner as feff_ws=false, so even the Unicode-aware allowlist in #5932 misses it. #2526 said not to hand-maintain a delimiter list. That was the right call and this is the branch that follows it.

A leading BOM is not an exotic input. crates/buzz-cli/README.md:34 documents buzz messages send --content - < message.md, and read_or_stdin at crates/buzz-cli/src/validate.rs:168 is a bare read_to_string with no BOM handling. On Windows most default text writers emit UTF-8 with a BOM. So the documented way to send a long body silently eats an opening mention, on the platform where BOM is the default file encoding.

I hit this in production on a Windows box running managed agents. A message reached the relay with U+FEFF at position 0 opening with an at-mention. accepted: true, zero p tags, addressee never notified, and the same name one line further down the body tags correctly. Position 0 is the only position that fails and it is the one that fails silently, because a name that gets extracted and does not resolve is a hard error at crates/buzz-cli/src/commands/messages.rs:140, while a name that never gets extracted is not an error at all. I have not isolated which component injects the BOM on my box, so treat that as a symptom report rather than a claim about Buzz. The parser behaviour in the table is measured, not inferred.

The doc comment two functions up already states the contract every "none" in that table breaks, at messages.rs:158. Publishing visible mention text without its intended p tag is worse than not sending.

I am not asking you to change anything. Three suggestions if you want them. Add Closes #2526 to the description, because on the measurement above this branch closes it. Add the BOM, paren and NBSP cases to the test module, since those are the ones that discriminate this fix from the other three. And a line in docs/mention-boundaries.md saying the rule is a denylist by design would stop the next contributor turning it back into an allowlist.

@Chessing234 Chessing234 changed the title fix(sdk): allow CJK-adjacent @mentions without breaking emails (#3904) fix(sdk): recognize CJK and Markdown-adjacent mentions Sep 12, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants