* fix(line): preserve ordered delivery of oversized markdown tables
* fix(line): type ordered delivery at provider and test boundaries
* fix(line): narrow ordered provider messages to flex or text
---------
Co-authored-by: Peter Steinberger <steipete@macos.shared>
* fix(channels): record account lifecycle facts
* fix(channels): bound recorded lifecycle grace
* fix(channels): preserve authored health state
* test: dedupe health snapshot type literal and fix spread order
* fix(imessage): stop the outbound sanitizer deleting fenced role keys
sanitizeOutboundText strips standalone `user:`/`system:`/`assistant:`
lines (leaked turn boundaries), `#+#` separators and `assistant to=`
markers, but the three regexes had no code-fence awareness. A bare YAML
mapping key like `user:` on its own line inside a ```yaml block matched
ROLE_TURN_MARKER_RE and was silently deleted before iMessage delivery,
reparenting its children under the wrong node — still-valid YAML, wrong
meaning, and nothing signalling a line was removed.
Skip matches whose offset falls inside a markdown code region for all
three patterns, reusing findCodeRegions/isInsideCode already applied by
the sibling reflection-guard on this channel. Regions are recomputed per
pass because each strip shifts later offsets. Leaked markers in prose are
still stripped.
Refs: #116942
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test(imessage): cover code-aware marker stripping
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(line): unify card and template alternative text limits
* test(line): use synchronous provider request listener
---------
Co-authored-by: Peter Steinberger <steipete@macos.shared>
Retain terminal and assistant-completion facts when pre-start notifications exceed the bounded buffer. Exclude commentary from replies, accept legacy unphased final messages, and let completed terminal items own the final answer while rejecting interrupted, failed, or non-terminal outcomes.
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
* fix(clickclack): answer thread replies past the server thread-reply window
Thread replies stopped being answered once a ClickClack thread passed 100
replies, with no reply, no transcript entry, no gateway warning, and no
replay after reconnect.
The gateway resolved a thread.reply_created event by fetching the whole
thread and searching its reply list. The ClickClack thread endpoint caps
that response at 100 earliest replies by default, so reply 101 was absent,
the lookup returned null, and the event was treated as handled while the
websocket cursor advanced past it. A DM thread reply was worse: it hit the
DM branch first, and thread replies never appear in the root DM timeline
that branch pages, so every DM thread reply was dropped.
Resolve the event's own message_id through the authoritative single-message
endpoint the plugin already uses, which collapses the three window
heuristics into one canonical path. Transient failures still propagate so
reconnect replays them; only a 404 resolves to unreadable, and that now
records an operator warning instead of counting as a handled event.
* test(clickclack): harden reply recovery proof
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(qa): update Codex auth fixture protocol version
* test(qa): bind Codex auth fixture to runtime version
* test(qa): load Codex fixture version through public surface