Last reviewed 2026-09-05Skill version 0.1.0Provisional
Prove that Slack holds this message in a direct message conversation. The post event states the channel_type im, so the message reached a direct message conversation and not a public channel. It does not prove which person.
Send the message to the person as a direct message.
What is the subject and the action?
Member
Value
Subject type
slack.message
Subject identity
message_ts = $action.result.ts
Canonical effect
messaging.message_post
Provider operation
POST /chat.postMessage
Idempotency
none, retry is not safe
How does the evidence correlate with this operation?
Strategy
Assurance
Keys
Required
resource_id
strong
message_ts from $action.result.ts
yes
fingerprint
weak
channel from $input.channel_id; text from $input.text
no
Which evidence does the contract require?
Minimum evidence level E2. An independent channel is required. Minimum channels: 1.
Channel
Level
Independence
Verifier
Description
message_readback
E2
provider readback
http
Read the one message of the conversation that carries this ts. The documented recipe sets oldest to the ts, inclusive to true, and limit to 1. A condition path is $observed.message_readback.messages[0].ts. The path $observed.message_readback.ok states whether Slack answered.
direct_message_posted_event
E3
provider event
webhook
The message.im events of this message in the intended direct message conversation. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. The value im of channel_type separates a direct message from every other conversation.
message_conversation_posts
E3
provider event
webhook
The messages of this text in this conversation since the operation started. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. A count above one shows a second post, and chat.postMessage has no idempotency key to stop it.
Which conditions must all hold for VERIFIED?
Condition
Meaning
Path
Operator
Expected
Evidence
read_succeeded
Slack answered the read. Every Web API response carries the boolean member ok, and Slack answers HTTP 200 for a failure as well, so the status code states nothing.
$observed.message_readback.ok
eq
true
message_readback
message_present
The conversation holds exactly one message at this ts. A hidden message, such as a deleted one, leaves the list.
$observed.message_readback.messages
array_length
1
message_readback
message_ts_matches
The ts of the message equals the ts of the answer of chat.postMessage. The member is a string in both places.
$observed.message_readback.messages[0].ts
eq
$action.result.ts
message_readback
message_text_matches
The text of the message equals the text that the intent stated.
$observed.message_readback.messages[0].text
eq
$input.text
message_readback
message_posted_by_an_app
The message carries the subtype bot_message, so an integration posted it. A message of a person states no subtype.
$observed.message_readback.messages[0].subtype
eq
bot_message
message_readback
message_posted_in_the_window
Slack posted the message after the operation started. The ts of a message is a Unix timestamp, and the bounds oldest and latest read the same values.
$observed.message_readback.messages[0].ts
time_after
$operation.created_at
message_readback
direct_message_event_names_an_im_conversation
At least one message.im event of this message names the conversation of the intent and states the channel_type im. A workspace with no event subscription cannot verify this level.
$observed.direct_message_posted_event.count
gte
1
direct_message_posted_event
Which conditions give CONTRADICTED?
Condition
Class
Reason
Path
Operator
Expected
message_text_differs
wrong subject
Slack holds a different text than the intent stated. Ask a person.
$observed.message_readback.messages[0].text
ne
$input.text
message_predates_operation
pre existing state
The message is older than the operation. It proves nothing.
$observed.message_readback.messages[0].ts
time_before
$operation.created_at
duplicate_message_present
duplicate side effect
Slack holds more than one message of this text in this conversation since the operation started. Do not retry.
$observed.message_conversation_posts.count
gt
1
Which observed states map to a verdict before completion?
Rule
Match
Verdict
Reason
read_refused
$observed.message_readback.ok eq false
UNVERIFIABLE
Slack answered the read with the status code 200 and the member ok false. The answer is a refusal and it is no evidence.
How long does the runtime observe?
Timing member
Value
Initial delay
1000 ms
Poll interval
5000 ms
Backoff
exponential factor 2, max 60000 ms
Maximum attempts
40
Timeout
900000 ms
Stale read window
20000 ms
On timeout
UNVERIFIABLE (evidence_unavailable_before_timeout), escalated to a person