Skip to content

fix(mattermost): key private channels as group on outbound routing#96645

Open
iloveleon19 wants to merge 4 commits into
openclaw:mainfrom
iloveleon19:fix/mattermost-infer-target-chat-type
Open

fix(mattermost): key private channels as group on outbound routing#96645
iloveleon19 wants to merge 4 commits into
openclaw:mainfrom
iloveleon19:fix/mattermost-infer-target-chat-type

Conversation

@iloveleon19

@iloveleon19 iloveleon19 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Resolves #95646.

Mattermost private channels are authoritatively classified from the channel type as
P/Ggroup on inbound paths, but they are addressed on the wire as
channel:<id>, just like public O channels. Outbound route reconstruction could
therefore key one private-channel thread under both:

  • agent:…:mattermost:group:<id>:thread:<root> (inbound)
  • agent:…:mattermost:channel:<id>:thread:<root> (outbound/cron)

The split breaks thread/session continuity, especially when an isolated cron run
reconstructs a route without the bound conversation identity.

Why This Change Was Made

The target string alone is lossy: channel:<id> cannot distinguish public from
private Mattermost channels. This change preserves authoritative information at
each boundary instead of treating the prefix as the chat type:

  1. The Mattermost opaque-target resolver fetches the real channel type after a
    user lookup returns 404.
  2. The outbound session route accepts authoritative group information from the
    resolved target or the exact canonical current Mattermost session key.
  3. Isolated cron delivery uses a bound Mattermost conversation key for route
    reconstruction, while non-Mattermost providers retain the existing isolated-run
    behavior.
  4. Directory entries report public O channels as channel and private P/group
    G channels as group.

The wire target remains channel:<id> for all non-DM Mattermost posts.

User Impact

  • Private-channel replies and scheduled deliveries reuse the existing
    group:<id> namespace instead of creating a phantom channel:<id> namespace.
  • Public channels remain under channel:<id>.
  • DMs retain their existing direct-session behavior and exact-recipient handling.
  • Other providers' cron routing is unchanged.

There is no migration or destructive rewrite. Existing duplicate session entries
remain readable; new affected deliveries stop creating the wrong namespace.

Implementation Notes

Authoritative target classification

The existing opaque-target cache is retained but hardened:

  • five-minute TTL;
  • maximum 1,024 entries (preserving the current upstream cap);
  • successful user or channel-type lookups only;
  • user lookup errors other than 404 are not cached;
  • failed channel lookups fall back to channel for compatibility but are not
    cached, so a later request retries the authoritative lookup.

This directly addresses the P1 review finding that a transient channel lookup
failure could pin a private channel as channel for the process lifetime.

Session-route and cron scope

currentSessionKey is accepted as an authoritative fallback only when the whole
key matches a canonical Mattermost direct/group/channel session for the same peer.
An unrelated or malformed key cannot leak a group classification.

The cron change is intentionally provider-specific. A bound Telegram or other
provider session is not substituted into its adapter's route resolution.

Related work

Evidence

Automated tests

Local verification after rebasing onto 1fc81c2054:

Mattermost focused tests: 3 files, 32 tests passed
Cron focused tests:       1 file,  4 tests passed
Production core types:    passed
Production extension types: passed
Extension test types:     passed
Core test-source types:   passed
oxlint (changed Mattermost + cron files): passed
oxfmt --check (8 changed files): passed
git diff --check: passed

Coverage includes:

  • Ochannel, Pgroup, and the unchanged channel:<id> wire target;
  • cache hit, 1,024-entry cap, five-minute expiry, and failed-lookups-are-retried;
  • group routing from resolved kind and matching current session;
  • unrelated/malformed current sessions cannot change a public route;
  • bound Mattermost cron sessions are reused;
  • unbound, cron, malformed, and non-Mattermost bindings keep the isolated key.

The local host has Node 24.13.0 while the current repository requires Node
24.15.0+, so the package-manager preinstall guard reports that environment
mismatch. The checked-in tool binaries still completed the focused tests, type
checks, lint, and formatting above; hosted CI is the authoritative supported-Node
run.

