Skip to content

workflow_sink's @-mention parser is a third divergent implementation — workflow-emitted **@Name** emits zero p tags #2686

Description

@bosoud

Split out of #2526 — noted by @SeanGearin while reviewing #2547.

Problem

#2526 identified two divergent @-mention parsers (Rust buzz-sdk/src/mentions.rs and TS desktop/src/features/messages/lib/hasMention.ts). There is a third: resolve_mention_pubkeys in crates/buzz-relay/src/workflow_sink.rs, whose doc comment says it "defines the matching contract" for workflow-emitted kind:9 p tags.

Its left-boundary check accepts only start-of-string, whitespace, or (:

let is_left_boundary = |i: usize| i == 0 || chars[i - 1].is_whitespace() || chars[i - 1] == '(';

So a workflow-generated **@Robby** emits zero p tags. Those p tags gate ACP agent wake (event_mentions_agent, crates/buzz-acp/src/lib.rs), which reproduces the exact stalled-handoff failure mode from #2526 on a surface where the text is machine-generated — an agent or template emitting emphasis around a mention is not a user typo, it's routine markdown.

The right side of this parser is already emphasis-tolerant (it rejects only name-continuation chars, alphanumeric | _), so only the left boundary needs widening. Note the _ wrinkle: a trailing _ after a name is a name-continuation char here, so _@robby_ has a second, smaller divergence too.

Suggested direction

After #2547 lands, buzz-sdk::mentions::is_mention_lead is the shared definition of "what may precede an @" (whitespace, (, *, _, |, start). buzz-relay already depends on buzz-sdk, so workflow_sink.rs can call it directly instead of keeping a private boundary rule — that would take the parser count needing manual sync from three to two.

Longer term (already noted in #2526): the Rust and TS implementations should be one contract with shared test vectors, or this class of drift recurs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions