One of the recurring questions I get is how can you make sure that what the agent built is correct?
We were having an AI sharing session at work and one of my colleagues showed his Event Modeling tool to help him get an overview of the module that he was building. He used his app to generate an event model of what had been built, and I spotted an event that was storing something it shouldn’t. We had already planned the slice to fix it, but it occurred to me that the event model is also a good way to do verification. A compiled event model is a really good way to check the agent’s work.
Making sense of agent generated output in a human readable way, backed by code, is a way to gain confidence in AI engineering.
I really like the analogy about how software should read like a book. It takes me back to when I started programming, the first thing they teach us is pseudocode. If you want to do something, write down the steps that will take you from point A to point B.
Event modeling is essentially the same thing, but with more structure. The steps would be broken down to in essence 2 things: something you observe, or something you intend.
When I first got the event modeling fever, the tools that were available were Miro and a plugin from Martin Dilger. It was a great tool that helped make the event modeling process a bit easier and according to spec defined by Adam Dymitruk.
This was around the time I was experimenting with OpenClaw and Telegram, on the train ride to work I would vibe code a bunch of stuff. Then I wanted to be able to do a bit more responsible vibe coding. I experimented a bit with text based notation where I would use emojis to express events, commands and read models in a sensible structure. While it worked very well for me to read, the typing process was very cumbersome.
That’s when I decided to vibe code an event modeling app for the mobile. The prototype is still up in my OpenClaw’s repo (didn’t have as much trust with it to give access to my actual repository :D)
It did an okay, acceptable job but I never really got into using it.
There are so many people building their own tools and I’m liking the variation but also consistency. You can pretty much open up an event model in a tool that follows the spec, and you’ll immediately know where to look for things you have questions on. Martin’s tool has come out of Miro and he has a whole new platform now, much more sophisticated, and now even integrated with agentic engineering.
My colleague building his tool inspired me to pick up my own tool and try to improve it.
You would think this app would look horrendous by now, but I looked at the code, and because it started out as an event sourced application in the beginning, it’s still pretty organized, and very extendable.
I started using it to import code of all my other apps that I’ve been building, again, all event sourced, everything maps cleanly to a slice.
Seeing the slices was useful. Understanding how they actually worked was better.
One of the key elements of Event Modeling are the Given When Thens. This is something that I didn’t really pay attention to before but now I realize what a big part they can play.
All my apps had existing tests, and while all had the structure of given events, when command, then event, there was not really a structure to how they were written. When I asked my agent to generate an import file for eventPAD based on the code, it did it, and I asked for a token summary. Barrio, the family app I’m building, is about 400 C# files and 230 test files, and the whole extraction took around 2 to 2.5M tokens. The events were cheap, about 46k. The tests were the biggest part: 1.2 to 1.5M tokens to turn about 1,000 tests into 3,800 Given/When/Thens, because the agents had to first understand the tests and make decisions on whether they were asserting things correctly.
I asked if there was a way to optimize this with a script, and now we have a test helper that explicitly follows the Given() When() Then() convention. Wishbook, my wish list app, already uses it: its tests write the Given/When/Thens themselves, and the model builds from the test run in about a second, with zero agent tokens.
While I write this, I’m asking my agents to refactor all my tests to use the helper so I can have all my projects on my shelf.
While reviewing the event model for eventPAD itself, I noticed that creating chapters was a shared slice for the board and the outline view, but AddOutlineProperties and Reoutline gained their own slices. One of the things in Vertical Slice Architecture is that each feature in the front end must have its own slice, never shared. But it made me think about that design choice.
When I looked at barrio’s event model I was pleasantly surprised at how many slices there were, some I don’t even remember prompting, but some really good ideas that I might find time to develop further.
The nice thing about the slice architecture is being able to just delete that folder and not have to worry about any dependent features that might be affected.
Anyway, now I’ve added exporting an eventPAD JSON to my standard build pipeline because I want to be able to review how things have been built, and maybe go back and remove features that were built but not really utilized as much.
For my personal projects, a script that exports what the code says and presents it in a way that I can get the bigger picture is a great addition, apart from testing the feature manually myself of course.
For my projects, it works because I’m the only customer and my projects are small-scale relative to what enterprise applications are.
If you have a structured codebase that uses vertical slices and event sourcing and your tests are formulated in GWT, and if you hopefully started the project with event modeling in the first place, you could easily create a script that extracts a model based on your code and check the diff between the plan and the actual implementation.
If a delivery is small, this can easily be reviewed by a human.
With event modeling, the point is not getting an event model of your entire system out in one go, because that would take a lot of time. An event model of an MVP of a component or a flow is enough to start implementing, and iterate from there.
If you build the safeguards around the code your agents write, you get to be creative about how you check it. For me, that means reading my apps like a book. Sometimes I even find a chapter I don’t remember writing.
