Files
pad/cmd
xarmian 02846a6785 fix(cli): the session's registered agent is the name its writes carry (BUG-2882) (#1248)
* fix(cli): the session's registered agent is the name its writes carry (BUG-2882)

Two seats booted under one name; one re-registered under the right one
with `pad session register --agent`; every write it made afterwards still
carried the wrong name. The registry row and $PAD_AGENT were two
self-declarations of "the same value" — the row could be rewritten, the
environment could not, and nothing reconciled them or warned. Night 10
read both live seats inverted against each other.

ResolveAgentName now consults the registry record for the session that
owns this process FIRST: a stat-and-read of one file, no MkdirAll, no
lock, ignored when malformed, legacy, or carrying a different
process-start token (pid reuse). A non-empty registered name wins over
.pad.toml and $PAD_AGENT; an anonymous row leaves an environment name in
force. `pad session register` without --agent keeps the current name, as
before, because its default is the resolver. Help text, the record's doc
comment and README's precedence list say what is now true.

Test: register as rook under PAD_AGENT=wren and a .pad.toml name → rook;
default re-register → rook; anonymous → the .pad.toml name; a record for
this pid with another process's start token → ignored. The registry-step
mutant fails the first two assertions.

Fixes BUG-2882

* fix(cli): a registry record names this session only when it is verifiably this session's, and the identity tests stop reading the real registry

Codex round 1 on #1248. (1) registeredAgentForThisSession compared
process-start tokens only when both sides had one, so a stale row with no
token under a reused pid — a dead session's — would have named a live
one. Fail closed: when this process can read a token, the record must
carry the same one; and the record must pass the same OwnerLiveness
verdict `pad session list` applies. The token-less case is now a test
row, with a positive control after it. (2) The pre-existing resolver and
header tests cleared PAD_AGENT/CLAUDECODE but not HOME or the session-pid
variables, so run inside a registered seat they would have read that
seat's row as the resolver's first answer. They now run from a scratch
HOME with no session identity.

Refs BUG-2882

* fix(cli): a registry row names this session only if its owner is this process or an ancestor, where that can be checked

Codex round 2 on #1248. (1) TestPushItemSendsResolvedAgentHeader was the
one identity test round 1's hermeticity fix missed; it now isolates HOME
and the session env like its neighbours. (2) The registry step accepted a
row whose owner pid was alive and token-matched but NOT this process or
an ancestor — a misconfigured CLAUDE_PID pointing at a sibling session
could borrow that session's name. Refused where the platform can walk
ancestry. Not gated on PIDVerified: CaptureSessionOwner records
"cannot check" and "checked and wrong" as the same false, and the flag
alone would have disabled the step on every non-Linux platform. The
check is re-run and only a checked-and-wrong answer refuses. Test uses a
live non-ancestor child as the claimed owner; the refusal-dropped mutant
lets it name us.

Refs BUG-2882

* docs(cli): session list help — a row's name outranks PAD_AGENT; change it with --agent, not by re-registering (BUG-2882, codex round 3)
2026-09-04 12:50:50 -04:00
..