Skip to content

fix(sessions): derive channel from direct-chat session keys in send-policy#92022

Merged
vincentkoc merged 1 commit into
openclaw:mainfrom
hansraj316:fix/send-policy-direct-channel
Jun 10, 2026
Merged

fix(sessions): derive channel from direct-chat session keys in send-policy#92022
vincentkoc merged 1 commit into
openclaw:mainfrom
hansraj316:fix/send-policy-direct-channel

Conversation

@hansraj316

Copy link
Copy Markdown
Contributor

Summary

deriveChannelFromKey returned undefined for direct/dm session keys, so channel-scoped send rules silently never fired for direct chats. Treat parts[0] as the channel for direct/dm keys too (canonical <channel>:<peerKind>:<peerId>), matching the sibling deriveChatTypeFromKey.

  • Files: src/sessions/send-policy.ts
  • No CHANGELOG.md edit (release-only per AGENTS.md).

Why core (not ClawHub)

Core correctness fix touching src/sessions/send-policy.ts — per AGENTS.md these stay in core (security/core hardening, bundled regressions, missing core APIs), not optional skill bundles routed to ClawHub.

Verification

  • node scripts/run-vitest.mjs run src/sessions/send-policy.test.ts => 7 passed
  • pnpm tsgo:core (tsconfig.core.json) => clean
  • oxfmt --check + oxlint on touched files => clean

Real behavior proof

  • Behavior addressed: Channel-scoped send-policy rules now apply to direct/dm sessions, not just group/channel sessions.
  • Real environment tested: macOS (Darwin 25.3.0); OpenClaw at base 2accfee; Node 22; Vitest via scripts/run-vitest.mjs.
  • Exact steps or command run after this patch: node scripts/run-vitest.mjs run src/sessions/send-policy.test.ts
  • Evidence after fix: 7 tests pass, incl. a new regression: a channel-scoped deny rule fires for a direct session key with no explicit channel field.
  • Observed result after fix: A direct key demo-channel:direct:user-1 resolves channel demo-channel; 2-token keys still fall through to prefix matching (unchanged).
  • What was not tested: Full Crabbox/live E2E across real channels; Linux CI; cross-OS.. Independently reviewed by a separate agent before commit; not yet run through Crabbox/$autoreview.

🤖 Generated with Claude Code

…olicy

deriveChannelFromKey returned undefined for direct/dm keys, so channel-scoped
send rules never fired for direct chats. Treat parts[0] as the channel for
direct/dm keys too, matching deriveChatTypeFromKey.
@openclaw-barnacle openclaw-barnacle Bot added size: XS triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels Jun 10, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0f54ae20d5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +52 to +53
parts.length >= 3 &&
(parts[1] === "group" || parts[1] === "channel" || parts[1] === "direct" || parts[1] === "dm")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Parse account-scoped direct keys before matching channel

When session.dmScope is per-account-channel-peer, buildAgentPeerSessionKey produces agent:<agent>:<channel>:<account>:direct:<peer> (src/routing/session-key.ts:239), so after stripping the agent prefix parts[1] is the account rather than direct. Consequently, a channel-scoped deny still fails whenever the caller has no session entry/channel metadata—the exact fallback scenario this change is intended to secure. Recognize the canonical account-scoped shape as well and add a regression case for it.

Useful? React with 👍 / 👎.

@vincentkoc vincentkoc self-assigned this Jun 10, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Maintainer verification complete.

  • Rebased onto current origin/main.
  • Extended the fix to the supported per-account-channel direct-key layout, which otherwise bypassed channel-scoped deny rules.
  • Focused proof: node scripts/run-vitest.mjs src/sessions/send-policy.test.ts — 8 tests passed.
  • Fresh autoreview: clean, no accepted/actionable findings.

@vincentkoc
vincentkoc merged commit a4a4c76 into openclaw:main Jun 10, 2026
174 of 178 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 11, 2026
…olicy (openclaw#92022)

deriveChannelFromKey returned undefined for direct/dm keys, so channel-scoped
send rules never fired for direct chats. Treat parts[0] as the channel for
direct/dm keys too, matching deriveChatTypeFromKey.
badgerbees pushed a commit to badgerbees/openclaw that referenced this pull request Jul 8, 2026
…olicy (openclaw#92022)

deriveChannelFromKey returned undefined for direct/dm keys, so channel-scoped
send rules never fired for direct chats. Treat parts[0] as the channel for
direct/dm keys too, matching deriveChatTypeFromKey.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: XS triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants