Why configuration became a runtime problem

At first, using Airtable for both editing and runtime lookup felt perfectly reasonable. A workflow could load a campaign, its questions, reminder rules, templates, and appointment settings, then continue with the conversation.

The trouble was not Airtable. The trouble was asking every live execution to reconstruct a small configuration graph from many related records. A conversation turn became dependent on several lookups being available and mutually consistent at the same moment.

That is an uncomfortable dependency for a customer-facing message.

The boundary I introduced

I separated editing from execution. The editable configuration remains where people can work with it. A publish step validates it and creates an active runtime snapshot. Conversation workflows load that snapshot rather than assembling the campaign from scratch.

editable configuration
โ†’ validate
โ†’ publish runtime snapshot
โ†’ load snapshot for a conversation turn

This is mainly a consistency decision. I do not want one message to begin under one set of questions and end under changed appointment rules because somebody saved an edit half way through the execution.

Save is not publish

The distinction also makes the operating model clearer. Saving means somebody changed a draft. Publishing means the configuration passed the checks required for live use.

That gives incomplete drafts a safe home. It also gives validation a proper boundary: missing template assignments, incomplete questions, or invalid appointment rules can be rejected before a lead depends on them.

The runtime side should be boring: complete, predictable, and read-only from the perspective of a conversation workflow. The editing side can be friendlier, more flexible, and willing to hold unfinished work.

What I learned

A configuration database is not automatically a runtime configuration system. Once several workflows rely on the same configuration, publication and versioning become architecture rather than administrative polish.

This also makes the workflow boundary healthier. The conversation flow can spend its attention on interpreting a message, selecting an action, and persisting state instead of repeatedly joining configuration records.

For the related design choice, see separating campaign configuration from workflow logic.

What should happen next

I want every execution to retain the runtime version it loaded and the publication event that produced it. That will make configuration incidents easier to investigate without trying to reconstruct what an editable database looked like at an unknown point in time.