Design note. This describes a capability we believe a production publishing layer should have. It is not a statement of current composerID functionality. What exists today: Triage makes the decision and composerID publishes its decision reference into configured downstream systems. What this article describes: a capability or engineering principle we are considering as composerID develops. It is not a claim that this functionality is currently available in production.
Sometimes a computer sends the same request twice. A network connection times out and the sender retries, not knowing the first attempt succeeded. A person clicks a button, sees nothing happen, and clicks again. Software that publishes records into other systems has to expect this, because it happens constantly.
A good publishing service should recognise that it has already processed a request, rather than accidentally performing the same action twice. Engineers call this idempotency: doing something once, no matter how many times you are asked.
Why it matters here
Duplicate records are the integration failure everybody has a story about. The retry that landed twice. The approval that created two requisitions. Each duplicate leaves two records where there should be one, and cleaning them up usually takes longer than the original request did.
Our proposed approach
The design we are working towards uses the decision reference as the protection. Every publish could be identified by a key built from things that are already known before the call is made: the decision reference, the version of the decision, and the destination it is going to. Nothing in that key is random and nothing depends on the clock, so two attempts to publish the same thing would compute the same key.
A publishing service holding that key should return the original receipt when the same publish arrives again, rather than creating a second record. And when the decision genuinely changes, the version changes, the key changes, and the next publish is correctly treated as new. Idempotency should never become a trap that silently swallows a real change.
When the destination helps, and when it does not
Some platforms accept an idempotency key of their own on create calls, and an adapter should pass one whenever the platform documents it. Others document no such mechanism. Beeline, for example, documents none, so an adapter there could search for an existing record already carrying the decision reference before creating one: find before create. That pattern only works if the reference was written into the destination’s own reference field in the first place, which is one more argument for the common reference.
What exists so far
Our reference sandbox implements this design end to end, and its automated tests replay publishes to prove that exactly one record results. That is a proof of the design, not a production guarantee. When a production publishing service carries this behaviour, the way to say so will be an acceptance test, not an adjective.
Written with Claude. This post was drafted with Claude, Anthropic’s AI model, working from the composerID repository: the registry, the schemas, the reference sandbox and the vendor documentation it cites. Edited and published by the composerID team.