Userinfo is everything before the last @ of the authority, which ends at / ? # backslash, quotes,
brackets, angle brackets or ASCII whitespace; a path @ (github.com/@user, pkg@1.2.3, a//b@c) is left
alone, non-ASCII stays inside userinfo. Protocol-relative // opens an authority only at a word start.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
NBSP, U+2028 and other Unicode whitespace stay inside userinfo, so a secret holding them is redacted whole.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Candidate run is everything to the next whitespace, userinfo up to its last @; protocol-relative
// and the narrow word:secret@host.tld/ shape are covered; scanning no longer slices inside a
multibyte character. persona::structured_output redacts each string through the same function.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
One function, redact_url_userinfo, owned by result_text: the journal line and the admitted
PipelineReply both read the result through it, and redaction runs before the reply is chunked.
scheme://user:tok@h and http(s)/ftp(s)://tok@h become scheme://<redacted>@h; ssh://git@h stays.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Bifrost b2e0bb2 sends [persona, deliveries, tail, tail_gaps]; a three-field decode failed LengthMismatch. The field defaults empty, so three-field answers still decode, and render_tail splits unknown (named) from quiet (unnamed, no line).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Soul s1 findings trace-and-render-wiring-unpinned and tail-and-earlier-role-unpinned:
trace inputs, earlier and tail lines, tail and burst size measures, the tell's
people and open_direct refusal now fail when handed an empty table.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Config::sender is deleted; sender_role over the session's addressing decides a
sender's role on message, earlier and tail lines, trace inputs, the names a
memory may be about, and who she may open a direct with.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Spawner::spawn takes the session to export; the Self run gives the bare run label (the spelling the run's opening receipt carries). The Persona gives none.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ChatPending gains a defaulted Option tail (old two-field mouths still decode), Chat::pending returns it, and a process's first line renders it: speakable rooms only, 20 per room and 60 in all, byte bound counting framing, quoted untrusted data, dedupe by event id against waiting deliveries, a marker for dropped lines and for rooms with none, and an unavailable note when the mouth sends no tail. A failed first poll fails the start as Chat again.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Matrix is the record and the mouth its only reader: the tail is assembled from the deliveries and contexts the mouth already sends (no new endpoint, no stored copy). Newest 60 lines / 24 KiB, oldest dropped with a marker; public sessions read the rooms she may speak in, a DM session its own room alone; a first poll that fails degrades to a tail-unavailable note instead of failing the wake.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Soul's surviving mutants n01, n08, n09 and the vacuous project test (n07, n11) now fail the suite.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Consumer half of ruling eureka-body:ruling:addressed-delivery-only. A delivery is for a Persona when it is a message and Matrix says
direct/tag/reply, or its mentions or text name her (address::is_for); notices, edits, @room and a nil basis (unproven) wake no one on
their own. The heartbeat's off-beat wake keeps its sender gate. The Persona acks the leading run of what is not hers in one ack and a
live session is told only what is hers. A mouth that does not serve the v2 request is asked the v1 way. Golden bytes pinned from Bifrost
tests/fixtures/persona-chat-v5; the public-surface snapshot is regenerated.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>