* fix(mobile): release cancelled relay stream subscriptions
* fix(mobile): keep shared-token relay siblings live on unsubscribe
nativeChat and terminal unsubscribe tokens are deterministic per view target,
and the host evicts on duplicate registration. Skip the unsubscribe RPC while a
live sibling on the same connection still owns that token.
* perf(cli): load error reporting without feature formatters
* test(cli): follow extracted error reporter in import guard
* chore(cli): track cli-error.ts in deferral equivalence baseline
The equivalence script restores TOUCHED files from the baseline rev to
rebuild the pre-deferral CLI. reportCliError/formatCliError moved from
format.ts into cli-error.ts, so the baseline arm must also drop
cli-error.ts (absent at older revs) or the old tree would still compile
against the new module.
* perf: find mobile Markdown placeholder prefixes in one scan
* style: format mobile Markdown benchmark guard
* docs: explain collision-free Markdown prefix length
* fix(native-chat): repair a structured tab fenced out by a returning publisher
A publication epoch is retired whenever another publisher takes over a worktree, and a
retired epoch is then rejected forever. But a live publisher can return after transient
interlopers - a `removed:` retraction, then a headless rebuild whose version restarts at
1 - and the structured tab publish inherits the worktree's existing epoch rather than
minting one, so it arrives under the blacklisted epoch and is dropped. The chat tab never
reaches the tab bar.
The fence is right to reject the frame: it cannot tell a returning publisher apart from a
delayed frame queued by a dead generation, whose version can outrank the live cursor. So
the drop is no longer final - it schedules one bounded, debounced authoritative
`session.tabs.listAll`, and only that census may revive an epoch, and only the one it
names current. Subscription frames stay fenced exactly as before.
* fix(native-chat): decay the structured tab repair cap and prune its state
The attempt cap latched: three transient RPC failures left `exhausted` set for the
renderer's lifetime, permanently hiding a chat tab behind a single console warning. It
now decays, so a worktree that has been quiet for a minute gets its full budget back.
The repair map was also missing from the sweep that drops publisher cursors for vanished
worktrees, leaking an entry per deleted worktree. Pruning it there required inverting the
repair lane's dependency on the inventory refresh, which is now injected.
---------
Co-authored-by: Merge Sim <sim@local>
The adhoc mac and dev-channel Windows builds vet the requested ref by
mirroring every branch and tag of this repo into a scratch bare repo and
proving the commit is reachable. Both runner disks are case-insensitive,
and the repo now has two branches differing only in casing, so the files
backend refuses the fetch outright — the whole job dies before checkout.
reftable keys refs in a table rather than as file paths, so both refs
store and every ref stays in the reachability set.