The hashme syntax to use is indeed as described in your code snippet, and as described in the hashme tutorial.
The decorator stores the function profile on a 1-level deep stack. This information is consumed by the first nd.Cell() encountered (possibly unwanted in a subroutine), and deleted at function closure.
In case (1) you describe, the nested hashme calls, the second hashme will override the first, so by the time you want to use the first, it is gone. This can be avoided placing calls after the
with nd.Cell() statement. Note that hashme=True keyword assignment is optional in newer Nazca versions since about 2020.
In case (2) I think the hashme is not closed yet and this messes up the stack.
Hence, the hashme creates a 1-level max deep stack and this info is consumed by the first nd.Cell() statement. The stack can probably be made deeper to allow for nested calls to work as well (although a similar result can be achieved by placing function calls in a decorated function after the with statement as mentioned, but the designer has to do the housekeeping).