Welcome, Guest | Browse

Software Factory Archive

← Previous Work All Works Next Work →

The Slack Twin: Block Kit

Rating:
General Audiences
Fandom:
StrongDM Software Factory
Characters:
Jay Taylor Navan Chauhan
Tags:
Digital Twin Universe Slack Block Kit Message Rendering Deep Dive
Words:
452
Published:
2025-08-03

The message payload was 247 lines of JSON. Jay scrolled through it slowly, the way you'd read a legal contract—not because you enjoyed it, but because missing a clause could ruin you.

Block Kit was Slack's structured message format, and the Slack twin had to understand every block type. Not just accept them—validate them, store them, and return them with the exact same structure when queried. A section block with a text object and an accessory image. A divider block that was literally just {"type": "divider"}. An actions block containing three buttons, each with a distinct action_id, each with a style attribute that could be "primary," "danger," or absent entirely.

"The context block is the one that trips people up," Navan said. He was running a scenario that had an agent posting a status update to a Slack channel via the twin. "Context blocks accept up to ten elements. Each element can be either an image or a text object. But not a button. Not a select menu. Just images and text. If you put a button in a context block, real Slack returns a 400 with a very specific error message."

"And our twin returns the same error?"

"Exactly the same. Same HTTP status. Same error code. Same error message string." Navan pulled up a diff view. On the left, a captured response from real Slack. On the right, the twin's response. They were identical down to the punctuation in the error description. "That's the fidelity we're targeting. An SDK that works against real Slack has to work against our twin, and an SDK that gets an error from real Slack has to get the same error from our twin."

Jay pointed at a nested structure in the payload. "What about the interactive components? If an agent clicks a button in the twin, does the twin post an interaction payload back?"

"Yes. The twin implements the full interaction flow. Button click generates an interaction payload sent to the registered callback URL. The payload includes the action ID, the block ID, the user who clicked, the message timestamp, the channel. All of it." Navan ran the scenario forward. The agent posted a message with an approval button. Another agent clicked the button. The twin fired the callback. A third agent received the callback and updated the original message. "Three agents, one message, one button click, full round trip through the twin."

The scenario passed. All assertions green.

"What about message updates?" Jay asked. "If you update a Block Kit message, do you replace the whole block array or can you patch individual blocks?"

"Replace the whole array. That's how real Slack works. There's no block-level patching. You send the complete new block array every time. The twin enforces that. If you send a partial update, it rejects it." Navan closed the diff view. "Block Kit is deceptively simple. The specification looks clean. But there are about forty validation rules that aren't in the official docs. We found them by sending malformed payloads to real Slack and cataloging the errors."

"Behavioral capture by antagonism," Jay said.

"That's one way to put it. I prefer 'exploratory validation.' Sounds more professional in the spec."

Kudos: 44

blockkit_enjoyer 2025-08-05

"Behavioral capture by antagonism" is exactly how I reverse-engineer APIs too. Send the worst possible input and see what screams.

slack_bot_builder 2025-08-06

The forty undocumented validation rules are SO real. I've hit at least ten of them building Slack integrations. This fic gets it.

← Previous Work All Works Next Work →