Welcome, Guest | Browse

Software Factory Archive

← Previous Work All Works Next Work →

The Webhook Simulator

Rating:
General Audiences
Fandom:
StrongDM Software Factory
Characters:
Navan Chauhan Jay Taylor
Tags:
Digital Twin Universe Webhooks Event-Driven Jira Slack Callbacks
Words:
458
Published:
2025-12-06

Most people thought of the twins as request-response systems. You sent an API call, you got a response. But that was only half of what the real services did. The other half was outbound: webhooks, event callbacks, push notifications. The services didn't just answer questions. They volunteered information.

The Jira twin fired webhooks on twenty-three distinct event types. Issue created. Issue updated. Issue deleted. Comment added. Sprint started. Sprint completed. Worklog updated. Version released. Each webhook carried a structured payload that matched the format of real Jira's webhook payloads, down to the field names, the nesting structure, and the timestamp format.

"The tricky part isn't firing the webhook," Navan said. "The tricky part is firing it at the right time." He was debugging a scenario where the Jira twin's webhook arrived before the twin had finished persisting the state change. An agent received notification that a ticket had been updated, queried the ticket, and got the old state because the update hadn't been committed yet.

"Real Jira has this problem too," Jay observed. "They call it eventual consistency. The webhook fires from the event bus, but the REST API reads from a replica that might lag behind."

"So do we replicate the lag?"

"We have to. If the twin is instantly consistent, agents will write code that assumes instant consistency. Then when they hit real Jira, that code will fail because real Jira has read-after-write lag." Navan added a configurable delay between the state commit and the API read path. "Fifty milliseconds. Enough to be realistic, short enough not to slow down testing."

The Slack twin had its own webhook complexity. It emitted event callbacks through the Events API: message posted, channel created, user joined, reaction added. Each event had a retry policy. If the receiving endpoint didn't respond with a 200 within three seconds, the Slack twin retried. Three retries with exponential backoff: three seconds, nine seconds, twenty-seven seconds. After that, it stopped and logged the delivery failure.

"We also model the verification handshake," Navan added. "When you register a webhook URL with the Slack twin, it sends a challenge request. Your endpoint has to echo back the challenge token. If it doesn't, the registration fails. Real Slack does this. Our twin does this."

Jay was reviewing the webhook payload for a Jira issue transition event. The payload included the issue key, the transition name, the from-status, the to-status, the user who triggered the transition, and the changelog. The changelog listed every field that had changed, with before and after values.

"The changelog is the most useful part," Jay said. "And the most complex. Different field types have different changelog formats. A string field shows old value and new value. A multi-select field shows the added and removed values. A user field shows the user's account ID, display name, and avatar URL."

"The twin generates all of it," Navan confirmed. "Every webhook payload is complete and structurally accurate. The agents downstream don't know they're receiving webhooks from a twin. They process them the same way they'd process webhooks from the real service."

That was the point. The twins didn't just respond. They initiated. They pushed. They behaved like living services, not like static mocks waiting to be called.

Kudos: 56

webhook_wrangler 2025-12-08

The intentional read-after-write lag is such a smart design decision. Twin testing that's too perfect trains agents for a world that doesn't exist. Realistic imperfection is fidelity.

event_driven_dev 2025-12-09

Twins that initiate webhooks rather than just responding to calls. That's the line between a mock and a behavioral clone. This series keeps making that distinction sharper.

← Previous Work All Works Next Work →