Soul findings on 77975b9: concurrent opens could make two rooms; a decline in an
encrypted DM was ignored; the not-E2EE notice could be lost after a held first
line; the unknown-kind refusal echoed an unbounded agent name; isServed could
read a mouth that had not started. Tests now pin the brake read before each
write exactly, the two-member DM rule, and that project rooms are not scanned.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
New chat_open_direct request/receipt pair on the existing endpoint. The mouth
creates an unencrypted private DM, invites the person (the line is the invite
reason), says the line with a not-E2EE notice, and records the room in m.direct.
Consent is the person's own membership: pending invite and decline are read from
room state, and a decline stands until the person invites her. One creation per
person per UTC day, the brake read before each write, a repeat by request id
resumes. A request of an unknown kind now gets a typed UnknownKind refusal and a
log line instead of silence. Golden fixtures in tests/fixtures/persona-chat-v4.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>