> What we mean to write is: auto plus(const std::string& s, const std::string& t) { return s + t; }
To a first-order approximation, sure. But arguably it's better to pass 's' by value and 't' by const reference, then do s += t and return s. That lets you reuse any existing buffer if you receive an rvalue, and lets the caller preallocate the buffer if it so desires. This can help you avoid a heap allocation.
> This function is wrong: auto plus(const std::string s, const std::string& t). The programmer meant to type const std::string& s.
Not necessarily. The const tells the programmer that s will never be modified. That's an excellent constraint that can make a nontrivial function easy to reason about. (Obviously that doesn't imply you should do this everywhere. I'm just pointing out it's not "wrong".) P.S. I hear optimizers can sometimes optimize const objects, though I don't have proof handy for that example, so someone else can fact-check that part.
> or maybe they meant const std::shared_ptr<Connection>& for efficiency (but in that case why aren’t they simply passing const Connection& from the caller?)
That "why" actually has an answer: "because the function might only copy the shared_ptr conditionally, and desire to remain efficient in the no-copy case".
> Const data members are never a good idea.
This one is correct!