Redacted deployed behavior

An equivalent deployed bundle patch was exercised against a real private
Mattermost channel. No credentials, message bodies, channel IDs, post IDs, or
session IDs are included below.

Before the cron fix, one redacted thread root had both namespaces:

{"label":"unpatched","matchingEntries":2,"kinds":["channel","group"],"allThreadScoped":true}

After the cron fix, the patched proof thread retained only the authoritative
namespace:

{"label":"patched","matchingEntries":1,"kinds":["group"],"allThreadScoped":true}

These values were regenerated from the current persisted session store using a
read-only script that emits only counts, enum kinds, and a thread-scope boolean.
The raw keys and entry contents were never printed. The deployed gateway was later
rebuilt/restarted and the persisted result remains the same.

The previously attached visual proof shows the scheduled reply landing in the
private-channel thread:

private-channel thread delivery

A new live post was not created solely for testing, per repository guidance.

Rollback

Revert the four commits in this PR. No data migration or cleanup is required;
rollback restores the previous route reconstruction behavior.

@openclaw-barnacle openclaw-barnacle Bot added channel: mattermost Channel integration: mattermost size: S labels Jun 25, 2026
@clawsweeper

clawsweeper Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 6, 2026, 12:41 PM ET / 16:41 UTC.

Summary
This PR updates Mattermost outbound session routing, target resolution, directory classification, and isolated cron delivery routing so private channels use the group session namespace while the wire target remains channel:<id>.

PR surface: Source +96, Tests +172. Total +268 across 8 files.

Reproducibility: yes. at source level: current main maps Mattermost P channels to group inbound while outbound session routing still collapses non-user targets to channel. I did not run an independent live Mattermost reproduction in this read-only review.

Review metrics: 1 noteworthy metric.

  • Mattermost target-kind cache: boolean cache changed to user/channel/group. The cache now controls whether a Mattermost target is stored under channel or group, so failed lookup caching directly affects session compatibility.

Stored data model
Persistent data-model change detected: serialized state: extensions/mattermost/src/session-route.test.ts, serialized state: extensions/mattermost/src/session-route.ts, unknown-data-model-change: extensions/mattermost/src/session-route.test.ts, unknown-data-model-change: extensions/mattermost/src/session-route.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #95646
Summary: This PR is the current broad candidate fix for the canonical Mattermost private-channel chat_type/session namespace mismatch, with one open partial sibling and one closed cache-based attempt.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦐 gold shrimp
Patch quality: 🦪 silver shellfish
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Fix the target-resolution cache so failed channel-kind lookups do not persist a channel classification for private channels.
  • [P1] Add inspectable redacted session-store or log proof showing the patched private-channel cron delivery reuses group:<id> and does not create channel:<id>.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The screenshot shows a real Mattermost reply and chat_type text, but it does not show session-store keys or logs proving the after-fix run avoided a phantom channel:<id> session; the contributor should add redacted logs, terminal output, copied live output, or a linked artifact and redact private details before updating the PR body for re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] A transient or unauthorized Mattermost channel-kind lookup failure can be cached as channel, leaving a private P channel misclassified for the process lifetime and recreating the split session namespace this PR is meant to remove.
  • [P1] The PR intentionally changes Mattermost session namespace selection for private channels and isolated cron deliveries, so merge needs upgrade-safe proof that private channels reuse group:<id> and public channels remain channel:<id>.
  • [P1] The visible proof artifact shows a chat reply but not the session-store or log state, so the central claim that no phantom channel:<id> session is created remains unverified by inspectable evidence.

Maintainer options:

  1. Fix fallback caching before merge (recommended)
    Only cache successful user or channel-kind classifications, or otherwise leave failed channel-kind fallbacks uncached and covered by a regression test.
  2. Require inspectable Mattermost proof
    After the code fix, require redacted logs, terminal output, or a linked artifact showing the patched private-channel delivery reused group:<id> without creating channel:<id>.
  3. Accept the compatibility risk deliberately
    Maintainers could merge on the existing source and screenshot evidence, but that would own the risk that a cached fallback or unverified live state still splits sessions.

