For example, you'll run into things like channel buffering (I see that our "operator" creates an unbuffered channel, so you already have a potential performance issue there), an aspect which is opaque to both sender and receiver (unless they explicitly check the capacity), and can result in surprising blocking issues. You'll also need to deal with channel ownership (the producer is, in most situations, effectively the only one who can close a channel). Usually one channel is not enough; in order to propagate errors and be able to cancel an arbitrary graph of pipes, you'll likely need 2-3. And regarding performance, all channels are protected by internal mutexes to make them thread-safe, so by using channels to pipe data, all your code will be slowed down by mutexes, even the parts that don't need to be thread-safe.
I recommend writing a dedicated iterator-style pipe interface type instead. Channels can then be used carefully for parallelization, fan-out and such, but direct data exchanges (e.g. transforming tuples) can be single-threaded and fast.
Lastly, I recommend annotating channels with arrows to make them read/write-only for the callee. You have "in chan interface{}", which should probably be "in <-chan interface{}."