Appearance
Step 4 · Rehearse workflows end to end
Each vendor has tested alone, in its own workspace. Now you play your story flows across every system in your house at once, and check that every system ends up agreeing about the story.
There are two ways, and they complement each other:
| What it tests | Status | |
|---|---|---|
| A rehearsal in the portal | The bus plays a newsroom workflow through your house step by step, cues the vendor connection you cast in each role, and has RND stand-ins play the roles nobody holds yet | Available now: Rehearse a workflow |
| A scenario run by hand | Real people drive real product screens; a run sheet records what each system should show after every step | Available now |
A rehearsal needs no vendors and no credentials to watch, so it's where an evaluation starts. A scenario run tests what a rehearsal can't: what each product does in its own screens, and what your people do.
A rehearsal Available now
On the portal's Rehearsal page you pick a workflow (a breaking story, media arriving, a tip-line clip, a standards gate, an AI skill, a killed story) and watch each step: which system played it, and what the bus did with each message. Every message goes through the same checks as your vendors' messages, so a step the workflow says is refused is refused here too, with its rule.
- With no vendors yet, turn the stand-ins on. The newsroom system, web CMS, graphics, playout, media store and skill executor each have one.
- As vendors join, cast each vendor's connection in its role. Its stand-in steps aside, and from the next rehearsal that step is cued to the vendor, with its connection's counts.
- Reset the house to start clean: story state, timeline and waiting messages go; grants and connections stay.
See Rehearse a workflow and Stand-ins.
A scenario run by hand Available now
- A run sheet per scenario (template below): each step's actor, the action, the message you expect on the bus, and the expected state in every receiving system afterwards.
- People: a facilitator with the portal's Story timeline open; one operator per system; an editor driving the story owner.
- Fresh ids: a new
story_idfor every run. - Drive the products, not scripts. The operator makes the change in the product's usual screens. The point is to test what the product actually sends.
- After each step, the facilitator checks the timeline and each operator checks their system. Note any difference at once, with the
message_id. - At the end, compare every system's view of the story with the last accepted snapshot.
The scenarios
Start with S1. Pick the rest by which of your flows from step 1 matter most.
| Scenario | What happens | Passes when |
|---|---|---|
| S1 · Breaking story | Story created, media arrives, assets added, a skill warning, standards clearance, graphics committed, on air, updated, off air | Every system shows the final snapshot's content; the timeline shows every message in causal order; every reaction's causation_id points at its cause; nothing was refused |
| S2 · Killed mid-flight | S1 until on air, then the editor kills the story | The owner publishes a KILLED snapshot; playout ends the telling; graphics withdraws its links; every system drops the story from live views. Reopening it is refused (story_type.left_terminal), and the owner product starts a new story instead |
| S3 · Media before a story | The media store receives a clip before any story exists | An ORPHAN shell story is created; when an editor matches the clip to a real story, the asset moves to it and the shell retires; no system shows the orphan as a live story |
| S4 · Standards gate | A skill raises a flag on a lower third; the gate is PENDING | Graphics doesn't commit while the gate is PENDING; standards clears it; then graphics commits. See Skills in your scenarios |
| S5 · Two editors, one story | Two people edit the same story at once | Still one writer on the bus: the owner product publishes consecutive snapshots. sequence_number.not_increasing or story.not_owner on the timeline means two writers |
| S6 · A system down | Stop one receiving system, run S1, start it again | It catches up in order and ends where everyone else did. Messages wait 14 days |
| S7 · A newer SOM version | One producer publishes at som_version 1.1.0 with an extra field | Every system treats it exactly like 1.0.0 (forward compatibility) |
| S8 · One bad producer | A product sends invalid messages, on purpose | The bus refuses them with rule ids; nobody receives them; every other system carries on |
Run sheet
Scenario: S1 Breaking story
Run / story id: dailyplanet-s1-20260924-1 correlation_id: ________
Facilitator: ____ Operators: NCS ____ GFX ____ MAM ____ CMS ____ PLAYOUT ____ SKILLS ____
# | Actor | Action (in the product) | Expected on the bus | Expected state after | OK? | message_id / note
1 | NCS | Create story, headline H1 | story.context seq 1 ACTIVE → 202 | GFX, CMS, PROMPTER show H1 | |
2 | MAM | Ingest clip C1 for the story | delivery.media_available → 202 | NCS offers C1 as an asset | |
3 | NCS | Attach C1 | story.context seq 2, asset C1 → 202 | CMS shows C1 | |
4 | SKILLS | (automatic) | skill.warning.raised, cause = seq 2 | NCS shows the flag | |
…What joint runs uncover
| Finding | Where you see it |
|---|---|
| A system applies snapshots as merges, so removed items linger | Its screen still shows something the last snapshot doesn't have |
| The owner publishes deltas, so fields go missing | snapshot.members_missing or snapshot.assets_dropped on the timeline |
| Two systems write the same story | story.not_owner warnings, or sequence_number.not_increasing from the other writer |
Reactions don't carry causation_id | Timeline entries you can't trace to a cause |
| A system shows killed or orphan stories as live | Its screen after S2 or S3 |
| Nobody turns a skill's flag into a gate | S4 stalls, or graphics commits unchecked |
A product's system_type isn't one of SOM's | envelope.enum on its very first message |