Next step before merge

  • [P1] Contributor and maintainer follow-up are needed for the cache fix plus live Mattermost proof; ClawSweeper should not treat this as a repair job while contributor-owned real behavior proof remains missing.

Security
Cleared: The diff stays within Mattermost routing/target resolution and cron tests, with no dependency, workflow, package, secret, or permission changes.

Review findings

  • [P1] Do not cache a failed channel-kind lookup as channel — extensions/mattermost/src/mattermost/target-resolution.ts:107
Review details

Best possible solution:

Keep this PR as the likely canonical Mattermost fix path, but first avoid caching non-authoritative channel-kind fallbacks and add inspectable redacted session-store or log proof for the private-channel cron delivery path.

Do we have a high-confidence way to reproduce the issue?

Yes, at source level: current main maps Mattermost P channels to group inbound while outbound session routing still collapses non-user targets to channel. I did not run an independent live Mattermost reproduction in this read-only review.

Is this the best way to solve the issue?

No, not as submitted: the owner-boundary fix direction is right, but the target resolver must not cache a non-authoritative channel fallback after a failed channel-kind lookup.

Full review comments:

  • [P1] Do not cache a failed channel-kind lookup as channel — extensions/mattermost/src/mattermost/target-resolution.ts:107
    When the user lookup 404s but fetchMattermostChannel fails, resolveMattermostChannelKind returns channel and this line caches that fallback. A private P channel is then pinned as channel for the process lifetime, so later retries never re-run the authoritative lookup and can recreate the phantom channel:<id> namespace. This is a late finding on code that was also present in an earlier reviewed head; please only cache successful channel-kind lookups, or leave this fallback uncached and add a regression test.
    Confidence: 0.91
    Late finding: first raised on code an earlier review cycle already covered.

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against cc147c6a4060.

Label changes

Label changes:

  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦐 gold shrimp and patch quality is 🦪 silver shellfish.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🦪 silver shellfish, so this older rating label is no longer current.

Label justifications:

  • P2: This is a normal-priority Mattermost routing bugfix with channel-specific blast radius but real session and delivery impact.
  • merge-risk: 🚨 compatibility: The PR changes how existing Mattermost channel targets map to channel versus group session namespaces.
  • merge-risk: 🚨 session-state: The central behavior determines whether one Mattermost private-channel thread is stored under one session key or split across two.
  • merge-risk: 🚨 message-delivery: The affected namespace is used by threaded and scheduled Mattermost delivery lookup.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦐 gold shrimp and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The screenshot shows a real Mattermost reply and chat_type text, but it does not show session-store keys or logs proving the after-fix run avoided a phantom channel:<id> session; the contributor should add redacted logs, terminal output, copied live output, or a linked artifact and redact private details before updating the PR body for re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The screenshot shows a real Mattermost reply and chat_type text, but it does not show session-store keys or logs proving the after-fix run avoided a phantom channel:<id> session; the contributor should add redacted logs, terminal output, copied live output, or a linked artifact and redact private details before updating the PR body for re-review.
Evidence reviewed

PR surface:

Source +96, Tests +172. Total +268 across 8 files.

View PR surface stats
Area Files Added Removed Net
Source 4 109 13 +96
Tests 4 173 1 +172
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 8 282 14 +268

