As far as I know we haven't tackled actions at all yet, and so there's no design doc or prototypes.
But the way I imagine it is as follows:
Services are asynchronous (with a synchronous API on top) and reliable. This means that you can make a request (async or sync) and you'll either get a response, or an error from the service server, or an error due to a timeout (no response from the service server). Additionally, you'll be able to associate requests and responses by comparison or with a unique identifier.
On top of this, Actions would provide a state machine on the server side allowing for preemption, as well as a way to do periodic feedback (pub/sub) between the original request and the final reply. There would be client and server side code to handle preemption requests and to generate feedback on the feedback topics.
The article "ros_rpc" that you linked was written when we were working the more abstract side of the research. It was actually written while we were prototyping with zeromq and protobuf and thinking about making our own rpc or using something like thrift. So it might be a little out of date or at least is limited to an abstract description of what we felt Services and Actions should be at the time. It's more memoranda at this point than our intention for the final design.
There was a time when we thought that having preempt-able services (basically Actions without feedback) would be desired, but I'm not sure it's an important distinction to have. Since the DDS RPC standard doesn't support preemption and most of other request-reply frameworks we looked at do not support it either, I'd say it would be best for us to implement that on top of services instead of incorporating it into services at the low level. That also keeps the rmw interface simpler.