Repository navigation
feat(chat): create a coalesced inbox record for DM replies (CHE-1793) [squash] - #276
Merged
congvc-dev merged 18 commits intoOct 17, 2026
Merged
congvc-dev merged 18 commits into
congvc-dev merged 18 commits into
Conversation
added 15 commits
October 16, 2026 02:31
…-n1-channel-settings' into n2work
…d keeps one unread (CHE-1793)
…conflict returns 409 (CHE-1793)
…et/che-1791-n1-channel-settings
…https://github.com/cheese-work/multica into agent/x99-claude-sonnet/che-1791-n1-channel-settings
# Conflicts: # server/internal/handler/chat.go
Base automatically changed from
agent/x99-claude-sonnet/che-1791-n1-channel-settings
to
main
October 16, 2026 08:56
added 2 commits
October 16, 2026 15:58
…et/che-1793-n2-dm-notification-record # Conflicts: # server/cmd/migrate/main.go
…et/che-1793-n2-dm-notification-record
…et/che-1793-n2-dm-notification-record
congvc-dev
deleted the
agent/x99-claude-sonnet/che-1793-n2-dm-notification-record
branch
October 17, 2026 02:19
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.
Status
Ready for Cheese's merge decision. This is layer N2 of the DM notification stack (CHE-1789). N1 (PR #272) merged to
mainas squash commit6b9b49d803db58ad37386bd2ac3233ab25e02c73, so this PR is based onmain. The accepted pair is head2d2ce28b7f2a5de02070e670f41ecab605cade07, base2b135399996d8072c5a99deb88ef55edb62f49b4. Merge stays Cheese's gate.Review: signed independent code PASS from x99-agy-gemini (Google), independent of the Anthropic author, comment
01a14774-b0ab-7a18-9d44-26233b4ed261on CHE-1793, with a current-pair delegation OCR receipt (24 selected and 4 excluded paths). It covers this pair only.Checks: exact-head CI run 38987688742 succeeded: 13 successful jobs, 6 skipped.
backend-testsandgo-lintran and passed. The PR rollup shows 15 success, 6 skipped, 0 failed, 0 pending. The earlier migration-prefix 627 blocker was repaired onmainby PR #290 (CHE-1824). A newermaincommit (dbf4adb6e, onlyserver/internal/daemon/execenvfiles) exists; a trial merge with this branch is clean.Conditions
main. A changed head or base needs fresh checks and independent review with OCR.Changelog: none. The PR that lands the stack onmaincarries the changelog line.dm_replyrows yet. A web or mobile row that opens the DM belongs to N4/N5. TheInboxItemTypeunion stays closed on purpose, so no label or translation is needed here.dmchannel switches. They staymentioneditems and are always delivered.Change
inbox_itemgainschat_session_id,chat_message_id,dedupe_keyand a nullableupdated_at.COALESCE(updated_at, created_at). ANOT NULL DEFAULT now()column would re-stamp every old row.(recipient_id, dedupe_key) WHERE dedupe_key IS NOT NULL AND read = false, and a listing index on the new sort key. Both useCONCURRENTLYin their own files.created_at.server/internal/dmnotify.Replyupserts one unreaddm_replyrecord per (recipient, DM) withdedupe_key = dm:<session id>. A later reply raisesdetails.reply_count, bumpsupdated_atand un-archives the row. A read record is never reused. The body stays empty: no message text.Replyruns inside the completion transaction (CompleteTask) and the failure transaction (failTask). It creates nothing for an archived DM, a DM with a current channel binding, a decision message kind, or a recipient with bothdmswitches off.in_appoff withpushon keeps the record, hidden from the inbox.dm_channel_enabledandinbox_item_visible. The inbox list, the archived pages, the unread count and the workspace summary hide a DM record when the recipient can no longer read the DM (membership, session ownership, private-agent access) or whendmin_appis off.POST /api/chat/sessions/{id}/readreads the DM'sdm_replyrecords. Reading a record, or mark-all-read, advances the DM cursor. Archive and delete read the records. Answering a decision reads its ping record.NotifyPingnow setschat_session_idandchat_message_id, so the decision item opens the DM.inbox:newfor a new record, newinbox:updatedfor a coalesced update, both sent only to the recipient. Old clients ignoreinbox:updated.chat_session_idandupdated_at. The zod schema adds both with anullcatch, so a wrong type cannot blank the inbox. A row from an older backend still parses.Evidence
fe4563c79changes only tests. Against its parent48b92ed3e, 9 Go tests (13 with subtests) and 1 vitest test fail on behavior:a93bfd18a(agent rollover regression, red:dm_reply records = 0, want 1 for the new DM, and a failing notification write returned 201 where 500 is expected), then fix45aeb358d. Review round 3: tests-onlyed6ff086d(continue leaves the source DM's unread records, redthe archived source DM still has 1 unread dm_reply recordsfor creator and agent; mark-unread of an older read record returned 500), then the fix commit at the PR head:ContinueChatSessionreads the source DM's unread records in the continue transaction and publishesinbox:readafter commit;MarkInboxUnreadreturns 409 when a newer unread record already holds the DM. Commitc708c74c5implements the original change. The same tests pass. Three tests in the same file were added after the implementation and are retrospective: mark-all-read, answering a decision, and theinbox:updatedevent.pgvector/pgvector:pg17container on127.0.0.1:57793.go test ./internal/handler ./internal/service ./cmd/server ./cmd/migrate ./pkg/...all pass.go vetis clean.vitest runinpackages/corepasses (177 files, 2266 tests).tsc --noEmitinpackages/corepasses.internal/cli,internal/daemonandinternal/daemon/execenvfail the same way on the parent. That claim is withdrawn: the recorded comparison did not show it. In the shell run withMULTICA_TASK_CONFIG_ROOTunset, the parent had 3execenvCursor MCP failures. The head had those plus anexecenvsidecar failure and a daemon watchdog failure.internal/clipassed on both. Treat the extra failures as environment-sensitive until reproduced. None is claimed as baseline.mainand in every open PR checked on 2026-10-16 (627 to 632 PR feat(wakeups): L9 scoped-event outbox capture and drain (CHE-1199) [squash] #172, 640 to 646 PR feat(wakeups): L10 custom event and condition rules with activation sweep (CHE-1200) [squash] #173, 627 PR feat(chat): deliver held decision groups atomically (CHE-1750) [merge] #260 and feat(chat): archived DMs are unpinned (CHE-1801) #275, 627 and 628 PR feat(chat): add per-channel notification settings for Inbox and DMs (CHE-1791) #272, 629 PR feat(chat): add a DM search endpoint and message anchor (CHE-1792) #273). Combined tree N2 + S1:TestMigrationNumericPrefixesAreUniquefailed with prefix 629 shared before the renumber and passes after it.inbox_item_visibleon a large workspace.task_token):ContinueChatSessioncallsdmnotify.Replyfor the new DM inside the continue transaction. A continue the DM creator submits does not notify. The old DM is archived by the same call, so the run's final reply there cannot notify. Design PR docs(chat): design DM search, DM notifications and Web Push (CHE-1790) #271 carries the matching inventory line (heade4e262ce4469938b831b470d29fdac27cee67f5b).Changelog: none
Refs CHE-1793