What I checked:

  • Root policy read: Root AGENTS.md was read fully; its ClawSweeper proof, plugin-boundary, session-state, and message-delivery merge-risk guidance applies to this PR. (AGENTS.md:1, cc147c6a4060)
  • Scoped extension policy read: extensions/AGENTS.md keeps bundled plugin production code inside plugin SDK/local plugin boundaries, supporting a Mattermost-owned route fix instead of a broad core fallback rewrite. (extensions/AGENTS.md:1, cc147c6a4060)
  • Current main still collapses outbound non-user Mattermost routes: Current main builds every non-user Mattermost outbound route with peer.kind and chatType as channel, so main does not already solve the private-channel group namespace split. (extensions/mattermost/src/session-route.ts:36, cc147c6a4060)
  • Authoritative Mattermost inbound mapping: Current main maps Mattermost channel types G and P to group while public O falls through to channel, which is the authoritative distinction outbound routing must preserve. (extensions/mattermost/src/mattermost/monitor-gating.ts:12, cc147c6a4060)
  • PR caches channel-kind result after channel lookup path: At PR head, after a user 404 the resolver calls resolveMattermostChannelKind and unconditionally caches the returned kind, including the fallback returned when the channel lookup fails. (extensions/mattermost/src/mattermost/target-resolution.ts:107, 7207b3f7d54b)
  • PR channel lookup failure falls back to channel: At PR head, resolveMattermostChannelKind catches any channel lookup failure and returns channel, so the unconditional cache can persist a transient failure as a process-lifetime channel classification. (extensions/mattermost/src/mattermost/target-resolution.ts:119, 7207b3f7d54b)

