husk up dev twice gives two running computers called dev. Not the reuse the homepage
describes, and not the error I expected instead.
$ husk up dev
✓ dev is up
id cmp_2p6pgx38a4gt
$ husk up dev
creating dev...
✓ dev is up
id cmp_gfevmyp99fg5
$ husk ls
name id provider state workdir age
dev cmp_2p6pgx38a4gt local running /work 3m
dev cmp_gfevmyp99fg5 local running /work 1s
The second up says "creating dev..." and means it.
Name resolution then quietly prefers the older one. Tagging each workspace by id makes it
unambiguous:
$ husk exec cmp_2p6pgx38a4gt -- 'echo FIRST > /work/which.txt'
$ husk exec cmp_gfevmyp99fg5 -- 'echo SECOND > /work/which.txt'
$ husk exec dev -- 'cat /work/which.txt'
FIRST
So the second dev is unreachable by name from the moment it exists. And rm takes one
of the two:
$ husk rm dev --yes
destroying dev...
✓ destroyed dev
$ husk ls
dev cmp_gfevmyp99fg5 local running /work 58s
That rm did its job properly — the first workspace was genuinely gone from disk, not
just from the record. It just did it to one of two machines while reporting on dev.
Why it matters past the tidiness
The homepage says "a stable key maps a conversation to the same machine, so its files
survive across tool calls without you tracking ids". On the MCP path that holds — one
session, one computer. On up it does not.
The worse half is cleanup. Someone who runs up dev twice and then rm dev has been told
the machine is destroyed, and one is still running with a workspace on disk. ls will
show it under a name that resolves to something else, so there is no sequence of commands
that makes the situation legible. It is #111 from the other direction: the two together
are how orphans accumulate without anyone doing anything wrong.
What I think the answer is
up on an existing name should return the existing computer or refuse. Silently creating
a shadow is the one option that cannot be right.
Returning the existing one matches the stable-key claim and matches what MCP already does
per session. Refusing is defensible if up is meant to be strictly a create verb, but
then it needs --reuse, and the error has to say that husk exec dev is probably what
was wanted.
Whichever it is, two computers with one name should be unreachable as a state, not merely
unlikely. If both are somehow allowed, ls needs to mark which one the name resolves to,
because right now the table gives no hint that one of those rows is unaddressable.
husk up devtwice gives two running computers calleddev. Not the reuse the homepagedescribes, and not the error I expected instead.
The second
upsays "creating dev..." and means it.Name resolution then quietly prefers the older one. Tagging each workspace by id makes it
unambiguous:
So the second
devis unreachable by name from the moment it exists. Andrmtakes oneof the two:
That
rmdid its job properly — the first workspace was genuinely gone from disk, notjust from the record. It just did it to one of two machines while reporting on
dev.Why it matters past the tidiness
The homepage says "a stable key maps a conversation to the same machine, so its files
survive across tool calls without you tracking ids". On the MCP path that holds — one
session, one computer. On
upit does not.The worse half is cleanup. Someone who runs
up devtwice and thenrm devhas been toldthe machine is destroyed, and one is still running with a workspace on disk.
lswillshow it under a name that resolves to something else, so there is no sequence of commands
that makes the situation legible. It is #111 from the other direction: the two together
are how orphans accumulate without anyone doing anything wrong.
What I think the answer is
upon an existing name should return the existing computer or refuse. Silently creatinga shadow is the one option that cannot be right.
Returning the existing one matches the stable-key claim and matches what MCP already does
per session. Refusing is defensible if
upis meant to be strictly a create verb, butthen it needs
--reuse, and the error has to say thathusk exec devis probably whatwas wanted.
Whichever it is, two computers with one name should be unreachable as a state, not merely
unlikely. If both are somehow allowed,
lsneeds to mark which one the name resolves to,because right now the table gives no hint that one of those rows is unaddressable.