Chief question replies: complete parsing and envelope checks (#33560)

Merged
TE
2d ago
+502-27

Completes the pure Rust question-reply follow-ups from #33537 and #33560. The plain-text helper strips Markdown, lists safe link destinations on separate lines, and splits prose at whitespace within 512-character paragraphs without dropping text (long unbroken text falls back to Unicode character boundaries). Links remain intact as a deliberate exception to the prose length limit. Numbered question rendering then collapses each prompt, label and detail onto one line and prefixes prompts with Question: so Markdown cannot inject misleading numbered choices.

Candidate question replies reuse the existing MAX_QUESTION_TEXT_BYTES (2,048 UTF-8 bytes) safety bound before normalization allocates; this is not a send, attachment, or ordinary message limit.

Replies accept 1, 1., #1, and leading-zero numbers; exact text wins over unique Unicode-folded prefixes of at least two original Unicode characters, and collisions remain Ambiguous. Yes/no aliases exist only when the caller explicitly declares a two-option permission prompt; ordinary choices never infer them. A result is still only a selection, never an authorization or person proof. Multi-item/multi-select selections explicitly report completes_question = false.

resolve_observed checks modeled connector facts before resolving: exact thread, Chief echo/self-thread distinction, known message time within the owner-supplied validity window, and tapback removal types (3000+). Associated-message summaries cannot become text choices. The adapter still authenticates the sender, identifies Chief's sent IDs, binds tapbacks to delivered messages, and revalidates/commits atomically. The pure resolver cannot validate caller-provided facts and does not replace those responsibilities. No connector-owner files, transport, backend, Feed, Swift, or approval execution are changed.

Leo-ask: ask-6ef2624788

oh stuff yeah actually we should be able to surface permissions/multiple choice related things inside chief... idk if y'all have researched dot/grokbot but those are def thng to look into

Preserves #22747 and #22941: no new Chief approval gates, no guessed approval, no relayed allow. This is the next slice of the original ask; the phone-to-Chief flow and native question bridge remain separate integration work.

Validation: formatting and diff whitespace checks pass. New coverage exercises Markdown/links/Unicode paragraph splitting, whitespace split boundaries, number aliases and leading zeros, unique/ambiguous prefixes, Unicode fold expansion, explicit permission aliases, partial selection, input-size boundary, connector freshness/echo/removal facts, and rejection of Markdown-injected choice rows in labels, details and a second-item prompt, including both literal backslash-before-digit and escaped-dot payloads. Single-character exact labels still match; single-character prefix guesses (including Unicode fold expansions) do not.

Fleet run 41622129146 passed all 41 tests (35 unit + 6 integration) and cargo clippy --locked -p cmux-conversation --all-targets -- -D warnings at final head 79eb7e0a40353ed0ecbc54b568147c4909043eca. Snapshot 85ae33a095ab16d20bf7b98751751222c5b1edcb has that head as its only parent and matches source tree 6dd035f2c32e559a1a702398d5bfc79bf656e33c; command exit 0. Five additional review-regression tests pass, including literal backslash-before-digit and escaped-dot row injection in labels and second-item prompts.

Dependencies pulldown-cmark and unicase already exist in the workspace lockfile. This exposes no new action or UI surface, default, polling loop or authorization operation. Prior-art search found only our #33537, now merged as 8cc02ce2c54ac43a6661cb8fbac8fdfb8434b788. This PR targets feat-cmux-next, rebased onto f0db13630a71a04c947f9692cb5972d7db13a999 before the review fix. The rebase preserved all three patches without conflicts; subsequent commits address the review blocker and both follow-ups. Its delta is three files, 85 additions and 18 deletions. Independent review must cover this new head before any merge.

Closes #33560.
šŸ¤– Generated with Codex

Agent session: agent session