My opinion on this: You are overthinking it. A lot.
Let's start simple. Cyclic dependencies between packages
are disallowed and whatever you do you packages must not
for an import cycle. This is the only hard rule. Note that this
rule is totally decoupled from the filesystem layout of your
packages.
The last point already hints at why I believe you are overthinking
the importance of the file system layout: It simply does influence
the one and only package rule.
Well, almost. There are two (I hope I did not forget one) special
file system folder names: "internal" and "vendor" and these do have
special semantics on how package lookup works. But these are
not at the heart of you question as far as I understand your question.
For the rest: Package spread on the filesystem is guided by the
following aspect:
You import by file system path so this hierarchical path can
be used to transport information to the reader of your code:
import "net/http/cookiejar"
and
import "household/kitchen/cookiejar"
will bot import a cookie jar but what type of jar this will be is
nicely explained in the file system path.
The file system also lets you group stuff that belongs together
logically or how it is used. Peek at the stdlib: In folder
encoding you will find lots of different encodings.
Note that this is a logical grouping and not a technical.
There are no "parent" and no "child" packages in Go. Do not
think about file system layout as parent/child, top/sub, whatever.
It is not. It is file system layout. Just like you would organize
your documents: You might do
documents/house/official to store bill of sale and property tax
and and documents/house/bills/garden to keep your landscapers
bills while putting general stuff into documents/house to keep
the separate from documents/school. You organize, but this does
not introduce a parent/top/abstract - child/sub/concrete relationship
between these documents.
Filesystem layout is (apart from internal and vendor) to group
packages logically and not technically. Do not overthink it.
V.