Principle: A stream must be designed so that it knows, by itself, when to end. A manual unsubscribe is a code smell.
Mental model: a stream is a BPMN-like diagram — operators are boxes with three wires between them: value pucks, the error puck, the "stream ended" puck. If you can draw it, you can build it. The error and complete wires are one-shot. And a puck can carry a whole other diagram — not wired in at design time like in BPMN, but arriving as data at runtime (higher order).
Wiring: subscribe connects the boxes back to front, and every subscribe is a new instance of the diagram (share plugs into a running one). Disconnection travels backwards too — so cleanup boxes (takeUntil…) belong at the end of the pipe.