Yes, this seems correct.
Basically, you want to multiply the transition matrices p(Z|Y) and p(Y|X). Viewing the data frame as a matrix in coordinate format, one can quickly check:

Yep, matrix multiplication is nice for this question. Initially I tried to get to the matrices without the sparse trick which depends a bit on the values of X,Y,Z. It went something like:

Had seen this trick somewhere on the J page where it had been used to implement stack. Working with indices can be quite cool and there are some neat identities, e.g., the rank of each element in a vector can be obtained as sortperm β sortperm.
Ideally, I would like to have a data notation that is somewhat independent on how its stored, i.e., long or wide. E.g., in TensorCast the matrix multiplication would be expressed as

@reduce pZX[z,x] := sum(y) pZY[z,y] * pYX[y,x]

just imagine that something similar would work on data frames

Seems to me unstack is a bit stuck in the matrix/pivot-table world and hasnβt advanced to the tensor world. More precisely, unstack takes one colkey variable which turns into an additional dimension, when it should be able to accept several colkeys and make an N+1 dimensional Array like type. Perhaps even directly into a NamedArray.
Perhaps the syntax should follow read which takes a βsinkβ type.