Fix #444: mentionTok bare usernames #452

Merged
crueber merged 1 commit from fix/issue-444 into main 2026-09-13 13:54:57 +00:00
Owner

Decision (a): extend the server mention grammar to bare @usernames instead of narrowing the renderer. The #440 renderer already links bare @username tokens, so they rendered as profile links yet emitted NO notification — this change restores render/notify parity from the server side.

Scope (emitters unchanged in shape):

  • internal/identity/mentions.go: mentionTok gains the bare-username alternative (email, then team, then bare — so @bob@example.com and @org/team still match whole); FindAllStringSubmatchIndex feeds the renderer-mirrored guards (/- or @-glued tokens skipped, leading-dot tokens skipped; email/team branches byte-identical).
  • internal/issues/refs.go: the issues-local mentionRe (the issues emitter's user-mention source; pulls/review read the identity parser) gains the same alternative, the same guards plus trailing-punct strip, and the '-' the identity/renderer left boundary already excluded.
  • Tests mirroring mentions_test.go table on both parsers (bare match, case-fold, bounds, trailing punct, dedup, code-skipped, plus never-cases: team tail, broken email, leading dot, @@/a@b/x@bob glue, bare address).
  • docs/features/06_notifications.md: section 3 grammar rewritten + #444 decisions entry with the verified parity battery and the three deliberate pre-existing residuals (team notifies-but-never-renders; markdown-link/URL interiors notify while the renderer skips them; @a@b.com@c renders plain but parses as email).

Verification: gofmt clean, go vet clean, -race green for identity/issues/pulls/review/notify, coverage identity 95.7% / issues 96.3% (gate >=95%), node suites green (mentions 18/18; markdown+md-urls+refs-autolink+blob-md 60/60; render/notify-adjacent battery 107/107). No new deps. No browser (no browser-facing change; task notes browser open explicitly). Fixes #444.

Decision (a): extend the server mention grammar to bare @usernames instead of narrowing the renderer. The #440 renderer already links bare @username tokens, so they rendered as profile links yet emitted NO notification — this change restores render/notify parity from the server side. Scope (emitters unchanged in shape): - internal/identity/mentions.go: mentionTok gains the bare-username alternative (email, then team, then bare — so @bob@example.com and @org/team still match whole); FindAllStringSubmatchIndex feeds the renderer-mirrored guards (/- or @-glued tokens skipped, leading-dot tokens skipped; email/team branches byte-identical). - internal/issues/refs.go: the issues-local mentionRe (the issues emitter's user-mention source; pulls/review read the identity parser) gains the same alternative, the same guards plus trailing-punct strip, and the '-' the identity/renderer left boundary already excluded. - Tests mirroring mentions_test.go table on both parsers (bare match, case-fold, bounds, trailing punct, dedup, code-skipped, plus never-cases: team tail, broken email, leading dot, @@/a@b/x@bob glue, bare address). - docs/features/06_notifications.md: section 3 grammar rewritten + #444 decisions entry with the verified parity battery and the three deliberate pre-existing residuals (team notifies-but-never-renders; markdown-link/URL interiors notify while the renderer skips them; @a@b.com@c renders plain but parses as email). Verification: gofmt clean, go vet clean, -race green for identity/issues/pulls/review/notify, coverage identity 95.7% / issues 96.3% (gate >=95%), node suites green (mentions 18/18; markdown+md-urls+refs-autolink+blob-md 60/60; render/notify-adjacent battery 107/107). No new deps. No browser (no browser-facing change; task notes browser open explicitly). Fixes #444.
Server mentionTok never matched bare @bob while the #440 renderer links
bare @username tokens, so they rendered as profile links yet emitted no
notification. Decision (a): extend the server grammar (both parsers —
identity.ParseMentions feeding pulls/review and the issues-local
mentionRe feeding the issues emitter) with the bare-username
alternative, mirroring the renderer guards cell-by-cell (left boundary,
/- and @-glued exclusion, leading-dot exclusion, trailing-punct strip,
code exemptions). Emitters unchanged in shape; bare names flow through
the existing ValidPrincipal probe + silent-drop contract.
06_notifications.md section 3 grammar plus decisions entry.
Sign in to join this conversation.
No description provided.