Repository navigation
fix(thread): render unresolvable task refs like the web - #4531
Merged
Merged
Conversation
A bare `#4442` that is no known task of the conversation being read is plain text (Web MessageItem bare task ref matcher), not a tappable chip that toasts "can't open". Remove the mobile-only guesses behind it: - "no known task list" no longer means "every #N is a task" - the bare-ref task status map only holds the current channel's tasks - opening a task ref asks only the conversation's channel (Web openTaskByChannelNumber): no server-wide task-list fallback, no "Ambiguous" candidate picker; a miss opens nothing and says nothing Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review fixes for #4531 (Web MessageItem `taskContextChannelId`): - A task conversation's bare `#N` renders and opens against the task's host channel (TaskConversationDialog `parentChannelId: task.channelId`), not the conversation's own channel. - The ref context is not gated on write access: a read-only reader, or one whose access is still resolving, keeps task chips and taps. The write gate stays on the Tasks tab and task writes; the refs load the context channel's tasks when nothing else does. - A 404 from `GET /tasks/channel/:id/number/:n` is NotFound (log only, no toast), as `openTaskByChannelNumber`; network / 5xx stay Failed. - The message's own linked task counts as known for its body's `#N`. - No `?: true` in the rich-text validator; the default tag validities know no tag. The forward note uses the thread's tag context like the body. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stamp-build
Bot
force-pushed
the
agent/lagoon/unresolvable-refs-web
branch
from
November 10, 2026 19:51
9325fca to
a656d0c
Compare
With no tag context a bare `#N` is plain text, so the agent activity summaries' `botiverse/stamp #1592` (a PR number, never a task) no longer draws a fake task chip; its four goldens are re-recorded. The task chip tests pass the known-task validity they render with. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Task #proj-mobile:#107 — owner: "just align with web"; add-on: "我们自己乱猜的那个可以干掉".
Web truth (botiverse/slock origin/staging 194e5d30 / 37d47d70,
packages/web/src/components/message/MessageItem.tsx)Every unresolvable ref renders as plain text — no chip, no special style, no tap, no tooltip:
#123: chip only for a known task of the conversation being read (taskByChannelNumber), else plain (L884-897, then#channelL900-906 → plain).task #Nkeyword always links (not in mobile's dialect; unchanged here).#channel: known channel only (L905).#chan:#7/dm:@peer:#7: plain when the conversation is unknown (L829, L838).#chan:shortid/dm:@peer:shortid: plain when unknown (L793, L808-810).#chan msg=…:<span>when unknown (L995, L1076-1077).taskByChannelNumber= server tasks + channel tasks + the message's ownlinkedTask, looked up withtaskContextChannelId = parentChannelId || message.channelId(L3823-3832); a task conversation passesparentChannelId: task.channelId(TaskConversationDialog.tsx:531). No write gate.GET /tasks/channel/:id/number/:nonly; a missing task isconsole.error, no toast (utils/openTaskRef.tsL27-50).Mobile change
isKnownThreadMarkdownTag: a bare#Nis valid only if it's a known task of the conversation (no list no longer means "every #N is a task"). Thread page / visual host fall back to the loaded task statuses.threadMarkdownTaskStatusesByNumber: only the current channel's tasks (server tasks of other channels no longer count).resolveSharedTaskReference: channel lookup only, like the web.NotFound: log only, no toast. A parse miss: log only. (Failednetwork errors still toast.)Review fixes (second commit)
#Nrenders and opens against the task's HOST channel (markdownTaskContextChannelId, from the header's resolvedparentChannelId), not the conversation's own channel. No context until the header resolves.taskChannelId(Tasks tab, task writes, convert-to-task) keeps its gate; when it is null the thread loads the context channel's tasks for its refs (shouldLoadMarkdownTaskContextTasks).tasks_404fromGET /tasks/channel/:id/number/:nisNotFound(log only, no toast). Network / 5xx stayFailedand still toast.RaftMarkdownOwnTaskStatusScopealso hands the body a tag validity that knows the message's own task (withRaftMarkdownOwnTaskNumber), so its#Nchips like on web.?: trueinRaftRichTextContract;defaultRaftMarkdownTagValidity/defaultThreadMarkdownTagIsValidknow no tag. The surfaces using the defaults (forward bundle page, forward preview, announcements, attachment comments, file preview, feedback, settings) have no task context, so#Nthere is plain as on web; the forward note of a thread message now uses the thread's tag context (it is the message's own text), so a known task still chips there.Removed (mobile-only guessing)
?: truefallback inisKnownThreadMarkdownTag(every bare#Ntreated as a task).loadTasksfallback infetchSharedTaskReference,SharedTaskReferenceResolution.Ambiguous,taskReferenceCandidates,NetworkServersource,channelQualifiedparam.ThreadPage.kt):ThreadMarkdownTaskCandidateModal,ThreadMarkdownTaskCandidateRow,ThreadMarkdownTaskCandidateModalState,markdownTaskCandidateModalState,threadMarkdownTaskCandidateHelperText/localized…,threadMarkdownTaskCandidateChannelLabel/localized…,threadMarkdownTaskCandidateDetail/localized…,threadMarkdownTaskCandidateListHeight, andMarkdownTaskNumberOpenResult.Ambiguous. It was the only app-specific panel a ref tap opened (checked everyThreadMarkdownTagKindtap path; no GitHub/PR guess or fuzzy ref matching exists). No files removed; symbols only.thread_open_task_number,thread_task_candidate_{none,open_match,choose,unknown_channel,current_conversation,tap_open,current,untitled},thread_state_no_tasks,thread_members_refresh_detail.markdownTaskNumberOpenShowsLoadedAmbiguousStoreWithoutNetwork→ replaced bymarkdownTaskNumberOpenNeverOpensAnotherChannelsTaskOfThatNumber.Tests
RaftMarkdownTaskRefTest.unresolvableBareTaskRefIsPlainTextLikeTheWeb:#4442→ no token, no action;#7and#triage:#169still chip.ThreadMarkdownTaskStatusesTest.anotherChannelsTaskIsNotThisConversationsTask.ThreadMarkdownTaskStatusesTest.taskConversationBareRefsNameTheHostChannelsTasks,.readOnlyReaderKeepsTheTaskContext.ThreadPayloadTest.taskConversationTaskRefOpensTheHostChannelsTask;markdownTaskNumberOpenNeverOpensAnotherChannelsTaskOfThatNumberpinned to a real 404 →NotFound;markdownTaskNumberOpenServerErrorIsAFailureNotAMiss(500/503 →Failed).RaftMarkdownTaskRefTest.ownLinkedTaskChipsInItsOwnBody,.noTagContextKnowsNoTask.#Nis a task" now pass their task context explicitly (markdown/rich-text tests,InlineChipWrapScreenshotTest,ThreadMessageRefPillPaddingScreenshotTest,RaftMarkdownTaskRefChipTest).members.agent-activity.{app-events,overview}{,.dark}.png: the summary'sbotiverse/stamp #1592(a PR number) no longer draws a fake task chip; it is plain text, as on web.Validation at 72c4317 (rebased on origin/main 8598def): local
:shared:testDebugUnitTestfor ThreadPayloadTest, ThreadMarkdownTaskStatusesTest, RaftMarkdownTaskRefTest, RaftMarkdownTest, RaftRichTextContractTest, SharedReplyThreadParentFailurePolicyTest and the markdown / chip / ref screenshot tests: all green (agent activity goldens re-recorded, above). Hosted PR CI and ascope=iosdispatch on this head.Changeset:
change-logs/1.24.0/changesets/unresolvable-refs-like-web.md.🤖 Generated with Claude Code