If you want to be sure to clean up the process state on your client, you’ll probably want to call close() whether or not you call terminate(), as older versions of OpenSSH (before 7.9) ignore requests to deliver signals to a server-side process. See the note at
https://asyncssh.readthedocs.io/en/latest/api.html?highlight=terminate#asyncssh.SSHClientChannel.send_signal for more details about this. If you are connecting to a server which doesn’t pass the terminate signal through, that server process could remain active indefinitely, keeping your client-side state active along with it.
If you call close(), the main impact to the server process is that stdin/stdout/stderr will all be closed. So, if the remote process tries to read input, it will get an EOF, and if tries to do further output, it may at some point begin getting EPIPE errors. This may prevent the process from completing whatever operation it was performing, but since you mention calling terminate(), that’s probably not a concern for you.
Also, you don’t say here whether you also want to close the connection or not, but if so you’ll need to do that with conn.close(). Just calling close() on the process won’t close the connections as you can open more than one channel on a connection, and you can keep the connection around to potentially use to open future channels on it even after all the previously open channels are closed, at least on some servers. If you do decide to close the connection, that will implicitly close all one channels, so you’d no longer need to do the proc.close() in that case. The results are basically the same from the point of view of the server process — as above, it’ll see stdin/stdout/stderr being closed when the connection is closed.
Doing a terminate() of a process followed by a close (of either the process or the connection) will probably give you the best results in terms of cleaning up as quickly as possible, on servers which honor the terminate() request. In theory, terminate() by itself would be enough on servers that support terminate(), as the server will trigger a close() when the server process exits and you don’t need to do the close() on the client side once that happens, but it’s better not to count on that.
Regarding not calling wait_closed(), you may see some errors when you try and exit the asyncio event loop if you have tasks which haven’t completed yet when you stop the event loop. These errors can generally be ignored, but they could be one reason to keep a list around of all the processes or connections you closed in this way, to potentially do a wait_closed() on just before you exit the loop and terminate your client.