RND Solutions · Sofia, Bulgaria · Est. 2014

← Insights

Field note · Story Object Model 1.0 · 24 September 2026

A bus you are allowed to break

Ten days ago we wrote that somebody has to run the bus. So we built one, put it online, and broke it. Here is SOM 1.0 from the operator's chair — and why you can now break it too.


We took our own advice

"Who runs the bus?" ended with a twelve-week plan whose first four weeks read: a bus you are allowed to break. A broker in your own cloud, a validating gateway at the edge, two producers, one consumer, retention and replay from day one. Nothing touches air.

That is what we built, and it runs in AWS eu-west-1. A gateway at the edge checks every message against the SOM 1.0 schemas with format assertion on, and every snapshot against the story's history. Accepted messages are delivered in order per story, duplicates are dropped by message id, and every consumer gets its own queue, dead-letter queue and replay. A small portal lets a person check a message before sending it and follow a story snapshot by snapshot.

Everything below comes from running it. We are ten days in — treat this as a field note, not a verdict.

A stale story snapshot arrives after a newer one and is refused by the gateway before Graphics, Web CMS or Archive can see it.

↔ Swipe to see the whole diagram

Fig. 6A stale snapshot arrives after a newer one. The gateway refuses it with the rule that fired — nobody downstream ever sees it.

The twentieth case is real

Last time we said that a gateway validating with schemas alone would score nineteen out of twenty on the published negative cases and quietly admit pre-1.0 traffic. Built and tested, that is exactly what happens: nineteen fail on the schemas; the twentieth, a message declaring version 0.3.2, is valid JSON Schema and has to be refused by a conformance rule. Ours does. It is one line of code, and it is easy to never write.

The skill library's own examples fail SOM 1.0

This one surprised us. Each skill in the draft library ends with a sample of the warning it raises, and those samples do not validate against the 1.0 schema: warning_id reads "wrn-7f2c9a41" where the schema requires a UUID, skill_warning_ref is null where it requires a string, and at least one sample stamps a system_type of playout, which the 1.0 envelope does not allow.

A vendor who builds from the samples gets every warning refused — and learns why only if the bus tells them. Ours does, rule by rule. None of this is a criticism of a 1.0: the library versions separately, is marked draft, and says so. It is exactly the gap a test bus exists to find before a newsroom does.

Skills listen for messages that do not exist yet

Skills say which messages should wake them. Across the library fifteen are named. Three have a 1.0 schema — story.context, link.committed and skill.warning.raised. The other twelve, including three different names for what looks like one "asset ingested" event, are proposals. A bus has to decide what to do with them today. Ours accepts them with envelope validation only and says so in the verdict; refusing them would break the vendors building ahead of the standard, and accepting them silently would hide that nothing checked them.

A legal kill can look like a delta

"Snapshots, not deltas" was the second of our eight problems, and it has a sharp edge. An ACTIVE story must carry lifecycle; any other story type must not. So a story that is killed has to drop a field — and the project's own sequence-checking tool reads a dropped field as the forbidden delta. A gateway that copies the tool's rule refuses every kill, spike and archive. Ours exempts removals the schema itself forces. We are writing this up for the working group, with the rest of this note.

Identity rides the transport

The envelope forbids a signature, so authenticity has to come from how a message arrives. On our bus every producer signs in — AWS request signing or OAuth2 client credentials — and may publish only the message types and system_ids it was granted. A message claiming system_type: compliance_engine is still a claim, but now it is a claim made by a known caller, from a known system, and it is logged.

A portal timeline follows one story through seven ordered snapshots, a skill warning and a refused stale resend, with a panel showing the changes from sequence six to seven.

↔ Swipe to see the whole diagram

Fig. 7One story as the portal shows it: seven snapshots in order, a skill warning, a refused stale resend, and what changed between versions.

We broke it on day ten

This morning a routine deploy failed. We had added a rate limit for a new public form; CloudFormation applied it to the API before the route it named existed, the update failed — and then the rollback failed on the same setting and stuck. The live site never noticed. We finished the rollback by hand, fixed the ordering, added a test so it cannot come back, and wrote the recovery into the runbook.

That is the whole job, really. Infrastructure breaks. What matters is the next ten minutes, and whether the next person has to work it out again.

What we are still not claiming

  • No production newsroom traffic yet. It is a test bus, with synthetic data.
  • No certification. SOM defines no conformance tiers, so neither do we. A result says exactly what passed: passes som-bus suite som-1.0.0+lib-0.2.2.
  • No endorsement. We still hold no position in the working group.

Break it yourself

If you build newsroom software, you can now test your SOM integration against a live bus: check a message before you ship it, publish with real credentials, and read every verdict with the rule behind it. If you run a newsroom, the next step is a sandbox where your vendors exchange real SOM traffic — and you watch every story arrive.

Access is by invitation while we are early. One review, then it is yours.