mirror of
https://github.com/block/buzz.git
synced 2026-10-29 21:41:33 +00:00
Compose edit fallback refs before exact occurrence selection. Keep ambiguous historical labels as non-authorizing blockers for rendering and body-based recipient fallbacks; qualified labels only disambiguate when they own an unambiguous occurrence. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com> (cherry picked from commit 30545075a876136467c07d82abac83ad1904df23) Signed-off-by: Logan Johnson <loganj@squareup.com> (cherry picked from commit df75b5d1ac6d7aaa2bf0dfb4dfaf43b92539249a) Signed-off-by: Logan Johnson <loganj@squareup.com>
66 lines
4.0 KiB
Markdown
66 lines
4.0 KiB
Markdown
# Mention editor contract
|
|
|
|
Autocomplete inserts a full literal label followed by a separator. Full labels
|
|
may contain spaces; internal spaces must not be mistaken for the final boundary.
|
|
The immediate next typed character goes after the separator even if the browser
|
|
remaps the DOM caret to the highlight edge. Explicit ArrowLeft or click cancels
|
|
that settlement so users can intentionally edit a mention. Plain typed tokens
|
|
retain their existing behavior; this does not change recipient resolution.
|
|
|
|
Regression coverage: `mentionHighlightExtension.test.mjs` simulates chip-edge and
|
|
whitespace-run rewrites, internal spaces, and deliberate motion. The ordinary
|
|
member browser cases in `mention-spacing.spec.ts` test immediate typing and
|
|
ArrowLeft without requiring remote discovery or invitation; `mentions.spec.ts`
|
|
also covers clicking chip edges and insertion before existing text.
|
|
|
|
## Exact recipient labels
|
|
|
|
A selected label is a binding to one exact public key, not a lookup by the latest
|
|
profile name. Selecting a second identity with the same name reserves a qualified
|
|
label containing its full key (and, if needed, a collision suffix). Team members
|
|
reserve labels sequentially. Automatic addressing inserts/restores/removes that
|
|
registered label, never a different recipient with the same name.
|
|
|
|
Manually typed member names with multiple exact-key matches are rejected with a
|
|
visible instruction to use the mention picker. Chat, edits and standalone forum
|
|
composition retain their draft and publish nothing on this error. An edit may
|
|
remove an ambiguous historical label; when the old content cannot be resolved,
|
|
all recipients in the valid replacement are revalidated. Selection stays bound
|
|
across profile renames. This does not expand eligibility or change relay
|
|
revalidation, invitation or publication authorization.
|
|
|
|
Coverage: `useMentions.test.mjs`, `useAgentAddressLockPicker.test.mjs`,
|
|
`submitMessageEdit.test.mjs`, `mention-recipients.spec.ts`, and the existing
|
|
same-name agent case in `mentions.spec.ts`. The integration-project
|
|
`onboarding.spec.ts` checks that an ambiguous Fizz mention cannot complete the
|
|
welcome flow, then selects the exact newly started starter and asserts its sole
|
|
recipient tag before checking the original completion and layout behavior.
|
|
|
|
## Exact occurrences and edit history
|
|
|
|
Draft presence, extraction, audience removal/restoration and persona preparation
|
|
share longest literal occurrence ownership, including typed-member and persona
|
|
competitors. A shorter alias cannot claim another label's qualified key or
|
|
collision suffix. Removing one recipient must preserve a different recipient's
|
|
full label and exclude only the removed identity from the composed send audience.
|
|
|
|
Rendering and edit hydration reconstruct qualified labels only for identities
|
|
already present in event `p` or `mention` tags. Body text alone does not authorize
|
|
a key. Tag order cannot resolve ambiguous aliases; an unqualified label is
|
|
restored only when one candidate remains. Qualified tagged labels can survive
|
|
profile renames or missing profiles. Historical arbitrary labels are not stored:
|
|
missing or genuinely ambiguous unqualified aliases remain unresolved,
|
|
non-notifying references rather than guessed recipients. Edit regression coverage
|
|
checks reference preservation, not a claim of new notifying edit `p` tags.
|
|
|
|
Occurrence recognition must retain every competing literal label before binding
|
|
eligibility is applied. The historical resolver's `mentionNames` includes
|
|
ambiguous aliases as blockers; its explicit `mentionPubkeysByName` map binds only
|
|
resolved aliases. Renderers leave unbound occurrences as literal text. Body-based
|
|
ordering and legacy send-to-channel fallback use both outputs, not the map alone.
|
|
Edit-open fallback refs enter the same candidate composition as current selected
|
|
refs, typed members and personas before presence selection; they are never matched
|
|
in a separate, narrower pass. Current selections (including unbound personas)
|
|
take precedence over same-label fallback refs. Historical unresolved identities
|
|
still preserve non-notifying metadata, without claiming a literal binding.
|