The legacy key form placement.<node> is gone from the client, so the readers and their fixtures lose it. The check noplacement
now also refuses the assigner's retired names in a manifest.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
A have of the bus module heard while the placement did not yet name its node as holding the bus
adopted nothing, and nothing adopted it again until the have changed, so a vault could stay without
the bus node's adoption and the loaded list's revision for good. The vault now keeps each node's
latest have and, on the placement's next change, adopts from the bus node's kept have if it was not
adopted: the placement's event, no timer. The rotation test now writes the have before the
placement (its wait for the vault's picture is gone), so it takes this path every run.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
The controller judged the operator's account for approving or deleting a
retirement, rotating a secret and exporting sealed copies; it is not
placed, and these verbs are reached through the mesh MCP server on each
machine. Each now answers the operator's account (person.<name>), or a
caller naming its own recorded hand act for that verb and subject, and
nothing else (ADR 0590 §8, issue 1126).
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
own/novox/nats/broker-nats-tools (moved in today) and mesh-controller's broker-address and broker-management (moved in
from the controller's store) are random values, not the account JSON a bus user is hashed from, so the hash step says
"not JSON" and the grants part leaves those users off the bus. The controller made them (fixed there, c421629f); the
vault kept them, since nothing it keeps judged a covered name's value.
Quick fix: refuse a plain value in move-in. Thorough fix: keepLocked, which every way into the store passes, refuses
for any covered name (broker, provisioner-broker, broker-<binary>, which catalogue.ToolsBusSecret names) a value that
is no account, saying "not issued". Chose thorough: one rule where every value is kept.
take-over waits on a hash for every user of the loaded list, and the vault holds no value for the controller's own
account, the node accounts and the enrolled devices. The bus node's engine now hands every loaded user's hash in the
bus module's have, sealed to the vault's key (mesh-host and mesh-sdk on the same branch). The vault answers its key in
node-key, reads the haves (manifest reads node-engine.have, granted from the manifest, no controller change), watches
the bus module's have, opens the handing with its own key, and writes each user it holds no value for into
bus-accounts marked adopted, with the list and node it came from, saying account-hashed. It never touches a user whose
covered account it holds or whose key is its own hash, writes an adopted key again only for another hash, and refuses
a handing from any node the assignments do not name as holding the bus module.
Tools: account_adopt adopts now from the have as the watch does; secret_own, unnarrowed by module, lists the adopted
accounts and the last adoption.
The controller still mints each covered account and hands it to the vault (ADR 0374); ADR 0547 clause 9 has the vault
write the bcrypt hash of what it holds into its own state, readable by the grants part, and say account-hashed. It
hashes on keep, at start every held account with no key of its generation, and again by hand (account_hash); a refused
write is owed and written at the next pass. secret_own says per bus account whether this generation's hash is written.
Issue: 1945