Building Use Cases

Luke and I need to firm up the API and lay out the common paths that an implementation has to handle, so this week we’ve been building out step-by-step instructions around some core use cases. In the process we’ve settled a few long-standing ambiguous points around how plans change, what is allowed, what is forbidden, and so on.

While the work is still young, I’m quite happy with it. We decided on four profiles to cover, and four individual sub-profiles of increasing difficulty within. Here’s a quick visual of what we laid out:

Some quick background on the terms — this is in the specification document, but that can be a hefty plate to finish if you’re just getting your feet wet with Sandpiper. Here are the relevant sections:


In the context of a connection, nodes, humans, and systems assume a role as an actor. Any connection has only two actors: a Primary Actor and a Secondary Actor.

The primary actor is the sender of data, responsible for providing information about and issuing updates from its canonical pools.

The secondary actor is the recipient of data. This actor can be a human or a full Sandpiper node. The former is known as Basic Secondary Actors, because it cannot engage in a true Sandpiper exchange, and the latter are known as Advanced Secondary Actors. Advanced secondary actors are responsible for providing information about their snapshot pools as well as processing updates provided by the primary actor.


One actor, known as the Initiator, connects to the other, known as the Respondent. At this point, neither actor is technically primary or secondary – that relationship will be established later, when the two actors decide the course of action they’ll be taking. A given actor could receive data for one set of product information, or send data for another; this is dictated by the plan, which will be agreed to in the negotiation.

Accompanying this is a workbook with one sheet for each category, containing explicit steps for each of the four columns of the difficulty matrix. We finished the first (Initiator – secondary) and will start with initiator – primary (and hopefully more) next week. It’s a bit rough to post here yet, but when it’s a little more polished, it will be one of the documents we publish to guide implementers bootstrapping their own nodes.

And it gives us tangible points to hit, too, as we define the expectations of the API, which at the moment is quite loose, containing vestigial pieces from past ideas. In particular, we’re adopting the Plan document as the means of communicating the plan when it changes. In the past, we have avoided this, because we didn’t want to put the burden of parsing XML on the node. But with a REST API it gets convoluted to handle a side-channel of plan change commands, and we also realized that every time the plan is modified, it needs a new UUID. So the alternative to parsing the XML would require multiple regeneration steps before finally approving the finished plan. From that perspective, XML starts to look pretty clean.

That being said, the Level 3 API will be over a persistent connection, which changes this complexity argument. We’ll have to address that when we come to it; for Sandpiper 1.0 we are focusing on levels 1-2, which use the REST API. At levels 3+, we’ll be defining a command channel, which could incorporate plan changes if designed correctly. That’s a river to cross another day!