Likely related people:

  • Vincent Koc: Recent history for Mattermost target resolution and runtime startup surfaces includes commits touching the central target/session files and bundled Mattermost runtime paths. (role: recent area contributor; confidence: medium; commits: e085fa1a3ffd, 4133e3bb1dc9; files: extensions/mattermost/src/mattermost/target-resolution.ts, extensions/mattermost/src/session-route.ts, extensions/mattermost/src/mattermost/directory.ts)
  • Gustavo Madeira Santana: Commit d6c13d9 moved Mattermost outbound session routing behind the plugin boundary and introduced the current helper shape that this PR changes. (role: introduced behavior; confidence: medium; commits: d6c13d9dc01e; files: extensions/mattermost/src/session-route.ts, extensions/mattermost/src/channel.ts)
  • Peter Steinberger: Commit 355b4c6 landed the adjacent private-channel-as-group inbound mapping that defines the P/G -> group side of the mismatch. (role: adjacent chat-type routing contributor; confidence: medium; commits: 355b4c62bcc2, 005b25e9d42a; files: extensions/mattermost/src/mattermost/monitor.ts, extensions/mattermost/src/mattermost/monitor-gating.ts)
  • vyctorbrzezowski: Current shallow blame points to a broad recent commit across the central files, but the commit summary appears unrelated to Mattermost routing, so this is weak routing evidence. (role: recent current-main file touch; confidence: low; commits: a03c828cadd8; files: extensions/mattermost/src/session-route.ts, extensions/mattermost/src/mattermost/target-resolution.ts, extensions/mattermost/src/mattermost/directory.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (2 earlier review cycles)
  • reviewed 2026-07-03T12:19:56.262Z sha 0ba2a22 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-06T10:33:21.036Z sha 7207b3f :: needs real behavior proof before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jun 25, 2026
@iloveleon19
iloveleon19 force-pushed the fix/mattermost-infer-target-chat-type branch from a4a3df2 to 1d0e840 Compare June 29, 2026 11:46
@iloveleon19

Copy link
Copy Markdown
Contributor Author

Updated with the complete fix + live proof.

Expanded scope to the path that actually splits the thread. The earlier revision fixed resolveMattermostOutboundSessionRoute, but the isolated cron delivery path (delivery-dispatch.ts) resolved the outbound route from the ephemeral run key, not the job's bound conversation key — so it still re-derived channel: and forked a phantom session. It now prefers the job's bound conversation identity (selectCronRouteCurrentSessionKey).

Deliberately no channel-kind cache. The sibling PR #96521 added a 30-minute channel-kind cache and its author documented two correctness issues with it: a cold-restart regression (empty cache → channel: route → thread recovery fails) and a TTL mismatch vs the 5-minute authoritative lookup. Keying off the bound currentSessionKey identity avoids both — correct even cold, no extra cache.

Live Mattermost proof (private channel, type P, redacted): scheduled announce delivery into a private-channel thread, watching the session store:

build before after
without the cron fix group:<id>:thread only phantom channel:<id>:thread created (the split)
with the cron fix group:<id>:thread only no channel: session — reuses group:<id>:thread

Both delivered into the thread. The same split is visible in untouched production data (existing private-channel threads carry both group: and channel: for one root).

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

iloveleon19 added a commit to iloveleon19/openclaw that referenced this pull request Jun 29, 2026
@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 29, 2026
@iloveleon19
iloveleon19 force-pushed the fix/mattermost-infer-target-chat-type branch from 0ba2a22 to 7207b3f Compare July 6, 2026 09:42
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jul 6, 2026
@barnacle-openclaw

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@barnacle-openclaw barnacle-openclaw Bot added the stale Marked as stale due to inactivity label Jul 22, 2026
@iloveleon19
iloveleon19 force-pushed the fix/mattermost-infer-target-chat-type branch from 7207b3f to fb2a31a Compare July 24, 2026 10:07
A Mattermost private channel (server type `P`) is authoritatively chat_type
`group`, but it is addressed as the delivery target `channel:<id>` — the same
prefix as a public channel. Inbound classified it correctly as `group`, while
outbound/session reconstruction re-derived `channel` from the target string, so
one conversation was keyed under two session namespaces
(`...:mattermost:group:<id>:thread` inbound vs a phantom `...:channel:<id>:thread`
on delivery). Threaded/scheduled deliveries bound to one then failed to match the
other (fail-closed delivery, or a conversation split across two session keys).

The Mattermost outbound path could not represent `group` at all:
resolveMattermostOutboundSessionRoute only produced direct/channel, and
resolveMattermostOpaqueTarget only classified user/channel.

- session-route: key a conversation as `group` from an authoritative signal — the
  resolved target kind, an explicit `group:` prefix, or the inbound
  currentSessionKey peer kind — so outbound shares the inbound `group:<id>`
  namespace instead of forking `channel:<id>`.
- target-resolution: classify a bare channel id by its real channel type
  (P/G -> group, O -> channel), cached per id.

The wire target stays `channel:<id>` (Mattermost posts to the channel id either
way; parseMattermostTarget only accepts channel:/user:) — the group distinction
lives in the session key. Adds unit coverage for both paths.

Resolves openclaw#95646.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
leonthe8th and others added 3 commits July 24, 2026 18:19
An isolated cron run executes under an ephemeral agentSessionKey that does not
carry the source conversation's namespace. resolveDirectCronDeliverySessionKey
resolved the outbound delivery route from that isolated key, so for a job bound
to a real conversation thread (e.g. the gitlab-pipeline-watch recheck bound to
agent:...:mattermost:group:<id>:thread:<root>) the lossy channel:<id> target was
re-derived as `channel`, forking a phantom channel:<id> session and splitting the
private-channel thread across two namespaces (openclaw#95646).

Prefer the job's bound conversation identity as the currentSessionKey used to
resolve the route (new selectCronRouteCurrentSessionKey helper), so the existing
currentSessionKey-based namespace resolution keeps group:<id>. No channel-type
cache is introduced — which is what made the cache-based attempts brittle on cold
restart (a sibling PR documented exactly that failure mode). Falls back to the
isolated key for unbound jobs and cron-namespace bindings. Adds unit coverage.

Refs openclaw#95646.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
listMattermostDirectoryGroups labeled every joined channel — public `O`
and private `P` — as kind `group`. A name-resolved public channel could
then be keyed as `mattermost:group:<id>` on outbound routing, forking a
phantom group session and splitting the transcript from the inbound
`channel:<id>` one. Derive the kind from the authoritative Mattermost
channel type (`O` -> channel, `P`/`G` -> group) and add a regression
test. This closes the public-channel regression path flagged in review
for openclaw#95646 while keeping private channels keyed as `group`.
@iloveleon19
iloveleon19 force-pushed the fix/mattermost-infer-target-chat-type branch from fb2a31a to ead7ab6 Compare July 24, 2026 10:28
@clawsweeper

clawsweeper Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: fix(mattermost): key private channels as group on outbound routing This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: mattermost Channel integration: mattermost merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: M stale Marked as stale due to inactivity status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mattermost: chat_type is non-deterministic for private channels (channel-type vs target-string inference); inferTargetChatType hook not implemented

2 participants