`token_path`'s doc claimed the compiler was the check and that nothing had to
remember to perform one. True of `agent`, which is an `Ident`. Not true of
`account`, a bare `&str` concatenated into the filename — safe only because
`deliver` happened to validate it first, which is the caller-must-remember
pattern the comment denied.
Observably a no-op today: the one call site already rejects a bad account
before reaching here. What changes is that the signature now enforces what the
comment asserted, so a second caller cannot skip it.
The check is `path::checked_segment`, made public rather than reimplemented.
Two copies of a charset are two charsets: they agree until one is edited, and
the day they diverge a name is legal in the store and not on disk.
An account name cannot simply become an `Ident` the way an agent name is:
it is an attribute name in `hyperhive.matrixAccounts`, so uppercase and
underscore are already configurable, and narrowing that is a decision rather
than a refactor. The new test's controls pin both.
Found by argus reviewing the merged PR.
mara ruled (a) on #3726: a thin workspace crate over `vaultrs` rather than
keeping bao access in nix and having each end trigger units. The HTTP is the
SDK's job; what this crate owns is the things the controller and a hive must
say *identically*, and which have no other home because neither end is senior
to the other.
Three such agreements:
`path::matrix_account` builds where a credential lives. It is fallible rather
than a `format!`, because both names reach it from elsewhere -- the agent name
from the topology, the account name from an agent's own config -- and a `/` or
`..` in either does not produce a malformed path, it produces a valid path to
a *different agent's* secret. The charset mirrors the KV bucket-name rule.
`Credential`'s `value` field is not a free choice: glue-matrix-bao-token.nix
reads the store with `bao kv get -field=value`, so the name is load-bearing
for a consumer no Rust test can reach. A test pins the serialised shape.
`client::Settings` reads BAO_ADDR / BAO_CLIENT_CERT / BAO_CLIENT_KEY /
BAO_CACERT explicitly instead of letting vaultrs fall through to its own
defaults, which look for VAULT_ADDR / VAULT_CLIENT_CERT / VAULT_CLIENT_KEY.
Every unit in this tree sets the BAO_ spellings, so the defaults would yield a
client with no identity at all -- surfacing as a TLS handshake failure, which
names neither the missing variable nor the reason.
The env read is split from the connect so every misconfiguration arm is
testable without a reachable store and without touching process-global env.
Dependency impact, measured against the lock at forge/main rather than assumed:
native-tls 0 -> 0, openssl-sys 0 -> 0, one reqwest (0.13.4) which vaultrs
shares, and 10 new crates that are all derive/proc-macro helpers.
Refs #3726