@@ -31,7 +31,20 @@ import {
3131} from "./prepare.test-helpers.js" ;
3232import { clearSlackSubteamMentionCacheForTest } from "./subteam-mentions.js" ;
3333
34- const enqueueSystemEventMock = vi . hoisted ( ( ) => vi . fn ( ) ) ;
34+ const { enqueueSystemEventMock, logVerboseMock, shouldLogVerboseMock } = vi . hoisted ( ( ) => ( {
35+ enqueueSystemEventMock : vi . fn ( ) ,
36+ logVerboseMock : vi . fn ( ) ,
37+ shouldLogVerboseMock : vi . fn ( ( ) => false ) ,
38+ } ) ) ;
39+
40+ vi . mock ( "openclaw/plugin-sdk/runtime-env" , async ( importOriginal ) => {
41+ const actual = await importOriginal < typeof import ( "openclaw/plugin-sdk/runtime-env" ) > ( ) ;
42+ return {
43+ ...actual ,
44+ logVerbose : ( ...args : unknown [ ] ) => logVerboseMock ( ...args ) ,
45+ shouldLogVerbose : ( ) => shouldLogVerboseMock ( ) ,
46+ } ;
47+ } ) ;
3548
3649vi . mock ( "openclaw/plugin-sdk/system-event-runtime" , async ( importOriginal ) => {
3750 const actual = await importOriginal < typeof import ( "openclaw/plugin-sdk/system-event-runtime" ) > ( ) ;
@@ -54,6 +67,9 @@ describe("slack prepareSlackMessage inbound contract", () => {
5467 clearSlackAllowFromCacheForTest ( ) ;
5568 clearSlackSubteamMentionCacheForTest ( ) ;
5669 enqueueSystemEventMock . mockClear ( ) ;
70+ logVerboseMock . mockClear ( ) ;
71+ shouldLogVerboseMock . mockReset ( ) ;
72+ shouldLogVerboseMock . mockReturnValue ( false ) ;
5773 } ) ;
5874
5975 afterAll ( ( ) => {
@@ -171,6 +187,28 @@ describe("slack prepareSlackMessage inbound contract", () => {
171187 expect ( prepared . ctxPayload . BodyForAgent ) . toContain ( body ) ;
172188 } ) ;
173189
190+ it ( "logs inbound metadata without logging message content" , async ( ) => {
191+ const body = "confidential acquisition target: northstar; do not include this text in logs" ;
192+ shouldLogVerboseMock . mockReturnValue ( true ) ;
193+
194+ const prepared = await prepareWithDefaultCtx ( createSlackMessage ( { text : body } ) ) ;
195+
196+ assertPrepared ( prepared ) ;
197+ const inboundLog = logVerboseMock . mock . calls
198+ . map ( ( [ entry ] ) => entry )
199+ . find ( ( entry ) => typeof entry === "string" && entry . startsWith ( "slack inbound:" ) ) ;
200+ const verboseOutput = logVerboseMock . mock . calls
201+ . flat ( )
202+ . filter ( ( entry ) : entry is string => typeof entry === "string" )
203+ . join ( "\n" ) ;
204+ expect ( inboundLog ) . toBe (
205+ `slack inbound: account=${ prepared . route . accountId } agent=${ prepared . route . agentId } channel=D123 message_ts=1.000 thread_ts=none from=slack:U1 chat=direct chars=${ body . length } ` ,
206+ ) ;
207+ expect ( verboseOutput ) . not . toContain ( body ) ;
208+ expect ( verboseOutput ) . not . toContain ( "confidential acquisition target" ) ;
209+ expect ( verboseOutput ) . not . toContain ( "preview=" ) ;
210+ } ) ;
211+
174212 it ( "prepares wildcard open-policy account DMs" , async ( ) => {
175213 const ctx = createInboundSlackCtx ( {
176214 cfg : {
0 commit comments