The "natural" way for template expansion to work in the legacy parser is by strict string interpolation. Unfortunately, that means that templates don't know whether they are in "start of line" context or not, and so a template with the contents * foo is not *guaranteed* to result in a list, depending on where on the line that template was included.
This was seen as undesirable, so T2529#31474 added a hack to "ensure" that the template was always expanded in start of line context, but adding an extra newline if the template expansion began with the start-of-line-sensitive wikitext token {|, :, ;, #, or *. T14974 was opened against the behavior introduced by the "T2529 hack", but it's been 14 years (as of when this bug is being created) and no one's come up with a better solution. In cases where the "T2529 hack" is misapplied, edits can "easily" workaround it by begining their template with <nowiki/> or similar to prevent the "T2529 characters" from appearing at the start of their template.
Unfortunately, the T2529 hack does not *always* ensure templates are evaluated in start-of-line context. In particular, the wikitext tokens == (for headings) as well as !, |, |} (table heading, table row, and table close) are also white-space sensitive, but don't trigger the T2529 hack to insert a newline. (Of these, ! and | depend on being "in table context" which the legacy parser can't easily know, but |} was probably an oversight and could have been easily added.)
The transition to Parsoid allows us to replace the "T2529 hack" with a simpler rule that templates are *always* parsed "in start of line context". That doesn't immediately solve T14974 (templates starting with a # turn into list items) but it at least makes the template expansion more intelligible/understandable to editors. (/Solving/ T14974 probably requires a typed template system that would declare the result of that particular template to be "plain text" or "an attribute value" or "a set of key/value pairs" so that it doesn't get parsed as wikitext.)
We will probably still require a way to reliably *exit* start of line context in a template without leaving a trace in the output. Perhaps <nowiki/> as the first construct of the template expansion should still be supported as a mechanism to do this, but perhaps ampersand encoding or typed templates or some other more natural means can be found.
As the first step in regularizing the SOL context for template expansion, we should probably try to lint away the cornercases where the "T2529 hack" doesn't work; ie, templates beginnning with ==, !, |, or |}.