# Clients

Document: SPEC-005. Revision: 0.214. Date: 2026-11-07. Lifecycle: Partially approved under delegated decision D-024; V1 resolution sections are active, later scope remains Draft. Supersedes: none. D-172–D-180 scope is accepted only as specified below; SPEC-013 records the approved one-message history exception. D-181 confirms the Gentoo overlay release requirement; D-182 confirms the persistent enabled-statistics footer. D-193 selects a native Qt Linux successor, D-194 selects its tabbed two-tree navigation and D-195 authorizes build/release with Portage delivery. D-197 selects desktop scaling and D-198 approves the named standard-widget presentation amendments. Separate viewer windows remain proposed.


## Developer library and control-message projection (D-227/D-228)

The API/library and its publication contract are owned by [SPEC-028](028-developer-api.md). Official clients expose no non-visible composer option. Default authenticated history/sync omits control records before client presentation, so existing clients cannot display, search, count or notify on them. Library consumers explicitly opt into control retrieval and authenticate/decrypt before acting. Current native sources remain compatible with this server-side projection; logical-server navigation/media is not advertised by official clients.

## Native transcript scroll retention (D-225)

CONFIRMED by explicit human request, 2026-11-07: when a native Qt transcript is viewing its bottom immediately before messages refresh, follow the new bottom after rendering the update. When the reader has scrolled above the bottom, retain the existing scroll position rather than moving to new messages. Apply the same rule to ordinary channel, direct/group and outgoing message rows in the shared native transcript. An initially non-scrolling transcript is at its bottom. Returning to the bottom resumes following; no near-bottom threshold is introduced.

This is fixed presentation behaviour with no configuration property. Capture the prior position before rebuilding and restore it after the complete message layout, including wrapped bodies and outgoing rows.

## Native composer keyboard shortcuts (D-223)

CONFIRMED by human request and clarification, 2026-11-07: in native Qt ordinary channel, direct/group and inline-reply message composers, Enter/Return (including keypad Enter) invokes the existing enabled Send action without inserting a newline. Shift+Enter/Return inserts a newline at the selection/caret without sending. Pending, disabled or read-only submission retains the draft and cannot bypass the existing action guards. Held-key repeats do not submit again; an active input-method preedit remains with the input method rather than submitting an unfinished composition. Other modifier combinations and unrelated multiline forms retain native Qt editing.

## Event hints (D-221)

D-221 (human selection, 2026-11-07): clients use [SPEC-027](027-event-hints.md) WebSocket hints to read earlier, with authenticated canonical synchronization and the existing polling retained as the fallback in every state. Client responsibilities (engineering selections under D-024):

- **Shared state machine** (`client/event-hints.ts`, used by browser, Electron, Android WebView and iOS): idle → ticketing → connecting → ready, with backoff and stopped/disabled states. A ticket is requested for every attempt through the ordinary authenticated API path (visitor proofs included). `404`/`405`/`400`/`403` on the ticket route, a missing protocol echo or a non-HTTPS base disable hints for that subscription, leaving polling unchanged. A ticket `401` retries after 30 s, or at once when a newer credential subscribes for the same account and destination; the ordinary read owns sign-out on `401`. Ready timeout 10 s; heartbeat every announced `heartbeatMs`, reconnect if no pong within 10 s; backoff random(0.5–1) × min(30 s, 1 s × 2^attempt), reset after 60 s ready or when the network returns. Renewal starts max(1 s, `ttlMs − 1 s − random(0–1 s)`) after READY; the previous socket is detached and closed first so it cannot outlive or interfere with its successor. `4001` reconnects within 1 s without growing backoff; `4401` asks consumers to read once and retries after 30 s. Every READY triggers one recovery read per consumer. Stale callbacks from replaced sockets are ignored.
- **Registry.** One socket per (account identity, destination base), shared by every consumer; watches are the union of consumers' watched rooms (≤ 8), sent only when non-empty or changed and at most once per second per socket (latest set wins). Each consumer resolves its own connection's current credential at ticket time (never a raw token in keys or logs); the newest subscriber's credential source supersedes older ones and closes an old-session socket on renewal. At most six sockets per account; further destinations poll only. The last unsubscribe (sign-out, account or destination change, workspace close) closes `1000`.
- **Scheduling** (`HintedPoll`). Without hints the cadence is exactly the previous two-second skip-if-running interval. A hint starts a read at max(now, last start + 1 s); a hint during an in-flight read marks it dirty and reruns once after completion; a hint-started read moves the next poll to 2 s after its start. At most 15 hint-started reads per loop per sliding minute, so a loop starts at most 30 + 15 reads per minute. After HTTP `429` hints are ignored for 60 s, rechecked when a queued hint or rerun executes; polls continue.
- **Consumers.** The selected-view loop (`main.tsx`) subscribes to the selected connection's authority and watches the selected channel, so unrelated public-channel messages start no read; `sync` hints and READY trigger it. The conversation-list loop (`direct-workspace.tsx`) subscribes to Home and each signed-in conversation authority, watches the open conversation on its own authority, and treats any hint or READY as an inbox trigger. Cross-authority sockets carry no cookies or reusable credentials.
- **Capability gate.** The selected-view loop subscribes only when the selected destination's `/info`, already read when that destination was selected, lists `event-hints/1` and its `baseUrl` normalizes to the selected API base. The conversation-list loop uses `DirectClient`'s existing five-minute `/info` capability window: values come from the descriptor and `/info` reads it already makes, and an authority not yet read (normally Home) is read once through the public `/info` route. If that read fails, it is retried after 30 s while polling continues. Without the capability there is no ticket request. The ticket-route disablement above remains the fallback probe when an advertising authority lacks the route.
- **Home work beside a foreign view.** With a visitor (foreign) connection selected, each selected-view refresh also reads the Home address book and profile (`/contacts`, `/rooms`, at most one in flight). Hints accelerate the foreign read, and the foreign authority's pacing cannot see the Home `api:` bucket, so this Home work starts only for refreshes beginning at least one fallback period minus `HOME_REFRESH_SLACK_MS` after the last refresh that started it (`CadenceGate` in `client/home-refresh.ts`). The gate is keyed by account and Home base and uses the refresh's monotonic start time, captured before its foreign read. Every ordinary two-second poll therefore qualifies as before, and hint-started refreshes inside the period add no Home requests. A different key is due at once and replaces the record. A time earlier than the record is due at once. Results are still applied only while the refresh's own API object, context and abort signal are current. Home requests are dispatched after the foreign read returns, so two dispatches may be closer together than the period when foreign latency varies; the per-minute count stays at the fallback cadence.
- **Platforms.** Browser, Electron and Android use the platform WebSocket (Android's assets share the service origin, so the HTTP Origin rule applies unchanged). The worker and local CSP add `wss:` to `connect-src`. iOS uses a native broker (`EventSocketBroker`, `URLSessionWebSocketTask`, ephemeral session, no cookies or Origin, `NativePolicy.eventSocketURL` path/offer validation, 512-byte frames, at most six sockets) exposed as `SloppyNative.EventSocket`; if absent, iOS polls only. The broker runs sockets in the foreground, and in the background only while a call already keeps the app running. Backgrounding without an active call closes existing sockets with `1001` and refuses new opens. Polling covers the gap, and call state is read only, never changed. On return from the background, the host dispatches the dedicated `sloppy-foreground` window event after re-allowing sockets. The shared client maps it to `EventHints.online()`, which resets backoff and reconnects within 1 s instead of waiting up to 30 s. It is deliberately not a synthetic global `online` event, which voice and media code also observe. The renderer may request only `1000`, `1001` or `1008` closes (anything else closes `1000`). Native close codes that cannot appear on the wire, or no code at all, reach the page as `1006`. The shared client treats every code other than `4001`/`4401` as an ordinary backoff. Native Qt Home `Client`, `DestinationClient`, `ConversationSession` and cross-home inbox coverage uses the same wire contract (next bullets).
- **Native Qt transport and registry** (`native-client/src/eventhints.{h,cpp}`, Qt WebSockets ≥ 6.8 `QWebSocket`). One `EventHints` registry per account holds at most six sockets, one per (destination base, session credential). Its keys hold only a hash of the existing non-secret session digest, never a token, and a renewed or replaced credential for the same base supersedes the old socket. Verified HTTPS bases map to `wss:` and only explicit loopback HTTP maps to `ws:`; any other base polls only. The ticket is `POST <base>api/events/ticket {}` through the connection's existing authenticated request path (bearer and, for visitors, the existing proof) and travels only as the second offered subprotocol token. The handshake sends no Origin, cookie, Authorization or URL credential and accepts only an exact `sloppy-events.1` echo. Incoming frames over 512 bytes, binary frames and invalid frames close the socket. Heartbeats are the exact text frame `{"t":"ping"}`, not WebSocket control pings. State, backoff, renewal, `4001`/`4401` handling and ticket-refusal handling follow the shared state machine above.
- **Native Qt sockets and watches** (`eventhintclient.cpp`, `destinationclient.cpp`, `conversationsession.cpp`). Up to three kinds of socket per account, within the six-socket cap. (1) Home: subscribes while signed in with the account or its text view active, and only when Home's `/info` lists `event-hints/1`. (2) The foreground destination: its verified, available channel view only; background destinations keep only their existing reads. (3) Up to four conversation authorities: the open conversation's authority first, then the most recently active. Each socket watches only the view that is actually open on that authority, otherwise an empty set: the Home channel while a Home text view is shown, the foreground destination's channel, or the open conversation on its own authority.
- **Native Qt consumers.** A per-loop `HintScheduler` applies the `HintedPoll` rules above (spacing, single dirty rerun, per-minute cap, `429` throttle) to the existing loops; their two-second timers and HTTP checks are unchanged. A `sync` hint or READY runs only the current text view bound to the hinting authority; a hint from another authority, or for a background view, starts no read. A Home `inbox` hint runs one Home `/direct/inbox` read without the contact list and moves the next inbox poll back by a full period. A conversation authority's `inbox` hint (also relayed from a foreground destination that hosts the conversation) runs one targeted list read for that authority only, never the full cross-authority batch. It is skipped while that batch or the authority's own read is in flight. A ticket `401` alone never signs out the account or ends a `ConversationSession`, and neither does `4401`: the channel retries after 30 s, `4401` asks consumers to read once, and the next ordinary authenticated read alone decides sign-out or session end. Sign-out, account change, credential expiry and session end stop the affected sockets and drop pending hint work without running it.
- **Native Qt capability gate.** Native Home is gated on Home's `/info` as above. The signed destination and federation descriptors carry no capability list. A new destination or conversation-authority subscription therefore requires that authority's own `/info` to list `event-hints/1`, read through the destination's `ServerConnection` (`advertises`). The read is a public `GET <saved base>api/info` with no bearer, proof, client header, cookie or Origin. It is accepted only when its `server`, `domain` and `baseUrl` match the connection's checked identity. The answer is cached for the 300 s capability window above. A refused, invalid, mismatched or timed-out read is retried no sooner than 30 s later, and only while a consumer still asks for it. Unknown or absent capability requests no ticket and polls silently. A read that completes after the session is replaced or the view leaves the foreground starts no ticket. An existing subscription is kept when the window expires, so no socket churns and no background `/info` polling occurs. A ticket-route refusal from an advertising authority remains the fallback probe and disables that subscription. This resolves the earlier OPEN conflict by implementing the SPEC-027 rule, not by amending it.

## Selected Electron and shared web testing alpha (D-215)

CONFIRMED 2026-11-05: the human selects B's topic-based organization, rejects C, and requests a new deployed testing alpha incorporating the accumulated refinements. This section applies to Electron and the shared web renderer; the native-mobile composition below retains D-161/D-163 and uses the human-selected persistent mobile call-context/base-statistics placement under D-219; native Qt's selected layout and desktop scaling remain governed by their own sections. D-215 authorizes a testing release before the independent highest-reference visual target is achieved; retain honest scores, outstanding qualification and known limitations.

User settings keeps a single category model: Appearance, Profile, Microphone, Privacy & joining, Listening, Saved servers, Devices & recovery, Help & feedback. Privacy & joining groups the existing relay preference and existing public-mode joining/optional-identity-change consent; preserve their independent controls, original consequences, false defaults and protected scope. Saved servers names existing saved connections. This supersedes D-176's earlier category destinations only to this extent. Server administration uses topic categories with original independent forms/revisions; channel settings puts identity/access before voice/sharing policy. Forms stay mounted, retaining drafts across categories and secondary details. Accurate per-form save/result coverage, saved effective policy facts, disabled-control explanations, qualified actor/target at commits and primary task headings are required. No global Apply, expanded command payload or autosave behavior is introduced.

At constrained effective window widths the selected common B composition offers Task/current section, Channels and People destinations while keeping actual core call destination, microphone/transmit/mute/recording state, qualified account context, enabled base statistics and statistics opt-out visible. Retain the existing user scale; do not shrink text to cancel it. The reviewed fixed layout threshold is 760 effective CSS pixels, not a persisted preference; adequate 800-pixel windows at 100% retain ordinary sidebars. Full notices use normal task scrolling and cannot collapse into an unreadable nested strip. At the qualified 800×700/200% layout, core state and useful Task content remain simultaneously visible. Very short enlarged windows use whole-layout scrolling to retain reachable controls; this fallback does not establish simultaneous visibility or comfortable editing at those sizes. Long identities, unavailable values, recording, active sharing and concurrent notices must retain meaningful reachable task controls; fix allocation rather than making an arbitrary diagnostic minimum the comfort claim.

Secondary measurement definitions, owner aggregate tables, diagnostics and extended presentation controls use a clearly named task detail page. Core actual capture state and Stop remain discoverable/reachable outside hidden detail. Back/Escape restores the exact mounted form/draft, originating focus and prior scroll; opening detail never moves voice, renews authority or starts capture. Keep base enabled metrics continuously visible independently of People scrolling; this refines D-182's placement for constrained shared layouts. Secondary tables and explanations are accessible on request, not asserted continuously visible. Existing owner authorization, statistics preference/reporting, labels/units/unavailable semantics and measurement definitions remain authoritative.

C's optional Focus task/Restore People behavior is excluded. A's continuous administration and D's scope-grouped primary rail remain historical references rather than selected behavior. No proposal selector, study/evidence note or experimental A/C/D route ships in the application. Preserve keyboard/focus, forced colours, semantic distinctions, complete identities and independent text/call ownership. Local connection loss and any server-observed attendance are described separately; permission rejection updates stale role/capability presentation without inventing authority or discarding dirty input. Existing server media/participant-wide audio restrictions and explicit source consent remain unchanged.

Configuration: no new saved preference, protocol property or authority default. Existing scale, sidebar widths, relay/public-mode settings, PTT, metrics and policy configuration retain their canonical owners and defaults. Responsive region/detail selection is transient UI state; ordinary reload does not invent a new saved navigation preference.

Testing: extend existing component/browser regressions for selected categories, true saved effective facts, draft/Back/focus/scroll retention, readable dynamic urgent notices during details, role/capability rejection, and core state/base metrics across constrained long-name, recording, sharing and loss states. Exercise actual post-composition saves, synthetic sender/receiver screen+sound and Stop/denial/source loss, moderator audio mute with permitted video, forced colours and actual Electron shell. Distinguish synthetic Chromium media, no-call shell fixtures, and unqualified physical Windows/global input. Packaging/deployment acceptance follows the existing release and rollout sections.

Acceptance: selected B ships without experimental routes or C controls; scoped settings remain findable and drafts retained; notices and save identity remain truthful; core state/base metrics and Stop remain reachable alongside useful task content in supported enlarged layouts; rejected authority changes cannot retain a knowingly stale claim of role; tested release assets and observed rollout match the new alpha and compatible Gentoo packages verify. These criteria do not declare the separate visual-score target complete.

## Mobile composition of selected B (D-161/D-163/D-215/D-218)

**CONFIRMED scope and placement under D-218/D-219 (2026-11-06).** The requested mobile adaptation retains the approved chat-first native shell and three-dot navigation disclosure. Desktop compact region switching applies only to the desktop composition: it must not hide the mobile main workspace. Secondary detail pages retain the mounted mobile account/settings and connected-call microphone controls. Expose the existing Presentation receiving controls from the mobile navigation disclosure; this does not select mobile screen broadcasting. Preserve independent call/account/draft owners and native safe-area/keyboard inset handling. Mobile settings reuse B's topic categories and retained forms in a full-width collapsible section picker. Selecting a section returns focus to the visible picker, and phone navigation retains explicit Back controls. Mobile primary navigation, section, Back, account and call actions have at least 44×44 CSS-pixel touch targets. D-219 retains ⋮ navigation and adds the actual connected local call destination, server and full qualified owning account in a wrapping labelled row in the bottom bar, independently of the viewed account. Label the viewed account separately. Enabled base statistics and their opt-out stay visible beneath main content, independently of ⋮ and People scrolling; use the existing protected showStatistics preference and unchanged false default. No duplicate reporting/controller is introduced. Long identities and enlarged scale wrap without covering PTT/settings. When required controls exceed a very short enlarged allocation, preserve readable text and reachable controls through whole-layout scrolling rather than clipping or shrinking text. Mobile form text uses at least 16 CSS pixels before application scaling, without disabling pinch zoom; the composer has no desktop resize grip. Native iOS safe-area backgrounds match the shared light/dark surface palette. Mobile shortcut hints omit desktop key chords, and held microphone controls suppress the WebKit text-selection callout. These are fixed presentation rules; no configuration is added.


## Native UI polish overhaul (D-211)

The human requests a thorough UI polish overhaul with independent scored council reviews of generated before/after screenshots, iterating until every available council member scores the result at least 9/10 (2026-11-04). The follow-up explicitly prioritizes the native Qt client; shared web alignment is secondary where practical. This authorizes presentation refinement within the existing native interaction contracts, not a new navigation or consent model.

Engineering presentation profile: retain D-194's two-root tree, tabs and independent call area, D-197/D-198's installed Qt style/palette/fonts/scaling, D-206/D-212's lighter continuous thread fields, and D-207's semantic navigation colours/access labels/handsets. Refine spacing, alignment and relative emphasis. Conversation headings use bold type at 1.25 times their current parent desktop font size, retaining its family and following live font/style/reparenting changes. Body, identity/address and control fonts retain their native sizes; no application zoom or font preference is introduced. Call buttons use their natural native sizes and wrap at available widths; wrapping labels are constrained to the row width and measured at that allocated width; their status shares the same wrapping row and the statistics bar remains content-sized. Expiring/Expired sign-in notice controls attach to the native status bar only while relevant and detach after renewal, so a hidden button cannot reserve unused height; renewal actions and warning timing are unchanged. Selected text and the current call retain separate labelled contexts. Empty status text consumes no conversation space. Empty workspaces and transcript views provide passive guidance without claiming that unavailable history is empty; access and encryption labels use readable names. Main and inline reply composers fit their actual wrapped text, growing from one visual line to four plus native frame/document padding, then scrolling. Clearing or widening shrinks them without changing text, selection or protected draft ownership. Composer placeholders derive a readable colour from the current desktop text/background palette and follow live font changes. Compact initials remain square when identity text wraps; native avatar fallback letters remain contrast-checked against their own fill; message metadata reflows according to available space and desktop font metrics. Complete identities, parent references, dates/ages, reply counts, outgoing status, keyboard inspection, selectable text and permitted actions remain available. Navigation uses continuous semantic row fields through the indentation gutter, retains native disclosure glyphs and omits redundant ancestor connector lines, with native selection/hover/focus; avatars align with the first text line and leave a style-derived gap of at least four logical pixels. Presence puts name and explicit voice state together above the complete address, wrapping as needed. Compact parent captions in the sender metadata band retain the actual signed parent message number, including on headerless continuations. Captions share the sender line only when the complete identity, self marker, parent caption and clock fit without overlap; otherwise they reflow below. The self marker stays adjacent to its identity. Focus callbacks retire before the action surface is destroyed. Complete qualified parent labels remain in existing inspection, Copy details, tooltip and accessibility text; complete sender addresses stay visible in their headings. Secondary ink retains at least 4.5:1 contrast on its actual surface. Essential inspection information uses readable selectable native text, wraps within the current display and never inherits low-contrast disabled-command ink; actual command enabled states and permissions are unchanged. Original date separators have centred bold native text and font-relative vertical spacing.

The human extends the review process on 2026-11-04: after the current round, compare the candidate with screenshots of Discord, TeamSpeak, Ventrilo, KDE System Settings and Windows Control Panel, plus professionally recognized interfaces found on the Internet. Give council neutral screenshot IDs and the same rubric, with source/award provenance recorded separately and withheld from the scoring brief. Visible product branding may remain recognizable. Continue improving SloppyVoice until every current council member scores it at least 9/10 and ranks it highest in the comparison set. Scores and ranks must be actual independent judgments; do not coach a desired winner, invent scores or weaken the reference set after seeing results. This extends presentation-review acceptance, with no new product behavior.

The subsequent human request adds Trillian Messenger, Microsoft Teams, Webex, Slack and Zoom to the reference pool, retaining the earlier references. It also authorizes exploring substantial rearrangement of UI elements. Keep no more than four active design variants. When a variant requires a material specification choice, label it as a proposal and continue evaluating and refining the multiple options in subsequent rounds rather than stopping at an approval question or treating the choice as confirmed. Source-withheld scoring uses the complete expanded pool; historical nine-image rounds retain their original scope.

No action gains authority or a new side effect through visual polish. Preserve protected drafts, text/call independence, account/connection fencing, permission filtering and explicit capture/voice movement. Preserve the approved thread palette and statistics values/order/units/visibility/reserved numeric widths in the implementation candidate; alternatives may be evaluated as explicitly unselected proposals. New interaction models, multi-window ownership and automatic section collapse remain proposals unless separately selected. Council scores are subjective review evidence, not a replacement for functional, accessibility or release checks.

D-212 qualified sender presentation applies to actual caller data, not only preformatted preview labels. The transcript composes each headed sender and complete parent reference from the caller’s literal display label plus the structured author username/domain. A nickname containing ` · `, `@` or markup-like text remains literal and complete; punctuation is not an identity delimiter. Already qualified history labels do not repeat their address. Compact parent captions retain the display name and exact signed sequence, with the complete qualified target in inspection, Copy details, tooltips and accessible descriptions. This restores the existing information contract without selecting the compact-heading proposals.

## Full-width workspace and grouped session area (D-213/D-214)

The human selects review option B on 2026-11-04 and asks to retain D's useful principle of collecting related bottom information so it reads as one. This supersedes only the unselected multi-option status of the workspace arrangement under D-211. Keep the permanent Servers/Direct Messages navigation, visible movable/closable conversation tabs and existing protected page lifecycle. D-214 supersedes the centred reading measure and surplus side gutters: the selected conversation heading, transcript and composer fill the available conversation page width, retaining only the current Qt style's ordinary left/right layout margin. Resizing the window or splitter immediately gives that width to the conversation, without a maximum character measure or font-dependent width cap. Align the native tab strip with the same leading edge where native tab padding permits, retaining native tab scrolling and closing. Live desktop font/style/direction changes preserve common edges and compact-width containment. These are fixed presentation rules, not an application zoom or saved preference. The conversation page uses the native Base surface continuously through its margins, heading and transcript. The composer remains on a native Window input band with a native separator so input remains distinguishable in dark palettes; its original editor and Send action retain their ownership and aligned full-width bounds. Decorative heading outlines follow the surface actually behind them.

Use one coherent content-sized bottom session area for the current call's complete destination/server/account context, explicit microphone state and existing microphone, sharing, leave and inspection controls. Keep complete call context and microphone state together in a naturally wrapping summary tier above the original command row; long labels prefer their complete natural width and wrap at the actual allocation. Keep related information and controls adjacent, with spacing identifying their roles and native wrapping retaining complete labels. The selected text destination's Join/Move action remains explicitly scoped to that destination; its placement in the session area does not transfer ownership of current-call controls. The selected text account and its original account action remain a separately labelled navigation context. Sign-in, call, capture, held-input and permission behavior are unchanged. Required actions remain reachable; no automatic control hiding, overflow policy or separate voice window is selected. The existing always-visible content-sized statistics area remains adjacent with D-200/201/203/205 labels, units, order, accents and reserved numeric widths.

D-212's complete visible sender addresses, actual parent captions, clocks/ages and lighter continuous fields remain the implementation contract, together with D-207's complete navigation identities, semantic fields, badges and native selection. The compact/neutral reading profile, quiet selection and alternative navigation interaction proposals shown during exploration remain unselected. The human's preference concerns layout and effective grouping, not approval of every bundled prototype detail or a claim that one arrangement is objectively superior. Historical A/C/D studies and their original ratings remain available as evidence; subsequent implementation/refinement concentrates on selected B. The expanded council uses every personality on every selected model; historical rounds keep their actual rosters and cannot establish the enlarged council's acceptance.

## Distributed Linux binary baseline (D-208)

**CONFIRMED:** the human requests on 2026-11-03 that the distributed Linux binaries be rebuilt to support all x64 processors, and that future builds use the same baseline without limiting source distributions from taking advantage of newer processors. Prebuilt Linux x64 packages, currently the native archive and the KDE Flatpak, target the **x86-64 baseline** ISA level (original AMD64 with SSE/SSE2). They must not require SSE3, SSSE3, SSE4, POPCNT, AVX, AVX2, BMI, MOVBE, AVX-512 or another later extension. This corrects alpha.57, whose packages inherited the build host's `-march=native` toolchain. Its bundled libsodium/Snappy trapped with SIGILL and its archive executables declared `x86-64-v4` as required.

Every distributed ELF is compiled inside the pinned `org.kde.Sdk//6.10`, using generic x86-64 GCC/glibc with `-march=x86-64 -mtune=generic`. The archive's focused Rust GCC plugin uses the official `org.freedesktop.Sdk.Extension.rust-stable//25.08` toolchain with `-C target-cpu=x86-64`; a host-native Rust standard library is never linked. The Flatpak bundles libsodium, Snappy and LevelDB compiled from pinned, checksum-verified official upstream archives instead of copying host libraries. Both packages build the PipeWire GStreamer adapter the same way. LevelDB retains Snappy support for Chromium-profile import. The archive links against the same SDK builds but continues to use the distribution's system libraries at run time.

Third-party code may contain later instructions only in reviewed functions selected by runtime CPU detection that checks every required feature, such as libsodium's CPUID dispatch. Application code, helpers and plugins contain no non-baseline instructions. libsodium 1.0.22 selects its AES-NI/AVX ipcrypt path after checking AES-NI alone. A packaging patch also requires AVX, matching libsodium's own AEGIS check, although the client does not call ipcrypt.

The baseline applies only to prebuilt distribution. Source archives, Gentoo ebuilds and `native-client/CMakeLists.txt` add no ISA flags. Source builds keep the builder's own compiler flags, including `-march=native`. Windows and Android packages contain no host-compiled native code: Electron is upstream's prebuilt runtime, and the Windows Go helper uses `GOAMD64=v1` with cgo disabled. Building against the SDK's older toolchain also lowers the archive's library floor. The packager measures that floor from the archive's versioned symbols and records it in `START-HERE.txt` and the release record. Distribution Qt/GStreamer/libsodium/LevelDB builds remain the distribution's responsibility. This adds no runtime or user setting.

## In-application bug reports (D-209)

D-209 (human request, 2026-11-03) adds “Report a bug”. [SPEC-026](026-bug-reports.md) owns the wire contract, limits, redaction and Markdown rules; SPEC-008 owns posting. PROPOSED presentation (made during the human's absence, open to confirmation):

- Web/Electron/Android/iOS (shared interface): **Report a bug…** in the server context menu beside Keyboard shortcuts, a button in the Keyboard shortcuts workspace, and a **Help & feedback** category in User settings. It opens a workspace with the public-posting notice, title and description fields with code-point counters, two opt-in checkboxes (recent voice diagnostics; account address) that start unchecked for every report, and a “Sent with this report” summary of client kind, version, platform, account and diagnostics with an expandable exact diagnostics preview.
- The client reads `/api/info` from the signed-in Home service. With `bug-reports/1`, **Send report** posts there with one UUID kept across retries of the same report and replaced after success; the result shows the issue number and a link. Without the capability, or after any failure, **Open on GitHub instead** opens the SPEC-026 prefilled link; `bug_reports_unavailable` switches the form to fallback-only.
- External links: the browser opens a new tab with `noopener noreferrer`; Android's main-frame gesture navigation hands the HTTPS page to the system browser; Electron uses a dedicated `openBugReport` bridge whose main process opens only bounded GitHub issue pages through the system browser (an older shell without the bridge offers copying); iOS keeps navigation inside the app, so it copies the link. Created-issue links are accepted only in `https://github.com/{owner}/{repo}/issues/{n}` form.
- Version: Electron and mobile shells report their application version when available; otherwise the bundled web version. Platform: the browser user agent, prefixed by the Electron platform name.
- Native Qt: **Help → Report a bug…** opens a modeless dialog with the same fields, notice, opt-ins, preview and buttons. It posts through the verified Home `Client` only when signed in with the capability, binding the request to the account generation that opened it; otherwise it is fallback-only and opens links with the desktop URL handler. Platform is Qt's product name, kernel, CPU architecture and Qt version; diagnostics are the native SPEC-021 journal without call identifiers.

No preference is stored; nothing is sent until the person presses Send report or opens the GitHub page.

## Native channel presence and navigation colours (D-207)

**CONFIRMED:** the human requests users present in each channel in the Qt tree, with clear, attractive foreground and background colours distinguishing servers, channels and users (2026-11-03). This refines D-198's neutral native navigation presentation within this scope. Show the existing SPEC-012 `room-tree/1` live voice participants as children of their own channel, after any nested channels. Preserve permitted hierarchy and qualified server/account grouping. Presence means current voice attendance, not saved membership, text readership or general online status. Use only each connection's authorized `voiceMembers` projection; deduplicate by qualified durable person identity. Show nickname (or username), full qualified address and explicit In voice / Muted state, with compact native pictures/initials. Omitted roster data remains unavailable rather than empty; the channel's tooltip/accessibility description distinguishes an authorized empty roster from an unavailable roster. Reuse the existing two-second active-account refresh and five-second saved-server status rotation: background server-list reads use the existing history-free `@server` sync with `tree=1`, including a call destination while another text context is selected. While a DM or foreign transcript is selected, the active Home address-book refresh uses that same server sync to receive contacts and presence together. It cannot read a transcript, select text, change membership or move voice. No new timer, admission, history or media operation is introduced.

Use blue server fields, quieter lavender channel fields and green person fields with readable foreground accents. Server headings are bold; hierarchy, labels, explicit presence state and native selection/focus reinforce colour. Derive rendering from the current desktop Base/Text palette, recompute on palette/font changes and keep at least 4.5:1 normal-text contrast (target 5:1). Retain desktop-scaled fonts, wrapped complete names/addresses, keyboard tree navigation and visible native selection. Direct-message person rows use the same person treatment without implying voice presence. Presence rows are informational: selecting, activating or opening their context menu cannot open text, switch an account, join/move voice, send a message or change admission. Existing conversation/member controls remain available in their established locations. Refreshes preserve tree expansion/selection where the keyed row still exists; disappearance removes its row. This is a fixed presentation rule, with no new preference, server setting or protected state.

The human additionally requests the web/Electron Public/Private discriminator and channel handset (2026-11-03). Port D-094's compact green Private/red Public text labels using authoritative access independently of encryption. Port the existing permission-aware handset for voice-capable channels: available, active green and disconnect-on-hover states, explicit Join voice in / Disconnect voice from accessible labels and native keyboard operation. Text-only channels have no handset; inaccessible targets disable joining. Bind actions and connected state to the full server/connection/account/channel, use the existing prepared admission/move/fresh-input controller and preserve ordinary text selection. The active channel's handset ends only that matching call. Retain the existing bottom call controls and channel context-menu alternatives. Labels and controls stay visible as long names wrap; fonts/icons follow desktop scaling. These are native ports of existing behavior, with no new permission, preference or protocol.


## Native muted conversation fields (D-206; lighter refinement D-212)

**CONFIRMED:** the human approves the final further-muted Astra Solid thread fields review and requests implementation. This narrowly supersedes D-198's message palette treatment and native SPEC-013/D-067/D-075/D-080 presentation where described here. Other clients retain their existing presentation. Keep the native tree model's original ordering, one-level replies, canonical authority, loaded eligibility and protected draft ownership; hide the transcript's table header and move Time/Status into full-width message widgets.

Every loaded original and its expanded replies, reply-date markers, inline editor, loaded-reply count and active conversation voice status share a continuous square background field. Narrow neutral gaps and a quiet one-logical-pixel edge separate roots. Repeat the author at each original even for the same account; suppress repeated headings only within the same conversation and local date. Keep original date separators, the strictly-greater-than-two-minute continuation clock rule and clock plus parenthesized elapsed age. Show exact datetime and qualified author through selectable text and keyboard/click inspection. Show the actual signed parent reference on replies. Counts describe eligible loaded replies only, use singular/plural grammar, remain visible and toggle the same tree expansion. Missing originals remain labelled, without fetching hidden history.

D-212: use readable sender bands with bold display names and visually secondary complete qualified addresses at the existing desktop font size. Keep identity data as plain text, including literal markup characters; measurement and painting use the same formatted text metrics at narrow widths and enlarged fonts. Retain compact initials, YOU and a native-link-coloured own initials marker; body text uses the field's contrast-checked foreground instead of blue-on-colour. Shared history remains provenance and stays readable during inspection. Outgoing Sending, Sent, Not sent and Confirmation pending remain explicit and cannot acquire canonical reply/pin/voice actions. Existing moderator pin attribution and permissions are unchanged.

Each body has a compact trailing inspection control. Pointer body/action hover and keyboard focus reveal an opaque, bordered toolbar with rounded corners over the trailing author-band area; sender hover alone cannot reveal it. It reserves no full action row: retain a four-logical-pixel body gap, stable text geometry and a twelve-logical-pixel text inset within the body area. Keep selectable message text unobscured on headed rows. Continuations may anchor the viewport-clamped toolbar just above their body. Controls remain reachable as pointer moves into the toolbar, through Tab/Shift+Tab, Escape, context menu and an always-available More menu. Small viewports use the same menu when direct controls cannot fit. Touch uses an always-visible native menu affordance with desktop-metric/touch-sized targets rather than an invisible hover requirement. These are the approved native D-080 alignment/reservation changes, not a protocol or permission change.

The palette is a fixed rendering rule, not a user preference. Start with sand/lavender/sage seed RGBs (light: `#c9953f`, `#9875b9`, `#4f9b8c`; dark: `#d5aa59`, `#b08bc9`, `#5aa997`). Choose light/dark from desktop Base luminance. Blend each seed at 24% with the 50/50 desktop Base/Text neutral, then form a reference tint by blending with Base at 54%, 46%, 58% respectively. D-212 supersedes the former final field weights: use 18% of that reference tint and 82% desktop Base for the continuous field (effective muted-seed weights 9.72%, 8.28%, 10.44%). This matches the lighter-fields render explicitly selected by the human on 2026-11-04. Use a sender band halfway between the final field and its readable under-colour; derive the quiet edge from 85% reference tint and 15% readable foreground. Preserve the existing contrast fallback and root assignment. Choose a readable desktop foreground and adjust the local field if needed for at least 4.5:1 normal text contrast (target 5:1). Recompute on live palette/font changes. High-contrast/monochrome palettes retain labels, edges and native selection rather than relying on hue. Root-scoped colour assignment uses a bounded cache of currently loaded roots, deterministic root candidates and neighbour avoidance; author changes, expansion, replies and ordinary refresh cannot recolour existing roots. No assignment is uploaded or added to protected preferences.

## Native implementation and delivery (D-195/D-196)

Native startup and sign-in retain the account runtime’s prepared-selection boundary: successful authentication must continue into a permission-filtered channel read and atomic workspace selection before ordinary/direct navigation becomes usable. The primary Sign in/Account action opens the existing chooser, including qualified addresses on another verified Home; account-specific password/device operations remain pinned to their initiating Home. Rendering and refreshing the startup window cannot cancel that preparation. These restore D-117 and SPEC-015/018; no permission, session or discovery exception is introduced.

**CONFIRMED D-199/D-200:** native statistics always appear in the bottom status bar, without a display checkbox, Conversations button or statistics popup. Include current service request RTT/upload/download, available voice RTT/jitter/loss and owner-authorized aggregate sample counts and average/minimum/maximum values. Use one line when space permits and wrap only as required by the actual available width; the bar’s height follows the rendered content and shrinks after widening or a shorter summary. Unavailable account/service measurements remain explicit placeholders without authenticated requests. Measurement provenance/units remain available in an accessible tooltip. D-200 retires native opt-in display: preserve the historical protected `showStatistics` value for compatibility/import, ignore it in this presenter and expose no replacement setting. Existing one-second local sampling and ten-second reporting/owner-summary bounds and source/owner authorization remain unchanged. Other clients retain their display preferences. Under D-201, separate latency, upload, download, voice and owner-summary components with category colours, clear horizontal gaps and quiet separators. Keep labels/units and emphasize values so meaning does not depend on colour. Adapt accents to the current desktop palette with readable text contrast, update on live palette changes, and measure the rendered styled text when wrapping/shrinking. Under D-203, retain the current client metric order (service request RTT, upload, download, available voice RTT, jitter, loss). Clearly label client measurements as Client and owner totals as Server, using separate bold section headings in the current desktop foreground colour (light on dark themes, dark on light themes), outside the metric accents, with extra space before Server. Order available owner aggregate fields after the server counts as RTT, voice RTT, upload, download, jitter, loss; omit absent fields without reordering the rest. Under D-205, reserve eight numeric characters for each client bitrate, one third less than the initial twelve-character treatment, following the human’s spacing refinement. Rates through 999999.9 kbps do not move the Server: heading at a fixed viewport/font and otherwise unchanged fields; longer values expand naturally rather than clipping, rounding further or changing units. Retain desktop-scaled text, exact visible values/units, plain accessible values and narrow-width wrapping/shrinkage. These are fixed presentation rules, with no new preference, measurement or severity classification.

D-196 confirms completion of the full replacement and closes the separate-preview publication option. The human authorizes implementing and deploying the selected native client and making its validated release available through `/var/db/repos/local-overlay`. Complete existing applicable delivered account, encryption, text, voice, sharing, administrative and upgrade behavior before promoting a native package over the current Linux release. This request does not approve a feature-reduced substitute or require another human release sign-off.

Implementation engineering profile: C++20 and Qt Widgets, dynamically linked to system Qt 6.8+ Core/Gui/Widgets/Network/DBus, native libsodium and OS Secret Service through libsecret. Application source is under `native-client`; the CMake build/test output is `.local/native-client`. The application does not embed a browser, QML or JavaScript runtime. The media implementation uses dynamically linked GStreamer WebRTC/app/audio components (1.24+) and libopus (1.3+) to implement the existing SPEC-004/016/017/023–025 contracts. Keep native codec/capture/transport secrets and real-time work outside the GUI event loop; marshal bounded results to Qt. This is an implementation dependency selection, not a protocol downgrade or new media setting. Existing TypeScript/Node service/crypto fixtures are build/test tools only. Preserve the Wayland application-window requirement; existing helper-specific XWayland exceptions remain separately scoped. The optional XWayland side-button helper is C linked to system X11/XInput2; portal registration uses Qt DBus. The app does not change desktop forwarding policy or device permissions.

The complete native replacement is published as alpha.54; the [release record](reviews/2026-11-02-native-qt-release.md) supersedes the earlier incomplete-development inventory. The following snapshots through revision 0.167 are historical and do not describe the current release. Native source includes protected multi-account Home/Host text and voice, device linking/recovery/both QR directions, encrypted direct/groups, retained exact commands, threaded replies/calls/pins, People/Recent/profile controls, native/managed presentations, original-authority administration and recursive deletion. Revision 0.163 passes the complete 47-suite release and verified ASan/UBSan core/HTTPS/codec regressions; its complete release and sanitizer media matrices pass. The corrected Home-slot lookup uses server-descriptor capabilities. Public convenience mode in revision 0.164 passes focused release and ASan/UBSan unit, generated HTTPS window/preference/restart and actual encrypted foreign-relay audio checks. Revision 0.165 retained-history browsing passes focused release and ASan/UBSan units and generated Home, Host, canonical foreign direct and closed-group checks. Revision 0.166 installed-profile conversion/adoption passes the complete 50-suite release core/HTTPS/codec run; its sanitizer run is in progress. Revision 0.167 separates unchanged pure input-binding validation from the runtime observer to reduce on-demand import linkage; this optimization is source-only until rebuilt and checked. Installed-profile adoption completion, physical/platform/resource qualification and immutable native release/Portage delivery remain incomplete. Never open an embedded browser or publish an unencrypted media fallback. The explicit --layout-preview flag uses synthetic data without keyring, account, capture or service access. Normal launch is not a preview. The separate development profile is not an installed-profile upgrade solution. The [development inventory](../native-client/README.md) and [progress evidence](reviews/2026-10-31-native-qt-progress.md) identify current implementation and validation limits.

Native conversation completion uses the existing SPEC-018/D-090 contract: temporary groups appear beneath Direct Messages and open independent tabs, with native actions for explicit admission, invitation, leave/removal/end and immutable retention selection. Only this device's explicit joins renew presence; inbox discovery, text selection and restart cannot join a group. Presence continues independently of the selected tab, expires conservatively, and requires a new explicit join after session loss. Closed groups clear their unsent draft and preserve eligible read-only history. Native call controls preserve contact/group approval, fresh authority checks, explicit answering and movement, the single-device voice fence and fresh input after movement. These are ports of accepted behavior, not new protocol or policy choices.

The same native call-intent controller handles explicit ordinary-channel voice joins/moves. Fresh target sync must confirm the exact account/device, admission and a voice-capable ordinary channel before showing any current-attendance move confirmation. Keep the old authorized call and held input until the user confirms; declining cancels only the new intent. Claim the move through the existing home voice fence before releasing old media, wait for the returned fence, then prepare/join the bound target with fresh input. Text selection cannot redirect that intent. Cancellation, account loss, stale authority, changed attendance, transport failure or a late response cannot start a replacement call automatically. Restoring an earlier direct/group call after a cancelled invitation requires the same active call ID/device, retained consent and live group membership; stale summaries cannot be labelled active. This extends the already selected explicit-movement workflow, with no protocol/default change.

The native saved-server workspace keeps one account owner and separate destination text contexts. Connection selection commits only after a checked destination read and atomic selection save; discovery, expansion and background status reads cannot join a channel, fetch conversation history or change capture. Home transcript polling pauses when foreign text is selected, while the active account's independent SPEC-018 inbox/address-book poll, explicit group presence and existing media retain their account owner. Saved destination tabs use qualified connection and channel keys, flush drafts before switching and retain the previous visible conversation on failed admission or selection. The existing rotating 5-second/one-in-flight/8-second background bounds from SPEC-015 apply. This increment wires ordinary foreign text and explicit Add server admission into the window for the selected account; full account switching and foreign voice remain release requirements, not implied completion.

The native workspace also owns one exclusive home-connection state view for ordinary-channel, direct and temporary-group draft keys. Home account tokens/keys/pending commands remain in the account profile; home connection drafts contain only text keyed by the existing qualified view locator. Coalesce edits for 300 ms, keep dirty text on a failed atomic save, and flush before leaving the home connection or closing the window. Restoring a draft cannot select a channel, join a group/call, send text or obtain history. Full saved view/cursor restoration, account switching and retained-history pagination remain separate requirements. These are implementation rules for the existing SPEC-015 protected-draft contract, without a new preference.

Native draft acknowledgement safety (SPEC-013/D-162): each nonempty protected draft may carry an independent random UUID in the connection's optional `draftTokens:{viewKey:UUID}` map. A changed edit gets a new token; clearing text removes its token. Tokens cannot exist without a corresponding nonempty draft. Capture the current token in the optional protected `pendingCommand.draftToken` before sending, alongside the exact existing command; it never enters the network payload. Confirmed sends clear only a draft with the same token. Later edits, including edits that return to identical text, retain their new token through acknowledgement/restart/retry. Missing legacy tokens cannot authorize automatic clearing. The old in-memory-only window uses a document revision snapshot for the same purpose. These local operational records add no setting, server field, plaintext digest or offline send queue.

Native account activity is separate from text activity: the existing two-second home inbox poll continues for the active account while a visitor transcript is selected. When home transcript sync is paused, refresh its account-wide Pinned contacts through the home `/contacts` read, without opening home history or a direct conversation. Coalesce each poll/read without overlaps, preserve original account generation, and keep the last address book on a failed read. A C++ account-activity gate (initially active for the selected profile) lets future inactive profiles pause this account poll without stopping explicit group presence or an owned call. This corrects the earlier engineering interpretation that paused inbox refresh with home text; SPEC-018 remains authoritative. No new preference, receipt, automatic consent or voice intent is introduced.

Native ordinary-channel type handling follows SPEC-012: voice-only and currently unadmitted ordinary state can omit history. A missing page in those states clears the loaded transcript and does not imply a malformed response or history permission. An admitted text-capable channel still requires a valid bounded page; an ineligible/voice-only state cannot supply displayed history. Native posting availability includes current admission, channel type, group liveness/closure and authoritative posting status before encryption/dispatch; disable Send when unavailable and omit the composer for a voice-only view. Opening or joining channel membership remains separate from voice admission.

Native account ownership is centralized in a runtime registry: one stable account controller and exclusive protected writer per loaded qualified profile, with separate connection writers. A selection job belongs to its initiating window/dialog, prepares verified account/destination/channel state without publishing it, flushes outgoing drafts, and atomically saves the profile/connection selection before binding the new view. Cancellation, supersession, failed authentication, denied state and failed storage preserve the previous usable text context. Loading an inactive account starts no inbox/transcript polling or automatic saved-login activation/recovery/link completion; explicit selection reconciles an exact retained login activation before preparing text. A rejected Home credential updates advisory readiness to sign-in-required without replacing device keys. Known expiry timers remain conservative. Loaded inactive accounts preserve their independent state; explicit group presence and the active call retain their original account owner. One runtime-wide rotating background status scheduler retains SPEC-015’s existing bounds and obtains no history. An intervening active menu or consequential confirmation cancels the new selection before its protected commit, preserving the previous view and dialog; initial startup binding waits on close events and rechecks the latest committed view instead of deleting an active dialog stack. This implements D-117/D-126’s existing ownership and selection rules without a new preference or permission. The development inventory distinguishes implemented registry behavior from remaining chooser, foreign-call and full release scope.

Native ordinary Home-channel navigation uses the same prepared-selection rule: validate the fresh approved-device, permission-filtered channel and history response before changing the client or visible page. Save the Home connection's selected room/cursor and profile/connection selection in one protected root write, then publish the prepared view. A denied, cancelled, superseded or failed-save open preserves the previous usable context and draft; a provisional tab cannot become a send destination. Leaving an account cancels its unfinished text-selection continuations while retaining independent calls and already-dispatched exact mutations. Standalone account-controller callers use the same prepare-before-publish check without a native-store selection write. These rules restore D-117's existing failure/ownership contract and add no setting or automatic channel/call admission.

Native direct/group opening follows that same preparation/commit boundary. Read the exact peer or conversation at its pinned Home, validate the returned authority, participants, membership and eligible history before replacing the usable view, then commit the Home view/cursor and account/connection selection together. A new contact with no conversation is a valid verified empty view; an invitation does not trigger admission or history access. Closed/departed group history retains SPEC-018's eligible-period rights. Tree, tab, invitation and New conversation actions use this path. Cancellation, supersession, denied/malformed responses and failed protected writes preserve the previous view/draft and do not move a call. Returning to an account with an exact retained direct/group operation prepares that same context for explicit reconciliation, without dispatching, replacing or clearing the operation; a different destination remains blocked until reconciliation. This restores D-117/SPEC-018 behavior and introduces no configuration or permission.

Native qualified-address selection uses SPEC-015 public authority discovery, independently of the service endpoint's hostname. Normalize the username to the protocol's lowercase form; a bare username uses the chooser's named destination authority, or the selected Home authority in the general chooser. Verify the canonical authority mapping and exact server descriptor before opening password/device-link/recovery controls. Retain a new profile shell with its verified UUID/domain/base pin in one protected write without changing current selection or generating keys. A matching retained qualified name reuses its profile only when the verified authority matches its existing pin/base; a changed endpoint or UUID cannot replace it. Cancellation, supersession, malformed addresses, discovery failure and persistence failure retain the prior view and account keys. The verified qualified address and Home endpoint remain visible in the chooser and authentication controls. Failed/uncompleted shells do not become successful account history. This implements D-117/D-120 without a new identity or trust mechanism.

The native Servers tree projects all retained ordinary connections through D-117/D-120's full UUID/domain/base grouping, with one browsed identity per server. Display the qualified username beneath its server heading; use the protected browsing hint only to choose the displayed identity, never to authenticate a fallback. Room lists and advisory status stay attached to that exact connection/account, including inactive accounts; projection and disclosure do not fetch history, join membership or alter capture. Activating another account's saved root/channel uses the same owner-bound prepared account/connection selection and preserves the previous page on failure. Direct Messages continues to project only the selected account. A background metadata refresh cannot invalidate a retained raw item pointer used by an open context menu: actions retain the qualified locator and re-resolve it when invoked. Remaining destination-specific identity/admission/management actions retain their separate implementation gates; displaying another saved profile does not authorize current-account commands against it.

Native destination-specific account opening retains the chooser's exact server pin and optional channel independently of the previously browsed account's connection key. A bare username uses that named destination's identity authority; qualified addresses use their own verified Home. Display the destination and the selected account's verified Home. Resolve the chosen profile's matching Home/visitor connection, reusing an existing retained destination sign-in without rotating it. If the explicit choice requires new or signed-out visitor admission, discover and compare the exact destination before the existing bounded grant/join flow; no Home bearer, password or private key reaches the Host. Reconcile pending destination commands before credential replacement. Authentication requests identify the initiating owner; cancelled, edited, superseded or closed chooser work cannot publish a later view or move a call. A same-authority destination/Home pin mismatch fails before showing credential controls. Saved successful profiles/admission may remain after a later channel denial, while the prior visible context and drafts remain usable. Only the prepared permitted state and protected atomic selection commit publish the chosen identity. Server **Sign in as another user…** and channel **Open channel as…** use this path. D-126's automatic Join-as uses the separate prepared-membership and captured-call continuation path above; ordinary text opening alone cannot move voice. No new preference or permission is introduced.

Native named-server Sign out resolves the row's exact retained connection/profile without selecting it or loading history. Lazy Home and destination public verification remain scoped to the initiating owner; cancellation cannot dispatch a later logout. Reuse that account's retained approved-device/session context, flush only its drafts and reject unresolved account/login/destination commands before retiring credentials. Sign-out ends only the matching account/connection call; it cannot sign out another identity at the same server or change the active text profile. A dispatched logout may complete its own protected result after the menu/owner closes, without publishing another view. Errors retain existing state according to the Home/destination logout contract and remain visible. Reuse the existing 15-second preparation bound and pending-work limits. Explicit rejoin/admission and authentication remain separate actions. These rules implement D-117/D-118 without new configuration.

Native saved-server Rejoin uses a standard modeless confirmation showing the exact saved server UUID/domain/base and qualified account. Public verification precedes enabling Rejoin; the explicit confirmation forces fresh admission for that named profile/connection, including an expired retained session. If Home authentication is required, retain the same target and request credentials only at that account's verified Home. A current admitted sign-in is reused for ordinary Open, but explicit Rejoin refreshes only that connection's login. Reconcile protected pending commands before any replacement Home grant/Host join. Keep the outgoing view, drafts and call while preparation runs; publish the named target only after its checked permitted view and protected selection commit. Denial, failed writes, cancellation, supersession and owner closure cannot publish a late target. A successful remote sign-in may remain saved after later view denial; never replace keys, use another account or resume voice automatically. The existing 15-second selection, 45-second admission and public-verification bounds remain fixed. This ports D-117/D-118's existing flow without new configuration or permission.


Native media admission uses the GStreamer codec-parser library (`gstreamer-codecparsers-1.0` >=1.24; the source Gentoo recipe follows its existing GStreamer >=1.26.11 floor through `media-libs/gst-plugins-bad`). Before queueing decoder input, validate every supported codec’s coded allocation geometry, reference/sequence bounds and output metadata against SPEC-023’s existing resource envelope. Codec parsers whose bit readers do not themselves check length receive only bounded, zero-padded private copies: check the VP9 superframe index against the received size before parsing it, and require each parsed VP9 uncompressed header and declared first partition to lie inside the received frame. AV1 temporal units are parsed from a private copy followed by 64 KiB of zero padding. Until a shown AV1 key frame has refreshed every reference slot, and again after a changed sequence header resets them, admit only a shown key frame, so no frame can take its size from an unfilled slot. Reject truncated or malformed input without reading outside it. Keep post-decode checks. Managed playback carries the original nonrenewable key deadline and a secretless key-validity token independently of renewable source/call authority; permission gaps or key/context loss clear the held picture, while renewed continuous authority preserves it without counting another frame. SPEC-024/025 own held-picture and managed-media semantics.

Native message readers validate the original room/server binding, effective encryption and complete signed conversation policy before selecting ordinary-device, recovery-key or linked-history decryption. Supported unbound legacy originals are local retained history only: require the verified protected Home UUID/domain/base, active local account and local author; mutable public display metadata cannot establish this exception. Home and visitor transcript caches invalidate at the earliest successfully verified original message expiry even when history, trust and room state are unchanged.

Native fixed decoded-JSON transport budgets complete the existing SPEC-009/011 page/device/share shapes: ordinary control and error bodies retain 4194304 bytes; one identity allowance is 413696 bytes (4096 metadata plus 100 signed roster changes of at most 4096 bytes each); history is 68455424 bytes (1024 page overhead plus 50 records, each allowing a 524288-byte original envelope, two identities, a 16384-byte encrypted share and 1024 record overhead); sync is 118569984 bytes (history plus 111 identity allowances and ordinary control metadata, including the second self projection). These are finite client implementation capacities, not configurable wire quotas or permission to expand message/roster fields. Home, visitor and frozen-history transport and JSON parsing select the same route budget; unknown-length and compressed responses count decoded bytes and abort at overflow. Enlarged history/sync requests set Qt's finite decompression threshold to their decoded capacity plus one diagnostic overflow byte, so high-ratio compression cannot reject an otherwise eligible page before the explicit guard; ordinary/public thresholds and the smaller error ceiling remain unchanged. Unrelated public discovery, publication/Home metadata, update manifests and picture reads retain their owning bounds. The 250-record native loaded view remains separate from the 50-record wire page.

Native voice output scheduling recovers a playback-only timing discontinuity without leaving or rejoining the call. Rebase the output timeline to the current pipeline clock and discard queued/decoded playback and ramps instead of generating a catch-up burst. Retain each source's press/end/replay floor, final listening preferences and original finite forwarding deadlines. Recovery neither grants authority nor changes microphone intent: healthy capture keeps its existing timestamp/press gates, and independent input-loss, lock/suspend, device failure and expired-authority handling remain mandatory. Genuine audio pipeline errors still close the affected call. SPEC-004 owns media/queue/capture limits; SPEC-021 owns bounded resynchronization diagnostics. Deterministic delayed-output and actual-call fixtures cover idle and transmitting playback recovery, unchanged attendance, continued encrypted audio, stale/ended-press rejection, mute and authority expiry. No new runtime preference or timeout is introduced.

Native renewable voice control uses an account-owned transport separate from interactive text/account requests. Its HTTP/1.1 policy permits one persistent connection per host, configured before the first request. The serial control transport selects HTTP/1.1 explicitly; interactive requests retain default HTTP/2 negotiation, and ordinary TLS verification remains unchanged. Relay control uses the same single-connection HTTP/1 policy in its own authority-scoped transport. This bounds unused control sockets and prevents an unrelated UI pool's idle closure/queue from failing a renewable lease. Home authority verification, account/device/room ownership, the aggregate 32 pending-Home-operation bound, owner cancellation and existing request/lease/attendance/input deadlines remain unchanged. No failed renewal is automatically retried under a new authority or resumed after expiry; existing manual-rejoin behavior remains. This is an internal transport policy, with no user/operator setting or protocol change.

Native call-input lifecycle keeps the effective shortcut bound to the active call's account and attendance, independently of text selection. Restore that account's saved valid binding for an active PTT call, retaining the existing portal/device fresh-neutral gate. No active/pending call, recorder or explicitly open shortcut-test dialog means no global-input observer, helper or polling timer. A live call retains lightweight lock/suspend monitoring even when voice activation needs no shortcut; no device reader or polling timer runs for that monitoring. A setup test belongs to its dialog; closing it stops idle observation without deleting the saved binding. Ordinary Preferences/listening controls preserve input under D-176/D-189. Starting a recorder pauses microphone intent and the matching input adapter; another account cannot replace or record over an active or pending call's input. Recorder cancellation/completion retains the previously saved binding until Save and restores observation only through a fresh-neutral gate, without resuming held PTT or voice activation. Disabling the current shortcut retains the saved binding for a later explicit call or setup test. An adapter failure is not automatically retried within that attendance; explicit re-enabling remains available. Reuse SPEC-005's existing device polling, stall, recorder and portal bounds. This adds no preference or permission and changes no call authority or media deadline.

Native binding recorders use standard modeless Qt dialogs owned by the originating Preferences dialog/account. Closing Preferences, switching that account or losing the recorder window's activation cancels its recording without saving a candidate. A completed press/release updates only the unsaved Preferences candidate; Save remains the protected commit. Retain the existing 30-second recording limit, explicit Cancel, source validation, held-input rejection and fresh-input rules. Heap-owned widgets, timers and selected-device observers end with the recorder; a late callback cannot address a former account or a destroyed stack object. Another account's live/pending call input remains protected by the call-input lifecycle above. These rules apply D-198/D-176/D-047 without changing the binding schema or capture permissions.

Native diagnostics retain SPEC-021's process-local 500-event journal across calls and sign-out, with existing ten-second numeric snapshots, thirty-second renewal summaries and 2.5-second scheduling-gap threshold. A strict field/value/counter allowlist precedes retention; names, addresses, content, credentials, SDP and arbitrary exception strings are excluded. A standard modeless Connection details dialog and the persistent unexpected-disconnection notice offer explicit JSON export through the native Save dialog. The failure notice retains its original channel/time/reason independently of ordinary polling or account changes, and closes only on dismissal or a fresh explicit attempt. Journal state is never put in protected profiles, history/recovery or automatic numeric reports. Configuration remains the fixed SPEC-021 bounds; tests cover redaction, ring eviction, failure-stage correlation, intentional closure, export and post-sign-out availability. Native setup failures retain their observed audio/control/connectivity boundary before attendance is assigned and project recognized local notices to SPEC-021's fixed safe codes; unknown text stays excluded. A fresh explicit attempt resets its stage/code without clearing earlier journal entries.

Native Linux packages include the small MIT-licensed PipeWire GStreamer 1.6.9 plugin needed for explicit source-loss cleanup, while sharing PipeWire/GStreamer core libraries. The Gentoo package therefore does not force a system PipeWire GStreamer USE rebuild. The Qt Flatpak uses its runtime’s compatible stock GCC estimator; the archive’s focused GCC 0.15.4 plugin namespaces its two internal GTypes to coexist with a stock full RTP plugin. The algorithm/property contract is unchanged. Fresh per-application plugin registries prevent test or other-application blacklists from substituting stale plugin selection. Package checks verify required symbols, plugin properties, type coexistence in both loading orders and actual camera pixels through the sandbox portal proxy. No device, network or capture permission is expanded.

The native Flatpak QR scanner uses the XDG Camera portal before enumerating permitted video-source nodes. It never grants unrestricted devices or opens the ordinary PipeWire socket as a camera fallback. Permission acquisition does not start capture: retain standard camera selection and a separate Start scanning action. Capture uses a fresh camera-only remote and the selected current raw-video node (input dimensions at most 960×960), with aspect-preserving bounded 640×480/5 fps local frames and the existing worker QR decoder. Unsupported camera formats fail visibly with the existing manual-code alternative. An independent helper watchdog ends only the scanner process if startup, capture or cleanup stalls beyond the three-second bound; the parent reports the fixed failure and does not dispatch a scanned value. This cannot end the main client or another helper. Renew the existing three-second capture deadline every second only while the existing fifteen-second foreground QR grant remains valid; GUI stalls, focus loss, hiding, cancellation, parent exit, node removal or source failure stop capture and close owned remotes. Portal prompts may temporarily own focus before acquisition completes; no pixels are captured in that state. Late responses cannot restart a stopped scanner. Host archive scanning retains Qt Multimedia’s explicit camera path. Generated portal/PipeWire optical and lifecycle tests qualify this adapter; physical camera acceptance remains separate. This ports existing camera/QR safeguards without a new preference or permission expansion.

Native message rows follow D-206’s selected muted fields and compact overlay controls; its scoped native amendment supersedes SPEC-013’s full reserved action row and own-message blue text. Retain body-only hover, keyboard/touch inspection, stable geometry, exact details and existing action authority. Context menus remain an additional access path. Confirmed ordinary-channel Leave stops only that account’s original qualified channel/derived-thread call after its exact command is protected and before dispatch; cancellation or a failed protected write does not stop it. A different server with the same room UUID remains independent. The remote command retains its original unknown-outcome reconciliation rules. Tests cover hover/focus/geometry, qualified call isolation and persistence-before-intent. These corrections add no preference, permission or receipt-authorization exception.

Native screen diagnostics count verified native chunks, assembled video/keyframes, decoder output, backlog/late/superseded drops, dependency resets, observed pause transitions and actual first paints of replacement images. Exposure/zoom repaints do not count as new frames. The original receiver and per-frame managed authority are checked again on every paint, independently of delayed GUI expiry timers. Fixed aggregate fields remain bounded by SPEC-021; unavailable provider measurements remain absent. Retained-history authors become Recent encounters only after successful authenticated display, using their original acceptance timestamps and qualified Home/Host context. These are parity corrections under the existing contracts, without new configuration.

The native renewable voice scheduler measures the whole control-plus-relay cycle from its initiating monotonic timestamp, waits only the remainder of the existing 1000 ms cadence, and schedules an overdue cycle on the next event-loop turn. Its actual-relay fixture delays a control response by 1037 ms and checks the successor begins within the observation allowance rather than waiting another full interval; failures and intentional closure retain the existing serialization/expiry rules.

Native relay-only transitions retain SPEC-017's route-only PTT continuity: a temporarily absent peer exchange may reuse its previously signature-verified sender-key acknowledgement only after revalidation against the current account/device, room/revision and both attendance sessions. This cache never renews offers, authority or key deadlines. A supplied invalid/replayed/conflicting exchange does not acquire validity from the cache; changed context, trust loss, unadvertised/expired keys or cleared state remain closed. Deterministic crypto tests and the actual direct-to-relay fixture verify the existing contract. Modeless member-root reviews retain their initiating account and session before and after consequence confirmation; account/session replacement disables or rejects the old action.

Native release staging retains the Sloppy Voice desktop/application identity and an explicit immutable release version. Qt's protected native vault stays separate from the old Electron profile; adopting that profile remains an explicit reviewed import. The native archive contains the application, bounded native helpers, focused GCC plugin and applicable notices/corresponding source; system Qt/GStreamer remain declared dependencies. Optional helper linking omits unused media libraries. Build/test staging cannot replace a published artifact or automatically install/start the application. Resource qualification compares all owned processes under the same generated encrypted text, window, draft and Preferences workload, recording PSS, RSS, CPU, startup scope and package/shared-dependency costs separately. These are implementation/release checks under D-193/D-195, not new user settings.

Native keyboard access retains the existing shortcut contract: Ctrl+, Preferences; Ctrl+Alt+S named server management; Ctrl+Alt+C channel settings; Ctrl+Alt+M member management; Ctrl+K channel search; Ctrl+Alt+H shortcut help. Standard Qt actions show their bindings in menus. A modeless channel-search dialog filters the already loaded ordinary-channel tree, retains qualified locators rather than item pointers, and re-resolves the chosen item before the existing text-opening action. Searching, changing selection or cancelling cannot join membership or move voice. Input recording and an active IME preedit receive shortcut keys without triggering application actions. Integration checks cover stale search results, cancelled search, keyboard access and unchanged drafts/call intent; no new configuration applies.

## Native tabbed navigation (D-194)

D-200: a single left click on an ordinary channel opens its prepared text view and makes that tab current, creating the tab only if needed. Clicking the same tree row while another tab is current returns to the existing channel tab without duplicates. Enter/keyboard activation remains available. Tree disclosure, metadata refresh, right-click and programmatic selection alone cannot activate text. Double-click must not dispatch a duplicate selection or join/move voice. The existing permission/authority validation, atomic draft/selection commit and failure preservation apply equally to Home and foreign channels. No automatic channel membership, call or capture follows this text action.

Closing a native conversation tab first saves its protected draft; a failed save keeps its page/edit intact and reports the error. A successful close destroys its widgets and rendered transcript cache, retaining only the protected draft and lightweight navigation locators. Background account/status/history changes cannot reopen a closed tab. Explicit verified opening restores it with its own draft. Closing the final text tab pauses foreground history polling while the selected account's inbox, explicit group presence and independent call continue. No membership, pin or call changes result from tab closure. Closed temporary-group drafts are cleared by their account/workspace model even without a widget; failed persistence retains a dirty clear for retry and stale editors cannot recreate a known closed-group draft. These rules implement D-193/D-194 and SPEC-018 without new configuration.

**CONFIRMED for the Linux successor:** use the selected tabbed conversation design with no application toolbar/ribbon and no right-hand People or conversation-details pane. Retain a conventional native menu bar and the independent persistent call controls. Channels and direct conversations may be open as tabs; changing or closing a text tab cannot implicitly change voice, unpin a contact or revoke membership. Closing a tab does not delete its conversation. This is a selected target, not an implemented/released native client.

The left navigation contains two separate expandable trees with **Servers** and **Direct Messages** as their actual root items. Root expansion changes navigation presentation only. Servers contains the saved servers and their permitted channel hierarchies, preserving account-qualified state, existing server grouping and access filtering. Right-clicking Servers opens a normal context menu offering **Add server…**, invoking the existing reviewed Add server flow; it does not provision infrastructure or grant admission. Direct Messages offers **New conversation…** in its own root context menu, invoking the existing permission/acceptance-aware conversation flow. Keyboard Menu/Shift+F10 and equivalent native menu actions preserve access without a pointer-only workflow. Opening a menu or choosing a contact to inspect cannot answer/move voice or dispatch a message automatically.

Direct Messages contains the current account's direct conversations and all its saved friends/pinned contacts, deduplicated by qualified durable person identity. A pinned contact stays listed without a recent message, without an open tab and after its tab is closed. A conversation can be listed without being pinned. Keep these distinct states rather than silently saving every conversation participant as a friend. Do not populate this tree with arbitrary channel encounters or imply contact consent/presence from an entry. The existing SPEC-014 account-wide Pinned and protected client-local Recent data retain their scopes; removal of the visible Recent/right-sidebar categories does not erase those records.

Sort the combined direct-conversation/contact list lexicographically by:

1. Last sent or received message time, newest first; contacts with no message follow conversations with a known message time. Opening a tab, reading a message or receiving a voice observation is not a new message timestamp.
2. When message times are equal or absent, pin time, newest first. A known pin time precedes an absent pin time. Pin status must not override a more recent conversation.
3. Alphabetical display label, then full qualified address and durable identity for deterministic ties. Missing legacy pin dates use the alphabetical fallback; never manufacture a historical pin time from load or upgrade time.

The compatible optional `pinnedAt`/`lastMessageAt` contracts are completed in SPEC-014/008/018 under D-194/D-195. Older services and undated legacy contacts use the stated unknown-date fallback; the sketch uses explicitly illustrative timestamps. No new sorting preference or server permission rule is introduced by selecting this order.

Full qualified identities, member/identity review, personal and moderator listening controls, administration, sharing and diagnostics remain accessible through their relevant native menus/dialogs and persistent controls. Removing the right pane does not remove these capabilities or the statistics requirement (always visible natively under D-200). The exact native action placement not selected here remains part of the P-037 completion review.

Scoped supersession: D-194 replaces the initial P-037 conventional three-pane/menu-toolbar recommendation and the right-sidebar placement/category obligations in D-071/R-084, D-090, D-094, D-142 and D-182 for the Linux successor only. The tabbed sketch's contextual right pane is also retired. D-104/R-109's server entries now sit beneath the Servers root; its account/permission semantics remain. The web, released Electron and mobile clients retain their current presentation contracts. The historical alternatives and remaining proposed P-037 amendments below are not competing native-layout requirements.

## Native Qt Linux successor (D-193; presentation proposal P-037)

**CONFIRMED:** replace the Linux Electron application with a native application in C/C++ or Rust, use Qt, minimize practical CPU and memory use, and keep installed disk requirements low. The human also requests native desktop behavior and suggestions for adjusting the earlier custom UI requirements for review. D-193 supersedes D-028's Linux Electron/shared-renderer implementation target only. D-193 initially retained the alpha.51 Electron archive/Flatpak during development. The validated alpha.54 native replacement is now published; its release record documents the measured resource scope and package transition. Other platform implementations and server responsibilities are outside this replacement scope.

P-037 is **selected within D-194/D-197/D-198's named scope** as specified above. The selected presentation profile uses C++ and Qt Widgets with the installed Qt platform style, palette, fonts, icon theme and conventional window decorations; prefer standard item views, ordinary layouts, menus, dialogs and splitters. Avoid an embedded browser, a JavaScript application runtime, an application-wide custom stylesheet and a continuously animated application scene. Native application services must preserve the existing wire, cryptographic, secure-storage, input and media contracts; changing the UI toolkit does not satisfy those contracts by itself. Qt and the named native presentation choices are confirmed; a separate screen-viewer window remains proposed.

Five presentation approaches were considered before D-194's selection. These are historical design assessments, not benchmark findings:

| Approach | Usefulness and feasibility |
| --- | --- |
| Conventional split main window | Initially recommended; superseded by D-194's tabbed layout. Server/channel tree, conversation and optional people pane with a persistent call-control area. |
| Tabbed conversations | **Selected/refined by D-194:** tabs for opened channels/DMs, Servers and Direct Messages trees, no toolbar/right pane, independent call controls. |
| Channel-first window | Tree plus one conversation; people and administration open on demand. Simple layout, but reduces the immediate visibility of Pinned/Recent and requires an explicit change to their persistent-sidebar requirement. |
| Compact voice controller plus separate conversation window | Unconventional: useful during gaming, but adds multi-window ownership, focus and call-target complexity. Not recommended as the initial replacement. |
| Server-browser window with separate chat windows | Unconventional: uses the window manager for arrangement and removes much custom pane management, but fragments account/call context and increases accidental-target risks. Not recommended as the default. |

D-198 approves the named standard-widget amendments below for the Linux successor, subordinate to D-194's selected no-toolbar/no-right-pane navigation. Exact call-control/statistics geometry remains an implementation placement choice under those approved controls; a separate viewer window remains proposed. Earlier documents remain authoritative for released/shared clients and for all behavior not explicitly superseded after review:

| Existing presentation | Native replacement and scope (D-194/D-197/D-198) |
| --- | --- |
| D-066 application light/dark palettes; D-141/D-142 colored rounded cards | Use the installed Qt style/palette, standard group boxes, separators and item selection. Keep readable states and accessibility; do not enforce lavender, custom radii or custom panel colors. GNOME integration depends on the installed Qt platform-theme/style support and needs platform testing. |
| D-065/D-070 main-workspace settings with Back and a no-modal rule; D-176 categories | Use a standard modeless Preferences dialog with category pages and native button ordering. Use properties/management dialogs for the named server/channel; retain draft/conflict and asynchronous account/target fencing. Only consequential confirmations use modal dialogs. Ordinary settings must preserve authorized voice input; recording and existing safety gates remain authoritative. |
| D-065/D-064 custom person menus containing sliders and controls | Use ordinary action menus. Open a small modeless listening dialog for the continuous volume control; keep Mute for me directly available. Separate and label moderator actions and preserve their authority/enforcement status. Opening listening controls does not disarm authorized input under D-189. |
| D-107/D-108/R-112 three Quiet Stack bars and custom diagnostics popover | Use one persistent native call-control area showing the actual call destination/account, connection and microphone state, Hold to talk and Leave, with a standard details dialog. Keep unexpected-disconnect guidance persistent and independently dismissible. The Linux three-strip geometry is superseded; the underlying states and input safeguards remain. |
| D-110/R-113 content-measured sidebar widths and CSS breakpoints | Use standard splitters, remember explicit user sizes and provide Reset layout. Keep people/nav available through View actions at small sizes. D-198 replaces automatic content-fitting and exact web breakpoints; full identities must remain readable/copyable. Initial development sizes remain as documented below; validate restored native state and preserve former web sizing preferences as migration metadata rather than applying CSS pixels to Qt. |
| D-104/R-110 animated unread badges; D-094/D-147 custom colored pills/icons | Use static unread counts, ordinary bold/selection/icon states and readable Public/Private labels. Preserve unread scope, access/encryption distinctions and personal-versus-shared effects. D-198 selects static native unread indicators; no idle pulse animation is required. |
| D-149 exact heading size and name-triggered lobster artwork; D-096 fixed circular thumbnail presentation | Use normal toolkit heading metrics and compact standard avatar/icon cells with initials fallback. Retain channel names and profile pictures, their validation and identities. D-204 restores only the static Lobbyster heading decoration described below; native font metrics and compact avatar presentation remain. |
| D-100 browser-style whole-interface scaling | **Selected by D-197:** inherit desktop fonts and display scaling with no separate native application zoom control. Preserve the old scale as migration metadata without applying it to Qt or deleting it from the source profile. Other clients retain D-100. |
| D-190 and SPEC-023 custom expanded/docked screen-view layouts | Use an ordinary native viewer with a toolbar for Watch/Stop, zoom, Fit and local presentation mute. Keep embedded viewing initially; a separate viewer window is an optional proposal requiring review. Preserve the live media session and chat draft across supported layout changes. |
| D-182 persistent statistics footer | D-199 supersedes the details dialog: D-200 keeps local and owner-authorized aggregate statistics always visible in the bottom status bar without a checkbox/Conversations button. Fit the actual text height, use one line when it fits and shrink again after content/width changes. Preserve measurement, reporting and owner-only aggregate contracts; native opt-in is retired. |

Preserve explicitly scoped text navigation versus voice movement, qualified account identities, separate personal/moderator effects, explicit device trust/link/recovery review, capture consent, stopped-input/fresh-press rules, current feature access and persistent failure guidance. Native menus, selection, focus and window activation cannot implicitly join a call, start sharing, accept a new key or execute a destructive command. P-037 is not approval to reduce the delivered Linux feature set.

Migration remains incomplete until the native implementation interoperates with existing services/clients, the protected device-state upgrade path is specified and validated, and applicable Linux release/package checks pass. Retain the prior released packages during development. D-181/D-184 still require immutable new artifacts, a higher Gentoo version, matching project/local-overlay metadata and fresh-cache Portage verification before release delivery is complete.

## Viewing and microphone usability (D-189–D-191)

Provide visible Zoom in, Zoom out and Fit controls whenever watching a shared screen, including the inline viewer. Show the current magnification relative to Fit and permit scrolling the enlarged picture with mouse, keyboard and touch; expansion/docking must retain the live decoder. Per-publication local sound mute is visible in the same toolbar, affects only that publication's presentation sound, and applies immediately in both native and managed playback. It is transient for the current call and initially unmuted; stopping watching clears it. It never changes microphone playback, remote publication or another listener.

Sensitivity increases from left to right, with the stored SPEC-004 dBFS threshold displayed alongside Extra low, Low, Medium, High or Extra high. The native client uses a standard horizontal Qt slider and label. Its account-owned queued writer survives Preferences closure/account selection, coalesces rapid edits to the latest microphone choice and reports Saving, Saved or an explicit unsaved error with Retry. Opening the controls performs no initialization write; binding and relay candidates retain their separate explicit-save behavior. Preserve existing stored thresholds; this is a presentation mapping rather than a preference migration. Sensitivity-only saves and ordinary navigation must not disarm an active microphone. Recording a binding, changing input mode and the existing SPEC-004 authority/focus/permission fences still stop input. Display a readable PTT required label beside the connected voice channel when the authoritative effective channel policy requires PTT; personal PTT alone does not claim that the channel requires it.

Configuration: zoom is transient per publication, initially Fit (1), with magnifications 1, 1.5, 2, 3 and 4; no server or persisted setting. Sound mute is transient per publication, initially false. The existing persisted dBFS range/default remains owned by SPEC-004. The five sensitivity descriptions divide the ordered range evenly. Sidebar sizing retains D-110's settings and bounds, measuring complete identity text plus trailing status/actions, including the bottom account bar and its buttons.

Testing: exercise actual MediaSession sensitivity edits during speech, mode changes and recording/focus safety; verify slider direction, all five descriptions and unchanged storage values. Browser tests zoom inline/expanded/docked without replacing the player, pan and reset, independently mute presentation sound with ongoing microphone/video playback, and automatically fit a long live voice identity while retaining manual sizing.

Acceptance criteria:

- Sensitivity edits during an enabled phrase preserve activation; input-mode changes still stop it.
- Moving sensitivity right detects quieter input and updates both the descriptive label and dBFS value.
- A required voice channel carries a visible PTT required label; optional channels do not acquire it from a personal preference.
- Inline and expanded shared screens expose zoom/reset and independent presentation mute without restarting playback.
- In a sufficiently wide window, automatic left sizing fits a voice identity and its status on one line; constrained/manual widths remain readable.

## Desktop certificate verification security update (D-183)

Desktop build safeguards for D-050/D-155/D-180/D-183: extract the exact pinned, checksum-verified Electron archive into fresh disposable staging. Record fixed build metadata for runtime version/platform/architecture, archive checksum and extracted runtime file sizes/hashes; verify it before desktop archiving and installer packaging. Refuse unstamped, modified or mismatched runtime stages, including unrecorded payloads outside the explicitly assembled application/helper/notice paths. Versioned archives, installers and blockmaps are immutable: reject existing destinations before work and publish completed bytes exclusively so a late competing output is also preserved. ZIP and NSIS payloads carry fixed `distributionFormat` metadata (`portable` and `installer` respectively); update-manifest selection uses the payload format rather than unrelated launch environment. These are build declarations, not application preferences. Native Linux/source Gentoo retains its selected D-193/D-202 packaging.

The human authorizes upgrading Electron and deploying rebuilt desktop packages on 2026-10-27. Pin Electron **44.9.1** for the alpha.48 desktop release; this is a build dependency, not runtime configuration. GHSA-jr5w-w6x2-84p9/CVE-2026-115570 affects the previous 44.9.0 verifier in both Chromium networking and Node HTTPS/fetch. Preserve certificate validation, renderer sandboxing, existing device vaults, discovery boundaries, capture permissions and call controls. Do not bypass certificate errors or replace an already published version's bytes. Rebuild the Windows installer/portable ZIP, Linux archive and Flatpak; update public manifests/checksums and the project/local Gentoo overlay under D-181. Installation/restart remains an explicit human action.

Validate the actual packaged Linux runtime's Node and Chromium HTTPS paths against the incident's affected-chain and no-CT test hosts: each must fail with a certificate-validation error, while ordinary public HTTPS succeeds. A timeout or DNS failure cannot count as rejection. Confirm exact Electron version and native executable provenance in every desktop format; distinguish Windows package inspection or Wine checks from physical Windows acceptance. Retain the existing native permission, discovery, vault, chat and voice regressions. This is a packaging/security correction, with no protocol, provider or application-policy change.

## Approved video-delivery successor — D-167

Implement D-168/SPEC-024 adaptation hysteresis, successful-progress recovery and failed-quality-trial rollback alongside D-167 independent presentation timing, paced native keyframe delivery, receiver-specific presentation-key readiness, local mute/ducking and bounded recovery before SFU evaluation. Select presentation routes by verified path liveness, deferring transient queue pressure without encoder/route churn. Report degraded/held video accurately; microphone observations drive ducking/diagnostics only. Managed RTP, frame transforms and global SFU routing are specified future integration, not enabled by this client increment. Keep capture/source consent and Stop behavior; native authority still expires under its existing contract. See [SPEC-024](024-presentation-delivery.md).


Confirmed: KDE Plasma, GNOME, Windows, and macOS support; global PTT; server-controlled rights exposed to clients; client-based administration. D-004 accepts one cross-platform interface with strong KDE and GNOME integration. D-010 prioritises KDE/Windows testers, Wayland-only Linux, a later macOS release, and a highly desirable first-version web client. Toolkit and language remain OPEN.


D-166: implement SPEC-023 adaptive video and held-picture recovery, with direct Start sharing after explicit source selection and no mandatory preview confirmation. Preserve source/audio consent, cancellation cleanup, selected ceilings and immediate clearing on authority/source/watch end.

## Direct voice and relay fan-out (D-086)

Implement [SPEC-017](017-voice-routing.md): sign/verify addressed signaling, distribute/acknowledge sender keys, establish separate participant connections, select direct/relay delivery per listener and reject expired sources before and during playout. The existing worklet independently clears each expired speaker. Keep route-neutral replay state and PTT rules. User settings expose **Always relay voice** with peer-address disclosure; `voiceRelayOnly` is an encrypted per-device/home-account boolean preference, omitted default false, invalid stored values treated as true, applied immediately and not synchronized across devices. Connection details show direct/relay listener counts, media-copy counts and direct round-trip aggregates without retaining ICE addresses/SDP. Moderator status explains conforming-client enforcement on private direct paths; do not claim host proof of private disconnection. Tests and acceptance follow SPEC-017 in addition to existing client gates.

## Screen sharing (D-128/D-129)

CONFIRMED D-224 (2026-11-07): in the native Qt client, configuration, explicit source consent and any required source-layout correction remain in the setup dialog. Once publication succeeds, close that dialog without stopping capture and show a compact native pane above the conversation in the main window, sized to its contents. Show the actual owning account/call, current sharing status and an accessible Stop sharing action. Keep it visible while browsing other conversations/accounts; navigation does not rebind publication. Stop, permission loss, call end or owner destruction removes the active pane. Cancellation and setup failures retain existing SPEC-023 cleanup/error behavior; never show successful sharing before publication. Reopening Share while already sharing must not open another configuration dialog. This changes outgoing publication placement only; embedded incoming viewers and the existing bottom call controls remain available.

Human presentation refinement, 2026-10-25: place each remote screen viewer's Watch/Stop watching, Expand/Shrink and available Zoom controls in one compact toolbar above the picture, alongside the presenter label and playback status. Use one row when space permits and wrap controls at narrow widths or increased UI scale; keep every control reachable without horizontal page overflow. The picture occupies the space below the toolbar in both inline and expanded views. An expanded viewer exposes Show chat to dock the picture above the current conversation, keeping messages and the existing composer usable; Larger view restores the expanded view. Preserve the active picture/subscription, selected zoom and chat draft across these layout switches. Shrink/Stop remains available in either layout. This changes layout only, without new configuration, persisted state or media behavior.

Stopping a remote screen view releases its local subscription and collapses its expanded panel in the same action. Automatic watch termination, removal of the offered source and replacement of the call's screen session also clear its expanded/docked layout and reset zoom to Fit before the ended view is painted; a later Watch starts inline. This applies to native-wire canvas and managed SFU video viewers. Temporary delivery stalls with retained watch intent keep their authorized picture and layout under SPEC-024. Stop watching remains available while another watch initialization is busy; it must not leave an empty expanded panel whose controls have disappeared. These are transient layout transitions, with no new configuration or saved preference.

Receiver dependency ordering and decoder replacement follow SPEC-023’s negotiated video-sequence profile. Discarded obsolete frames cannot shift the video clock, and callbacks from replaced decoders cannot queue pictures or clear replacement state. Firefox software-decoder fixtures supplement Chromium regression; exact physical browser/GPU acceptance remains separately recorded.


D-165 adds per-share resolution/frame-rate selectors and native-size Quality up to 4K under SPEC-023. The client owns these encoder preferences; they do not alter server policy. Receiver renewal must replace watched sessions without freezing, clear expired pictures and require fresh keyframes after recovery. Key-context recovery retains explicit publication/subscription intent while obtaining fresh authoritative state.

D-136: capture failures use a full-content-width reddish panel with a visible border, readable text and an accessible alert role inside the sharing dialog. Explain how to recover from denied capture. Detect desktop wrappers without the native source-selection bridge before requesting capture; explain that an updated desktop app and an application restart are required, and disable unsupported sharing actions. A page refresh cannot add native integration to an older installed wrapper. Browsers with display capture retain their normal permission picker. Unsupported system sound and a granted source without requested sound remain explicit; do not silently change the presenter's audio choice. The corrected desktop bridge advertises `screenCaptureVersion: 1`; absence or an unsupported version requires an update even when an older partial bridge is present. Electron’s empty-type media permission request is admitted only while explicit, unexpired display selection is pending in the selected main frame; it does not grant camera access. A failed desktop preview clears the consumed selection and lets the presenter choose again. No configuration property or default is added.

R-117–R-121/D-128–D-133 add the requested client outcomes reviewed in [SPEC-023](023-screen-sharing.md), including the selected transport direction and initial defaults. D-134 approves completion and game-audio capture initially on. Local alpha.24 integrates the chooser, encoded-video transport, presentation-audio worklet and listener settings; physical platform acceptance remains separate. Own the deliberate sharing popup, OS/browser capture adapters, combined-desktop composition, preview/Stop, intent-based codec negotiation, effective bitrate/route display and synchronized rendering. Offer All screens as one combined view, One screen and One window; use separate Productivity apps/Games and videos and Quality/Speed choices. Source selection requires real platform consent. Preserve the actual channel/account destination while navigating text; the alpha.23 same-channel identity switch ends the previous share rather than reusing its capture authority.

PTT controls microphone voice only. Expose listener settings for ducking received game/application sound during held PTT or speech, preserving independent normal volume and mute. SPEC-023 owns the confirmed half-volume default and proposed trigger/gain/ramp/preference details; no server may change a listener's personal ducking setting. Render the composite with usable zoom and indicate constrained, paused or unsupported media accurately.

D-134 accepts SPEC-023/P-035 and delegates its documented/tested technical completion; D-144 selects native Linux application sound. The client consumes server-resolved capabilities/ceilings; it does not grant itself an administrative exception. A high-rate direct path must reduce to a permitted relay rendition or pause before fallback. Preserve mandatory E2EE and current microphone timing/mute gates. Browser focus loss retains its microphone behavior; capture-source loss cannot silently select a display or resume a stopped share. Capability tests must not present latest API documentation as tested desktop/browser support.

## Conversation extension — 2026-10-19

D-067–D-069/R-079–R-082 add the compact grouped conversation view, inline replies and isolated thread-call controls specified in [SPEC-013](013-conversations.md). This supersedes only the earlier rule that activating an already displayed channel is a navigation no-op. First selection still preserves voice. Client grouping, colour, inline editors, capability gating, D-080 body-hover action placement and call status follow SPEC-013; parent permissions remain server-owned.

## Scope and responsibility

D-081/D-082: implement [SPEC-016](016-key-lifetimes.md) key generation, signed peer validation, in-memory retirement, expiration capture gates and explicit capability checks. Routine rotation is silent; unavailable encryption is explained in the existing voice status, without a modal dialog. Never persist media secrets with device/recovery keys or rotate stable device identity as a side effect. Keep text/history unchanged during text protocol evaluation.

This specification owns the desktop and web clients: presentation, OS/browser integration, local state and preferences, client-side encryption/key handling, media capture/playback, and consumption of server APIs. The separate [server specification](008-server.md) owns authoritative authentication/authorisation, room/event processing, federation handling, persistence orchestration, administrative mutations, and media grants.

The clients implement the client-side portions of [identity/security](003-identity-security.md), [media](004-media.md), and [data/delivery](006-operations-data.md). Those shared specifications remain the owners of their cross-component contracts; this document must not redefine their defaults or protocol behaviour. Moving server responsibilities out of the former clients-and-permissions document does not change those behaviours.

## Shared interface and platform integration

Use one cross-platform interface and shared protocol, encryption, media, and state-management components. OS integration modules handle hotkeys, audio devices, capture, notifications, secure credential storage, accessibility, packaging, and lifecycle. D-004 refines the original GNOME/GTK wording: a separate GTK implementation is not required. It does not remove the GNOME support obligation.

Evaluate toolkits against global press/release detection, Wayland capture, low audio latency, native library integration, accessibility, startup/resource use, and packaging. Do not select a browser wrapper merely because it runs on all four systems; prove the critical integrations first.

| Platform | Required evaluation |
| --- | --- |
| KDE Plasma | Supported Wayland sessions; global shortcuts; screen/window capture; PipeWire/audio integration; notifications and theme behaviour |
| GNOME | Supported Wayland sessions; shortcut registration/release; capture; audio integration; notifications and accessibility |
| Windows | Global key events under supported game focus modes; audio and loopback capture; device changes; capture permissions; privilege-boundary behaviour |
| macOS | Required permissions; global key events; display/window capture; microphone/camera access; sleep/wake and signing/distribution |

X11 is out of scope under D-010. KDE on Wayland and Windows are the initial human test platforms; macOS follows in a later release. GNOME remains a required target with its delivery stage undecided. The D-160 x86_64 Flatpak packaging profile is selected below, and D-208 sets the x86-64 baseline ISA level for every prebuilt Linux x64 package. Other CPU architectures, minimum native OS/desktop versions, additional native packages and later update distribution remain open. Unsupported privilege contexts, compositor combinations, or anti-cheat interactions must be identified by tests; do not promise universal global input.

The XDG GlobalShortcuts interface specifies focus-independent activation and deactivation signals. This establishes an API candidate, not uniform backend support on all versions. ScreenCast provides a separate capture interface. Validate actual supported combinations. [GlobalShortcuts](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.GlobalShortcuts.html), [ScreenCast](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.ScreenCast.html).

## Android client (R-122/D-152)

The human requests an installable Android client, emulator instructions and calls that continue while backgrounded. Reuse the shared interface, protocol, encryption, account/device linking, text and media implementations. Android is an additional native integration target; it does not change server responsibilities. The following engineering profile completes that requested behaviour under the implementation authority, while platform acceptance remains evidence-dependent.

Package the renderer with the APK and serve its exact bundled files in a WebView at the configured HTTPS service origin. API/discovery/media traffic retains its existing authenticated destinations under SPEC-009/010/015/017; do not change CORS, trust, permissions or server defaults to accommodate Android. Allow native messages only from the exact configured origin and main frame; block arbitrary top-level navigation, file access, mixed content and unrequested capture resources. Missing required WebView features produce an actionable error before creating device/account state; probe Web Crypto Ed25519 verification and require Web Locks, AudioWorklet and WebRTC. Chromium WebView 137 adds the required Ed25519 capability; an Android OS version alone is insufficient. Do not grant microphone permission on launch: request it for an explicit call join, and start the microphone/media-playback foreground service while the activity is visible, before capture. If denied, show an error without starting a call. D-171 subsequently adds scoped QR camera access; Android screen publishing is not claimed by this increment; existing receiver capabilities remain feature-detected.

Retain the WebView while a call is active, with an ongoing notification and an **End call** action. Preserve the call on Home, activity recreation and screen off. Held touch/keyboard PTT always releases on focus loss, cancellation or hiding. Previously explicitly enabled voice activation may continue in the background only where current room policy permits it; backgrounding never enables activation or changes PTT policy. This Android-specific exception refines the browser focus gate and the generic lock-stop rule only for an already-active Android call. Device/audio-focus loss, revocation, process/renderer loss and expired leases close publication; resumption never auto-joins or silently rearms input. Ending a call releases capture, foreground notification, audio focus and wake lock. No incoming-call push service or automatic call answering is added.

Use Android Keystore AES-GCM for the existing bounded JSON device vault, with ciphertext committed atomically in private no-backup storage. Do not persist plaintext keys/passwords or use a browser-storage fallback when native protection fails. Disable app backup/device transfer of this device identity; uninstall/clear data removes it, so use existing linked-device or recovery flows for a new install. Keep media keys memory-only under SPEC-016. APK upgrades with the same package/signing key retain device state. Debug signing is suitable for emulator/testing only and must be labelled.

D-161: Android opens with channel chat filling the available height between the channel heading and a persistent bottom user bar. Keep the account identity and user configuration icon visible in that bar. Show its Hold to talk (or existing voice activation) control if and only if this device has an active, non-connecting voice session; omit it when disconnected, connecting or connected only on another device. A labelled three-dot disclosure in the heading expands server/channel navigation, voice status/actions, channel options and people in the conversation area. It starts collapsed, can be toggled closed, and closes when opening a channel or settings/workspace. Expanding or closing it does not join, leave, move voice or arm input. The bottom user bar stays available while it is expanded. Preserve visible failure notices, touch-release safety, readable chat/composer and scrolling at narrow widths and with the software keyboard. The Android layout supersedes the three permanently visible Quiet Stack bars only on Android.

Android navigation retains access to channels, conversation/settings and people on a narrow display without changing the active voice target. Reuse touch PTT and existing explicit voice activation. Touch cancellation/hidden controls must stop held input. Expose unsupported native/global shortcuts honestly. The first supported test target is Android 17/API 37.0 x86_64 emulator with Android System WebView 145 (older API 35/36 images require a WebView update); minimum installation API 28 is an engineering floor, not proof of older-device support. Real hardware, Bluetooth routing and battery/OEM behaviour require separate evidence.

## iOS client (R-123/D-163)

CONFIRMED: provide an installable iOS client based on the Android D-161 presentation, using Codemagic macOS builds and TestFlight distribution. Calls must continue while another app is foregrounded or the phone is locked in the first delivered build. Preserve chat-first presentation, the bottom identity/settings bar, connection-gated microphone controls and the three-dot navigation disclosure. Retain shared account/device linking, encryption, server authority and voice contracts in SPEC-003/004/009/011/015/016/017. Native source, including D-171 QR camera integration, passes shared checks, four Swift core units, native compilation and both simulator UI checks on iOS 27.1. Signed build 0.1.0 (4) is uploaded successfully, Apple processing/compliance are complete and Owner testing reports Testing. Physical QR/upgrade/background acceptance remains separate in the [release record](reviews/2026-10-25-ios-qr-release.md).

The primary physical test target is an iPhone 13 mini running user-reported iOS 27.0.1. An iPhone XS running iOS 18.x is an additional compatibility target; the exact version remains OPEN. These are test targets, not evidence of compatibility or a selected deployment minimum. Record the actual OS build and installed app build with each test result.

Background continuity does not enable microphone transmission automatically. As on Android, held PTT releases on hiding, cancellation or loss of focus, and requires a fresh press after returning. Previously enabled voice activation may continue only within the existing user and room policy. Publication and playout retain all existing authority and key-expiry deadlines. Ending a call, loss of authority or unrecoverable process/audio failure stops media; returning to the app does not silently rejoin or rearm input. This narrowly refines the generic lock-stop behavior in SPEC-004 for an already-active iOS call. Incoming-call push, automatic answering and screen broadcasting are not selected by this request.

Implementation engineering profile under the human's 2026-10-25 request: bundle the shared renderer in a Swift/UIKit WKWebView shell, served through a read-only `sloppy-voice://app/` asset handler. Only the exact app origin and main frame may invoke native methods; deny foreign navigation, camera requests outside D-171’s scanner, arbitrary files and unknown assets. HTTPS control/discovery requests use an origin-bounded renderer bridge to an ephemeral URLSession, preserving application signatures and authentication while omitting cookies and refusing redirects. This is native-client networking, not a server CORS exception. Asset requests stay inside the bundle. Probe secure context, Ed25519, Web Locks, AudioWorklet and WebRTC before creating identity state; unsupported WebKit capabilities fail with actionable guidance.

Use CallKit for the explicit outgoing call's lifecycle and system End and Mute actions, and AVAudioSession play-and-record/voice-chat for real call audio. Configure the audio category during the start action, then wait for CallKit's audio activation before allowing renderer capture; do not activate call audio ahead of the system. Configure WKPreferences inactive scheduling to `.none`; declare the audio background mode without silent-audio loops or private API. A native ownership-fenced watchdog stops capture/playback when renderer heartbeats fail. System mute closes native capture and remains effective across renderer heartbeats and visibility changes; unmute still requires the existing foreground/background and shared transmission gates. Native system-mute state starts false for each call and is never persisted. Native background microphone permission is false initially and renewed only from the shared current voice-activation/authority gate; held PTT must never survive backgrounding. End/interruption/process loss closes capture and the native call without automatic rejoin. This engineering path remains a background-call candidate until real locked/backgrounded media and protocol renewal are observed. If WebKit suspends required processing, replace the affected media/control integration before claiming the first-build requirement satisfied; a declared background mode does not prove it.

Protect the bounded shared JSON vault using AES-GCM, with a random 256-bit key in the non-synchronizing Keychain using AfterFirstUnlockThisDeviceOnly accessibility. Commit ciphertext atomically in application-support storage protected until first unlock and excluded from backup. Scope its key/file namespace to the configured service; keep media keys memory-only. A missing installation marker resets only this app's old key so reinstall does not reuse a prior device identity. Lost keys, corruption or protection errors fail closed with no browser/plaintext fallback. Normal upgrades preserve the marker and identity. The deployment floor is iOS 18.0, an engineering installation floor rather than evidence that every iOS 18 device works. Use the Codemagic Xcode 27.1 image for initial compilation; record the actual Xcode/SDK build in evidence.

The initial recipient is the human owner through internal TestFlight testing. A later iPhone XS participant can use external TestFlight without developer-team access, subject to Apple's beta distribution requirements. Keep account enrolment, signing/upload, installation and physical acceptance as separate observed states. No public website download or public App Store release is implied. See [account and TestFlight setup](../docs/ios.md).

## Web client

A web client is highly desirable in test version 1. Reuse the same interface and protocol behaviours where practical, with explicit platform capabilities instead of pretending browser and desktop integration are identical.

Normal browser keyboard events target the focused document/element; they do not establish a system-global hotkey service. Discord also documents focus-only browser PTT. The accepted capability boundary for this project is D-012 below. [UI Events](https://www.w3.org/TR/uievents/), [Discord voice input modes](https://support.discord.com/hc/en-us/articles/211376518-Voice-Input-Modes-101-Push-to-Talk-Voice-Activated).

CONFIRMED D-012: web PTT works while focused and stops transmission on focus loss; use desktop clients for global PTT. This is the explicit web-client refinement of R-022. Focus-only PTT may be used in PTT-required rooms; it must never silently become voice activation. After focus returns, require a fresh press rather than resuming the previous held state. Test tab switching, focus loss while held, browser suspension, device permission changes, and reconnect. No native companion is required by this decision.

Browser support also needs an explicit browser/version matrix, secure-context deployment, microphone permission and playback handling, local key persistence/recovery, and media/E2EE compatibility. A browser-delivered client trusts the origin serving its executable code; compromise of that origin can compromise endpoint encryption. Describe that trust boundary separately from servers merely storing or forwarding ciphertext.

Consume the routing/origin contract in SPEC-002. A successful native connection is not sufficient evidence that an independently hosted web client can access the same foreign room. Keep home credentials and room-host credentials scoped to their destinations, and surface origin/transport refusal separately from account permission denial. The supported secure key-store integration is a platform contract, not an option to downgrade to plaintext preference storage.

Do not assume a shared UI mandates a specific web technology or desktop wrapper. Choose architecture after proving the required desktop integrations and browser media/crypto support.

## Main client behaviour

Proposed navigation: accounts/domains, communities, rooms, direct conversations, then the active conversation. Keep live voice state accessible while reading another text room. A prominent global microphone state shows whether the client is muted, waiting for PTT, transmitting, blocked by policy, or disconnected.

The selected text view and active voice-session target are separate state. Opening a text view does not move the voice session or its PTT target. Leaving or switching the active voice session closes the transmit gate and clears held input before changing the target; after the new session is authorised and ready, require a fresh press. Browser focus loss retains its stop rule. This does not select simultaneous multi-room voice or multi-account transmission; those remain Q-20. V1's one active account device under D-020 also applies when desktop and web clients use the same account.

Clearly label local actions “Mute for me” and “Volume for me”; label moderator actions “Mute for everyone” and “Volume for everyone.” Put moderator controls in a distinct area and show their scope and acting identity. A room-local moderation action must not appear to apply to the entire federation.

Display encryption mode, remote host/domain, connection quality, and actionable permission errors. Do not automatically start capture when switching the active voice session or accepting a permissions dialog. Multi-account operation is proposed; prevent ambiguous sender identity and accidental transmission to another account's room. Distinguish unavailable historical keys from missing server permission: the host may retain eligible ciphertext that a V1 device can no longer decrypt under D-022.

Accessibility requirements are proposed: complete keyboard navigation, screen-reader names, focus visibility, scalable text, non-colour-only status, and accessible PTT alternatives permitted by policy. Global hotkeys must be configurable to avoid collisions. Translation-ready strings are proposed; initial languages remain open.

## Consuming server permissions

Consume the capability and administrative contracts defined by [SPEC-008](008-server.md#authorisation-and-capability-contract). The client uses effective rights to adapt its interface; it does not become the authority deciding what an account may do.

Proposed client behaviour: read action identifiers, resource scopes, effective allow/deny, constraints, policy revision, and safe denial reasons from the server. Subscribe to permission changes, invalidate stale display state, and handle action-time rejections. A cached grant is only a display hint; expiring/revoked media grants must reach the client's publication state machine.

Unknown capabilities must not be interpreted as permission to invoke an action. Local controls remain local even when the same user also has moderator rights. Server-role evaluation, delegation, privilege escalation prevention, and last-owner protection belong to SPEC-008, not duplicated client logic.

This boundary does not remove client validation of encrypted object operations. Under SPEC-006, clients verify authenticated historical authorisation evidence, sender identity and the shared rules over decrypted content. They do not recalculate server role precedence or substitute today's permissions for the revision applicable to the accepted operation. Missing/forged evidence and untrusted snapshots produce the specified rejection/recovery response, never implicit authority.

## Administration in the client

Native recursive deletion ports SPEC-012/D-138 at the original Home authority. Before enabling Delete, validate the preview target, exact confirmation digest over its at most 100 ordinary channel descriptors, unique valid IDs, bounded names and a connected acyclic descendant tree. Display every listed name and the irreversible history/membership/call consequences, with Cancel initially selected. The existing server-context ticket contains exactly the reviewed target and confirmation. A changed tree requires fresh review. Validate the accepted deleted-ID receipt under the existing JSON bound; internal thread IDs may accompany ordinary descendants. Cleanup removes only those ordinary room keys from the owning connection's main/reply drafts, tokens, cursors and selected-room hint, preserving unrelated channels, private conversations, accounts and credentials. Failed local persistence must retain a retryable exact operation; it cannot recreate a confirmed deleted-channel edit. Call/selection cleanup and inaccessible/deleted fallback retain SPEC-012's original requirements and need composed fixtures before release. No policy or user setting is added.

Native administration uses standard modeless scrolling Qt forms for the named Home server/channel. Channel creation retains the existing preset, access/encryption defaults and immutability, parent/inheritance, initial grants and optional PTT overrides. Existing settings show current values and preserve unsaved input on refresh/conflict. Member management shows explicit permits/denials, effective account access, propagation, owner-only principal/role controls and shared moderation. Invitation receipts retain their submitted account identity even if the form changes before completion. A single one-second read timer follows pending enforcement only through its original deadline plus two seconds; it stops when settled, expired or closed and never starts media. SPEC-008/012/022 remain authoritative for defaults and permissions. Other administration screens and original foreign management retain their implementation/qualification gates.

Native administrative completion ports existing SPEC-008/012/022/023 operations into the original-authority forms. Channel removal, role changes, local login replacement and invitation cancellation require a standard explicit confirmation with Cancel initially selected; freeze target, payload and revision for that review. Foreign account login replacement remains unavailable. Owner-only visitor blocking is a separate server action with its own target/consequences; unblock does not restore sessions or admission. Screen policies show current server/channel values, distinguish null inheritance from false, preserve authorized bitrate exceptions on unrelated edits and submit only changed fields at the reviewed revision. A save cannot discard edits made after submission. Public notices retain their existing type/message/duration bounds. Owner opt-in directory and shortcut publication uses credential-free bounded public metadata, the canonical coordinator, the original server nonce/pin and validated returned link; never forward an account token to the coordinator. Existing owners retain all policy defaults, permissions and limits. These forms do not start capture or move voice.

Native named tree management prepares its exact saved profile/connection without selecting text, loading history, obtaining another grant or changing credentials. Use the existing bounded account discovery and exclusive connection owner, with at most 32 preparations and a 15000 ms preparation deadline. Closing the preparation cancels its late result. The resulting modeless form retains that account and original Host; current browsing identity, Home roles and later rejoin credentials cannot substitute.

Native foreign ordinary-channel management uses that retained DestinationClient and its existing exclusive connection writer, never the Home role or token. Fetch capabilities and state from the original pinned Host, validate the same qualified Home account/device, and derive controls from its current Host role/admission. Retained management commands include their original intent and prior text view; exact retries survive restart without selecting the managed target. Closing/rejoining the destination fences preparation and late results; a new session cannot silently replace the original management authority. Foreign visitors may be Host-local moderators but cannot own the Host, replace foreign account credentials or manage private/derived channels. This ports SPEC-008/012/015/022 without changing permissions or defaults.

Native management operations retain the initiating account, original service and explicit channel or server context independently of text/call selection. Read only the requested state/account/permission/policy endpoints while their management dialog is open. For existing ticketed operations, preserve the current revision and exact body through the account/connection's existing sole protected pending-command writer, with kind `management` and the previous text `viewRoom`. Permit only the existing SPEC-008/012/022 action/scope combinations; server context permits ordinary channel creation/deletion, while ordinary channel administration retains its existing role/admission constraints. No private conversation or derived thread becomes independently administered. Closing before dispatch cancels preparation; closing after durable dispatch retains the exact operation for explicit retry/restart. An ambiguous result must not mint another operation. Completion can update its originating dialog and named metadata, but cannot navigate text, move voice, replace credentials or borrow a newly selected account. Existing request limits, authority checks and server validation apply; no new role, permission, policy default or user setting is introduced. Native forms must retain edits on conflict and show authoritative results and enforcement state, rather than exposing raw command payloads as product controls.


Expose the reference server's supported domain/community/room settings through the authenticated client: permissions, federation policy, media settings, PTT requirements, retention, quotas, moderation, and audit views as applicable.

Proposed client workflow: fetch the current value and revision; show effective inherited policy; validate against advertised ranges for immediate feedback; submit with expected revision; display the server's applied value and propagation state. A conflict preserves the user's input for review rather than pretending it was saved. The server performs authoritative validation, revision checks, persistence and live-session propagation under SPEC-008.

For moderator mute, display accepted/pending, effective or failed enforcement with the action's operation identity and revision. An accepted change is not proof that remote forwarding has stopped. A timeout is an unknown outcome to reconcile through the server's result query/retry contract, not an automatic failure or reason to create a different command. Preserve newer state when late results for an older action arrive. “Mute for everyone” covers all participant audio under D-019; video may continue.

Provider credentials and bootstrap recovery are server concerns under SPEC-008. The client must not require or expose raw provider credentials to perform routine supported media-policy changes. No cloud provider console should be required for that routine workflow after setup.

If an action is forbidden, hide it or show a disabled control with an appropriate reason. Do not expose private room names, role details, or administrator-only data solely to explain a denial.

## Linked accounts and device management (D-059/D-060; SPEC-011)

D-044–D-046 request one account across KDE, Windows and web, shared permissions/history, separate recovery and explicit voice movement. SPEC-011 selects the following workflow and supersedes the single-device parts of the older V1 client contract.

Use the same domain, username and password on every client. On a new installation/profile, generate independent keys and show a pending device-approval screen. Let any existing approved client inspect the request, compare its code/fingerprint and approve or reject it under SPEC-003. No dedicated primary phone or permanently online primary desktop is required. Present a device list with user-facing name, current-device indication, trust/status and explicit revoke action; a friendly name is not authentication evidence.

After approval, expose the server's current account permissions and eligible text independently on every client. Show history transfer progress, verified coverage and unavailable ranges, distinguishing missing keys from lack of permission or expired content. Linking must not silently reset the password, replace an existing device, join voice or copy the source's local settings. The same hardware running a browser and desktop app constitutes separate devices.

Provide recovery-key setup/confirmation and a clearly separate all-devices-lost recovery path under SPEC-003. Explain what was backed up, its retention, and what losing both devices and the recovery key means. Never put the secret in diagnostics or an ordinary server setting. Restoring uses current server permissions and requires a new explicit voice join. D-060 requires the password as well as the recovery key; forgotten-password recovery is not included. SPEC-011 defines the mechanism.

Show the active voice client and a destination “Move voice here” action under SPEC-004. All other approved clients retain text/account access. Keep microphone/output choice, PTT binding and personal playback preferences local to each client; shared roles and moderator mute remain account/room authority. PTT and playback preferences remain local; account permissions come from the server.

## Recording a PTT binding (D-047; P-025 workflow PROPOSED)

D-047 confirms configuration by pressing the desired keyboard key, mouse button or joystick button. D-048 identifies the immediate ProtoArc mouse button 4 fixture on KDE and Windows and requires joystick validation before leaving testing. Global desktop PTT and focused-only web PTT remain the accepted boundaries; unsupported adapters must be shown as incomplete support, not used to remove an input class from the requirement.

Proposed configuration page workflow:

1. Show the saved binding and effective input capability, with “Record binding”, “Clear” and an accessible cancel control. Starting recording closes the transmit gate and clears any held input; it does not record microphone audio.
2. Wait for the activating click/key and any already-held candidate inputs to be released. Only a fresh press after the recorder is armed can become the candidate. Ignore key auto-repeat, pointer motion, wheel scrolling and joystick axes; these are not held buttons.
3. Capture one physical keyboard key, mouse button or joystick button. Show its readable name and source, such as “Mouse button 4” or “Joystick … / Button …”. The physical button used in Discord is the acceptance target; DOM/native numeric codes may differ. A wheel's physical click may be a button even though wheel rotation is not.
4. Wait for candidate release, then offer Save or Cancel. Configuration inputs must not trigger voice, browser Back/Forward or unrelated in-app actions while capture is active, to the extent permitted by the platform. Report reserved/unobservable inputs instead of claiming success. The on-screen cancel action must work even when Escape is the chosen key; chords are not required by this first proposal.
5. Save only a validated binding with successful registration/observation support. On Wayland, use any required portal approval and show the effective returned trigger; if it differs from the requested key, obtain an explicit selection rather than showing the request as active. A cancelled or failed change preserves the old preference but leaves transmission off until that binding is usable and newly pressed.
6. Provide a non-transmitting press/release indicator to test the saved binding. After recording, saving, cancellation, registration changes or reconnect, require a neutral state followed by a fresh press before speaking.

Use one configured held input initially. Support keyboard keys beyond the current Space/F1–F12 list, mouse buttons including the user's button 4, and joystick/controller digital buttons exposed by the supported adapter. Modifier chords, multiple alternative bindings, axis thresholds and toggle-to-talk are not selected. Keyboard layout handling and canonical physical code mappings need an adapter contract; never silently substitute a different key after a layout change.

Normal desktop observation should coexist with the foreground game rather than grab the entire input device exclusively. A platform-reserved shortcut or privilege boundary may prevent a binding; show that failure. Do not require root, blanket input-device access or an X11 fallback as an undocumented dependency. Native adapter permission needs must be reviewed before selection. Browser use must stop on blur/tab hiding for every input type even if gamepad polling continues; focus regain while held is not a fresh press. Ordinary typing suppression remains separate from intentional recording in the settings control.

Persist a joystick binding to a recognised local device/control, not a transient enumeration index. Disconnection, ambiguous identical devices, permission loss, stale input or helper failure stops PTT. Reconnection cannot silently retarget to a different joystick or resume while held; require reliable identification or explicit re-selection. Exact identity, polling/watchdog and hardware coverage remain Q-45. Platform evidence and official API references are in the [PTT review](reviews/2026-10-18-ptt-input.md).

## Account and lobby workflow (D-052)

R-070–R-072 amend the shared web/KDE/Windows interface. Signed-out `/` shows account sign-in and an “I have an invite” action. Only an uninitialised service also offers a link to `/setup`, allowing desktop operators to reach setup without an address bar. `/setup` shows initial owner creation only when the service reports bootstrap available. A legacy root bootstrap fragment may be moved to `/setup` before use. After authentication or logout, reset the mode to normal sign-in; do not recreate or delete registered device keys. Show the connected service origin and retain the last registered username for returning sign-in. D-052 originally excluded multi-device login; D-059/D-060 and SPEC-011 now provide it through the linked-account workflow above.

Keep the label “Invitation key”. Accept a trimmed raw 43-character base64url key or an absolute same-origin invitation URL containing exactly one appropriate fragment key (`invite` for registration; `roomInvite` for legacy room admission). A registration URL may supply its username; reject a conflicting typed username, wrong purpose, malformed/ambiguous keys or another service origin before submitting credentials. Do not navigate to a pasted origin. The configured origin remains owned by SPEC-002.

Server members and lobby access are managed together: create a server invitation, then allow or remove lobby access for the registered account. Display whether each account is in the lobby, allowed to join, or awaiting access. A permitted nonmember clicks “Join lobby”; no code is required. An unpermitted nonmember sees an access explanation, with legacy room-key entry available separately. Permission grants do not automatically open history or voice. Use the authoritative capabilities and access state from SPEC-008/009; keep server-side checks authoritative.

## Compact interface and system-selected appearance (D-065/D-066)

R-077/R-078 select review boards A–E with the human's amendments: remove A4 entirely; moderator controls are below personal controls in the same menu, never a second tree. D is approved for implementation and subsequent usability review. The mockups' colours, sample identities and incidental decorative details are not configuration or new features. This section supersedes D-063/D-064's modal settings/listening presentation and the fixed-dark V1 styling, while preserving identity, permission, history, local audio and PTT contracts.

- One server/channel tree replaces the server rail, large room cards and separate voice/member sidebars. Channel rows have explicit expansion controls and small, labelled `+` action buttons. Voice participants are children of their own room, with bold nickname and smaller full address. Tree arrows/Home/End navigate; Left/Right collapse/expand; Enter selects a channel or opens a person's menu. Visible focus and all controls remain keyboard reachable. Expansion is local, transient view state, initially expanded for admitted voice-capable rooms; search filters channel names without changing admission or voice.
- The tree consumes SPEC-012 `room-tree/1` data. Only admitted channels expose their voice roster, including while another text channel is selected. Do not convert missing/unauthorized roster data into a claim that a room is empty. Channel-member and identity/trust controls remain accessible in a main-workspace member list for the selected admitted room, including people outside voice. No persistent duplicate member sidebar remains.
- Channel `+`, right-click and Shift+F10 open the same anchored menu. Actions expose supported text/channel opening, explicit voice join/move/leave, channel members, invitations/access and properties according to current capabilities. Opening a menu neither admits the user nor changes text/voice targets. A chosen action operates on the named channel; changing text does not move voice. Server menus expose supported administration and sign-out. Existing keyboard shortcuts and bottom-left user cog remain.
- Person menus show local volume, mute and reset together, then identity/trust, then a separated `For everyone in <channel>` section for permitted moderation. The latter retains server authority, shared gain and visible pending/effective enforcement. Self entries lead to user settings. Menus have no backdrop, window heading, modal role or Close button; Escape/outside click dismisses and focus returns appropriately. Arrow keys navigate controls without stealing slider/input keys; Tab can leave and dismiss. Menu size/position remains inside the viewport with scrolling if needed. A stale account, room, participant or permission context closes/disables its actions. Menus suppress PTT and require fresh input afterwards, retaining D-064's safety contract.
- Settings, channel creation/properties, member management, identity review and shortcut help occupy one main workspace with a Back control at the top-left, preceding the heading in document and keyboard order (D-070). The heading stays left-aligned beside it, wrapping below when space is limited. Preserve the room tree and voice status; keep related sections visible on one scrollable surface rather than tabs. Focus enters the workspace heading and returns on Back/Escape; do not trap focus or dim/block the rest of the app. Navigation can leave a workspace; pending results remain bound to their original account/channel. Input recording retains explicit Cancel and input suppression.
- Member management uses a searchable member table and adjacent selected-member controls, distinguishing server role, channel permission and actual membership. Pending invitations remain separate. Consequential actions use inline review/confirm/cancel controls with the existing exact target and effects, including invitation cancellation, removal, role changes and login replacement; opening a confirmation does not execute its action. Keep ordinary linking separate from replacement. Nickname conflict review, key verification, recovery-key acknowledgement, unknown command reconciliation and failed saves remain explicit.
- Chat uses a compact header, ordinary message rows and a rectangular composer; remove introductory marketing content and unsupported attachment decoration. Authentication uses a plain form with connected service, invitation/link/recovery entry points and inline errors. D-073 restores a subdued green background and edge on the PTT bar only while actual transmission is active, in both application palettes. The transmit label and microphone state remain legible; forced colours use system roles. Idle, muted, blocked and disconnected states return to the ordinary surface. D-108 replaces the single full-width strip with the Quiet Stack below, retaining these controls. Status does not rely only on colour. Narrow layouts scroll/stack content without hiding required actions or forcing horizontal page scrolling.
- D-066 supersedes exact system-colour inheritance. Use application-defined light and dark palettes, following the OS/browser appearance live. Dark mode restores the earlier blue-grey surfaces, soft off-white text and lavender accents. Light mode uses pale blue-grey surfaces, charcoal text and deeper lavender accents. Thin subdued separators preserve the approved compact grouping outside the D-141/D-142 User settings and sidebar exceptions below; do not reintroduce large spacing or modal dialogs. Native controls follow the chosen light/dark mode. Forced-colour accessibility uses CSS system roles instead of either application palette.
- Web and older desktop clients follow `color-scheme: light dark`. The alpha.8 desktop bridge supplies a validated light/dark hint from KDE's active colour scheme where available; consume only that boolean, never its colour values. Other platforms and missing/malformed hints use the browser/system appearance. Switching appearance updates without restart, without saving an app override or changing OS preferences. [CSS light-dark()](https://drafts.csswg.org/css-color-5/#light-dark) selects the application colours using the active scheme.

This shared-interface update works in existing desktop packages; no package replacement is needed. The alpha.8 native adapter remains wire-compatible, but its custom RGB values no longer override application colours. Its bounded read-only KDE integration is retained solely to determine light/dark appearance. The ordinary startup configuration-error window remains system-styled and unprivileged. The bottom-left microphone bar reports moderation and input state for the active voice room even while another text channel is selected.

## Current channel heading (D-149; native exception D-204)

Enlarge the current channel title at the top of the main conversation from 15 to 24 CSS pixels at 100% interface scale. Retain readable wrapping, the channel description, access/encryption labels and settings control. When an ordinary channel name contains the whole word **Lobbyster**, ignoring case, place a static cartoon lobster behind that word. Preserve the original spelling, full title text and accessible heading name. The decoration is local, non-interactive and hidden from assistive technology; ordinary words, server-only headings and Messages receive no lobster. Text remains in front with a surface-colour halo. Forced-colour mode hides the decorative artwork while retaining the larger readable heading. This narrowly refines D-065's compact header; it introduces no interaction or change to stored channel names.

D-204 restores the existing lobster behind the current ordinary channel title in Qt, superseding D-198’s artwork retirement only. Use native desktop heading fonts/scaling, a bundled static vector illustration and a background-colour text halo. Match whole-word Lobbyster without regard to case, preserving original title text and its accessible label. Reserve heading space so artwork cannot overlap the account/encryption line or controls. Wrap long titles; omit artwork on a line too narrow to fit it or splitting the matched word, and fall back to native text if heading height is constrained. No separate image widget, focus target, accessible artwork node, network fetch, timer or animation is added. Direct/group titles, tab labels and navigation rows remain undecorated. Both original and foreign ordinary channels update the decoration when renamed.

## User settings section hierarchy (D-141)

The human requests a solid colour box around each section heading and a softer matching box around its settings, with significantly rounded corners. This supersedes D-066's separator-only/no-card rule only in User settings. Use restrained accent colour, quiet backgrounds, consistent padding and clear gaps between sections; readability takes priority over retaining lavender. The [VLC redesign reference](https://www.youtube.com/watch?v=ERFeOgqk324&t=965s) informs visual hierarchy, not new settings or navigation behavior. Main section headings have the strongest emphasis; nested profile, input and recovery groups use a quieter version of the same treatment. Labels, descriptions, controls and focus indicators remain legible in both system-selected palettes and forced colours. Keep the existing section order, settings values, permission rules, keyboard navigation, PTT suppression and one scrollable main workspace. D-176 subsequently introduces left-hand category tabs and recording-only input suppression; its scoped rules supersede the earlier no-tabs and settings-wide PTT pause requirements.

## Sidebar visual hierarchy (D-142)

The human approves the settings preview and requests the same visual quality for both sidebars. Group each server branch and each Pinned/Recent/Server Members section with a soft panel, rounded border and clear heading. Server headings distinguish the selected server; the selected channel retains its own visible highlight and accent edge. Keep nested channels and voice participants compact with branch guides, readable full identities and access labels. People rows keep their existing avatar/name/actions/context order, with consistent action spacing and clearly visible unread indicators. Search, Add server, section counts, Clear recent, resizing/reset and persistent call/microphone/account controls remain reachable. Retain existing voice-state colours and actual-transmission semantics; section colour is not a presence indicator. System-selected light/dark palettes and forced-colour system roles apply. This extends D-141's presentation treatment and narrowly supersedes D-066's separator-only rule in these sidebar groups; it adds no navigation, permission, voice or stored-preference behavior. Automatic width measurements include the rendered group insets; existing width bounds, saved manual choices and reflow breakpoints remain unchanged.

## Quiet Stack (D-107/D-108)

R-112 relocates the connection and microphone controls beneath the channel tree, above the existing identity bar. Keep three separate compact bars with modest gaps, aligned edges and subtle rounding. Preserve the D-100 connection colours and D-073 actual-transmission highlight. Keep the composer beneath the conversation; do not retain duplicate full-width voice bars there.

The connection bar names the active destination and state. Its status button opens a bounded, scrollable non-modal panel above the stack with full server/account context, current status, connection diagnostics and the existing contextual Join/Move action for the viewed channel. Initial join and connecting cancellation remain directly accessible. The phone icon leaves the actual active call regardless of selected text/server; identify its destination in its accessible label and tooltip. Never compare room IDs without server/account context. Remote-device ownership stays explicit and any move remains deliberate. Escape closes the panel and returns focus; outside interaction dismisses it. At short/narrow or scaled viewports keep the panel and controls reachable.

The microphone bar places the held PTT action and effective binding beside an input-settings icon. Retain keyboard Space/Enter, pointer capture/release/cancellation, focus-loss shutdown, moderator mute and unavailable-input explanations. Permitted voice activation uses the same area for enable/disable and listening/transmitting state. D-113 replaces Re-enable PTT with a non-interactive **PTT disabled** notice explaining settings pause, missing binding or unavailable shortcut, and uses the existing held on-screen control as **Click to talk**. Label it as requiring a hold. The on-screen input is independent of shortcut readiness and never re-enables the shortcut; it is usable only in an active PTT call with settings closed, a focused visible window and normal capture authority. It stops on pointer/keyboard release, cancellation, focus loss, suspension or other capture-gate closure; no automatic resume. Keep the disconnected/settings-paused control disabled with an explanation. Voice-activation input recovery remains available only for an active local call with settings closed. Settings, authority and input gates remain unchanged. The identity bar includes a small circular profile picture/initials, readable qualified identity, unread summary and user-settings icons. This smaller self picture does not change the authoritative people-list thumbnail size.

Unexpected-disconnect alerts remain persistent above the stack with channel, reason, time, log download, manual Join/reopen-call guidance and dismissal. Keep failure text scrollable if necessary; compact status cannot hide it. Full server/account and input context remain available without relying only on colour, hover or truncated text.

## Interface scale and functional surfaces (D-100)

User settings offers a whole-interface scale control and Reset to 100%. Apply immediately to every shared-client screen, including sign-in/recovery, channel and direct/group text, threads, people, settings, administration, voice controls and context menus. Scale fonts, spacing, icons and images together; use the effective available width to reflow the layout, and keep menus anchored and inside the viewport. Narrow layouts stack and scroll; Back, reset, navigation and voice actions remain reachable. Browser/OS zoom and display density remain independent and combine with this application scale. Shared renderer changes work with existing desktop wrappers; native title bars, OS dialogs and the wrapper’s pre-renderer configuration-error page remain controlled by the OS.

The preference is local to this installation/browser origin, shared by its accounts, saved servers and open windows, and survives sign-out/restart. It contains no identity or secret and is available before vault unlock. It is not sent to the server, linked-device history or recovery copies. An invalid stored value uses the default and shows an actionable notice in user settings without discarding unrelated settings. A storage failure still applies the chosen scale for this open window and explicitly reports that it could not be saved. Updating another local window or removing the preference updates the current window as well. Reset remains available after a storage error.

The bottom-left voice connection bar uses a soft green surface when this client is connected, amber while connecting or when voice is active on another device, and muted red while disconnected. Text names the actual state; colour cannot imply local connection for a remote device. Channel, thread-reply and direct/group message composers use a distinct soft lavender-grey surface and boundary. Define paired light/dark semantic tokens, maintain readable text and visible controls, and use system colours/borders in forced-colour mode. D-073’s separate PTT bar still becomes green only during actual transmission.

## Server tree and unread navigation (D-104)

R-109/R-110 replace the top-left server selector with server roots in the left tree. Show saved ordinary server connections with their qualified host/account context; conversation-only connections remain outside the tree. Selecting a server preserves active voice and each connection's existing drafts. Each server has a disclosure, right-click/Shift+F10 menu and keyboard/touch action button. A visible **Add server** action opens the existing reviewed Join workflow; it does not provision a new host or bypass join confirmation. Server context actions target the named saved connection, with current permission checks before administration. Keep server settings, creation, supported member/invitation management and sign-out; do not mix another server's authority into those actions. Channel creation is also available from a channel menu and names the parent. SPEC-012 owns hierarchy/access/depth semantics.

Remove the top-bar Messages and Channel members buttons. Retain contextual channel member/trust management and the right-side people lists. Put an accessible message-bubble icon beside the bottom-left self identity, showing the number of conversations with locally unread incoming messages. Clicking opens the Messages summary without reading a previously selected conversation automatically. The summary prioritizes unread conversations and provides request/call/group entries; selecting a conversation opens it and advances its local read position only after its eligible history has loaded while visible. Navigation never answers or moves voice.

Right-sidebar DM icons show a small red circle for an unread one-to-one conversation with that qualified person. Use a slow three-second opacity pulse, always leaving the circle visible; reduced-motion users get a static circle. Accessible names include **unread messages**, and forced colours retain a visible system-colour indicator. The same qualified person has consistent state across Pinned, Recent and Server Members. Group messages do not falsely badge each participant's private DM. Indicators are client-local unseen-content state, never remote read receipts or presence. Account and authority boundaries remain SPEC-018's.

These presentation constants and transient tree/summary selection add no saved settings. Client unit tests cover unread scope/self exclusion and server/channel tree flattening; browser tests cover unread-summary/DM selection, read persistence, qualified identities, keyboard menus, narrow layouts, reduced motion and active voice preservation.

## Quiet identity (D-117/D-118, presentation refined by D-120)

R-115 supersedes only D-110’s duplicate visible server/account roots. Group ordinary saved connections by the full pinned server UUID, authority and service base. Render one server heading with its selected qualified username as the subdued second line in the same tree item. D-120 replaces the repeated domain subtitle and removes the separate account button/dropdown row. Keep the underlying connection keys, drafts and permissions account-qualified; do not merge channel lists or authority. Multiple servers still expand independently, with existing automatic/manual width behavior. Server context menus expose **Sign in as another user…**, opening the existing non-modal workspace chooser. Right-click, Shift+F10 and the server action button provide access.

History lists successful local account profiles, deduplicated by authority plus account UUID, never server directory/Pinned/Recent entries. Distinguish Current, Ready and Sign in required; readiness is advisory until authenticated requests succeed. Show full addresses, allow another bare username (destination authority) or qualified address, and keep the verified destination visible. Ordinary password/device-proof login goes only to the verified home authority; unapproved devices still require the existing linking/recovery flow. Never save passwords or count failed sign-in attempts as history.

D-126 refines the channel-menu Join as select: changing its account immediately opens/joins the target channel with that identity, without a second Open action. If this device is already connected to voice in that exact server/channel, the selection also switches that call to the chosen identity; a call in another channel/server stays untouched. Selecting the identity already used by the call must not toggle voice off. Explicit Open channel as / Join voice as actions remain available. The action first checks the selected account’s server admission and filtered channel list; inaccessible targets give generic feedback without exposing another account’s channel metadata. Successful text switching updates that server’s browsing identity and account-wide Messages, Pinned, Recent, self bar and User settings. Server/channel administration uses the selected destination permissions. A voice action for the already selected identity preserves the current text view. The active call retains its original account, keys, input and listening preferences; only explicit voice movement, including the D-126 same-channel identity selection, may change it. No account-wide content is combined. If sign-in is needed, the chooser retains the requested same-channel voice switch until successful authentication; cancellation, lost access or a changed/ended original call cancels that voice continuation. Rejoining never resumes held PTT or voice activation automatically. New voice-connection failure is reported through the existing voice status; the old call is not silently restored.

Fetch and validate the target account, server and channel state before replacing the usable text context. Failed login, unavailable services and denied channels preserve the prior context and draft. Cancelled/superseded chooser work cannot redirect the workspace. Saved authenticated profiles may survive a later destination-admission failure. Clear stale menu/management/history state on successful switching; delayed results retain their original account/destination binding. Sign-out affects only the named account and its matching call; it never signs out another identity at the same server. Existing connection removal retains account profiles/keys; never silently fall back to another account after authentication fails.

Configuration: `Vault.serverAccounts` is optional protected device state mapping the JSON-encoded tuple [server UUID, canonical domain, canonical base] to an existing ordinary connection key. No operator setting. Write on successful explicit selection. Omitted/invalid/missing targets use the globally selected matching connection, otherwise the first stored matching connection for display only; never issue a login, join or voice action through that fallback. Keep at most one entry per existing server group and remove orphaned entries on writes. Account activation must not copy this device-wide map into individual profiles. It is not synchronized or included in account history transfer/recovery. History reuses existing protected profiles and the existing vault size limit without an additional unbounded username log.

Testing: unit coverage for grouping, qualified candidates, session-readiness hints, preference validation/migration, profile isolation and credential destination validation. A-48 browser fixtures verify the compact account subtitle and menu-based chooser, then cover same-server accounts, same usernames across domains, per-account channels/drafts, expired/failed sign-in, cancellation/stale results, reload, account-wide labels, keyboard and scaled layouts. Active voice integration must verify unchanged call ID/account and continued media before explicit movement, plus immediate dropdown text admission, same-channel voice identity switching, no voice toggle for the already active identity, retained unrelated calls, failure/cancellation and fresh-input behavior under D-126.

Acceptance: R-115/A-48 require one root per verified server, an accessible account/history chooser and channel dropdown, separate account state, no inaccessible-channel disclosure, previous-context preservation on failure, and explicit voice movement.

## Multiple expanded servers and sidebar sizing (D-110)

R-113 extends the D-104 tree. Each saved ordinary server/account connection expands independently; initially expand the selected connection. Expanding or collapsing only changes navigation presentation, and selecting another server leaves previously expanded roots open. Show channels indented beneath their server with a continuous branch guide and distinct server heading. Namespace keyboard navigation, selection, ARIA references and actions by server/account plus room ID. Background lists use authenticated, identity-checked `/rooms` reads through SPEC-015's scoped client. Expansion performs an immediate read; existing background refresh updates expanded lists. Do not load message history, join channels or start capture merely to populate a branch. Background voice rosters need not be fetched; show the existing open-channel guidance where unavailable. Failures clear inaccessible cached rows and show a retry action. Stale responses from removed connections or replaced credentials must not repopulate a branch. Selecting a channel or its context action resolves its own saved connection before using existing scoped state/permissions; voice moves only through the existing explicit action.

Automatic widths fit visible server/channel labels and people names/qualified addresses where available space permits. Preserve complete readable labels by wrapping at the width cap; do not hide identity or access labels to force one line. The left tree uses stronger indentation and guides, including nested channels. Manual widths prevent content-driven resizing on that side. Each vertical boundary has a pointer/touch drag target and a focusable separator with arrow-key adjustment, Home/End limits, current width and a named reset action. Double-click or Enter on the separator resets that side to automatic. A visible reset control appears for a manually sized sidebar. Respect device UI scaling in measurements and pointer coordinates. Keep Quiet Stack and the composer reachable.

Presentation bounds (engineering choices implementing the requested small-window constraint): automatic base widths remain 245/235 CSS pixels (left/right); minimum widths are 180/200 and maximum widths 480/440. With both sidebars alongside the conversation, reserve at least 420 CSS pixels for the conversation; reduce automatic space before a manually chosen width, then proportionally constrain requested excess if necessary. Existing responsive breakpoints remain: at 1050 CSS pixels the people region moves below the conversation; at 520 both side regions stack. In the two-column layout reserve 340 CSS pixels for the conversation where possible and use the existing 180-pixel left base below 650. Horizontal drag controls are unavailable when their sidebar is stacked. Constraining a width for the viewport never changes its stored manual request.

## Channel names (D-074)

Channel settings expose an editable name and explicit Save name action under the existing server settings permission and the `room-rename/1` capability. Preserve failed drafts; read-only users still see the name. SPEC-012 owns validation, identity preservation and compatibility.

## Channel access labels (D-094)

Show a compact rounded **Private** label with a green border and softer green fill, or **Public** with a red border and softer red fill, in each channel-tree row and the selected channel header. Read the authoritative SPEC-012 `access` value independently of encryption; an encrypted public channel remains labelled Public. Labels contain readable text, remain visible at narrow widths and use system colours in forced-colour mode. Long channel names wrap without hiding the access label. This presentation adds no configuration or permission change.

## Pinned and recent people (D-071)

The right sidebar contains **Pinned**, a personal saved-contact list without mutual approval, followed by **Recent**, a list of people encountered in conversations. This replaces the absence of a right sidebar under D-065; channel members remain in the left tree and member workspace. Pinned follows the account across approved devices; Recent remains in each client’s protected account profile, per the explicit follow-up answer. SPEC-014 defines the bounded data and encounter contract. The sidebar uses compact rows, full account addresses, explicit Add/remove friend controls, and a Clear recent action. SPEC-018/D-090 supersede the original primary last-channel action: clicking a person opens a DM without joining voice; D-092 removes the secondary last-channel button from the sidebar. A saved contact grants no messaging, presence or channel permission. On narrow screens, Pinned and Recent remain reachable in a compact expandable region below the main view.

### Profile label refresh (D-185)

Refresh known Pinned, Recent and loaded Server Members profiles on each authenticated client entry/sign-in and when 24 hours have elapsed while open (within the periodic check interval). Use bounded authenticated reads from the selected server and home account service, preferring a person’s authoritative local home projection over a cached visitor snapshot; do not establish foreign admissions, enumerate private channels or infer presence. Reuse more recent live contact/channel projections immediately. Refresh only nickname and optional picture for matching domain, account ID and username, including cleared labels/pictures; retain saved channel context, Recent encounter timestamps, unread state and identity/device trust. Apply refreshed names to filtering, labels and actions consistently. Last-seen context remains a snapshot.

Configuration: fixed client interval 86,400,000 ms, retry delay 300,000 ms after failed requests, overdue check every 60,000 ms plus focus/online events to catch sleeping/offline clients. No user preference or server override. Batch size follows SPEC-008. Requests run outside chat/voice polling, never overlap within a refresh scope, and abort/ignore late responses after account/service/login changes. Keep cached labels on unavailable, unsupported or failed reads, retry when due, and never replace a person with a different identity. A newly known identity is eligible for its first read immediately. The directory also reloads its current search on the daily boundary; query changes retain existing debounce/pagination behavior.

Testing: unit tests exercise login/daily boundaries, newly known people, failures/retry, deduplication, batching, mismatched identity and cancellation. Real sidebar browser tests exercise server-side nickname changes, Pinned/Recent/Server Members labels and search, clear-name/picture handling, and stale response isolation.

Acceptance criteria:

- A renamed known person is displayed under the current name after login or the next daily refresh, without altering saved context or encounter time.
- Newer authorized live projections update matching rows immediately; failed reads retain usable cached rows.
- Background refresh does not change chat/voice cadence, create foreign memberships, expose activity or apply another account's response.

## Direct conversations and people actions (D-087/D-090)

D-087 requests Message and Call from the right sidebar and a new **Server Members** section. D-089 requires first-contact acceptance before ordinary messages or ringing. [SPEC-018](018-direct-conversations.md) is the approved shared contract under D-090. These implemented presentation rules replace SPEC-014's primary last-known-channel action; D-092 additionally removes the secondary last-channel and group buttons from these rows.

Keep **Pinned**, **Recent**, then **Server Members** in the right sidebar, with a people search field filtering the sections. Pinned remains account-wide, Recent stays client-local, and Server Members follows the selected server. Use compact qualified-identity rows; clicking a name or the message icon opens its DM, and the phone button/menu action starts an invitation subject to effective contact permission. D-147 supersedes D-092’s Friends label and red/grey hearts with **Pinned** and thumbtack toggles. Use a filled warm-amber pin and a subtle matching background/border for pinned people; inactive pins are muted outlines. All icon controls retain qualified accessible names, tooltips and keyboard focus; Pin/Unpin exposes saved state with `aria-pressed`. Update related menu actions, notices and empty-state guidance consistently. Existing `contacts/1` data and account synchronization retain their meaning; no data migration is needed. No Group or Channel button appears in these sidebar rows. D-094 stacks the qualified identity above the action icons and the existing last-seen channel/encounter context below them. Last-seen context remains a recorded snapshot, not current presence. Filter pinned people out of the displayed Recent rows and count using domain plus account ID; keep them eligible in Server Members. Preserve underlying Recent history, retention and Clear behavior so an unsaved person can reappear when their encounter is still eligible. Expose the same actions through keyboard/touch and participant context menus. Keep pinning/unpinning independent. Use the server's directory projection rather than the administrative member table or guessed channel rosters; no inferred online indicator.

D-147 activity indicators reflect this device and the selected account. Highlight the message button in lavender only while that person's loaded one-to-one transcript is displayed in Messages; clear it for the summary, group creation/group transcripts, settings, channel views or another account. Expose `aria-current="page"` and readable state text. Highlight the handset in green only for people with current voice attendance in this device's connected private direct/temporary call, with a readable “In private call” description. Ringing, connecting, invitations, remote-device calls, ordinary channels (including private channels) and channel-thread calls do not activate it. Clear it on departure/disconnection or account mismatch; it can remain active while a different text workspace is open. Use full domain/account identity, never name matching or a saved last-seen room. Keep unread indicators separate, and use a filled handset/border alongside colour. These buttons retain their existing navigation/invitation actions; they are not disconnect toggles. Forced colours retain a visible active border and filled/outline distinction without animation.

Add a **Messages** workspace reachable independently of the selected server. It lists accepted DMs, contact requests, active temporary groups and eligible retained group transcripts. A local unread badge means locally unseen content, not a receipt sent to the other participant. Selecting a DM does not change the selected community or active voice target. Keep draft/history/async responses scoped to the full account, conversation authority and ID. A visible active temporary-group entry remains available while viewing other text. Ended groups show read-only history and their expiry policy; a new interaction with the same group creates a separate session.

Conversation call controls offer **Call**. Under D-092, show **Add people** in that call section only once this device is connected to the selected accepted call; hide it before connection, while ringing, after the call ends and when another device owns the call. This replaces the unconditional header action. The standalone Messages group-creation entry and participant context-menu actions remain available. The picker searches Pinned, Recent and selected Server Members, deduplicates qualified identities and supports exact account-address entry through authenticated discovery. Selected people appear as removable chips with a participant preview. From a DM, the primary action is **Start temporary group**; from a group it is **Invite people**. Show that earlier DM text stays private. Creating a group from a connected DM keeps the current call until the user explicitly moves; explain that invitees must accept and connect to the group. Inviting into an existing group preserves its current call and requires explicit acceptance from newcomers. Show the group's retention value to creator/invitees; SPEC-018 owns its schema and D-088 defaults, so the UI must not invent another limit. A normal user need not create/manage a persistent server channel for this flow.

Incoming calls show the verified caller, proposed participants and Answer/Decline without interrupting typing or starting audio. If voice is already active elsewhere, **Move to this call** is explicit; present ringing on signed-in devices and dismiss it when another device answers. Browser/autoplay/desktop notification limitations must not produce a false ringing/answered state. A same-host foreign move can leave a destination shutdown fence after the home fence clears. The pending explicit join retries only `409 voice_moving`, at 250 ms intervals for at most the existing SPEC-004 hard-mute window. Every retry checks cancellation and still requires server admission; other failures are not retried. This is transient connection handling, not a setting or authority extension. The voice dock keeps PTT, current destination, connection details and Leave visible. Direct routing and relay-only preference remain SPEC-017's. This increment uses visible in-app incoming invitations, including when another text workspace is selected; it does not add an alert sound or OS notification service.

D-089 selects first-contact requests. The UI for opening a new DM offers **Request conversation** and a clear pending state; do not send its draft or ring until accepted. Block/decline and unavailable-service states use authoritative safe responses. The Block action explains any effect on the current direct/temporary call. On narrow layouts, all three people sections and Messages remain available through ordinary disclosures, without focus traps or horizontal page overflow.

Client test and acceptance additions are in SPEC-018. In particular verify access labels against public/private settings independently of encryption, labels in both appearance modes and forced colours, stacked identity/action/context order, Pinned exclusion from Recent without exclusion from Server Members, name/message-icon versus phone-icon actions, filled/outline pin state and accessible labels, absence of sidebar Group/Channel controls, Add people appearing only in the connected call, cross-server/account identity isolation, no earlier text on Add people, retained read-only temporary history, keyboard/touch access, simultaneous device answer and no automatic voice movement.

## Server and channel PTT settings (D-095)

The server owner can edit the server duration in Server settings. Channel settings and voice/combined channel creation offer **Use server PTT limit**, initially selected for an inherited/new channel, and an explicit seconds field when unchecked. Show the resolved server/effective duration. Saving null restores inheritance; retain failed drafts and existing permissions/stale-revision handling. Gate inheritance controls on `ptt-inheritance/1`; older servers retain their numeric room-setting workflow. SPEC-004 owns values and live-transmission rules; SPEC-012 owns migration/wire metadata.

## Account creation clarity (D-186)

Owner setup, invitation signup, public signup and creation on another service require a second **Retype password** field with new-password autocomplete. Validate exact equality locally before creating/persisting pending account keys or sending any registration request; never submit or persist the repeated value. Show an accessible mismatch error, allow correction, and clear it with the creation credentials on success, cancellation, service/account-flow changes. Existing sign-in, renewal, QR linking and recovery do not ask for repetition.

Use **Create account** as the explicit signup action, name the selected identity service and show the prospective qualified address. Show username/password guidance from the existing protocol policy; owner bootstrap remains a distinct setup action. When the connected server permits local registration, expose direct account creation and do not require an invitation. When closed, explain that an account invitation is required. Pasted bound invitations still select their canonical username and must match the selected service. Public registration uses the existing challenge/proof contract; this presentation does not open a closed server or bypass approval for existing accounts on new devices.

Configuration: no new persisted setting or operator policy. Confirmation is transient form state only; SPEC-003/009/015 own authentication and service selection.

Testing: browser checks exercise mismatch/match, keyboard submission, cleared/cancelled state, invite-bound names, open/closed signup guidance, owner setup and registration on another service. Assert mismatch sends no registration/key-generation request and sign-in remains one password.

Acceptance criteria:

- Every creation flow requires matching passwords before local pending-key persistence or network registration.
- Public registration is reachable directly when permitted; the form names the service/address and clearly distinguishes existing-account sign-in from creation.

## Personal listening volume presentation (D-187)

Display **Volume for me** as 0–400%, with 100% normal and Reset volume restoring 100%. A 0% slider value is exact silence independent of the retained Mute for me toggle. Use one-percentage-point steps, readable percent output and accessible value text; the value survives reconnect in its existing qualified local account/device scope. SPEC-004 owns conversion, storage compatibility, shared baseline composition and output limits. Apply the same control in both channel member and voice-participant contexts. Tests exercise endpoints, reset, muted/zero behavior, persisted legacy values and listener isolation.

Native conversation-summary validation is independent of the displayed Home view. Validate every summary against its original checked endpoint pin and qualified account, retain the existing type/membership/retention/call bounds, and require a direct pair's canonical authority domain under SPEC-018. Temporary groups keep their original checked authority after ownership transfer. A summary alone supplies no connection, membership or media permission. The existing Home-only controller retains its current restriction until the foreign conversation gateway is connected; the shared validator supports that gateway without weakening endpoint verification.

An explicit native private-conversation open may create a missing Host connection through the distinct conversation-purpose admission above. Persist the complete validated session atomically as conversation-only before publishing its locator, with no provisional ordinary-server record, text selection, history load or call. Reuse an existing valid retained Host session through the immutable borrower instead of rotating its credential, including an existing ordinary-server session. Changed saved authority, concurrent admission, cancellation, missing Home approval and failed protected persistence cannot publish a later locator; signed-out or invalid retained sessions require their explicit reconnection path. These are SPEC-018's existing scoped connection rules. Canonical conversation operations and text/call UI remain separately required.

A native conversation controller may borrow an existing admitted visitor endpoint without selecting its ordinary text view, fetching transcript history, obtaining another grant or rotating credentials. Freeze the original retained account/device, full Host pin and saved login; publicly recheck the direct-conversations capability and deliver the same immutable session only while that snapshot remains current. Cancellation, changed pin/login/account, missing admission, signed-out state, failed capability verification or timeout cannot deliver a later or replacement credential. Reuse the existing 15-second preparation and 32-job bounds, exclusive connection writer and Host proof/expiry checks; public verification shares one lazily created workspace transport. Reusing an uninitialized saved session coalesces its account-owned public/session checks; an ended requesting owner receives no endpoint and cannot cause later selection or credential replacement. The borrowed session retains its original API after subsequent text navigation; credential retirement fails that session rather than borrowing a new one. Home endpoints remain owned by the account's Home client. This is an internal ownership seam for SPEC-018, without new persistence, privilege or automatic admission.

Native saved visitor state may retain `conversationOnly` as a boolean operational scope marker; omission means ordinary state for compatibility. A Home record cannot be conversation-only. Keep its fixed account/server/session, drafts and exact pending data in the protected store with the existing exclusive writer and bounds. Credential-free metadata may expose this marker, but ordinary browsing projections, Servers navigation, selection and background ordinary-channel reads exclude it. A private conversation connection cannot become an ordinary browsing selection just because its session exists. Only the existing explicit ordinary-server admission path may promote its scope after policy checks; a local marker grants no remote permission. A first ordinary admission/promotion adopts the verified returned public landing channel when present under SPEC-015, rather than carrying a conversation-only placeholder into ordinary browsing; an existing ordinary Rejoin retains its selected channel. Canonical foreign-conversation controller and adoption of these records remain separately required.

Native cross-domain direct/group access begins with distinct purpose-bound conversation admission. Reuse the fixed Home/account/device and publicly reverified destination, directory delegation, signed login and existing 45-second admission/32-job bounds; send the distinct direct-connect proof to `/direct/connect`. Require the advertised direct-conversations capability after public verification. Ordinary server admission remains a separate explicit action; new conversation-only sessions grant no ordinary channel, member-directory, administration or media access by themselves. Cancellation, changed authority, malformed grant/proof/login and Home authority loss preserve the existing account/device keys. This is the existing SPEC-018 engineering profile, not a public-admission bypass or full foreign-conversation delivery claim. Durable conversation-only records, canonical direct/group control, text and call integration remain separately required.

Native **Join as** uses a standard channel-context account menu and applies D-126 immediately: retain the exact server/channel, authenticate/admit the chosen identity if needed, prepare membership, then commit the permitted view atomically. Capture voice continuation only for an ordinary active call in that exact full server identity and channel. Bind it to that call object and attendance; a changed/ended call, cancelled chooser, superseded selection, denied membership or failed selection write cancels continuation. Successful selection keeps all account content separate and may replace only that captured call. Choosing its existing qualified identity preserves voice without toggling it. A call in another channel/server is unchanged. A replacement uses the chosen identity's existing Home movement checks, fresh input and failure status; it never restores a revoked attendance automatically. Explicit Open channel as remains text-only. The chooser retains these same semantics through required authentication. This is the approved D-126 port, not a new behavior choice.

Native prepared channel membership uses the chosen account's verified permission-filtered room list and exact ordinary-channel state, without publishing a provisional text destination. Already admitted channels require no mutation. Otherwise check join eligibility and retain the exact ticket, target room, revision and empty `room.join` payload before dispatch, using the existing one-unresolved-command limit. Cancellation before dispatch cannot send a later command. After dispatch the account/connection owns result persistence independently of the initiating chooser; closure prevents late selection or voice continuation. A lost reply retains that exact operation for explicit retry, without generating a replacement ticket or selecting its target. Retain the previous text room/direct view separately from the membership command's target through restart. Reconcile it before further mutation or credential replacement. Successful membership alone cannot move voice; the checked permitted text view and atomic selection commit still precede D-126 continuation. This ports existing membership, prepared-selection and pending-operation rules; no new permission, default or retry policy is introduced.

Native explicit cross-source call movement is owned by one call runtime, independently of the text selection. It retains the current immutable context and creates at most one pending target context. Bind each confirmation to the original attendance and target generation; cancellation before an accepted authority change preserves the old call and its held input. When the checked Home move/claim acknowledges revocation of that exact old attendance, stop its local input immediately and observe the existing fence. A different account's old local call ends when the replacement is ready; the replacement starts with fresh input and its own account preferences. A changed or ended original attendance before commitment cancels continuation. Failure after revocation leaves voice stopped, without restoring or rearming the old call. Unknown direct-command results remain owned until reconciled, including after cancellation. Automatic D-126 Join-as and its prepared membership/selection remain separate required work. This implements the existing explicit-movement contracts without configuration or permission changes.

The native window binds its media/controller lifetime to the exact retained call connection, independently of the displayed text connection. From an idle local controller it can join a verified admitted foreign ordinary channel through that context. Show the actual call account and server, retain its input/listening ownership through text/account navigation, and route Leave and named sign-out only to that call. An explicit connection ending is ordinary disconnection status, not an extra failure alert. These controls use the cross-source call runtime and D-126 continuation defined above; complete native parity and platform qualification remain required before replacement delivery.

For a context-bound Home call on a federation-capable authority, use the same fixed state/Home-slot inspection so an existing foreign attendance is visible. An approved move to Home uses the existing Home `/voice/move` operation and monotonic bounded fence before local admission. Closed single-server authorities retain their existing local inspection path; an advertised federation failure is not an authentication fallback. Direct/group invitation checks remain Home-owned and exact-call-bound. Both movement directions preserve cancellation before authority is changed and require fresh input after movement.

A foreign ordinary-channel call intent first checks its frozen Host state and the account's current verified Home voice slot. Only admitted, voice-capable ordinary channels qualify. An existing live slot requires the existing explicit move confirmation for its exact observed attendance; recheck after confirmation and require renewed review if that ID changed. Declining/cancelling before claim preserves the original call and capture state. The Home claim performs the existing cross-host fence; the new attendance still requires fresh input. Foreign controllers cannot issue Home direct-conversation commands for a matching unqualified room UUID. These are the existing SPEC-011/015 call-movement rules; the native call runtime owns local orchestration and D-126 identity continuation follows the rules above.

Native media may be constructed against that immutable call context. Foreign joins require the verified Home reservation and existing movement fence before opening the audio pipeline; carry its exact call UUID to Host admission and reject a different returned attendance. Route preparation, join, renewal and bounded cleanup through the frozen Host session. Cancellation immediately stops the reservation and local pipeline, with existing Home release/Host cleanup bounds. Losing the context cannot fall back to the currently selected Home or another connection. Existing encryption, trust, codec, lease-expiry, PTT/VAD and fresh-input gates remain unchanged. Production navigation/call-controller wiring and two-authority relay tests remain acceptance gates.

Native call control freezes its retained profile/connection, server pin and approved device independently of the mutable text workspace. A foreign call retains its original admitted destination session while a later text Rejoin replaces the browsing controller. If the Host retires that original token, its 401 ends the matching context under the existing session-expiry contract; never borrow the new browsing credential or resume voice automatically. Preparation for other views preserves a still-authorized call. Explicit sign-out of that named connection, account authority loss or workspace destruction ends the matching context. Read only `/state` for target voice eligibility and the verified Home voice slot for movement; a legacy single-service Home without visitor federation reads its own slot through server-level sync, which omits transcript history; do not fetch transcript history to inspect a call. Owner-bound state/control requests and bounded cleanup keep their frozen recipient after text navigation. State/Home-slot reads have a fixed 3000 ms deadline, ordinary voice control retains the existing 15000 ms transport bound, and detached cleanup has a fixed 3000 ms deadline. No call or capture starts merely by constructing a context. This implements the existing independent-call/prepared-selection requirements; production call wiring and relay validation remain required.

Native destination voice control uses a separate serial HTTP/1.1 transport within the same fixed server connection, created only on first use. It shares the ordinary connection's bounded pending set, public-authority verification, exact login/device/room proof, expiry checks and owner cancellation. Only destination `/voice/` requests use this path; ordinary requests retain their current transport. No retry, deadline, credential or permission change is introduced. This is a transport seam for the remaining foreign-call integration, not a declaration of completed foreign media.

Native cross-host voice preparation uses the existing SPEC-015 Home reservation contract in a separate account/device/server-bound module. It sends a fresh call UUID and only the observed previous call when moving; reservation alone cannot capture audio or join the destination. Renew without overlap every 1000 ms with a 3000 ms request deadline, including while waiting for the existing movement fence. Check the returned call/device/server and integer attendance/fence timestamps, reject substitutions, clock rollback and expired replies, and require a fresh renewal after the monotonic fence before readiness. Cancellation stops local readiness immediately and sends bounded best-effort Home release through the retained account; unavailable cleanup remains subject to the existing server attendance timeout. Home renewal records its renewal/expiry timestamps separately: tolerate only processing/one-millisecond rounding within the observed response duration, capped by the existing request bound, while the local attendance deadline remains at most request-start plus 15000 ms. These reuse SPEC-015/006/011 values and add no setting. Production call integration and destination/relay validation remain delivery requirements.

## Personal PTT and speech sensitivity (D-105)

User settings always exposes **Always use push to talk** (`pttEnabled`) and speech sensitivity (`voiceActivationThresholdDb`) inside **Push-to-talk configuration**, above the binding controls, including when disconnected (D-112). Use the canonical types, defaults and validation in SPEC-004 Configuration. They persist in the encrypted local account/device profile alongside existing input preferences, without syncing through profile/history/recovery. Administrators cannot write them. Label lower thresholds as more sensitive. D-188 supersedes explicit save: apply each checkbox/sensitivity edit immediately to the account's active call, stop prior transmission using existing fresh-input gates, and enqueue protected local persistence automatically. Remove the Save microphone mode button. Keep controls usable while writes are pending, serialize writes so the latest selection wins, and report Saving/Saved only for the current selection. A failed write retains the selection, clearly reports it was not saved and offers Retry; later edits retry automatically. Do not let an old completion overwrite another account's UI or report an obsolete selection saved. Existing protected vault writes remain account-scoped and survive closing settings; cancellation/unmount does not silently drop an already edited preference. No initialization write or new setting is introduced. Unit/browser checks cover rapid edits, pending/failure/retry, account changes, reload persistence and live-mode safety.

Server settings exposes mandatory/optional PTT and channel settings exposes Inherit / Mandatory / Optional, with resolved status; gate new controls by `ptt-policy/1`. Keep local PTT available in every policy. When voice activation is selected and permitted, the dock offers **Enable voice activation** / **Disable voice activation**, with explicit listening/transmitting state, no required keyboard/mouse binding and the existing browser focus boundary. SPEC-004 owns detection/gating and SPEC-012 owns wire semantics. Policy or account changes cannot arm activation. After desktop lock/suspend, offer **Re-enable microphone input** for voice activation; D-113 uses the disabled-PTT notice and held on-screen fallback for PTT; re-enabling input does not itself arm speech detection.

## Profile pictures (D-096)

SPEC-019/D-096 owns the profile-picture contract. User settings offers upload, crop position/zoom, circular preview, save/cancel and removal. Render 56-CSS-pixel circular thumbnails at 100% UI scale (D-100) beside sidebar people, with initials fallback and unchanged qualified names. Decode and crop locally, send only the canonical thumbnail, and preserve drafts on profile conflicts. Use verified home discovery for foreign references without credentials; no external image URLs or persistent image-byte cache.

## Unexpected voice disconnection (D-098)

Preserve the existing no-automatic-rejoin behavior and media authority deadlines. An unexpected end or failed connection creates a prominent `role=alert` notice with the original channel, local event time and available reason. Distinguish server/relay renewal timeouts, server rejection, network failure, home reservation loss, call expiry and transport loss; when no reason is available say so rather than infer a cause. Keep the notice through ordinary polling and workspace navigation until explicit dismissal or a fresh connection attempt. Give manual Join voice/reopen-call guidance. Ordinary Leave, cancellation, sign-out, connection removal and intentional call movement do not create a failure alert. Authentication expiry must retain its specific reason rather than silently calling ordinary Leave. Keep one current failure in memory, without tokens, SDP, IP addresses or an additional diagnostic persistence setting. Existing small status text and local aggregate connection details remain available.

Unit coverage checks reason classification, one notice per failed session, timestamp/channel retention, dismissal, fresh-attempt reset and no alert on intentional leave. Browser coverage checks the persistent alert during an injected control timeout and access to existing manual reconnect controls. Real unexplained disconnections require actual client/server observations; simulated failures do not establish their cause.

Renewal scheduling must not skip a whole interval merely because a previous renewal took longer than the nominal 1000 ms cadence. Serialize the complete control response and relay acknowledgement, then wait only the remainder of that cadence; an overdue next attempt runs on the next event-loop turn. Do not overlap renewals or accumulate missed timer ticks. Leaving cancels the schedule, and a late response after intentional closure cannot increment active-call failure diagnostics or create an unexpected-disconnection notice. This is a client scheduling correction; SPEC-003/017 authority deadlines, packet gates, generation closure and explicit-rejoin rules remain unchanged.

## Voice audio cues

D-097/R-103: implement the four profile sound controls, revision-safe drafts, previews and local voice/PTT cues in SPEC-020. Use home-account preferences for the active call, independent of the currently browsed server. SPEC-020 owns defaults and event/synthesis rules.

Public server/channel menus and Add server implement SPEC-015 public join links (D-115), including persisted pending roots, permission-filtered text navigation and explicit separate voice.

D-138: implement the owner confirmation, public channel-link settings and missing-default/empty-server navigation defined by SPEC-012/015. Purge deleted-channel local workspace state and preserve independent active voice. D-139: replace the channel tree’s Voice here text with a compact handset icon, with Voice here as tooltip and accessible label. No new configuration defaults apply.

## Public usability increment (D-172–D-180)

The human requests the reviewed client outcomes in [the 2026-10-27 increment](reviews/2026-10-27-public-usability-operations.md): pinned comments with conditional service notices; optional bottom-right statistics and admin aggregates; channel handset actions; opt-in low-friction public mode retaining channel encryption; left-hand User settings categories; recording-only PTT suppression; seamless held-input continuation when participants join; Wine/Proton application audio; directory discovery and published-update offers. Implement against SPEC-013/016/021 and server/discovery contracts. This section supersedes D-141's no-tabs rule and settings-wide microphone suppression only within D-176. Recorder/focus/lock/moderation protections remain. Technical completion and test evidence are recorded in the increment review; delivery is not implied by this requirement entry.

## Published update offers (D-180)

The Qt successor uses a standard status-bar notice with explicit Get update and Later buttons. Its production reader has the fixed official manifest URL and the D-180 anonymous transport, deadline and response bounds below; test readers are C++ fixtures only. Get update opens the official download page through the desktop URL handler. Keep Portage installations under package-manager control. A missing or unsupported development version produces only the available-download wording. The notice has no account, capture or call authority.

Native clients check the anonymous, CORS-readable `https://www.sloppyvoice.com/releases.json` at startup and hourly while running, with a ten-second timeout and 20000-character response bound. The endpoint is generated from the same validated manifests as the download page. Compare numeric semantic/alpha versions, including Android build suffixes, rather than lexical strings. Validate platform/format, exact version-derived filename and release path, HTTPS destination, positive bounded size and SHA-256 metadata. Ignore invalid/unavailable results without disturbing calls. Later dismisses that offered version for the current run; a newer version can be offered. Existing native shells lacking version metadata display an available-download notice without claiming the installed version is outdated. Windows installer/portable, Linux archive/Flatpak and Android APK use their corresponding manifests; iOS remains on its TestFlight delivery path. The update offer opens the official download/install flow on explicit action and never overwrites a package-manager installation or restarts a call automatically. These fixed check intervals and bounds are implementation constants, not user configuration.

## Pinned channel comments (D-172)

Clients render the SPEC-013 pin above conditional status notices, expose verified-message Pin/Unpin only to local owner/moderators, authenticate the moderator assertion and automatically copy it to currently approved member devices. A missing encrypted delivery shows waiting and retries without approval. The pin grants no ordinary history or thread-call eligibility.

Native fixed conversation session engineering profile (SPEC-018/D-196): a session retains its original Home account generation and approved device, checked conversation Host, composite connection ID and optional original visitor API. Home operations use the guarded Home API; foreign operations use only that retained visitor API. Navigation cannot retarget either. Owner-scoped requests are bounded to 32 with a fixed 15000 ms total monotonic deadline; owner destruction cancels delivery and Home loss or original-session 401 retires the context. Opening validates canonical pair authority; view/list/operation replies validate their original Host/account and exact room. Existing direct operation ID/time/action/payload and message ticket/revision/envelope are dispatched unchanged without automatic retry. Typed history reads require accepted/eligible membership, retain the existing 250-message bound and authenticate every message against its exact Host/room/conversation. Encrypted sends verify the own signature and exact approved recipient set; no plaintext or recipient omission is accepted. Account policy/block and new group creation remain Home responsibilities. Conversation room state must be e2ee, combined, bound to its exact Host/room/kind/retention and approved own device; participant rosters must verify and belong to the summary. No new user setting or wire default is introduced. Protected command orchestration and UI integration remain required subsequent work.

Native foreign conversation integration (SPEC-018/D-196): resolve the canonical pair domain or an existing group's retained Host through public discovery and the saved full pin, reuse/create its scoped private connection, and prepare its view before committing the existing Home-owned conversation workspace. The sole account writer retains foreign pending operations with exact connection ID, checked Host, original credential digest, conversation summary and encrypted-state snapshot; this adds no private key copy or second profile writer. Save before dispatch; unknown outcomes survive restart and exact explicit Retry uses the original session only. Automatic session replacement cannot reconcile the old operation, and ordinary replacement/sign-out remains blocked while that account owns a pending operation for it. Revision 0.124 below supersedes this restriction only for explicit, checked conversation-session recovery with atomic credential adoption; active calls retain their original immutable session and are ended before recovery. Text navigation, drafts and call attendance remain independent. Home-only policy/new-group operations retain their Home route. This integration is not itself screen/media/migration/package completion.

Native foreign inbox/presence engineering profile (SPEC-018/D-196): the Home inbox remains authoritative for blocks and authenticated foreign notices. Treat a notice as a locator until its full Host is publicly checked and its scoped conversation list is read; never use it to select text, admit membership, start capture or replace credentials. Include retained conversation-only connections and already opened private endpoints. One account batch runs at a time with at most four concurrent Host preparations/list reads; each uses the existing owner-bound endpoint deadlines and account generation, with a fixed 45000 ms total monotonic deadline. Original context ending finishes that read once and cannot strand the batch. Preserve cached summaries on a failed Host read, replace only that exact Host's successful result, retain newer checked revisions and key all groups by Host UUID plus room UUID. Prioritize active context/ringing locators before remaining sources. Existing joined-group presence follows that same frozen Host endpoint independently of text navigation; restart requires explicit rejoin and a closed/departed group stops presence and clears only its qualified draft. No new user setting, permission or wire default is introduced.

Native foreign conversation call integration (SPEC-018/D-196): select the saved connection from the checked conversation's Host and qualified account, independently of the ordinary server/text selection. Invitation control and completion events require that exact Host plus room, and group liveness is checked in the same qualified scope. Reuse the existing immutable voice context, Home reservation, explicit movement confirmation/fence, E2EE recipient/voice-key gates and fresh input requirements. Ring/decline performs no capture. Text/account navigation and unrelated same-numbered conversation updates cannot retarget an active call. Actual cross-authority DM and temporary-group fixtures must use encrypted audio through the real relay before this path is qualified. No new call policy, user setting or automatic answering/reconnection is introduced.

Native cross-authority group invitation preparation (SPEC-018/D-196): freeze the originating account/device, target group's exact Host/ID (or creator Home for a new group), selected qualified people and fixed retention. Obtain each existing accepted direct pair at its canonical authority, request its existing capability bound to the exact group Host, validate the returned capability authority/token, and only then persist/dispatch the immutable group command at that Host. Reuse valid saved private sessions and existing Home routes; do not route through the displayed text endpoint. One account-owned preparation runs at a time with a fixed 45000 ms total monotonic deadline and existing per-request bounds. Account/device loss, timeout, changed/ended group or failed capability stops preparation without a partial group mutation or navigation/call change. Acquired unused capabilities expire under the server contract. Group creation remains creator-Home owned; invited accounts still accept explicitly, get no earlier transcript and never join voice through invitation. No new user setting, server permission or wire default is introduced.

Native explicit conversation-session recovery (SPEC-015/018, D-196): match the existing browser Reconnect conversation service action using the original saved qualified account, same approved operational device and exact publicly reverified Host. The user explicitly invokes recovery; never change Home keys/sign-in, create ordinary membership, select text, answer/rejoin voice or automatically retry a pending command. End contexts using the old credential before recovery. Use purpose-bound conversation admission and retain the connection's private/ordinary scope, drafts, cursors and exact pending commands. Atomically save the renewed visitor login plus the matching Home-owned pending operation's credential digest in the sole protected root, while preserving its command ID/ticket/time/action/payload, Host/room and state snapshot. Require the old binding and same account/device/Host; changed identity/pin/device or failed persistence leaves all saved data intact. Existing held media never adopts the new credential. Only a later explicit Retry dispatches the unchanged retained operation with the renewed authorization. This supersedes the 0.120 engineering prohibition on explicit same-binding recovery, not its ban on automatic credential handover. Use existing bounded admission/cancellation contracts and a standard modeless account-qualified dialog accessible from Direct Messages. No new user setting or wire profile is added.

Native profile editing (SPEC-019/D-196/D-198): use standard modeless Preferences with native category tabs and controls for the current qualified Home account, independent of displayed foreign text and active call ownership. Reuse the self-only ticketed `account.profile` command, optimistic profile revision and exact protected command reconciliation. Preserve nickname/crop drafts on conflicts; require explicit review before rebasing an edit. Picture source selection, square position/zoom and circular preview obey SPEC-019; strip source metadata and upload only its bounded canonical thumbnail. Profile refresh and saves never select a channel, join membership, rotate identity keys or alter media/input. Capture the originating account/device in each editor and cancel undispatched work when it closes or that account ends. No new wire profile, setting or permission is introduced.

Native profile picture presentation (SPEC-019/D-198): display compact circular pictures/initials using the desktop style icon metrics in native person rows. Load only pictures requested by visible native item painting, resolve foreign Home domains through checked public discovery, and fetch the exact current UUID resource anonymously with no credentials, referrers or redirects. Validate the complete canonical PNG before decoding. Use an account-bound transient cache of scaled icons, with at most four concurrent discovery/image reads and a fixed 2097152-byte icon budget; failures retain the neutral initials fallback and never block text or voice. Cancel outstanding reads and clear the cache when the account/device session changes. All native HTTP deliveries explicitly fence owner destruction before aborting the request; a Qt widget destruction signal can precede clearing its QObject pointer, so a canceled synchronous completion cannot call into partially destroyed widgets. No image bytes enter contacts, history or protected identity projections; no new user preference or server configuration is added.

Native voice cue port (SPEC-020/D-196): reuse the existing four account-wide switches, shared volume, explicit revision-checked profile save, silent initial/stale attendance baseline and actual PTT-gate transitions. Compare qualified live voice accounts rather than devices or saved channel membership. Synthesize the existing short sine-wave shapes locally, with no sound assets or network reads. Cues and previews use playback only and cannot enter capture or outgoing media; failures never interrupt voice or visual controls. Keep the active call bound to its owning account settings through independent text/account navigation. Use 16000-Hz mono PCM for local synthesis, one output worker only while cues are active, at most eight scheduled oscillators and existing system output selection. Drop newly queued cues if output startup exceeds 200 ms or the output worker stalls more than 100 ms; do not replay them after suspension. These fixed implementation bounds introduce no user setting. This ports existing behavior without selecting custom sound files or introducing new settings.

Native unread state (SPEC-018/D-104/D-198): reuse the protected client-local `directRead` map keyed by qualified account plus Host UUID and conversation UUID. Count conversations whose checked incoming-message position exceeds that account-scoped read position, retaining the existing legacy summary fallback; never treat own-only messages or group membership as another person's unread DM. Advance monotonically only through the lesser of the selected checked summary's last message and its successfully loaded eligible history cursor, after the corresponding tab is visible. Inbox/background discovery, opening a summary, another account/Host, a failed history read and hidden/closed tabs do not mark content read. Persist through the sole account writer before clearing indicators; failed saves preserve prior positions and content. Use static counts and ordinary native bold/accessibility states, with a standard conversation summary and no animation, remote read receipt or voice side effect. No new preference or protocol is introduced.

Native video-decoder engineering foundation (SPEC-023/024): decode only already authenticated, complete frames from the owning presentation context. Query installed GStreamer video decoder capabilities without claiming hardware use; unsupported formats remain unavailable. Bound pending encoded inputs to three and queued Qt picture delivery to one, validate decoded geometry against its verified header and retain original source/timing metadata. Where supported, cap an automatic or higher decoder thread setting at two while preserving an existing lower value. Stop/replacement purges the old delivery object and its queued picture storage before retiring the pipeline; a failed replacement also retires old output. No capture, network admission, permission or viewer action is provided by this decoder module. Codec-internal allocations retain SPEC-023’s stated limits of observability. These fixed resource choices add no user or server setting.

The native call area exposes Share screen and a persistent Stop sharing action while preparing or publishing, alongside the original call identity. Its standard modeless dialog retains the existing content/priority, resolution/cadence ceilings, bitrate and initially permitted-audio defaults; these per-presentation choices are not new persisted preferences. Applications is the initial sound mode. Refresh/mode changes clear selections; Start requires explicit current sound offers or disabled audio. The desktop chooser grants the sources, and incomplete source geometry is completed explicitly before publication. Closing during preparation cancels the original operation and releases consent; closing after publication leaves sharing active with the call-area Stop available. Desktop lock/suspend has a dedicated safety signal; ordinary input recording/focus/Preferences must not be mistaken for session closure. Application shutdown retires capture and reaps only its own retiring sound helpers. These port existing SPEC-023 lifecycle and D-198 presentation behavior.

Native VPX encoder target updates are coalesced through GStreamer’s asynchronous element callback, using the installed VPX runtime bitrate property. Keep the existing encoder/capture identity and dependent frame state during a target-only change; unsupported factories retain checked replacement. Qt cannot wait for an encoder’s frame lock on a regular bandwidth update. Stop invalidates the callback owner, and an old callback cannot revive a retired pipeline. Validate actual encoded/decoded output after rate changes in addition to ordinary input/output bounds.

Native outgoing-message state ports D-162/SPEC-013 using process-local records separate from protected pending commands and history cursors. A record retains submitted text, author/device, original view/channel, optional reply root/parent, envelope identity and acceptance status/sequence when known. Definite failure retains the draft; ambiguous dispatch retains the existing exact-command retry and shows Confirmation pending. Authenticated eligible history replaces a record only on envelope ID, qualified author, device and channel, never repeated text. Clear records on view/account context retirement without deleting protected drafts or retry data. Local rows do not enable reply, pin or call actions or count as canonical history. No offline queue, delivery/read receipt or configuration property is added.

Native pin maintenance runs only for the selected active text context, using its existing status refresh rather than another polling timer. Recheck current admitted membership, original channel/expiry, moderator identity trust and current approved recipient rosters. Preserve the moderator assertion unchanged when re-encrypting; submit at most 50 recipient deliveries or reject the digest of an invalid own delivery. Keep at most 32 memory-only attempt keys and retry a particular pin/recipient or rejected-delivery set no faster than SPEC-013's ten seconds. The standard pinned-comment area precedes status notices and transcript and displays author, approving moderator, verified text or explicit waiting/error. Owner/moderator Unpin uses the original revision-checked durable command; pin changes do not move voice or alter text history. No user setting is added.

Native pinned-comment authentication ports SPEC-013's channel-pin/1 and channel-pin-copy/1 profiles without expanding ordinary history. Validate the exact original channel/server/header digest, retained expiry, original author signature, historical approving moderator role and approved device, copying device signature, encrypted target and unchanged moderator-signed content. Plaintext retains SPEC-009's 4096-byte bound. Server-readable pins authenticate their original; encrypted pins explicitly wait when no valid delivery is available. The original account/Host owner must additionally enforce its existing identity trust before display or automatic copying. A pin's message is never inserted into ordinary history or treated as an eligible reply/thread target. These are existing protocol rules, with no additional configuration.

Native thread-call resolution follows SPEC-013 through the original Home or ordinary destination context, using only an authenticated eligible loaded message and the advertised thread-voice/1 capability. The fixed POST contains only that message's host sequence; it does not admit or capture. Validate the response's exact channel/root binding, distinct UUID voice room, original server/domain/access/encryption, voice-only preset and bounded derived name (256 UTF-16 code units). Private conversations and already derived rooms cannot create another thread call. A late/wrong context cannot select text or start media. UI call intent must then enter the existing original-account CallRuntime confirmation/movement/voice-admission path, retaining fresh-press PTT and independent text navigation. This introduces no new user setting, room policy or permission algorithm; lost metadata requests use the existing Host's root-idempotent resolution and cannot duplicate external media resources.

Native main-window transcripts bind the checked item view and inline replies to their original account/connection/page. Discover advanced protocols without changing selection; refresh availability on explicit reopening, and disable actions while a source is inactive, unavailable, busy or awaiting command reconciliation. Preserve reply edits through temporary empty/error history. Before sending, flush the original protected drafts, resolve the selected parent only from authenticated eligible loaded history, and reuse the existing signed/encrypted envelope, exact pending command and retry path. Known acceptance clears only matching tokens through the original owner; foreign cleanup shares the pending-command commit, while Home reports a known-sent draft-save failure and retains the edit. A restored editor can recognize its durable token. Closing a tab flushes both main and reply drafts before destroying its widgets. Known closed groups clear unsent reply drafts under the existing group contract. Thread-call/pin controls remain unavailable until their native implementations and qualification exist; the replacement remains unreleased until all applicable functions are complete.

Native reply drafts extend protected connection state with optional `replyDrafts`, initially absent, mapping the existing qualified view key to decimal root positions and `{text,parent?,token?}` records. Text remains unsent local state; parent defaults to the root when absent for legacy compatibility. New writes retain a UUID edit token, while a legacy record without one receives a fresh token on explicit restoration. Validate positive safe root/parent positions, parent at least root, canonical decimal root keys, at most 250 drafts per view, bounded view keys and a two MiB aggregate field ceiling; the enclosing vault's existing total limit still applies. Home and foreign connection owners merge coalesced changes through their existing 300 ms draft writer and flush before selection/close/send. Failed writes retain the usable editor/cache and prevent a destructive close/selection. Reply acknowledgements clear only their submitted token, including after restart; typing identical text again creates a new token. No draft text/token is sent to another service as a preference.

Native advanced-message availability comes from bounded protocol capability metadata at the original service. Home reuses its verified info; ordinary destinations and foreign canonical conversation sessions read info through their existing credential/proof/public-pin context. Validate the returned server identity/domain and at most 256 capability strings of at most 128 characters; retain only message-threads/1, thread-voice/1 and channel-pins/1. This discovers protocol availability, never membership/trust/moderation authority. Owner destruction or account/session retirement cancels the read, and metadata cannot select text or move voice. Unsupported or failed reads leave advanced actions unavailable with their safe error, preserving existing text and drafts.

The native transcript uses a standard Qt item view for SPEC-013 conversation grouping and one-level replies, with plain author/date headings, system-palette own-message distinction, exact timestamp inspection and visible relative ages. Count only loaded eligible replies. An unavailable original remains a marker without an inferred history request. Context actions and keyboard equivalents operate only on verified canonical messages under the original view's advertised capabilities. Standard inline reply editors preserve their drafts when collapsed or rebuilt; acknowledgements clear only the exact submitted edit token, and errors retain text. The standalone presentation component is bounded by the existing 250-message loaded window; it grants no account, message, voice or pin authority. Thread-call, pin, draft persistence and encrypted-send integration require their original-context application fixtures before release.

Native RTP packets retain local original-key deadline, epoch and audio-gate metadata across packetization and congestion pacing. Recheck these gates at final pacer output, including VP8 packet lists; expired, superseded or muted queued packets cannot regain authority after a later unmute. Receiver delivery applies equivalent epoch/audio generations before submitting typed protected frames. These local buffer annotations do not change the wire protocol.

A screen consumer's independent expiry/source-loss worker closes the frozen original portal session as well as retiring its graph, without waiting for Qt. A stale worker can close only its original bus/session. Ordinary consumer-graph replacement for profile changes or no audience retains consent; explicit Stop still owns full source/portal/Host teardown.

Native managed playback translates the RTP segment, pipeline clock and negotiated sink latency onto the application monotonic clock. It does not apply the native-fragment 120 ms timing profile to managed RTP. Decode only typed authenticated frames, retain at most three pending decode timings and three ready pictures within 64 MiB, and recheck original key/managed/call deadlines at display. Epoch changes purge queued pictures and sound without replacing a valid RTP connection. Presentation audio uses the existing bounded stereo mixer with one 20 ms output quantum for worker handoff; observed presentation output may anchor video, never microphone timing or a feedback loop that repeatedly delays sound. Hold the last valid picture only within its original authorization. These are fixed implementation bounds, not new user preferences.

The native call owns one combined presentation model across native and managed transports. Watch intent remains bounded to two aggregate publications, requires the original call's acknowledgement before managed allocation, and stops exact owned resources on known source/call loss. Shared embedded controls retain transient local PC-audio mute, original source scope and explicit Stop. Management and playback integration tests must cover the composed service path before enabling the managed controls in the released client.

Native managed publication retains the original acknowledged publication UUID and native source-consent deadline while selecting only the advertised managed transport; it cannot initialize native screen packets as fallback. Its fixed VP8 encoder follows native RTP bandwidth estimates under the selected/Host ceiling and the SPEC-025 video/audio reservation. Mixed PCM is encoded once at the managed 96 kbps Opus target, retaining original capture timestamps, rather than bridging through decoded Opus. No-audience or insufficient-capacity pauses retain only the original consent and cannot add sources. Known loss/expiry stops source/encoder/RTP/audio resources and backend cleanup remains independently pending until confirmed. The source and Watch viewer must pass composed current-service/private-provider scenarios before replacing the deployed Linux client.

The native managed stream owner composes the existing finite Host signaling controller, native RTP connection and per-role authenticated ciphers under one original approved source/call/publication context. Complete publisher offer/answer and subscriber offer/answer in their required order. Apply increasing revision/key contexts without recreating a valid RTP connection; reject older contexts and require a fresh video keyframe. Keep original key deadlines through queued output, gate presentation sound independently of microphone PTT, and verify every received frame before passing typed plaintext to playback. Cancellation/source/call loss ends local RTP and keys immediately while retaining exact backend cleanup semantics. A generated fake-provider/private-WebRTC composition fixture qualifies this module before capture/window integration. No new preference or provider credential is introduced.

The native managed connection attaches upstream rtpgccbwe pacing/bandwidth estimation through the documented webrtcbin auxiliary-sender interface and negotiates transport-wide RTP feedback. Encoder target estimates are coalesced to one pending Qt notification and bounded by the selected aggregate ceiling; the application remains responsible for distributing the estimate among video and sound under SPEC-025’s rate contract. Source discovery/plugin availability is not proof of useful estimation or capacity. The private runtime builds only the unchanged upstream GStreamer 0.15.4 GCC module, with MPL-2.0 notices, verified source-archive hash and checksum-pinned minimal Cargo dependencies; retain corresponding-source build material in release packaging. No Rust runtime/toolchain is required by the installed application.

Native decoder/viewer metadata distinguishes verified managed frames from native fragment headers. Managed local metadata carries the authenticated source/publication/revision/encryption/audio-clock context, actual VP8 dimensions/keyframe and original timestamp without fabricated native parts/sequence fields. The native wire parser and its limits remain unchanged. Accept at most SPEC-025’s two MiB encoded managed frame, preserve decoder queue bounds and apply the same final original-scope, picture-age and expiry gates before display. This local metadata is not a new network profile or permission grant.

Native managed RTP uses a dedicated GStreamer webrtcbin connection with fixed VP8 video and optional Opus stereo presentation audio, one shared stream identity and no capture/microphone API. Inputs/outputs remain protected sfu-frame/1 data; only the owning verified transform may supply or consume them. Native appsrc/receiver delivery queues are bounded, capture/key/managed deadlines gate final send and queued receive delivery, and an independent sleeping worker retires the RTP graph on expired managed authority even if Qt is blocked. Expiry cannot be revived. Subscriber answers constrain codec selection to this supported profile even when the provider offers other codecs first, while preserving negotiated dynamic payload numbers. Publisher offers identify each primary RTP source before capture starts, using distinct nonzero SSRCs that match the corresponding packetizer; asynchronous appsrc caps negotiation cannot omit video source identification. Negotiate bounded one/two-section SDP and gather for at most three seconds; production uses the existing fixed public STUN endpoint, while private fixtures bind loopback and disable public STUN. Codec recovery uses native RTP keyframe feedback. Provider ownership/signaling/closure, final decoded picture/audio authorization and congestion/performance evidence remain separate integration gates.

Managed Host signaling uses a separately and lazily allocated authenticated HTTP pool for Home and saved visitor sessions, retaining the original public pin, credentials, proof, account generation and room. It cannot consume the microphone serial-control pool. Only the fixed /screen/sfu route receives the existing managed 20-second control bound; other requests retain their bounds. Frozen call contexts accept the typed managed state string through their dedicated controller while ordinary room-state validation stays unchanged. Detached cleanup permits only the exact close action/connection/voice IDs under that original context. No provider path, secret or arbitrary new account authority is exposed.

Native managed control binds one original voice ID and fresh application connection UUID, with serialized create/tracks/subscriber-answer/refresh/close operations. Never automatically retry creation or replace a pending resource. Validate exact publication track names/media sections and bounded SDP; the Host resolves subscription source tracks. Anchor each at-most-30-second grant at request start, refresh by half a shortened grant or five seconds, and preserve the original deadline on transient refresh failure. Hold refresh through the subscriber’s fixed 20-second answer window. Cancellation immediately removes local authority, waits for an outstanding allocation result and closes any late allocation under the same ID. Closing/lost/uncertain responses retain cleanup pending until an exact Host response confirms closed; backend reconciliation and movement fences remain authoritative. These fixed SPEC-025 bounds add no user settings and require independent fake-control and current-service qualification before use.

Native managed VP8 packetization uses an in-process GStreamer RTPBasePayload extension because the installed VP8 payloader parses entropy-coded fields which sfu-frame/1 deliberately encrypts. Use RFC 7741’s standard partition-agnostic mode, one frame per RTP timestamp, a 15-bit picture ID, first-packet S and final-packet marker; never rewrite authenticated codec bytes or parse encrypted partitions. GStreamer owns RTP sequencing/timestamping and the WebRTC media stack retains congestion/retransmission/feedback. The extension has no socket, custom application fragments, key or permission state. Bound original/protected frames to SPEC-025 and preserve the configured native MTU, including extension headroom. Actual VP8 encode → protected RTP → standard depayloader → verified decrypt → decoded pixels is an integration gate, distinct from provider signaling/closure and live compatibility.

The native managed transform receives memory-only copies of the already acknowledged ephemeral sender-media keys through the existing VoiceKeys owner, matching the transitional SPEC-025 adapter. Export only advertised, activated, unexpired keys for a currently required source, ordered newest generation first, intersecting original retirement/expiry and the five-minute maximum. Own copies come from ephemeral media secrets; received copies come from verified sender distribution. Empty/changed authority returns no keys. Recovery and static identity-box secrets are never transform key material. Original cipher deadlines remain authoritative across refresh. This is the accepted stricter transitional native-key dependency, not completion of independent managed epochs.

Native managed-frame authentication ports the exact SPEC-025 sfu-frame/1 contract independently of RTP signaling or capture. Bind the canonical immutable source/publication/role/revision/encryption/audio-clock context, preserve the VP8/Opus codec prefix, sign every protected frame and use only acknowledged ephemeral media keys. Keep original key deadlines, the 512-key history bound and the 2,048-counter replay window; invalid signatures, decoded media, changed contexts and expired keys cannot advance usable replay state or publish plaintext. The module supplies no managed permission, provider connection or transport fallback. Native/browser bidirectional fixtures and sanitizer checks qualify this boundary before RTP integration.

Native presentation composition belongs to the original call/account/device/Host. The source chooser uses standard controls and explicit portal consent; incomplete multi-source geometry requires explicit layout completion. Prepare settings and selected sound offers before starting the original Host publication, then start capture only after its acknowledged current grant. Feed consented raw frames through the checked common codec/profile and its current rendition targets; preserve aggregate pacing and original timestamps. Drop old queued capture/encode/mix output across membership/key epochs, with a fresh keyframe before new video. Stop, call/account/desktop-session closure, any selected source loss and expired authority retire all owning media/portal resources without automatic recapture. Independent text/account navigation, ordinary Preferences and microphone settings cannot retarget or end a valid presentation. Managed capability selects its separate RTP path; no native/plaintext fallback is allowed. Composition and visible Share/Stop controls require complete generated relay/portal/audio validation before release.

Native presentation-sound mixing retains the existing common 48 kHz capture timeline, ten bounded 10 ms packets per selected source, explicit source allowlist, 40 ms application/80 ms filtered-output alignment and final stereo clamp. Preserve sample continuity across small timestamp jitter and dropped packet sequence gaps; source queues cannot grow with stalled consumers. Generate at most one current 20 ms block per timer tick, skipping obsolete work after a scheduler interruption. The native Opus boundary uses the existing music/audio 128 kbps, complexity-five, constrained-VBR and non-DTX profile. Managed RTP consumes the raw mixed PCM directly; it cannot use an Opus encode/decode bridge. These are ports of existing fixed media behavior, not new user settings or a microphone path.

Native application/PC-audio integration reuses the existing C helper and its PID-tree exclusion, PipeWire-instance/serial binding, explicit source selection, fixed PCM framing and source-loss rules. Compile this client's helper with a 1,000 ms heartbeat lease while preserving the legacy build's existing bound. Renew every 250 ms only when the owning native grant has more than 1,100 ms remaining; otherwise retire the source. This conservative remaining-validity check prevents a blocked Qt loop from extending capture past its existing grant and is not a permission extension or user setting. Inventory remains an explicit bounded operation; opaque source offers expire after 60 seconds and cannot survive owner/call closure. Selected-source kinds cannot be mixed, no microphone/default-source fallback is permitted, and late helper output is discarded.

Native consented capture reads only the checked PipeWire remote descriptor and selected node IDs, never a default video device or ambient server. Validate the completed composite layout, scale to the selected bounded output profile and retain at most one queued raw Qt frame, with one buffer per source queue. Combined scale/colour conversion uses one worker per source and the compositor is capped at two blending workers, avoiding its automatic processor-count expansion. Derive capture timestamps from the live pipeline clock into the client monotonic timeline. An independent sleeping expiry monitor retires the capture pipeline on expired authority or any selected source's EOS/error even if the Qt thread is blocked; main-thread delivery checks authority again. Original call/consent closure stops every source. No expiry, late result or stopped source can silently restart capture. Tests use private synthetic PipeWire nodes; physical capture evidence remains separate.

Native raw-frame encoding retains the owning capture timestamp/context through a bounded GStreamer pipeline. Probe supported actual codec/factory configurations, prefer available hardware implementations before compatible software fallback, preserve selected width/cadence/rate ceilings and treat plugin/driver hints as distinct from measured GPU use. Bound queued raw inputs to two and queued encoded Qt output to two within the existing sender residence rules. Encoder stop/replacement purges queued delivery and pending metadata before retiring its pipeline. Read keyframe flags from actual encoded output, request recovery and the existing native periodic keyframes, and never label a delta as a keyframe. Property units and low-latency settings follow the selected plugin's public interface; unsupported configurations remain unavailable. Encoding opens no desktop/camera/microphone or network endpoint and cannot authorize publication.

Native screen consent uses only the desktop ScreenCast portal after an explicit source-selection action. Query the installed portal's source/cursor capabilities, select displays/windows without remote input, and request multiple sources with non-persistent permissions and no restore token. Bind its exact generated session path, monitor Closed/service loss, validate at most eight unique PipeWire node IDs and bounded optional geometry, then obtain only that session's PipeWire descriptor. Portal positions/sizes are compositor coordinates, not proof of pixel geometry. Missing multi-source layout requires the existing explicit layout completion before publication. Cancellation, original owner/call closure and late replies cannot reopen consent or obtain a new source. This consent module alone does not start encoding or claim physical capture qualification.

Native encoder/profile adaptation ports the existing SPEC-023/024 defaults, resolution/cadence ceilings, monotonic capture scheduling, burst-deduplicated pressure, progress-gated recovery, bounded failed-trial rollback and least-pressured current receiver feedback. A permission pause is not evidence of workload pressure. Receiver feedback reports only currently authorized watched streams. These fixed profile mechanisms cannot change source consent, raise the selected rate ceiling or extend a key/lease.

Native presentation reception (SPEC-023/024/D-198): retain explicit Watch intent in the original call, with at most two simultaneous presentations and no microphone, text-selection or capture side effect. Native screen packets use only the existing screen data channel and verified fixed call/source/device/presentation/revision context. Intersect the call lease, trusted source attendance and presentation validity, anchored at request start, and require acknowledgment of this device's watch intent. Verify signatures before decryption, replay and bounded assembly. Moderator mute suppresses presentation sound while video remains eligible. Completed video uses the independent presentation clock, dependency ordering, bounded decoding and final permission/key checks before display. Expiry, Stop, original-call closure and substituted source authority purge queued output; late completion cannot restore stopped intent. Managed RTP retains its separate SPEC-025 controller and cannot fall back to native packets.

Native encoded publication transport retains the existing 2 MiB reservation and 500 ms send deadline, signs/encrypts each chunk once before per-recipient fan-out, paces successful sends through the per-recipient direct budgets, independent total queue/work bounds and combined relay budgets and gives microphone data priority. A large keyframe may span multiple burst windows. Transient send pressure preserves its selected route; missing authority, expired queued dependencies and key/context replacement discard dependent video and request a fresh keyframe. Sound may precede waiting video within the same budget. Publication start/stop is serialized with the complete voice lease/relay-acknowledgment cycle, and only an acknowledged publication UUID enters leases. Native immutable call routes permit the existing `/screen/publish` endpoint under their original account/Host scope; this provides no general server-setting or text authority. Capture consent and managed RTP remain separate owners.

Native presentation sound uses system libopus at the existing 48 kHz stereo/20 ms profile, the SPEC-024 fifty-packet/one-second queue and final per-source gain/mute/authority checks. Retain original key deadlines in queued packets, independently of later lease renewal. Mix no more than two watched sources, clamp output, and apply the existing single ducking envelope with 20 ms attack/250 ms release. Only authorized audible microphone output or the owning call's accepted local transmission triggers ducking; presentation sound cannot trigger itself or move microphone timing. Persist the existing `presentationListening` setting through the sole protected account writer, with SPEC-023's canonical defaults and validation. Standard Listening controls expose it; the embedded viewer's PC-audio mute remains presentation-local.

The playback-only output opens no capture device, starts one worker only for queued sound, uses at most two appsrc buffers and retires the pipeline when idle. Keep a monotonic live sink timeline, account for its reported output latency once, and stop stale work after a scheduling interruption. Bound queued Qt playout observations to the latest event for each of two sources; original-owner destruction purges delivery and prevents late callbacks. Output failure does not stop ordinary voice. These fixed engineering bounds add no user setting or server permission.

The D-198 embedded viewer uses standard Qt zoom, scrolling, Fit, Stop watching and independent PC-audio mute controls with a plain qualified heading. Keep controls and playback status above the picture, wrapping the ordinary controls to a second row at narrow widths so they remain reachable. Share immutable decoded pixel storage rather than creating an additional full-size pixmap. On Wayland, an OpenGL viewport allocates only the visible widget's framebuffer; fall back to raster when that context is unavailable. Neither support probing nor this rendering choice establishes physical GPU use. A viewer's expiry timer clears its image independently of decoder callbacks; its scope cannot be retargeted to another account or source. Receiver, sound, capture and managed-SFU integration remain separately traceable completion requirements.

Native people/Recent port (SPEC-014/D-194/D-196): keep account-wide pinned contacts in the Direct Messages tree and retain protected client-local Recent independently of tree/tab closure. Record only verified authors of displayed eligible text and trusted people in this device's active voice scope; no unselected roster or remote-device call is an encounter. Preserve the existing bounded qualified snapshots, last-known ordinary-channel context, accepted/observed encounter times, minute-bounded voice refresh and clear cutoff. Do not copy image bytes, private keys, messages, presence or conversation permissions into these snapshots, and do not export Recent through linking/recovery. Native people selection/management uses standard on-demand controls rather than restoring the retired right pane; browsing members uses only the existing selected ordinary server/account and never admits a new visitor or changes voice. Existing Home pin/removal and explicit canonical Message/Call actions keep their authority and consent contracts. No new preference, server policy or wire profile is introduced.

The native People picker exposes Pinned, Recent and Server Members through standard modeless tabs, with qualified account entry, filtering, explicit Message/Call and Pin/Unpin controls. Canceling a lookup or closing its originating picker cancels only its pending navigation. Directory queries retain the existing 200 ms debounce, bounded pages and explicit pagination. D-185's profile-label refresh uses the original existing Home/selected ordinary service sessions, batches at most 100 known identities and retains its daily, five-minute retry and one-minute check constants above. Presentation updates preserve identity, context, encounter/pin times and unread state; newer live label changes win over an earlier in-flight response. A replaced Home login retires the old read scope even when the account and approved device remain unchanged; create a fresh scope from that account's newly protected login. Home self-profile/sound/role refresh comes only from the original authenticated Home response; a visitor self projection can update proof history without replacing Home preferences or permissions. Legacy Home responses omitting the optional profile revision retain already known profile/settings values while still validating the account proof.

Native retained-history browsing ports the existing SPEC-006 eligible-period history contract without search or export. A standard modeless History window reads one page of at most 250 records from the original verified account, service and conversation. First, Previous and Next use the existing forward cursor; keep only the displayed page and at most 4096 prior cursor positions, with First always available. Each read validates monotonic safe-integer positions, the exact room/service/account, current history revision and ordinary or closed-private read eligibility. Navigation, credential replacement, source destruction or a changed history revision invalidates the browser and clears its displayed records; reopen it from the current view to obtain a new scope. Closing cancels its sole pending read. It does not alter live sync cursors, protected drafts, unread positions, admission or voice. Display uses the existing verified message reader and standard transcript grouping, with unavailable/expired/invalid content labelled; no plaintext fallback or new history entitlement is introduced. No background history polling or application preference is added.

Native installed-profile adoption is a read-only source conversion followed by one authenticated native-store commit. An on-demand helper reads the selected existing keyring backend and closed Electron snapshot, validates every private/public key pair, qualified identity, signed roster, saved authority, credential scope, pending link/recovery record and local preference before returning a bounded candidate through private process pipes. It creates no device keys, source files or source keyring entries. The review lists account addresses and counts only; Import explicitly rechecks the original vault and scale snapshots immediately before committing. Source changes, helper cancellation/timeout, unsupported or malformed records, duplicate native accounts and failed destination writes leave both original and previously durable native data intact. Merge distinct accounts and connections atomically; retain existing native selection when present. Preserve pending account keys, login renewal and exact direct operations for original-authority reconciliation, and map ordinary/direct/group/reply drafts without losing account/Host qualification. Preserve original scale only as historical metadata under D-197. Unknown source fields stop conversion rather than disappearing silently.

Migrated legacy visitor credentials have no saved issue/expiry metadata in the Electron profile. Keep their original opaque 32-byte token, original Home account/device and Host pin in an explicitly marked migrated connection; never invent signed session metadata or treat a Home/JWT credential as a visitor token. Existing verified discovery and per-request visitor proofs remain mandatory, and the Host decides whether the token is still valid before supplying any state or accepting an operation. The native local cap is twelve hours from import, retained across restart; it cannot extend server validity. Revoked/expired credentials offer the existing explicit Rejoin flow with unchanged keys and drafts. This special restoration path is unavailable to newly admitted native sessions and never changes the strict signed/finite-session validators used for them.

The import helper has a fifteen-second CPU limit, 128 open-file limit and 16 MiB individual-file limit, preserving the existing private LevelDB clone bounds. The native parent allows thirty seconds for initial reading or the final source recheck, and five minutes for the explicit review; cancellation/close kills and reaps that helper and discards its candidate. Pipe frames contain at most 2097664 bytes with a four-byte length, while native protected state retains its existing 2 MiB bound. Only the helper links legacy OpenSSL/LevelDB readers; no decoder/keyring reader runs at ordinary startup. The helper does not record plaintext files or log account keys/tokens. These are fixed engineering bounds, not user preferences.

Native invitation/leave parity ports the existing D-052 and server membership contracts. Account invitation input accepts the raw key or an exact same-origin/mounted-path invitation URL, extracts a single purpose-specific fragment key locally and honors its optional account name without selecting a service. Reject conflicting names, wrong purposes, credentials, queries, duplicate/unknown fields and invalid keys before generating/saving account keys or submitting credentials. Native input is bounded to 4096 characters. Use older room invitation opens a standard modeless form showing its frozen original ordinary channel/service; cancellation does nothing, and explicit Use sends the existing room.join payload through only that original Home or Host. Source destruction cannot fall back to another service. The Channel management page exposes the existing explicit Leave channel action for admitted nonowners, with the original named-channel consequence confirmation and retained exact-command retry. Existing service permissions, membership-period history, call revocation and owner refusal remain authoritative. No new setting, permission, invitation format or wire action is introduced.

## Saved visitor startup recovery (human request, 2026-11-06)

The Qt client must serialize initial account startup ahead of advisory saved-server reads. When restoring a previously joined ordinary foreign server fails, attempt one automatic visitor reauthentication with the original Home account and verified pinned destination before presenting the failure. Preserve drafts and selected channel. Do not automatically join pending/new connections, undo explicit sign-out, replace a session carrying unresolved commands, or bypass changed-authority checks. A failed automatic recovery reports the error and retains saved state. This does not automatically join voice.

Clarification (engineering bug fix, 2026-11-07; restores the requirements above and introduces no new human selection): only a retired destination session counts as a restore failure that triggers the one automatic reauthentication. That means the saved session has reached its own signed expiry locally (`ServerConnection::expired`), or the Host answered `401` with no later success (`DestinationClient::sessionRejected`). Integrity, permission, identity-substitution and local save failures are not retired sessions. They report the error and keep the saved state without minting a new Home grant. The one-attempt limit, pending/new, `conversationOnly`, explicit sign-out, unresolved-command and changed-authority protections are unchanged. Evidence: `.local/native-client/native-admission-repair-*` and its ASan counterpart in `.local/native-client-asan`.

D-222: continuous-transmission duration values and the one-time saved-policy upgrade are owned by SPEC-004/012. Clients accept and expose the ten-minute ceiling; the server upgrades saved shorter limits transactionally before serving current state. Existing authorization and fresh-input rules still apply.

### Server user invitations (D-226)

D-226: each saved server context menu exposes **Invite or create user…**. Open an original-account/server-owned Invitations page with separate existing-account address and new local username actions. Explain propagating server access, explicit denial/inheritance exceptions and separate joins. Require `server-invitations/1`; unsupported hosts show a clear upgrade result and receive no new invitation command. Owner-only controls and pending cancellation use SPEC-022; copied links are never sent automatically. No new configuration is introduced.

## Configuration



D-224 introduces no configuration or persisted layout preference. The active Qt sharing pane uses native style/font metrics and content height; media defaults remain owned by SPEC-023/024.

D-223 shortcuts are fixed native client behavior; there is no new configuration property or preference.

D-221 event hints add no user preference or operator setting. Fixed client values (`EVENT_CLIENT` in `shared/event-hints.ts`, engineering selections under D-024): ready timeout 10000 ms; pong timeout 10000 ms; backoff 1000–30000 ms with ×0.5–1 jitter, reset after 60000 ms ready; renewal lead 1000 ms plus 0–1000 ms jitter, floored at 1000 ms; watch-frame spacing 1000 ms; hint spacing 1000 ms; 15 hint-started reads per loop per minute; throttle 60000 ms after HTTP 429; 30000 ms retry after `4401`; at most 6 sockets per account; fallback polling 2000 ms (the existing cadence, unchanged). Home address-book cadence beside a foreign view: period equal to fallback polling (2000 ms) less `HOME_REFRESH_SLACK_MS` = 50 ms (`client/home-refresh.ts`), keyed by account and Home base on the refresh's monotonic start time. `DirectClient` capability window: 300000 ms (the existing direct-conversation window); failed capability read retry: 30000 ms. iOS broker fixed values (`EventSocketPolicy` in `ios/Core`): at most 6 sockets; 512-byte UTF-8 text frames; 16 incoming and 8 outgoing frames per second (excess closes `1008`); 4 pending sends (excess closes `1013`); 60 s URLSession request timeout and 330 s maximum transport lifetime. Transport: ephemeral session, no cookie storage, no Origin header, default TLS evaluation, redirects and HTTP authentication challenges refused. These are fixed implementation values, not settings. Server values are owned by SPEC-008 and wire values by SPEC-027.

D-221 native Qt adds no setting either. `EventHintProfile` in `native-client/src/eventhints.h` mirrors the `EVENT_CLIENT` values in the preceding paragraph one-for-one (including the watch-frame spacing and the renewal floor) together with the SPEC-027 wire values. Those remain the canonical definitions, so changing one requires the matching native change. Native-only fixed values: at most four conversation-authority sockets, so that Home, the foreground destination and four authorities make up the six-socket cap. `ServerConnection::CapabilityWindowMS` = 300000 and `CapabilityRetryMS` = 30000 mirror the `DirectClient` capability window and failed-read retry above. The destination/authority `/info` read uses a 65536-byte response bound and a 30000 ms overall deadline; the existing 10 s authority check and 15 s transfer bounds normally settle it first. It wakes at most eight consumers per connection. A hint-started list read for one authority releases its in-flight slot after 20000 ms if the session ends without replying; the session's existing request deadline normally settles it first. `EventHintChannel::Timing`, `EventHints::configure` and `HintScheduler::setTiming` are test-only injection seams, and production always uses the defaults. Build dependency: Qt WebSockets ≥ 6.8 (`find_package(Qt6 6.8 REQUIRED COMPONENTS WebSockets)`, linked privately into `sloppy-native-core`). The matching Gentoo dependency `>=dev-qt/qtwebsockets-6.8:6` ships in the higher alpha79 source package under D-184; both overlays, offline staging, public fetch/digests and ordinary upgrade selection are verified in the [native event-hint release record](reviews/2026-11-07-native-event-hints.md).

Saved visitor startup recovery is fixed client behavior, with one attempt per saved-server opening and no new configuration setting.

D-215 adds no saved configuration: the 760-effective-CSS-pixel responsive boundary is a fixed desktop/shared-web layout rule (native mobile retains D-161/D-163 composition). Existing preferences and policy defaults retain their owners. Region/detail selection is transient.

D-213/D-214 add no runtime, server or user preference. Full available conversation width with native style margins, native tab alignment and the grouped bottom session are fixed presentation rules; D-214 retires the 64-character reading target and surplus gutters. Existing splitter persistence and desktop font/style sources remain authoritative.

D-211 introduces no runtime, server or user configuration. The 1.25 desktop-relative conversation heading, one-to-four-visual-line composer viewport and one-pixel quiet field edge are fixed native presentation geometry, not settings; draft lengths and submission limits retain their existing contracts. Native layout uses current desktop font/style metrics and available widget width. Inspection information uses a fixed 54-average-character reading measure bounded by the current Qt screen width minus 32 logical pixels; this is local font-relative presentation geometry, not a setting. The synthetic visual test output directory `SV_POLISH_IMAGES` is an opt-in test-only path (absent: skip screenshot generation); it does not enable account, network or media access. Test-only `SV_POLISH_SCHEME` optionally selects `light` or `dark` for a matching native colour-scheme process; absent runs both synthetic palettes. Task-owned XDG cache/config directories isolate native-theme fixtures from the real desktop. The optional test-only directory `SV_AUTHENTICATED_POLISH_IMAGES` enables the dedicated generated HTTPS account/message capture case; absent skips it. That fixture uses temporary profiles, explicitly trusted generated identities and signed messages through isolated services, with no real account or media access.

D-207 introduces no configuration. Navigation colours are fixed desktop-palette-derived rendering; presence is transient connection-scoped SPEC-012 state, not a saved setting.

D-206/D-212 introduce no preference or server setting. Their fixed native palette, bounded root-colour state, four-pixel gap, twelve-pixel inset, font-scaled controls and live palette updates are specified in the native muted conversation fields section. The review mockup’s palette selector and example-hover checkbox are not shipped.

The native CMake build property `SV_CLIENT_VERSION` is a release-engineering string, default `0.1.0-native-dev`; it is not a runtime/user preference. Accept only numeric `major.minor.patch` with optional `-alpha.N` or `-native-dev`. Release staging requires the exact immutable manifest version and retains the stable Sloppy Voice desktop identity; no account data enters this property. The native Flatpak profile is `packaging/flatpak/qt-profile.json`, using `org.kde.Platform` and `org.kde.Sdk` branch `6.10` with recorded commits. D-193 supersedes only the Electron/BaseApp/Zypak implementation below for this successor. Keep the existing app ID, branch, separate protected profile, explicit import/update behavior and permission allowlist; remove unrelated SDK-inherited host-file/bus grants before export. The current SDK build provides Qt 6.10.3/GStreamer 1.26.11; publishing remains gated on actual sandbox/package qualification.

D-208 prebuilt-package build declarations live in `packaging/flatpak/qt-native-sources.json`, schema 1. They are fixed release-engineering inputs, not runtime or user configuration; only a new human decision changes the ISA level. `baseline.isa` is `x86-64-baseline`. `baseline.cflags` is `-O2 -pipe -march=x86-64 -mtune=generic` for C/C++, and `baseline.rustflags` is `-C target-cpu=x86-64`. `rustExtension` names `org.freedesktop.Sdk.Extension.rust-stable` branch `25.08`. Each `sources[]` entry pins an official URL, exact byte length, SHA-256, SHA-512 and optional reviewed patches. Currently these are libsodium 1.0.22, Snappy 1.2.2, LevelDB 1.23 and PipeWire 1.6.9, each cross-checked against the Gentoo Manifest. A missing archive is fetched into `.local/linux-native-sources`. A size or digest mismatch stops before extraction, and there is no unverified fallback. `dispatchAllowlist[]` entries name a package file, a compilation-unit source pattern and/or symbol pattern, and a review reason. An empty list permits no non-baseline instruction, and rules apply only to unstripped ELFs with symbols; source rules also require debug information. `SV_PACKAGE_JOBS` is build parallelism, an integer from 1 to 6 with default 3. `package-qt.mjs --stage-only` leaves the archive candidate outside `artifacts/` for qualification. `package-qt-qemu-smoke.mjs` defaults to CPU models `Opteron_G1,Nehalem,Westmere,Haswell` and a 150-second offscreen launch window, accepting 10 to 1800 seconds. Source packaging (`package-qt-source.mjs`) and the Gentoo ebuilds read none of these properties.

The existing `directRead` operational map is protected client-local state, not a user preference. Omission initializes an empty map and an unseen position of zero. Keys are canonical qualified account plus Host/conversation UUID; values are nonnegative safe-integer message sequence positions (at most 9007199254740991), never times or remote receipts. Validate retained data before account activation; invalid data is preserved for repair. Successful loaded-view saves only advance the current account/conversation entry and preserve all other retained entries.


Native pending operations use protected `pendingCommand:{room,command,kind?,directPerson?,directSummary?,draftToken?}`. Omitted `kind` selects the existing room ticket route; `kind: "direct"` selects the home direct-operation route with immutable UUID, safe-integer millisecond `issued`, action and payload. `kind: "membership"` retains the prepared ordinary membership command and original `viewRoom`; `kind: "profile"` retains the self-only Home `account.profile` command at `room: "@server"`, with its original `viewRoom` and optional direct view metadata preserved across restart. Profile dispatch bypasses displayed foreign text and uses the originating account generation. Unknown kinds fail closed. Optional direct view metadata retains the qualified tab across reconciliation; it cannot authorize a different service or account. Persist successfully before every send/retry, retain unknown outcomes, and remove a confirmed/rejected operation only after saving that removal. Existing binding/PTT/activation/relay preferences retain the defaults and validation in their owning configuration sections; they remain encrypted local preferences and are not uploaded by native settings.

Native source-side device work ports SPEC-011's existing manual linking, explicit approval/revocation and retained-history-copy contracts. A protected public `sourceLinkSlot:{id,account,domain}` records the original slot before creation; it contains no code secret, and restart offers cancellation rather than reconstructing a lost secret. Protected `pendingDeviceAction:{route,body}` retains the exact signed approval or revocation before dispatch. Only `/devices/link/approve` and `/devices/revoke` are valid routes, bound to the active account/device and original roster change. Before retrying, a verified current roster can reconcile that exact committed change; unknown outcomes cannot generate replacement signatures/ciphertexts. Omission means no pending operation. Copies remain bounded by SPEC-011's existing batch/expiry/eligibility and are explicitly reported incomplete on interruption or unreadable text. These are local operational records, not new server settings. Implementation/validation status remains in the development inventory.

Native group live-session IDs and conservative monotonic presence deadlines are memory-only, initially empty. They use SPEC-018's fixed 5000 ms heartbeat and 20000 ms presence lifetime; no timer may create or resurrect a missing session. An explicit group create/accept/join or call join can establish live intent; service discovery, text navigation and profile restoration cannot. Native outgoing/answered call intent is also memory-only and starts no capture until the authoritative call is active on this approved device. Ring/connection deadlines and movement retain SPEC-018/011 bounds. No new user/operator timing preference is introduced.

D-195 native development profile: `SLOPPY_VOICE_URL`, legacy `VOICE_CHAT_URL`, the one-line `sloppy-voice/server` file beneath Qt's generic user configuration directory, then the deployment default `https://chat.sloppyvoice.com/` select the service, in that order. These are non-secret client service inputs using SPEC-002/010 validation; explicit invalid/empty environment values fail. Existing base-path and credential-destination rules remain authoritative. `--layout-preview` is a command-line boolean, default false, confined to synthetic layout demonstration; it makes no network or protected-storage request. `--help`/`--version` use the ordinary Qt command-line parser. No option bypasses TLS or key storage.

Native development storage uses `QStandardPaths::AppConfigLocation` with organization `SloppyVoice` and application `sloppy-voice-native`; the active account/service, independent device keys, token and trust pins remain inside its protected JSON, with `nativeProfileVersion: 1`. The vault file is `vault-v1.bin`, the process lock `instance.lock`. A random 32-byte master key is stored by Secret Service under schema `com.sloppyvoice.NativeVault`, attributes `application=sloppy-voice-native` and `scope=<absolute native profile directory>`. An existing vault with a missing key fails closed; no regeneration or plaintext fallback. The file is atomically written with owner-only permissions and authenticated XChaCha20-Poly1305, a fresh 24-byte nonce and fixed version header `SVQT1` plus NUL. Vault size is bounded to the existing 2,097,152-byte plaintext contract; media secrets remain outside persistent storage. Tests may inject an ephemeral key provider through the C++ interface; no runtime input enables that provider. This development namespace leaves installed profiles intact pending a separately specified/tested upgrade path. Manual linking uses fresh independent keys under protected `pendingLinkKeys:{code,keys}` before submitting a request; `code` contains public binding metadata only, excluding the link secret. After submission, `pendingLink:{code,token}` stores the restricted completion token before polling. Omission means no pending request. Poll at the existing 2000 ms cadence without overlap until the original five-minute SPEC-011 deadline; normal network errors retain the state. Verify the original code/root/approver/revision, complete signed chain, exact bootstrap hash and encrypted transfer context before accepting a signed login and atomically activating the keys. Retain prepared keys on interrupted responses; a password login may reconcile them only after verifying the signed approval against the retained public code. Explicit cancellation requires authenticated server confirmation and never removes an approved device. The device-label input follows SPEC-011, defaulting to `Linux Qt app`; this adds no server setting or key-copy mechanism. Reading a history share verifies its original message, sharing account/root, source-device evidence, exact context/signature and current expiry; unavailable or invalid copies fail closed.

Native transport has fixed defensive bounds: 32 pending requests, 786432-byte request bodies, 4194304-byte responses, 64 JSON nesting levels and a 15000 ms total request deadline as well as an inactivity timeout. Reject duplicate JSON fields, malformed UTF-8, redirects, ambient cookies and HTTP authentication reuse; retain ordinary TLS verification. Read-only sync uses the existing 2000 ms cadence without overlaps. Unchanged text history/context/trust avoids repeated transcript decryption; expiration or trust changes invalidate that rendered state. Unchanged navigation projections leave existing tree items intact; changed projections preserve expansion and selection by stable identity. Before dispatch, retain a command with its original opaque ticket, action/payload, expected revision and room under the protected `pendingCommand:{room,command}` field. Unknown outcomes survive restart and require reconciliation of that same command; do not mint a replacement ticket or permit destination changes/logout while it remains unresolved. Clear it only after a definitive response has been durably recorded; an unsuccessful vault write retains the pending state. Absence is the initial condition, not a configurable preference. The development loaded-history window is at most 250 records; complete retained-history pagination remains a release requirement. These are implementation bounds, not administrator preferences. Initial development window size is 1040×700 Qt device-independent pixels, with a 245-pixel left split request; both roots initially expand. Installed layout/preference migration and remaining media settings retain their current incomplete status.

D-194's native tree membership/sort order and absence of a toolbar/right pane are fixed presentation requirements, not user settings or server policy. The creation actions reuse existing Add server and direct-conversation configuration/permissions. Pin chronology is non-secret contact metadata with a compatibility contract still to be completed under SPEC-014 before application implementation; it is not a configurable default. No native tab/session persistence or new metadata API is implemented by the sketch.

Native personal listening retains SPEC-004/D-187's approved gain/mute semantics. Protected `gains` and `muted` dictionaries use qualified `domain:account` participant keys inside the current service/account profile, with 0 dB/false defaults. Home-only legacy bare UUID entries remain readable; new writes use qualified keys. A modeless native Listening dialog provides volume 0–400%, exact silence, 100% reset and Mute for me; its participant menu also offers Mute for me. While connected it always uses the actual voice destination rather than selected text. Apply changes to queued decoded audio as well as future packets, with local mute as the final silence gate and the existing output limiter unchanged. Save errors remain visible and restore the displayed durable value.

Native public discovery is a separate unauthenticated module implementing SPEC-010/015's existing locator/identity/destination validation. It accepts a canonical identity domain or pasted server/shortcut URL, authenticates the identity-origin mapping and exact UUID/domain/base triple, and returns metadata without saving a connection or admitting an account. Follow the existing public JSON byte, request and overall deadlines; no cookies, authentication reuse, redirects, credentials or insecure fallback are permitted. A caller's cancellation/destruction fences every pending result. An injected public reader is a C++ test adapter only, with no runtime TLS/network bypass. Native visitor proof builders use SPEC-015's existing host/method/URL/body/token/nonce/time bindings and SPEC-003/011 device keys; creating a proof by itself grants no admission. Saved-connection and selected-account UI integration are described above; full multi-account/media orchestration remains release work.

Native destination sessions take the known home identity explicitly and validate their bound signed or finite opaque visitor login, qualified account/name, unchanged root, extending signed approval history, exact server UUID/domain/base and active approved device before use. A destination response cannot select a different home account or replace/roll back its known proof. Their module independently checks public discovery before dispatch, caching a matching result for at most SPEC-010's 300 seconds measured from verification start on a monotonic clock; expiry or clock regression requires verification again. A changed identity or endpoint requires explicit reconnect/review rather than token forwarding. Foreign requests carry only that destination's token and a new SPEC-015 device proof for each method/full mounted URL/body/token/nonce/time. Queued requests retain the existing 32-pending and 786432-byte request limits; cancellation, account closure and destruction fence late results. Metadata, sender and clock adapters exist only in the C++ test interface and introduce no runtime configuration or trust bypass. This transport implementation does not by itself complete admission, saved account profiles, background connection scheduling or UI activation.

The installed-profile migration decoder reads only the existing Linux Electron `v11` storage format using an already retrieved OS keyring password. Its pure decoding implementation uses system OpenSSL Crypto for that legacy format, with the existing 2 MiB plaintext bound. It cannot query or create a keyring entry, read/write a profile, import an account or enable plaintext/hard-coded/empty-key fallback. Decoding the legacy CBC envelope does not authenticate its contents: migration must separately validate the saved private/public device keys, signed account roster, canonical home/destination scope, protected operational records and source consistency before adopting anything. Missing/wrong keys, unsupported format, malformed padding/JSON or invalid identities preserve the source and cannot create a replacement device. Native protected storage remains the existing authenticated format. The full read-only import helper, installed-Electron interoperability and profile/preference migration are still required; a standalone decoder is not upgrade completion.

The separate legacy KWallet reader is intended for the on-demand import helper; the development library currently runs only in C++ fixtures and is not linked into the GUI. It reads the existing Chromium storage entry under the original `Sloppy Voice` or `Voice Chat` application identity through the selected KDE 4/5/6 wallet protocol, with no daemon activation, folder creation, entry replacement or key generation. Require an already running, enabled and unlocked wallet; missing, locked, wrong-type or unavailable entries stop import with retry guidance. Reads have a fixed 15000 ms overall deadline and close only their own non-forced handle. This helper's ephemeral process lifetime bounds framework-owned secret buffers. The Secret Service reader below is also implemented; complete protected profile adoption remains implementation work.

Legacy source selection follows the released wrapper: use `sloppy-voice` beneath the user's generic configuration directory when it exists; otherwise use the first existing `Voice Chat`, then `voice-chat` legacy directory and retain its `Voice Chat` keyring identity. For the configured canonical service, the source filename remains `vault-<sha256>.bin`, hashing the origin without a final slash for a root base, or the complete canonical base for a mounted service. The source reader opens only that existing owner-held regular file without following a file symlink, bounds its encrypted size, and never modifies source files, permissions, locks or keyring entries. A live/unknown-host/malformed Electron singleton lock stops import; a definitively stale lock can remain untouched. Retain file identity/timestamps and ciphertext digest, then recheck both source bytes and singleton state immediately before adoption; changes stop import rather than copying a mixed snapshot. These are deterministic migration rules under the existing service/profile scope, not new runtime preferences. Full profile/key/account conversion remains required work.

Legacy UI-scale extraction is confined to the on-demand migration library and uses system LevelDB with Snappy support, never linked into the main GUI. It receives the same verified closed-profile source snapshot and canonical service base, and selects only the unpartitioned origin’s `sloppy-voice.ui-scale.v1` item (mounted services share their origin’s local storage). Open source directories/files read-only without following symlinks; inspect at most 128 owner-held regular database files, 16 MiB per file and 64 MiB total, using fixed LevelDB filenames. Clone them into a private temporary directory, open only that clone with creation disabled, paranoid checks and read checksums, and accept only Chromium local-storage schema version 1. Never open, lock, recover, compact, truncate or delete the original database. Verify directory/file identity, timestamps, full inventory and SHA-256 content digests after the read and immediately before future adoption, as well as the original vault/process snapshot. Missing directories/items remain absent. Accept the existing canonical decimal scale range/step only, decoding Chromium Latin-1 or UTF-16LE strings; ambiguous, malformed, unsupported, invalid or unreadable values stop import visibly and preserve the complete source. Return historical metadata `{version:1,origin,key,status:"missing"|"valid",percent?}`; `percent` exists only for a valid saved value and is never applied to Qt. The importer process must supply its own deadline/resource fence before GUI integration. These fixed migration limits are engineering safeguards, not new user settings; the current library remains fixture-only until complete adoption exists.

The legacy Secret Service reader uses maintained libsecret under the original application identity, searches the existing Chromium schema without creating/unlocking an item, requires a single matching unlocked textual password, and rejects missing or ambiguous results. Resolve the currently running service's unique D-Bus owner before opening it, so loss/replacement cannot activate or redirect to another daemon. Its cancellable 15000 ms overall read deadline matches the isolated legacy-reader bound. Normal libsecret session negotiation remains authoritative; no runtime option changes it. This reader is also confined to the future import helper and generated fixtures, with no GUI or installed-profile call site until full adoption validation exists.

Native QR scanning uses a separate on-demand Qt Widgets/Multimedia process with local ZXing decoding and libqrencode rendering, following D-171's bounds and lifecycle above. Only a visible scanner with explicit Start may request a camera; no microphone is attached and no frames or decoded secrets are logged or written. The application accepts one bounded UTF-8 result from its packaged helper and validates the selected service and protocol before dispatch. Backgrounding, hiding, permission expiry, parent exit or successful decode stops capture; reopening requires another explicit action. `pendingPair` retains public rendezvous metadata and fresh pending keys in the protected vault; its optical secret remains memory-only. Restart without an encrypted offer requires cancellation/new pairing, while an already saved restricted completion resumes normally. These states have no configurable secret/default or camera preference.

Native recovery implements SPEC-011's existing password-plus-key ceremony. Source key creation displays an `SVREC1` code in memory and requires explicit acknowledgment that it was saved before activating its signed public recovery recipient. The private seed is never saved as an ordinary preference. Retain any signed setup mutation in the existing protected `pendingDeviceAction:{route,body}` state for exact reconciliation. Recovery history copying uses the active public recipient and existing original-message eligibility/expiry. On restoration, protected `pendingRecovery:{keys,recovery,before,completion,expires,expired?}` contains the fresh installation keys, derived recovery keys, verified pre-recovery identity and exact completion body before dispatch; absence is the initial condition. Resume that body after interruption rather than minting another device or transition. `expires` is the validated service deadline in Unix milliseconds; optional `expired` defaults to absent/false and is set only after a definitive `recovery_expired` response. Password sign-in may reconcile the same pending fresh keys, accepting only the exact saved signed recovery transition. After definitive expiry, explicit password-plus-key recovery may restart with those same fresh keys only for the same account/generation; a failed restart retains the original pending record. No pending key is silently discarded or replaced. Successful completion verifies the exact signed roster transition and login authority, stores `historyRecovery` solely as a retained-content decryption key and clears the pending state atomically. Never use that key for ordinary sign-in or media. Source profiles and unrelated preferences are preserved. Missing recovery copies remain unavailable; the consumed key cannot restore again and a fresh key must be saved to re-enable recovery. These are fixed protocol state fields, not user-selectable configuration defaults.

D-198 native layout persistence uses protected device-local `nativeLayout:{geometry,splitter}`, with Qt geometry/splitter state encoded as base64url strings. Absence uses the initial development window/split sizes above. Decoded geometry is bounded to 4096 bytes and splitter state to 1024 bytes; reject other fields/types, malformed encoding and failed toolkit restoration with a visible error/default layout. Coalesce explicit splitter changes for 300 ms; save geometry on window close. Reset layout restores the initial split and saves the current native window geometry. Never write layout/preferences after an unreadable or unsupported profile load; preserve that existing vault. Former CSS width/scale preferences remain migration records, not Qt coordinates. These values are local and never uploaded.

D-197: native rendering inherits Qt's desktop font and display scaling. There is no application zoom preference or control. Migration retains any source `sloppy-voice.ui-scale.v1` value as historical metadata, never as a Qt font/display override. The source's valid percentage is an integer from 75 through 200 in steps of 5; an absent value remains absent. Invalid or unreadable source values are reported and the source data retained. Complete protected profile migration remains a release requirement; the current development profile does not read the installed Electron profile.

Toolkit selection introduces no new server policy or numeric resource budget; native local state and preferences are specified above. Existing service selection, account/device preferences, secure storage, input and media configuration retain their canonical owners. Remaining build/package inputs must be specified with types, defaults, validation and precedence before their implementation; toolkit choice and style-derived metrics are implementation/presentation rules, not invented account/server settings. Preserve existing Electron device vaults during development and specify and validate a protected upgrade path before using an installed profile; unreadable protected state must not be treated as an empty installation.

Native public convenience mode ports D-175 through explicit original-room trust checks. It is enabled only by the protected local publicMode boolean, a known qualified own account and a verified room projection with publicServer true and public access. Other participants still require a valid signed roster with their presented device currently approved; this does not grant admission, permissions, key access or plaintext fallback. The own account, private contexts and empty/invalid public flags retain existing strict trust. Optional public identity changes do not overwrite private/root trust pins. Pass the validated original room explicitly to text, pin and voice trust consumers; never make the account-wide strict verifier implicitly depend on the currently browsed room. Explicit public-link resolution may reuse the existing single reviewed join intent under D-175; cancellation and original authority fences remain. No new setting or default is introduced.

Native statistics sources freeze the selected account/device and original Home, ordinary destination or canonical conversation Host. Read capabilities at that exact Host, send reports only when it advertises connection-statistics/1, and cancel prior reads when the source changes or ends. Under D-200 the standard status area always displays statistics independently of the two scrolling trees; there is no display preference or checkbox. The retired showStatistics boolean remains compatibility metadata and is not rewritten to force visibility. Validate owner-only aggregates against the shared counts/ranges; wrap at the actual width and recompute the necessary height on text/width/font changes, including shrinking. An unavailable context displays placeholders and cancels its owned timers/requests. No statistics popup or status-bar Conversations button is used. API instrumentation excludes cancelled owner work and protected headers; voice/native-screen sends count accepted application packets and managed presentation counters use RTP payload after the final pacing/authority gate, excluding RTP headers. Reuse existing managed maintenance rather than adding a media measurement timer. Conditional service notices remain below pins, expire through the existing bounded UI deadline and contain plain text.

Native connection statistics port the existing measured-payload profile: retain at most 32 service contexts and 1000 samples per context over 30000 ms, with displayed rates/request RTT over the latest 10000 ms. Use a monotonic clock, a minimum 1000 ms rate denominator, and count body/media payload bytes without operating-system or transport overhead. Cancelled requests do not mark availability failure; two successive failed service reads mark unavailable and a successful read clears it. No sampling timer runs solely to prune this bounded memory. The existing ten-second authenticated report and owner-only aggregate contract remains authoritative. Native display belongs in the D-198 status area, independent of tree scrolling; opt-out remains reachable. These are fixed engineering bounds, not additional settings.

For shared/non-native clients, D-173/D-175 add local account/device boolean preferences `showStatistics` and `publicMode`, both default **false**; only explicit true enables either. They use the protected local profile, do not synchronize or broaden permissions, and take effect immediately. D-182: when enabled, keep statistics anchored at the bottom of the right/People panel, outside the independently scrolling people list. Scrolling or collapsing the people list must not hide or move the enabled statistics, including narrow/scaled layouts. Bound expanded statistics to the scaled viewport with their own overflow if necessary; preserve access to the opt-out checkbox. This refines presentation only, with no measurement, reporting or permission change. Display statistics at the bottom of the people panel when enabled; report bounded current connection metrics every ten seconds independently of panel visibility, only to the authenticated selected server advertising `connection-statistics/1`. User settings categories are transient UI state, initially Appearance. The input recorder exclusively owns native registration only during the record/test/save-or-cancel workflow; ordinary settings do not register a second shortcut observer or pause the saved binding. Wine compatibility permits the exact `wine`, `wine64`, `wine-preloader` and `wine64-preloader` playback binaries when the advertised PID has no host process; a real denied process remains denied. These adapter rules are fixed, not configuration.


**QR linking (D-171):** SPEC-011 owns both initiation directions and fixed bounds. For the 2026-10-25 foreign-home iOS regression, a scan follows SPEC-011’s verified automatic home-service selection and submits the request with the default device label; no separate service confirmation or request button is required after a successful scan. Show the qualified account while waiting for the existing device’s explicit approval. Keep native bundle navigation and protected storage intact, preserve existing profiles, and fence delayed discovery after cancellation. An installed default service must never receive a foreign account token during startup or completion recovery. Devices and Link this device expose Show QR code, Scan QR code and legacy manual-code fallback. QR paths omit the password; manual legacy linking retains it. The source shows the full qualified selected account, requesting label and key fingerprint before explicit approval. Camera permission is requested only from a visible, user-opened scanner; process frames locally with no recording/upload. Stop all tracks on successful scan, Cancel, navigation, hiding/backgrounding and teardown, including delayed permission resolution. A new explicit action is required to reopen. No persisted camera preference or operator setting is introduced. Fixed processing bounds use QR correction M, a four-module quiet zone, a 960-pixel maximum decoded side and at most five decode attempts per second. Native scanner permission is armed for 15000 ms and refreshed every 5000 ms while visible; these are lifecycle bounds, not configurable preferences. SPEC-011 owns payload limits.

This is a scoped successor to desktop/iOS camera denial and Android's no-camera profile: trusted origin/main frame only, video-only capture during an explicitly armed native scanner session. Native background/lifecycle loss disarms it; camera does not become a call publication source. Unsupported old wrappers show update guidance and retain manual/QR-display paths. Browser permission denial/absence also retains these paths. SPEC-011 owns cryptographic/payload limits; do not duplicate them as user configuration. Native permission/lifecycle units and disposable-account integrations must cover denial, delayed permission, all exits and preserved voice. Physical desktop/Android/iOS scanning remains separately reported acceptance.

iOS build settings are owned by the packager. `IOS_SERVICE_URL` is a build-time string, default `https://chat.sloppyvoice.com/`; require an absolute HTTPS DNS origin without credentials, port, mount path, query or fragment. `IOS_BUNDLE_ID` defaults to `com.sloppyvoice.ios`, validated as a reverse-DNS application identifier. `IOS_BUILD_NUMBER` defaults to `1` locally and uses the positive Codemagic build counter in CI; increases are required for uploaded builds. The short version is numeric `0.1.0`, derived from the package's numeric prefix; its alpha suffix remains in the native build metadata. Values are embedded at packaging, with environment overrides taking precedence over defaults; invalid/empty explicit values fail rather than reverting. There are no runtime endpoint overrides. The fixed renderer origin is `sloppy-voice://app/`; asset and bridge limits are defensive implementation constants: 2 MiB vault/request bodies, 4 MiB HTTPS responses, 32 pending bridge/network requests, a 15-second active-call heartbeat deadline, a 120-second pending-start deadline and 30-second native HTTP timeout (renderer abort can cancel earlier). No server lease is extended by these bounds. The existing shared account/media configuration remains authoritative.

Codemagic's initial machine is `mac_mini_m2`, with Xcode `27.1` and Node `26.12.0`, and no automatic trigger. The workflow verifies the actual Node version before dependency installation and fails on a mismatch. Simulator qualification chooses the numerically newest available iOS runtime with an iPhone, creates an iPhone 13 mini simulator when its device type/runtime support it, otherwise prefers a conventional iPhone and records the actual available fallback model, and records the actual runtime/device. Simulator boot starts after shared checks and native core units, before the Xcode UI run. This choice does not establish older-device or physical support. The simulator qualification workflow has a 30-minute timeout; signed TestFlight packaging has a 45-minute timeout. The local macOS packager bounds each native Swift/Xcode child process to fifteen minutes and reports a timed-out process as failure. Apple team/app identifiers and signing resources are account-specific required inputs with no invented default; the protected integration is referenced by its observed name `Codemagic Sloppy Voice`. The signed workflow references protected Codemagic code-signing identities with distribution type `app_store` and bundle identifier `com.sloppyvoice.ios`; a matching Apple Distribution certificate/private key and App Store provisioning profile must be stored there before it starts. Initial upload does not submit for public App Store publication or external beta review. The physical-device OS versions above are test metadata, not configuration defaults. API keys and signing private keys must not appear in source or logs.

The Android options disclosure is transient UI state, initially closed, with no persisted preference or server configuration. The bottom account bar and connection-gated microphone control are fixed presentation requirements under D-161.

Android build settings are local build-time inputs, owned by the packager: Gradle `serviceUrl` defaults to `https://chat.sloppyvoice.com/`; accept an absolute HTTPS origin only, with no credentials, query, fragment or mount path for this first package profile. Invalid or empty values fail the build. `versionName` defaults to the package version plus `-android.1`; `versionCode` defaults to `6` and must be a positive integer, increasing for distribution updates. These are the current checked-in build defaults; a qualification-only artifact does not advance the distribution version. `ANDROID_HOME`/`JAVA_HOME` select installed SDK/JDK tooling; they are not embedded secrets or server settings. There are no runtime endpoint overrides or exported URL intents. A different service build needs a separately approved account/device setup; do not reuse protected identity across origins. Native vault aliases/files include the origin hash. The fixed package ID is `com.sloppyvoice.android`. The APK contains no user vault, service secret or release signing key. Native call state starts inactive, is never restored after process death and is not a saved preference. Existing PTT/activation and server limits retain their authoritative defaults. The native implementation uses fixed defensive bounds, not user settings: 2 MiB UTF-8 vault payloads; 32 pending renderer bridge requests; 10-second bridge deadlines except 120 seconds for a visible permission/start flow; one-second call heartbeats with a 15-second native watchdog; and a two-second cleanup grace before destroying an unresponsive renderer. The partial wake lock has a 65-minute safety timeout and renews every 30 minutes only while the same native call remains active. This avoids adding a client duration limit to direct-hosted calls; it does not extend any server lease or Cloudflare generation authority.

D-204 adds no Qt setting, dependency, server property or runtime default. Native fonts and display scaling remain owned by D-197; artwork geometry is derived from the current font metrics.

D-149 uses a fixed 24px channel-heading size, scalable through the existing device UI scale, and a bundled inline vector decoration selected by the displayed channel name. No new preference, server property, network request or default is introduced.

D-147 adds only client presentation constants for amber pins, green private-call state and lavender current-DM state. There is no new saved preference, backend property or default. SPEC-014 still owns saved contacts; private-call and reading indicators are transient local state, not global presence.

D-144/D-145 add desktop capability `applicationAudioVersion: 1` and explicit Application sound checkboxes for game/music mixing. SPEC-023 owns the native capture scope, adapter constants, dependencies and lifecycle. The client must show actionable PipeWire/helper errors, keep PTT limited to the microphone, and preserve the existing presentation audio and listener settings. Older Linux wrappers remain video-only and require a package update for this capability.

D-141/D-142's section heading/panel colours, spacing and corner radii are shared client presentation constants in `client/style.css`, scoped to User settings and the sidebars. They add no persisted preference, server property or migration. Existing system appearance and interface scale still apply; forced colours use system border/text roles. Sidebar widths remain governed by D-110.

D-142 uses compact row arrangements below 240 CSS pixels on the left and 260 on the right, based on the displayed sidebar width after scale/layout constraints. These are presentation breakpoints, not new width limits or preferences: channel labels gain a separate row beneath their icons, and people actions/context can use the row's full width. Avatar sizing remains D-100's.

Screen-sharing configuration and each default's approval status are in [SPEC-023 Configuration](023-screen-sharing.md#configuration), including presenter intent/bitrate, explicit sound capture and receiver ducking preferences. Reference its single inventory rather than duplicating defaults. Policy, capture lifecycle, playback clock and presentation-audio tests accompany synthetic browser integration. Source permission, active capture, effective codec/route and clock state are ephemeral state. Listener preferences persist in the protected active account/device profile. New shares reset bitrate and intent and require new capture consent, as specified in SPEC-023.

D-124/D-125: SPEC-022 owns the new permission and named-account invitation contracts. With `channel-permissions/1`, Members & invites separates **Invite an existing account** from local account creation, presents explicit permit/denial lists and per-member effective access, and provides per-channel propagation and owner-only server propagation controls. Channel settings exposes the same inheritance control at every depth. Pending invitations display the qualified recipient, expiration and cancellation action. Copy a locator for Add server; never send a message automatically or claim a forwarded locator grants authority. Permission conflicts remain visible and do not silently change inheritance. Existing-server compatibility retains the predecessor controls until the successor runtime is activated. All new channels inherit by default. Creation explains that inherited permits also apply to private channels; the same inheritance toggle is available at every level. SPEC-022 owns the approved migration and defaults.

D-110 device-local user preference: `sloppy-voice.sidebar-widths.v1` in origin-local storage contains `{left: number | null, right: number | null}`. Units are integer CSS pixels at 100% scale, independently bounded to the presentation ranges above. Null/absent means automatic (default on both sides); zero, nonnumeric, out-of-range or incompatible values reset to automatic with a visible storage notice. Only explicit drag/keyboard resizing saves a manual width; reset saves null. Apply immediately and share storage updates between windows of the same device/origin. Never sync widths through accounts, profile history or recovery. A storage failure leaves the requested width active for this window and displays that it could not be saved. Expansion/collapse state is transient and adds no stored setting.

Quiet Stack adds no persisted preference. Existing UI scaling and appearance apply to the entire stack and its details panel; sizing is presentation only. SPEC-004 owns all input defaults and precedence.

R-108/D-102/D-103: show a subtle home-account expiry notice in the shared workspace during the final 24 hours, capped at the final 10% of the issued duration. Unlimited sessions have no expiry notice. User settings exposes session status and “Sign in again to renew”; its inline password form names the qualified account, clears the password after submission, and reports failures. Use authenticated server time with a monotonic local anchor; refresh session metadata on entry, once per minute, focus and renewal. Preserve channel/conversation selection, drafts, device keys and voice attendance during renewal. SPEC-003 owns policy/defaults and security rules; SPEC-009 owns metadata/renewal routes.

Verify every newly issued signed login credential against the selected home service's public key and the returned account/device/issuance/expiry binding before accepting it. Save a prepared replacement durably in the existing encrypted device vault before activation. Merge credential entries under a cross-window Web Lock; stale preference saves must not overwrite a replacement. Reconcile saved pending activation idempotently after response loss/restart. A failed preparation/save leaves the original authority unchanged; a lost activation response is retried from protected storage. Route all request snapshots and other same-origin windows to the active token in the same home/account/device/session family. Do not treat renewal as an account switch or forward a home token to another server. Credentials are never broadcast in plaintext. Storage/network reconciliation failure must not stop a heartbeat still authorized by the old credential; ordinary expiry/revocation still requires a new sign-in and explicit voice rejoin.

Advertise `login-sessions/1` and expose controls only when the home service supports it. The server owner edits the SPEC-003 duration through Server settings, with an explicit Unlimited checkbox and text explaining that existing expiry dates stay unchanged. Browser and compatible desktop renderers use the same interface and secure-storage paths.

D-094 adds presentation only: channel access labels and people row ordering/filtering have no user or deployment setting. SPEC-012 owns access; SPEC-014 owns contact and encounter storage.

D-084 connection diagnostics are transient call state, with no saved preference or upload setting; see Local voice diagnostics below. Codec limits are fixed by SPEC-004.

D-066 fixes appearance selection to the system; no stored theme choice, manual toggle or user palette editor is introduced. `client/style.css` owns the paired semantic colours: surface, field, text, button, selection, muted text, separator, control border, link, focus, positive and negative status, own-message foreground/background under SPEC-013, subdued transmit surface/text/edge under D-073, and voice connected/waiting/disconnected surfaces/edges plus message-composer surface/edge under D-100. The light palette is used when no dark preference is reported. These values are client presentation constants, not account/server configuration. Alpha.8's existing KDE bridge reads `$XDG_CONFIG_HOME/kdeglobals` (default `~/.config/kdeglobals`) over `$XDG_CONFIG_DIRS` (default `/etc/xdg`), with the selected simple scheme name under `$XDG_DATA_HOME/color-schemes` (default `~/.local/share/color-schemes`) then `$XDG_DATA_DIRS` (default `/usr/local/share:/usr/share`). Reads remain bounded to 256 KiB and monitored every second. The client uses only the derived boolean; missing/invalid values fall back to system appearance. Legacy native colour properties are removed from the renderer. Forced colours disable the native appearance override. Tree expansion, selected workspace and menus remain transient per-window state.


Alpha.6 uses SPEC-010's full service-base configuration in place of the old origin-only desktop setting. Explicit **Find another account service** performs fresh authenticated discovery and switches the current desktop window only; restarting restores the configured service. It never carries a bearer token to the new endpoint. Browser users open the verified endpoint explicitly.

The protected vault is bounded to 2,097,152 UTF-8 bytes; a failed write retains prior saved data and reports an error. Existing root browser/desktop vault names remain unchanged. A path mount namespaces storage by the full canonical base URL. Each account's keys, trust pins and recovery decryption key are retained in a separate local profile when switching accounts; ordinary sign-in reactivates the matching profile. Each new link slot uses fresh keys, including re-linking a revoked installation. Pending keys and restricted completion proofs are saved before irreversible approval/recovery completion so interrupted responses can be reconciled. The link-code secret and newly generated recovery code are not ordinary persisted settings. PTT preferences are not copied from the approving client.

### Approved room-creation scope (D-055)

R-073/Q-48 restrict the new creation control to the owner; moderators manage rooms they can access. The human approved text, voice and combined rooms under Q-47, with meetings deferred. The client owns the creation dialog, explicit access/encryption presentation, named room navigation, per-room access management and independent text/voice selection selected under D-058 in the [room creation review](reviews/2026-10-19-room-creation.md). SPEC-001 owns creation fields, SPEC-003 encryption, and SPEC-004 media settings. Server validation and authority belong to SPEC-008. Do not expose controls for unsupported capabilities. SPEC-012 defines the alpha.6 wire and migration profile.

### Qualified accounts and discovery (D-056–D-058; SPEC-010)

Apply SPEC-003's address parser to account sign-in, invitation and account-selection input; show the full account address and use the selected account service for an omitted suffix. Keep an explicit foreign suffix distinct, with a clear unsupported-domain result in the closed alpha. SPEC-010 owns authenticated discovery, URL joining, cache limits and mount-prefix behavior. The browser uses the public identity-origin descriptor; native clients may also inspect DNS. No login credential, device proof or invitation key goes to a location merely supplied by DNS. A discovered service change requires explicit reconnection. Preserve the existing device store and sessions during the naming update; logical storage namespaces do not isolate mutually untrusted same-origin apps.

Logical names/defaults are PROPOSED unless stated otherwise. Exact OS representations must be resolved before implementation. Sensitive credentials are referenced through secure storage, never treated as ordinary UI preferences. Server-side settings displayed by the client are owned by SPEC-008 and its linked configuration contracts.

| Property | Scope and type | Default and status | Behaviour |
| --- | --- | --- | --- |
| `client.ptt_binding` (logical name; selected/pending schemas below use `pttBinding`) | Device; supported keyboard key or mouse/joystick button under P-025 | See the selected V1 and proposed successor schema below | First-run setup asks for a binding; no arbitrary key is captured implicitly. The configured shortcut remains unavailable until a usable input is bound; D-113 permits the independent held on-screen control. This row does not select chords or a second persisted property. |
| `client.self_mute_binding`, `client.deafen_binding` | Device; optional key/button chords | Unbound — PROPOSED | Additional configurable hotkeys; conflicts are detected and reported. |
| `client.audio_input_device`, `client.audio_output_device` | Device; OS audio-device selector | System default — PROPOSED | Resolve the selected device at session setup; device loss follows the stop/recovery rules rather than silently resuming capture. |
| `client.deafen_also_mutes_microphone` | Client; boolean | OPEN — not selected | Determines coupled self-mute/deafen behaviour. |
| `client.notification_policy` | Account/community/room; notification preferences | OPEN — not selected | Mentions, unread state, preview visibility, and quiet-mode behaviour. |
| `client.theme` | Client presentation; system appearance | System selection — CONFIRMED D-066; no persisted property | Select application light/dark palette; forced colours take precedence. |
| `client.ui_scale_percent` | Device-local user preference; integer percent | 100 — selected D-100; allowed 75–200 in steps of 5 (engineering completion) | Supersedes the unimplemented `client.text_scale` proposal; applies to the entire shared renderer. Persistence and failure semantics below. |
| `client.locale` | Device; language preference | Follow OS — PROPOSED | Available locales and fallback language remain open. |
| `client.capability_cache_ttl_seconds` | Client; bounded seconds | OPEN — not selected | Bounds cached display hints, no longer than the server's advertised maximum; every server action still rechecks current rights. |

`client.ui_scale_percent` is owned and written by the local client through user settings, without account/server permission or inheritance. Store its canonical decimal integer as the non-sensitive `localStorage` item `sloppy-voice.ui-scale.v1`; changes take effect immediately and same-origin storage events update other windows. Missing/removed storage means 100%; null, zero, fractions, out-of-range values, non-five-point increments, strings in the runtime setter and malformed stored representations are invalid. Reading invalid/unavailable storage falls back to 100% with a settings notice; a failed write preserves the selected in-memory scale and reports that persistence failed. Explicit Reset writes 100. Do not modify any other storage item. This additive v1 preference requires no vault, account or server migration. It does not change OS appearance, OS scale or browser zoom. Palette values, reflow breakpoints and the 56-pixel picture target are presentation constants, not additional user/server settings.

Volume/transmit preferences belong to [SPEC-004](004-media.md#configuration), account security to [SPEC-003](003-identity-security.md#configuration), and deployment credentials to [SPEC-002](002-architecture.md#configuration). The supported-platform matrix is a release declaration, not a user setting that can make unsupported integrations conformant. Web stop-on-focus-loss and server-side authorisation cannot be disabled through client configuration.

Active account, account/service records, selected text view, active voice target and operation outcomes are client state rather than configuration. Proposed initial conditions: no signed-in account, empty account list, no selected room and no active voice session; sign-in/discovery supplies endpoints explicitly with no assumed reference domain. Secure credential/key storage is a platform integration contract still to be selected, not a selectable user preference. Persisted state and schema migrations still require documentation and tests.

### Proposed successor input configuration

Canonical owner: this specification. These are proposed client preferences/profile rules, not changes to current stored `pttBinding` strings. Linking/recovery settings reference SPEC-003/006; no copies of their defaults are defined here.

| Property | Type, scope and writer | Proposed default, validation and application |
| --- | --- | --- |
| `pttBinding` successor schema | Versioned nullable tagged record: keyboard physical code, mouse button code, or joystick device selector plus button code; local client user preference | Default `null` (unbound). One binding, local encrypted storage, no account/server override. Omitted on a new profile means unbound; explicit null clears; unknown tags/codes or malformed records fail closed. Exact field names, permitted codes and device selector schema OPEN until adapters are selected. |
| Input freshness/recording bounds | Fixed client-adapter timing rules, positive milliseconds/seconds | Defaults/ranges OPEN — not selected; bound recorder lifetime, controller polling and stale-event detection before implementation. These are not arbitrary user switches that disable release safety. |

Proposed persistence/migration: convert supported existing Space/F1–F12 strings to the new keyboard record without changing the chosen key; preserve an unreadable old value for repair while leaving PTT disabled. Persist only after validation and effective registration succeeds; failed persistence leaves the change visibly unsaved and transmission closed. Cancel restores the previous valid preference, never its held state. Restore/linking must not import another platform's binding automatically. Registration, focus and current pressed state are operational state initialized inactive, not persisted settings. No secret or global key-event stream belongs in diagnostics.

### Input implementation profile (D-047–D-049)

D-049 authorises implementation of the reviewed PTT workflow. This profile resolves technical input details for that work, replacing the keyboard-only selector for upgraded clients; physical platform acceptance remains pending under D-048. It does not select the linked-device protocol.

The protected vault field is `binding`: null or `{version: 1, kind: "keyboard", code: string}`, `{version: 1, kind: "mouse", button: integer, source?: string}`, or `{version: 1, kind: "joystick", button: integer, source: string}`. Mouse buttons are DOM codes 0–4 (left, middle, right, side/button 4, extra/button 5); joystick indices are zero-based 0–127, limited further by the selected adapter. Native mouse buttons beyond the first five require a later adapter extension. Keyboard codes cover letters, digits, F1–F24, ordinary navigation/editing/punctuation and left/right modifiers/numpad keys; unavailable/reserved controls fail explicitly. Legacy Space/F1–F12 strings migrate to keyboard records. Unbound remains the default; unknown records fail closed, without changing unrelated vault data. Bindings are local user preferences with no server/account override. Clear sets null; failed save retains the prior value.

Recording times out after 30 seconds. Browser Gamepad polling runs every 16 ms while visible/focused; a gap exceeding 250 ms invalidates the held state until neutral. Native polling uses 5 ms, with the same 250 ms stall cutoff. Helper heartbeats run every 250 ms; absence for 1000 ms stops input. These are fixed input profile values, not user settings. Every activation path requires fresh input after configuration, focus/lifecycle loss or reconnection.

Linux keyboard uses the existing GlobalShortcuts portal with effective-trigger reporting. Because the portal has no held-key snapshot, an initial press/release arms a newly registered shortcut; the client shows that instruction and does not enable transmission before the release. A changed portal shortcut stops input until the user confirms it again. Mouse input reads current button state through read-only evdev on an explicitly selected `/dev/input/by-id/*-event-mouse` device; no exclusive grab, event logging, root helper, input-group membership or automatic permission change. Mouse nodes without read permission remain unusable until the user grants access to that specific device. Joystick input uses the Linux joystick API on an explicitly identified by-id device. Windows uses key/button state observation and WinMM joystick button polling, with explicit device identification and duplicate-model refusal. These adapters do not promise every controller family or elevated/anti-cheat game context; missing required hardware support remains a test gap to resolve. The browser uses focused keyboard/mouse events and Gamepad API button state. Device disconnect/ambiguity stops input; indices alone are not persisted device identity.

Native source selection lists only input-device identifiers, never arbitrary filesystem paths. The configuration page selects a source for native mouse/joystick recording where required. Input is observed non-exclusively. Diagnostics show selected control/status only, never general keyboard events. Desktop lock/suspend shuts down the helper and requires explicit reactivation; returning from a browser blur waits for fresh input.

### XWayland mouse input extension (D-053)

The human approved an X11 dependency after the installed Discord comparison. This narrowly supersedes the no-X11-dependency requirement for an optional Linux mouse helper; the application and desktop session remain native Wayland. Existing portal keyboard, selected-device evdev and joystick adapters retain their contracts.

Add the fixed input source ID `xwayland:pointer`, displayed as “KDE / XWayland side buttons (all mice)”. It uses XInput2 2.0 or later to query the logical client pointer's selected button state without event grabs, injection, keyboard key observation or direct input-device access. It supports DOM buttons 3 and 4 (physical side/button 4 and extra/button 5), mapped to X11 buttons 8 and 9. It cannot identify a physical receiver; the all-mice scope is visible. Left/right/middle remain on the existing evdev adapter because KDE's forwarding path excludes them. Reject other combinations in shared binding, IPC and native validation.

Keep the version-1 binding schema and persist this source only after explicit selection and successful input validation. Existing bindings are not migrated or automatically replaced. The list offers the source on Linux when a local `DISPLAY` is available and explains that KDE's existing legacy mouse-button forwarding must be enabled. No device permission, group or compositor policy is changed by the app. The helper accepts local UNIX-socket X displays only, uses the existing Xauthority authentication, and does not support network displays. DISPLAY/XAUTHORITY are OS session inputs, not application preferences or secrets to log.

Use the existing 5 ms sample interval, 250 ms stall cutoff and fresh-neutral gate. Initial display/extension negotiation must finish within 1000 ms; each button-state query has a 250 ms deadline. A blocked connection, unavailable pointer, stopped forwarding, helper loss, lock/suspend or display failure cannot preserve an asserted PTT state. Without a reliable indication of forwarded button state, input remains unavailable. Report the effective source and ask the user to test the indicator with another application focused; registration is not proof of physical acceptance. No automatic fallback is allowed.

For this source, recording observes both supported side buttons through the native helper rather than relying on DOM mouse events. The first fresh press after a neutral sample becomes the candidate; completion requires that same button's release. The opening click and initially held buttons cannot become candidates. The existing 30-second timeout, focus-loss cancellation, explicit Save and non-transmitting indicator remain. Native recording is allowed only for joystick sources and this Linux mouse source; other mouse/keyboard recorders retain their existing path. A source that cannot record through the installed helper reports the error without replacing the saved binding.

The Linux helper links libX11/libXi through a small C bridge; Linux builds require cgo, a C compiler and the corresponding development headers/pkg-config metadata. Windows cross-builds remain CGO-disabled. Gentoo packages declare runtime libXi and XWayland dependencies in addition to the existing X11 library dependency. The package reports its tested platform and actual ELF/glibc requirements rather than claiming universal portability.

### Selected V1 client contract (D-024/D-028)

Select React/TypeScript for the shared interface, a browser build and an Electron desktop build. A small Go helper implements XDG GlobalShortcuts activation/deactivation on Linux and Windows key press/release observation. Electron globalShortcut's press-only callback is not used as the PTT gate. Linux requires a Wayland session and native Wayland window. D-053 permits only the optional XWayland mouse-input dependency specified above; a full X11 session/window remains unsupported. Unsupported or lost global input leaves desktop participation listen-only with an explicit reason.

Initial validation targets are x86_64 KDE Plasma 6.4+ with a working GlobalShortcuts portal, Windows 11 24H2+ in ordinary non-elevated application/game contexts, and current Chromium-family browsers with AudioWorklet/WebRTC. These are selected target fixtures, not already verified support claims; record the exact actual version at each run. GNOME/macOS remain later implementation obligations. No universal anti-cheat/elevated-game claim is made.

Show account/domain, immutable private/E2EE room state, participant fingerprints/trust changes, text history, independent join/leave voice, PTT state, personal controls and a distinctly labelled moderation section in the same participant menu under D-065. Trust-on-first-use is visible; changed keys require explicit confirmation. Show unavailable historical keys separately from server history refusal. Pending/failed relay enforcement remains visible until the corresponding revision is effective.

`pttBinding` is a per-device preference, initially null (unbound). Supported initial bindings are Space and F1–F12, with no modifier combinations. A chosen binding is persisted in encrypted device storage; capture of a browser shortcut is suppressed while typing in an editable field. The desktop helper must confirm registration before transmit becomes available. Local input/output use the system default audio device; device loss closes capture instead of silently resuming. English is the initial interface language; D-066 supersedes the original fixed dark palette and D-065 exact system colours with system-selected application light/dark palettes. No deafen coupling, notifications, multi-account UI or offline send queue is introduced.

`SLOPPY_VOICE_URL` (with legacy `VOICE_CHAT_URL` fallback) selects the desktop's control origin, defaulting to loopback development only when running from source. Packaged clients require a configured HTTPS/loopback origin, supplied either at launch or by the deployment-specific package metadata under D-050. Generic packages assume no public service. Configuration ownership and precedence are in SPEC-002. Node integration is disabled, context isolation and sandboxing are enabled, and IPC is restricted to the selected origin and a narrow credential/input API. Untrusted message text is rendered as text, never HTML. Navigation to another origin is blocked.

Read-only state/history polling runs every 2000 ms while signed in; voice leases renew every 1000 ms under SPEC-003. These are fixed profile timings. Error/retry UI never equates a timeout with rollback or silently creates another command identity. Device material uses the SPEC-003 storage contract; personal gain/mute defaults remain owned by SPEC-004.

### Gentoo package and project identity (D-032)

D-202 supersedes the historical prebuilt installation contract below for new Gentoo packages. Portage fetches an immutable, public source archive and checksum-pinned Cargo registry sources, then compiles the C++20/Qt client, C helpers and focused Rust GCC plugin locally. The PipeWire GStreamer adapter comes from the system `media-video/pipewire[gstreamer]` source package. No downloaded application executable or library is installed. Use Gentoo CMake/Cargo eclasses, the selected system toolchains and user compiler/linker/job settings; configuration and compilation must work offline after fetch. Keep the established launcher, desktop identity, helper discovery, private GCC plugin path and protected profiles. New source bytes require a new upstream package version under D-184; preserve historical ebuilds and distfiles.

Build configuration: `SV_CLIENT_VERSION` is the exact immutable upstream version derived from `PV` (required, no development-version default in releases); `BUILD_TESTING=OFF` for the normal package. CMake/Cargo build directories and flags follow Portage/eclass settings. `kde` remains enabled by default; `gnome` remains disabled by default. No application setting is introduced. The source archive excludes credentials, profiles, caches, build outputs and precompiled objects. Its manifest records filename, version, byte count and SHA-256.

The display name is Sloppy Voice. The executable, package slug and Linux desktop identifier are `sloppy-voice`; native binaries use `sloppy-voice-ptt` and `sloppy-voice-relay`. The first local Gentoo package is `net-voip/sloppy-voice-0.1.0_alpha1`, installing the prebuilt Linux x86_64 Electron client and input helper under `/opt/sloppy-voice`, a `/usr/bin/sloppy-voice` launcher, icon and application menu entry. It does not start or install a control service, alter an account, merge packages automatically, or disable Chromium's sandbox. The historical alpha.1–alpha.5 archives were staged locally in Portage's `DISTDIR`. D-061 supersedes that requirement for alpha.6 onward: the ebuild fetches the published, versioned Linux archive from the existing `www.sloppyvoice.com/releases/` service using ordinary Portage distfile configuration, without a manual copy or private-repository credentials. D-035 replaces the application's temporary `all-rights-reserved` marker with Apache-2.0 and removes the licence-based `bindist` restriction. Those historical prebuilt ebuilds remove `RESTRICT=fetch` and the manual `pkg_nofetch` instructions; their `mirror`/`strip` restrictions and dependency licence entries remain. D-202 source packages retain ordinary fetching and standard strip/QA behavior. The ebuild source retains its explicit GPLv2 header.

D-181 makes project and local-overlay alignment a client-release completion requirement. The ebuild and Manifest in `packaging/gentoo` and `/var/db/repos/local-overlay` track the latest published compatible native source package under D-202, with a fresh-cache Portage fetch/digest check for a newly published package. A shared-interface-only release may retain its compatible native sources; verify the overlay still points to that current installable package. Existing versioned archives/digests remain immutable, and updating the overlay never merges the package automatically. The release procedure is in [docs/deployment.md](../docs/deployment.md#automatic-gentoo-downloads-d-061). This adds no runtime setting or application unit; package/manifest/fetch verification is the acceptance evidence.

D-184: every ebuild update, including changes to installed launcher/files or packaging behavior, publishes a higher Portage package version. Use the new upstream version when publishing new archive bytes; for the same immutable archive, increment the ebuild revision (`-r1`, then `-r2`, and so on). D-210 (alpha releases): keep only the current ebuild, its files and its Manifest entries, matching the website's most-recent-build-only downloads; remove earlier ebuilds from both overlays when a newer one is published. Installed older versions still upgrade normally. The ebuild resolves its archive from `PV`, excluding `PR`, so a packaging revision still fetches the same digest-verified release bytes. Verify version ordering and an ordinary Portage update/pretend plan against installed versions; never rely on an in-place ebuild edit or `--changed-deps` to trigger the update. Both project/local overlay must agree. No new runtime setting or application unit applies. This is package revision metadata; installation remains a human action.

Desktop package metadata declares `Apache-2.0`. Each Linux/Windows archive includes the project's LICENSE and NOTICE as `LICENSE.sloppy-voice.txt` and `NOTICE.sloppy-voice.txt` at the archive root and as `resources/app/LICENSE` and `resources/app/NOTICE`. Electron's existing `LICENSE`, Chromium's `LICENSES.chromium.html` and the native helper's `LICENSE.godbus.txt` remain intact. The copyright and interoperability policy is owned by SPEC-000; packaging does not change it.

D-144 Linux archives additionally include `resources/sloppy-voice-audio`, dynamically linked to the host `libpipewire-0.3` library. Source builds need its development headers and pkg-config. SPEC-023 owns runtime capture dependencies and behavior. The alpha.27 Gentoo package declares the PipeWire library dependency; immutable older packages retain their original dependencies and video-only behavior.

The launcher requires Wayland, uses KDE's secure key storage when available, and reads an optional per-user origin file as data rather than shell code. Its environment/path configuration is owned by SPEC-002. Existing browser device storage remains `voice-chat-device-v1`; the desktop retains its pre-rename profile when found, preserving encrypted keys. The `voice-chat/1` wire profile remains unchanged. A product rename is not a key rotation or protocol migration.

Package validation covers metadata/Manifest resolution, shell and desktop-file syntax, launcher origin precedence and argument preservation, and Portage's unpack/prepare/install phases into a staging image. For D-061, run the real Portage fetch phase with an empty disposable distfile cache and verify the downloaded bytes against the unchanged Manifest; no new application unit is needed for the ebuild URL. Archive inspection checks the exact project licence/notice contents and package metadata and confirms that existing third-party notices are preserved. Native physical key handling and microphone acceptance remain the separate real-platform gates above.

### Linux Flatpak publication (D-160)

Public platform labels say Linux, without naming a desktop environment/display protocol as the product. Precise native prerequisites and validation limits remain in technical installation/release records. Publish a downloadable x86_64 `.flatpak` bundle using the existing verified Linux desktop archive, with an independent manifest under SPEC-002. The bundle preserves the archive's wrapper version and hosted-service default; it does not bundle concurrent client changes. This first distribution is a direct website bundle, not a Flathub listing or automatic-update repository. Present Flatpak before the x64 archive in the Linux download card, keeping each package’s installation guidance with its download.

The packaging profile is `packaging/flatpak/profile.json`: application ID `com.sloppyvoice.desktop`, branch `stable`, Freedesktop Platform and Electron2 BaseApp branch `25.08`, command `sloppy-voice`. Use Zypak for Electron sandbox integration, retain renderer sandbox/context isolation and OS-backed encrypted storage, and never add `--no-sandbox` or a plaintext vault fallback. Runtime dependencies are obtained from the official Flathub runtime repository; record exact runtime/base commits as build evidence. Generated AppStream catalogue metadata explicitly declares CC0-1.0 as the format requires a supported permissive metadata licence; application code and notices retain Apache-2.0. No application signing identity is invented: this alpha bundle is unsigned and its exact size/SHA-256 are published.

Grant only the integrations required by this desktop client: network/IPC, Wayland and X11 sockets (the native mouse adapter also uses XWayland), PulseAudio microphone/playback, GPU and input devices (host read permissions still apply), the PipeWire socket for explicitly selected application sound, read-only `xdg-config/kwinrc` for existing compositor mouse-forwarding policy, and specific Secret Service/KWallet D-Bus names for OS key storage. Do not expose the whole home directory, session/system bus, arbitrary host command execution or all devices. Portals retain their approval flows. A packaged PTT launcher reads the conventional host `.config/kwinrc` path via the declared read-only mount while keeping the application profile in Flatpak's private configuration directory; nonstandard host XDG config layouts may require a portal/raw-input source instead. No host settings or input permissions are changed automatically.

Flatpak has its own profile under `~/.var/app/com.sloppyvoice.desktop`; do not share/copy the native archive's device vault. Link the Flatpak as a new approved device using SPEC-011. Installing a newer bundle with the same application ID/branch retains its profile. Ordinary uninstall retains app data unless the user explicitly chooses data deletion. The download page gives `flatpak install --user ./FILENAME` and `flatpak run com.sloppyvoice.desktop`, states that Flatpak and the runtime download are required, and explains manual bundle updates and separate-profile linking. Device/capture support remains dependent on the host portal, audio service and permissions; packaging success alone does not establish physical microphone, global-input or capture acceptance.

### Portable Windows publication (D-155)

Publish the existing install-free Windows x64 ZIP format as a separate download option. Extract the complete archive and run `sloppy-voice.exe` inside its folder; no installer, administrator access, Start menu registration or automatic updater is required. Bundle the Electron runtime, matching native PTT helper, project/third-party notices and START-HERE instructions. Retain the existing packaged HTTPS server default and override contract from SPEC-002. Device keys/settings remain in the normal Windows user profile under the existing OS-protected vault contract; copying the application folder does not transfer an approved device or its keys. Close the app before extracting an update into a new folder. This does not introduce USB-carried profiles or claim completed physical Windows acceptance.

The public page shows the ZIP's own version, format, size, SHA-256 and launch/profile guidance beside the installer choice. Its version may differ from the retained installer/Linux pair because compatible desktop wrappers load the current hosted interface. SPEC-002 owns the required portable release manifest and SPEC-008 owns download responses.

### Windows installer and deployment packages (D-050)

Alpha.3 packages the existing PTT implementation and adds a Windows x64 offline NSIS installer using pinned electron-builder tooling. Technical completion choices under D-024/D-050: install for the current user under the standard local Programs directory, retain the stable application ID `com.sloppyvoice.desktop`, provide a Start menu shortcut and Windows uninstall entry, and require no elevation. The assisted installer allows choosing an installation directory. No desktop shortcut, automatic application launch, login startup, service, file association or automatic updater is installed. The existing portable ZIP remains available.

Updates replace application files in the selected installation directory. Install/uninstall does not delete the separate device profile or encrypted vault; uninstall is not account deletion. Preserve legacy profile selection and per-origin vault identity. The installer includes the same native helper, runtime, project and third-party notices as the portable client. This testing build is unsigned; neither a compiler success nor a Wine smoke test establishes Windows SmartScreen reputation or Windows hardware acceptance.

The release configuration is `packaging/windows/electron-builder.json`: `oneClick=false`, `perMachine=false` with a forced-current-user installer macro, `allowElevation=false`, `allowToChangeInstallationDirectory=true`, `createStartMenuShortcut=true`, `createDesktopShortcut=false`, `runAfterFinish=false`, `deleteAppDataOnUninstall=false`, and `packElevateHelper=false`. These are fixed package profile choices, not server policies. The package's optional public origin is owned by SPEC-002. No credential, bootstrap token, TURN key or user vault belongs in distribution artifacts.

Validation covers origin precedence and rejection, package identity/payload, installer compilation and extraction, and install/update/uninstall behavior with a disposable profile where a compatible test runtime is available. Preserve a marker in that disposable device profile across updates/uninstall. Real Windows 11 installation/launch, secure storage, microphone and physical PTT remain platform acceptance gates. Gentoo validation uses the matching release archive and staged Portage phases without merging the package.

### Selected Cloudflare alpha behavior (D-043, D-054)

D-043/D-054’s Cloudflare client first prepares a relay path without joining live attendance. Show connecting state and permit cancellation; poll the same preparation ID within its server deadline. Use only the returned, validated Cloudflare TURN UDP/TLS URLs with relay-only ICE. Gather a usable relay candidate before requesting live admission and a fresh forwarding grant; renew admitted authority during connection establishment. Show the shared generation's remaining time, warn within its final five minutes and close at its deadline. Cancellation, stale generations, provider failure and restart clear PTT and never automatically rejoin or select a direct/reliable transport. Detailed preparation wire fields are owned by SPEC-009; timing/defaults by SPEC-002.

### Public website (D-051/D-151/D-154)

D-158: sections offering browser participation on the homepage and download page state that browser use requires local storage on the device for encryption keys. This describes the existing SPEC-003 browser key vault (IndexedDB), introduces no new storage mechanism or configuration, and does not mean the JavaScript localStorage API. Validate the rendered wording in both sections and preserve working browser/download links. Static copy needs no new application unit test.


D-170 adds the existing Android test APK to `/download` in an explicitly labelled **Experimental** card. Show its own Android build version, APK format, byte size, SHA-256, direct public download and installation instructions. State that it is debug-signed, has emulator validation and has not been validated on physical phones. Explain opening the downloaded APK and granting installation permission to the chosen browser/file manager if prompted, recent Android System WebView requirements from the Android contract, device linking, and that uninstall/clear storage removes this Android device identity. Updates with the same signing key retain it. No store listing is implied. Keep desktop packages available.

The public website presents a landing page and `/download`. D-151 replaces the Windows-first presentation with equal Windows and Linux download cards, side-by-side when space permits and stacked on narrow screens. Each exposes its actual package version, format, size, installation guidance and SHA-256 verification. Preserve the unsigned Windows alpha notice and platform validation limits. Use a reusable card layout that can accommodate another desktop package and adjacent mobile store links later; do not render macOS, iOS, Android, placeholders or coming-soon claims before those apps exist. This does not select future packaging or store URLs. The existing required release manifests and build verification remain owned by SPEC-002; no new runtime configuration is introduced.

The homepage uses the Editorial design approved under D-154. Lead with self-hosting and federation while making hosting optional: a public server operator can handle setup and maintenance, and either kind of home account can join permitted channels on compatible servers. Explain separate access and encryption choices, invitation-free public admission versus private-server invitations, and server/channel/user bandwidth controls. Higher direct video rates apply only to eligible private encrypted calls and still respect personal limits; relayed traffic remains subject to host/channel limits. Describe video as screen sharing, not webcam publication. Do not highlight push-to-talk in homepage/download promotional copy. SPEC-015/022 own federation and access, SPEC-003 encryption and SPEC-023 screen-sharing/rate policy. D-153 enables public visitors and local registration on sloppyvoice.com, so the site may name it as an invitation-free public example. Do not promise unrestricted admission, universal interoperability or a turnkey hosting installer. Current hosting requires technical deployment work and source access remains restricted during testing. Account instructions reflect linked devices under SPEC-011, superseding the obsolete one-device website wording. Reuse Sloppy Voice branding and the reviewed lavender editorial treatment, follow system light/dark appearance on these two pages, keep mobile and keyboard navigation usable, and require no account or script to read the page or download. Preview-only design controls and inert mock buttons must not ship; real navigation/download actions use working links.

The desktop window sets Electron `webPreferences.backgroundThrottling=false` as a fixed implementation policy so voice renewal and input gates remain scheduled while minimized or behind another application. This does not inhibit OS sleep or change lock/suspend PTT shutdown. The browser client retains its focus-loss gate and browser scheduling limitations. Relay renewal allows up to 2500 ms for the HTTP acknowledgement, including its JSON body, instead of the premature 1500 ms client cutoff found during the hosted soak. Require an acknowledged `expiresAt` equal to the current control grant and still in the future. This never extends the SPEC-003 three-second lease: expiry closes the local gate and the relay independently rejects expired authority. A late success cannot restore a held PTT input. Error, denial or deadline still closes the session without automatic rejoin. Disconnect status is published immediately when local media closes, before best-effort remote cleanup, and remains visible until explicit rejoin or another lifecycle action. No automatic rejoin or longer forwarding lease is introduced.

The D-053 helper checks `kwinrc` in the standard user configuration directory at registration and every 250 ms. It requires `[Xwayland] XwaylandEavesdropsMouse=true` and an explicitly supported `XwaylandEavesdrops` mode (`Modifiers`, `Combinations` or `All`). Missing, unreadable, disabled or unknown policy fails closed with setup guidance. It never writes that file. These external KDE prerequisites are not application defaults.

D-162: Render local outgoing messages under SPEC-013 before awaiting network acceptance. Apply eligible synchronized history before unrelated visitor home contact/profile requests; slow address-book refresh must not delay an already-received transcript or the next transcript poll. Run at most one independent home contact/profile refresh at a time. Preserve account/channel context checks, encrypted-history verification and the original pending-command retry boundary.

Native account-store engineering profile: the root authenticated vault may use `nativeStoreVersion: 2`, `profiles: {<local UUID>: {base,data}}` and optional `selectedProfile` (absent means no selection). Each record keeps an unchanged version-1 native profile in `data`, bound to its canonical service `base`; the local record UUID is a storage locator, never an account or server authority. The existing total vault byte bound, OS key, locking, atomic writes and unreadable-data preservation remain authoritative. Upgrade a valid native version-1 root into one record without replacing device keys or dropping preferences, history keys or pending records; reject unsupported versions without writing. A client obtains one exclusive writable profile view; writes preserve all other records and cannot change the bound base or an established qualified account. Local selection alone has no remote or media effect. Metadata listings exclude tokens/private keys. Failed persistence leaves both in-memory and protected state unchanged, and views fail after their owner closes. Normal startup now supplies the selected profile view to the GUI; an empty root creates only a configured-service profile shell, without generating or replacing device keys. An existing native-v1 root follows the same lossless upgrade. A selected retained profile uses its own pinned service base, independently of the configured base for a new profile. An existing store with no selected record opens the account chooser without loading another profile or dispatching an authenticated fallback; selection requires an explicit choice and the same checked transaction. Full destination/account action coverage and installed Electron conversion still require their separately validated paths. No runtime plaintext adapter or new user preference is introduced.

Native ordinary destination-channel context engineering profile: an explicit context receives one known home account, one pinned destination and its exclusive protected connection-state view. It retains no duplicate private account keys, passwords, recovery secrets, trust or listening preferences. Revalidate public destination authority, restore only its scoped session, and obtain a permission-filtered room list without joining text or capturing media. An explicit channel open validates the exact requested room/server and extending current own proof before replacing its previous usable view or persisting selection. Authoritative destination self/role stays separate from the home account role. Only verified public own root/roster advancement may update the home profile, atomically and without copying destination roles. Stale/invalid state cannot enable posting.

The context uses existing bound message encryption/decryption and qualified home trust; missing recipient verification pauses posting, without plaintext or recipient omission. Keep its channel drafts and last history positions in the exclusive connection view, coalesce draft writes for 300 ms with at most the existing 2 MiB vault bound in dirty draft bytes, flush before leaving a view, and merge writes through the native root owner, and retain one bounded 250-message loaded window. Only an explicitly opened foreground channel polls the existing sync route every 2000 ms; background room-list refresh is explicit and cannot load conversation history or join. Ticket/payload/revision/room are protected before a command is sent; retain unknown outcomes across restart and require exact explicit retry, without retargeting another room. Authentication/permission failure (401/403) on retry cannot prove the earlier mutation was rejected, because SPEC-009 checks current permission before result disclosure; both native home and destination paths retain the exact pending operation until authorized reconciliation. Account/key loss and destruction fence late callbacks and stop this context; changing text selection cannot mutate another API or call. This increment owns ordinary foreign channel text only: native multi-server/account UI, global background scheduling, cross-host voice claims and source-host history management remain required integration work. No new runtime preference or protocol default is introduced.

Native retained destination-session proof restoration: restoring an already protected, previously validated session may encounter a genuine older public login proof after the known home approval head advances. A C++-only `RetainedSession` construction source verifies that the known current home proof extends that saved proof, requires the unchanged qualified account/name/root and exact still-approved operational device, and advances only the runtime account's public root/roster fields to the already verified home head. Preserve destination role/labels, original token/session deadlines, issuer/audience and server binding; never copy a home owner role or replace a saved device. No account/device is approved by this normalization and no authority is inferred from the old proof alone. Fresh login construction remains strict: returned proof must extend the known home head. Root forks, changed identities, removed devices, wrong endpoints and invalid/expired credentials remain rejected. The source selector is a typed internal call-site distinction for protected restoration, never a JSON field, runtime setting or remote trust override. Subsequent live destination snapshots retain their independent current-proof and recipient checks.

Native saved visitor sign-out state (D-118/SPEC-015): a destination connection can retain `pendingJoin:false` and `signedOut:true` while keeping its qualified account/profile reference, pinned server, public prior destination identity, selected room, drafts/cursors and pending state. `signedOut` is optional operational state; omission means no explicit local sign-out marker, and only literal true is accepted when present. A signed-out `login` contains only public `self`, `server` and optional validated `landingChannel`; it must omit both token and session metadata. Cached public verification keys may be omitted, or retained only with the matching issuer/audience. Home credentials remain solely in the account profile, so this flag is invalid for home records; it cannot coexist with `pendingJoin`. Signed-out metadata cannot create a runtime authenticated connection, imply current channel access or delete remote membership. Explicit rejoining replaces only its destination login state while preserving its drafts/selection. A genuine older public approval proof may remain readable after that same account's approved device changes, but a substituted root or fork remains invalid. Local sign-out, not-joined, expired authorization and remote membership remain distinct. The native selected-server Sign out action retires only its destination credential after confirmed logout (or an explicit authentication rejection), keeps account keys/home login and scoped drafts/positions, and stops that connection's runtime authority. Pending commands must be reconciled first. A failed request/save reports the failure without claiming successful remote sign-out. A retained signed-out context restores public status without authenticated requests or conversation history. Explicit Rejoin uses fresh checked admission and changes only the destination login. Admission owns a process-local mutation guard so another send, logout or competing rejoin cannot race replacement of the same destination credential. Ordinary Add server reuses an existing admitted saved sign-in instead of rotating it. Full multi-account/media orchestration remains required.

Native saved-connection storage engineering profile (SPEC-015): version-2 roots may additionally retain `connections`, `selectedConnection` and `serverAccounts` alongside profiles. A connection key includes the exact destination UUID and qualified home account; its immutable record references the sole account profile and pinned UUID/domain/base. Metadata listings exclude session material. Home connections retain their account-owned credentials, while visitor views contain only destination session/context and independent channel/draft/cursor/pending state, without duplicating private account keys or personal trust/preferences. The central root writer merges account and connection saves atomically. A changed UUID/domain/base or account/profile reference cannot overwrite a retained connection; a display-name update may. Persisted expired sessions remain dormant data and require normal fresh discovery/session validation before dispatch. Selecting a connection updates its qualified profile and that exact server group's browsing selection in one protected write; selection alone has no remote/media effect. Removing an unopened visitor view removes only its connection data/drafts and orphaned browsing selections, returns a selected visitor to the same account's home connection if present, and retains that account's keys and remote membership. Home records cannot be removed while their profile is retained. The runtime controller must close the matching call/view before removal. Existing roots without connection records remain readable without a rewrite. Failure leaves both root and runtime state unchanged; closed owners cannot write. Full multi-server UI, background scheduling and call orchestration remain required separately.

Native visitor-admission engineering profile: only an explicit join invocation starts admission. Snapshot the selected signed-in home account, approved device, canonical home descriptor and account generation. Revalidate the destination through bounded public authority discovery before requesting the existing destination-scoped home directory grant; send that grant and a fresh signed visitor-join proof to the exact destination, never a home token/password/private key. Validate returned home/host bindings and a nonexpired safe-integer grant timestamp. Fetch destination login verification keys without credentials and validate the destination session, exact server identity and unchanged qualified home/root/approval history before returning a connection. Signed JWT sessions bind `aud` to the exact destination UUID, as SPEC-003 requires. Existing SPEC-015 visitor sessions remain canonical 32-byte opaque credentials with explicit `signed:false`, exact account/device/server binding and finite 12-hour issuance/expiry metadata. This format is accepted only for a foreign account and cannot admit a local account, malformed JWT, missing/expired timestamps or unlimited data. The module does not save/select a connection, join channel text, create voice/capture, create an account or follow a redirect. Owner loss, home logout/replacement/destruction and explicit cancellation suppress all late results and later dispatches; returned connections also close when that home account ends/changes. Limit admission jobs to 32 and use a fixed 45000 ms total deadline in addition to existing per-request deadlines. Metadata-reader injection exists only as a C++ test seam; no runtime network/authentication bypass is added. Full saved-connection/UI orchestration remains separate required work.

Native login-session integration engineering profile (D-103): one session controller belongs to each native home account and shares its guarded immutable API/active-token provider. Refresh authenticated metadata at account entry, every 60000 ms, application focus and Preferences entry, with one controller job at a time. The pure clock schedules warning/expiry presentation transitions. Known expiry/rejection retains identity keys, room/history selection, drafts, pending commands and preferences, while stopping ordinary account dispatch, group presence and media; explicit same-key sign-in remains available through the verified home authority. A failed password renewal cannot expire an otherwise valid old credential.

Persist `nativeLoginRenewal:{version:1,base,serverId,account,device,previousToken,login,loginKeys}` in that account's protected profile before activation. Validate its exact home/account/device, unchanged root/extending proof, signed candidate, pending status, token difference and signed session-family continuity before any candidate credential dispatch. Private account keys remain solely in the profile's existing key field. Activate with the existing purpose-bound device proof; verify returned active metadata and fresh home login keys before adoption. Successful renewal changes only active credential/session state and never emits a voice-ending event or changes selection/drafts/keys. The durable candidate survives unknown activation/restart. After confirmed activation, use the new verified token immediately; a failed final protected write retains the durable candidate for idempotent reconciliation and does not revert runtime authority to the retiring token. Stale account preference writes preserve this pending record through the single owning profile writer. One immediate retry after 1000 ms addresses an unknown activation result, followed by the existing minute refresh or an explicit Retry; do not start overlapping jobs or retain/retry a password. Logout/account loss/destruction cancels in-flight work; a normal fresh sign-in or confirmed device logout clears a superseded pending credential. Invalid/revoked pending credentials cannot become ordinary authority. These are fixed engineering/state rules, without a new user setting.

Preferences uses a standard scrollable form bounded by the available desktop viewport, with Close outside the scrolling body and wrapping qualified identity labels. It uses modeless controls with qualified account, session status, an inline password field cleared on submission, Renew/Retry actions and visible failures. The main workspace shows only the existing subtle due/expired notice with an action to open these controls. Native session behavior remains an implementation-in-progress release gate until generated lost-reply/restart/storage/expiry/call-preservation fixtures pass.

Native login-session time model (D-102/D-103): validate home-authenticated session metadata against the exact account/device and SPEC-009 fields without treating metadata alone as token authorization. Require safe integer millisecond timestamps within the supported Date range, an explicit boolean signed flag, a present finite expiry or signed null Unlimited, and no prepared/pending session as active authority. Optional retiring state remains finite. Validate a new observation completely before replacing the prior clock. Anchor server time conservatively at metadata request start on a monotonic clock; elapsed request time cannot extend expiry. Compute the existing final-24-hour/final-10% warning boundary, exact expiry and next presentation transition without a one-second GUI polling loop. Clock regression or unsupported elapsed time invalidates the estimate until fresh authenticated metadata arrives. Missing/invalid metadata never becomes Unlimited. This pure model owns no credentials, network, storage, renewal or capture; its native metadata refresh, protected handover and Preferences integration follow the preceding profile and remain a release gate until combined validation passes. No new configuration is introduced.

Native home authority revalidation engineering profile: initial public info establishes the protected exact home UUID/domain/base, including before restricted linking/recovery stores completion credentials. Subsequent account operations (including password/restricted operations) wait for a matching authority verified within SPEC-010's 300000 ms maximum, measured from request start on a monotonic clock. The fixed canonical home `api/server` read sends no bearer, device proof, cookies or application capability header; use the existing 16384-byte public JSON and 5000 ms absolute request bounds, with no redirects. Public HTTPS remains required except the existing explicit configured loopback development service. Concurrent operations share one metadata read, retain copied immutable request context and remain inside the existing 32 pending-operation bound. Cancellation, account generation and owner destruction suppress late credential dispatch. Beginning logout fences older queued account work before its own logout request; a failed logout may resume text/status polling but cannot restore voice/group presence automatically. An unavailable/late response never extends cached authority; clock regression requires fresh verification. A changed UUID/domain/base permanently closes that instance's account transport and media intents with credentials/data retained for explicit repair/reconnect. A name-only change does not change authority. The C++ metadata-reader/clock adapters exist only for deterministic tests and add no runtime setting or network bypass. This completes periodic authority checking separately from session expiry/renewal and full multi-server orchestration.

Native home-startup binding: before any restored credential or account operation is dispatched, validate the configured service’s initial public info and exact server UUID/domain/base against the protected `homeServer` descriptor. An older native signed profile without that descriptor may recover the pin only from its already protected token’s exact issuer/audience/account/device fields; absent or incompatible legacy trust requires explicit repair/reauthentication with keys/data retained. A successful authenticated login checks the public keyset audience against the verified info UUID and retains that home descriptor. Keep public info unpublished to the UI and the account transport disabled until these checks succeed; mismatch cannot be bypassed by opening another account dialog. Pin persistence must succeed before credential dispatch and a failed write retains prior protected data. This restores SPEC-015’s startup boundary. The periodic revalidation profile extends that startup check. Native session renewal/expiry follows the preceding integration profile; complete saved-account orchestration remains required release work.

Native current-account sync remains bound to the requested channel and, when the room carries a server UUID, the verified selected server. Reject a different account/device/name/root or non-extending own approval history before publishing state. Advance only the own signed root/roster fields in the protected account identity, retaining its keys/token and unrelated profile fields; persist before exposing the newer proof. Identity-proof or persistence failure stops this account’s polling/media intents, closes its account transport and invalidates late callbacks while retaining protected data and unsent text. A wrong-channel text response is rejected without moving an unrelated call. These are SPEC-003/011/015 integrity rules, not new account or media policy.

Interrupted recovery in a retained native profile keeps its prior approved identity/private keys separate from the new protected pending recovery keys. Startup validates the historical saved identity against the prior stored device, never against the replacement pending device, and keeps any prior account bearer inactive while resuming the restricted recovery completion. Server/domain/base pins still apply. Successful recovery/login alone atomically activates the pending keys; lost/expired completion follows SPEC-011’s existing exact-retry or explicit same-key restart behavior. No new device is approved and no prior key/token is silently reused for normal account actions during this pending state.

Web authenticated API reads stream and count decoded bytes before parsing, cancel on overflow and retain account/abort fences. Fixed conservative client capacities derive from SPEC-009/011 limits: metadata/errors use the existing 16384-byte discovery allowance; history uses `DISCOVERY.bytes + LIMITS.historyPage * (LIMITS.envelope + 3 * LIMITS.body + DISCOVERY.bytes)` (145014784 bytes); control uses `(LIMITS.accounts + LIMITS.members + 4) * LIMITS.body + (ROOM_LIMIT + DIRECT.conversations * (LIMITS.members + 1)) * DISCOVERY.bytes` (109314048 bytes); sync permits their sum (254328832 bytes). These implementation capacities preserve supported envelope/roster/share/navigation shapes; they are neither new server quotas nor a claim that maximum-size responses are cheap. Public discovery and native bridges retain their distinct owning contracts.

Web retained-history work is owned by the exact account/API/Host context. One refresh issues at most two history requests at the existing two-second poll cadence, retaining cursor/revision state and a loading indication until older eligible pages finish; unchanged polls do not refetch old pages or rewrite protected state. Revision changes rescan safely and reauthenticate changed copies. A single collection deadline removes expired records/plaintext, with visible-resume checks. Reader caches retain only immutable records under unchanged account/keys/trust/room/encryption/retention; collapsed replies release hidden DOM while eligible reply drafts and older retained history remain available. Resolve a saved reply target from current verified retained records again at submission, including original expiry before a display tick; preserve the draft and use the permitted surviving anchor if its former parent expired. Keep an explicit eligible parent when it remains available. Recent/local read evidence comes from the authenticated projection committed to the selected visible transcript, including only original rows and currently expanded replies; expansion and collapse update that projection. Never derive encounters from download cursors, collapsed unmounted reply content or unverified author metadata. No arbitrary new loaded-history cutoff is selected. Presentation accounting belongs to the publisher attendance across publication/encoder replacement; direct recipient meters retire only when their authenticated voice attendance ends or changes. Unwatch, key unreadiness and route pauses retain credit. Retiring a recipient also drops its old queued copies, and call disposal releases all meters. This lifetime follows SPEC-023’s existing bucket rule, without a new aggregate bitrate or identity quota.

## Testing

D-227/D-228: apply the library, logical-server isolation and control-projection tests in [SPEC-028](028-developer-api.md#testing); official-client compatibility is established by default-history filtering, separately from API opt-in.

D-226: generated Qt/service tests exercise the saved-server context menu, initial Invitations tab selection, new local account registration with the copied link, existing-account server grant and unchanged inviter channel/keys. Management and URL units cover allowed server commands and the scoped accounts route.

D-225 native transcript units exercise incoming appends at bottom and above bottom, returning to bottom, consecutive refreshes before the next event-loop turn, tall wrapped messages, short-to-overflow transitions and outgoing-row updates. Assert the final scrollbar maximum when following and the exact prior position when reading above bottom.

D-224 widget/integration tests verify that setup stays a dialog until publication, successful sharing destroys setup without stopping capture, a main-window child pane exposes the original account/call and Stop, ordinary text navigation preserves the share, and Stop hides the pane and releases capture while voice remains active. Verify inactive/unbound and owner-destruction cleanup, call switching, setup cancellation/failure and native large-font reflow. Generated private portal/native and managed fixtures validate media lifecycle separately from actual desktop consent.

D-223 actual-widget keyboard tests cover Return and keypad Enter, Shift newlines, disabled/pending/read-only submission, held-key repeats, input-method preedit and reuse of the ordinary Send and inline-reply actions. Assert exact multiline payloads, unchanged drafts after blocked/rejected sends and existing retry behavior.

D-221: `tests/event-hints-client.test.ts` (fake sockets and clock) covers ticketing and the exact subprotocol offer without URL credentials, watch union/deduplication, heartbeat, ready/pong timeouts, malformed frames, disablement on old servers/`401`/missing echo, backoff on `429`, renewal closing the predecessor (including failed renewal tickets and stale callbacks), `4001`/`4401`, stop and context switches, registry sharing/caps/close, the unchanged two-second cadence, spacing, single dirty rerun, poll push-back, the per-minute hint cap, `429` throttling including a rerun queued before throttling, and busy external reads. `tests/event-hints-budget.test.ts` couples the real hub pacing with real `HintedPoll` loops for two devices and records per-window counts, `429`s and commit-to-read latency across arrival phases, busy and unrelated-room traffic and heavy background load (`reports/server-performance-council/websocket-budget-simulation.json`). `tests/ios-event-socket.test.ts` covers the iOS bridge `EventSocket`; Swift broker compilation and device behaviour require macOS/Xcode qualification. `tests/event-hints-lifecycle.test.ts` covers the foreground hook: only `online` and `sloppy-foreground` reach `online()`. A no-call background (`1001` then refused `1006` opens) followed by the foreground event reconnects within 1 s with reset backoff and a READY recovery read. Without it the grown backoff exceeds 1 s, and ready or closed channels are unaffected. A static check confirms VoiceHost dispatches the event only on return from the background, after re-allowing sockets, without touching capture or call state. `tests/home-refresh.test.ts` covers `CadenceGate`: defaults, the 1950 ms boundary, jittered ordinary polls all qualifying, hint-paced starts limited to one per period (≤ 31 per fixed minute), and key change and rollback. `tests/event-hints-foreign-budget.test.ts` is a composed seam. It uses the real Home and host Services, the real host hub and the real `HintedPoll`/`CadenceGate`, and mirrors the `main.tsx`/`direct-workspace.tsx` request plan without rendering the components. Two or three simulated devices share one visitor session and one Home session, because both buckets are per account. It records Home and host per-minute counts and `429`s against the pre-hint plan, and it reports already-over-budget baselines separately (`reports/server-performance-council/websocket-foreign-home-budget.json`). Browser evidence beyond unit tests: `tests/event-hints-browser.mjs` (client module injected into a real page) attributes latency to each exact accepted sequence for hinted and polling-only runs. `tests/event-hints-app-browser.mjs` runs the actual bundled application (private temporary build) against the local server. It covers:
  - hinted retrieval and render with the causing hint frame;
  - socket loss recovered by polling without a visible error;
  - foreground reconnect and recovery read;
  - a held stale lobby response not repopulating another channel or its draft;
  - no hint for an unwatched channel;
  - silent polling on a server without the capability and on a ticket `404`;
  - an unchanged active call;
  - same-account session replacement re-ticketing with the new credential only.

  Both browser runs use ten or fewer samples per phase and are smoke evidence, not percentile estimates.

D-221 native Qt unit tests: `native-event-hints` (CTest, `native-client/tests/event-hints.cpp`) has 12 test functions (14 QtTest results including init/cleanup). They run against a real loopback `QTcpServer` front end that hands accepted handshakes to `QWebSocketServer`. They cover:

  - frame parsing parity with `parseServerFrame`, plus bounded watch frames and URL mapping;
  - a handshake carrying only the subprotocol ticket;
  - ticket outcomes: `400`/`403`/`404`/`405` disable after one request, `401` uses the slow retry, `429`/`5xx`/transport errors and malformed tickets back off without disabling;
  - replayed, expired and unechoed tickets never reaching READY;
  - invalid, oversize and binary frames closing the socket;
  - heartbeat, pong and idle reconnect, plus `4001`/`4401`/restart recovery;
  - coalesced watch frames;
  - registry sharing, the six-socket cap, supersession and `clear()`;
  - stale ticket callbacks unable to retarget a stopped channel;
  - the scheduler's single rerun, spacing, per-minute cap and `429` throttle.

Integration fixtures run outside CTest because they need Node. `scripts/test-qt.mjs` runs both in the release gate and the `--sanitizers` gate and writes their evidence to `native-integration-events-{service,federation}-evidence.json` in the selected build directory. Routine gates therefore never overwrite the published `reports/server-performance-council` evidence.

  - `native-events-service.mjs` drives `native-event-hints-service-tests` against the real Node `Service` (SQLite through `observeSql`), `EventHub` and `ws` adapter. It covers hinted latency against socket-refused polling, outage, restart and READY recovery, one rerun for a hint during a held in-flight read, two native clients on one account across two 30 s budget windows, and sign-out closing every socket with no later owner request.
  - `native-events-federation.mjs` drives `native-event-hints-federation-tests` against two canonical authorities over TLS through the CONNECT proxy. It covers Home plus a foreground destination and a cross-home conversation authority, upgrades without Origin, cookie, Authorization or proof, destination and foreign hinted latency, watches limited to the open view, targeted authority list reads during acceptance, and a revoked visitor session closing `4401`, after which the ordinary read ends the session and its socket.
  - With `SV_NATIVE_EVENTS_VOICE=1` the service fixture also starts the real project relay (`.local/native-client/fixture-relay`). It keeps one real native call active on one of the two clients through both windows (`VoiceSession`, fixture `AudioDevice`, no microphone, speaker, camera or screen, private D-Bus session) and skips the latency and outage segments. Its per-route counts include the actual `/voice/lease` renewals. The statistics footer (`ConnectionStatus`, `sloppy-native-ui`) is not linked into this core fixture, so its `/statistics` requests are not measured.

  - The capability gate is covered at two levels. `native-server-connection` (`eventCapabilityGateUsesCheckedPublicInfoWithBoundedWindows`, injected clock and sender) covers a credential-free single read after the authority check, the 300 s window boundary, absent capability, and 404, transport, mismatched-identity and invalid-metadata failures, each retried exactly at 30 s. It also covers a due retry waking its waiter, late answers after `close()` being ignored, and destroyed waiters never being called. `native-capability-federation.mjs` drives `native-event-hints-capability-tests` against the same two canonical authorities, with the foreign `/info` advertised, stripped, refused (`404`) or held, and the ticket route optionally `404`. It covers an old destination and an old conversation authority (zero tickets and upgrades, one `/info`, polling within 2.6 s), a refused lookup (silent polling, then exactly one retry and READY at ≥ 28 s, then hinted latency), a held lookup released after the view left the foreground (no ticket; returning reuses the cached answer), and an advertised authority's ticket `404` (one ticket, disabled, polling). Every foreign `/info` is checked to carry no Authorization, proof, client header or Origin. `scripts/test-qt.mjs` runs it in both gates and writes `native-integration-capability-federation-evidence.json` in the selected build directory.

ASan/UBSan runs of the unit suite and the event-hint fixtures exercise ownership and cancellation. That includes stopping during ticketing, superseded sessions, `clear()` at sign-out, session revocation and subscriptions replaced from queued reconciliation.

Cover advisory expansion before runtime startup, automatic saved visitor restoration after expiry, recovery failure, explicit sign-out, changed authority and pending-command preservation.

D-215: test selected B taxonomy and retained mounted drafts; detail Back/Escape restores focus and scroll. Cover dynamically inserted urgent notices, accurate actor/target and authoritative effective values, rejection after changed authority, long identities, recording/mute/loss, base-stat visibility and explicit sharing Stop in enlarged layouts. Distinguish actual local synthetic media and Electron shell checks from physical-platform acceptance.

Native audio tests inject a delayed output callback during setup and an existing call: playback clears/resynchronizes without changing attendance or healthy microphone intent. Processor tests retain press/end/replay floors, listening mute and finite authority across the playback reset; actual encrypted media continues afterward. Keep genuine pipeline/control failure, startup-stage/code redaction and independent capture-freshness checks.

D-213/D-214: actual-widget tests verify common heading/transcript/composer alignment, full available page width with only native style margins at wide and compact windows, expansion with window/splitter resizing and no font-dependent reading cap; complete native tabs and call controls; separate selected text and current-call contexts; long full account/destination text at 9/16/24-point fonts in LTR/RTL; live resize/font/style/direction reflow; unchanged button objects, enabled/checked states, action ownership, protected drafts and held-input release behavior. Enter in the composer must never trigger a call command. Screenshot and strict complete-message containment checks record usable reading space without treating a passing geometry probe as physical-platform or accessibility acceptance. Capture fixtures include ordinary nickname plus structured author data, exact non-root reply parents and full qualified sender inspection; preformatted history labels remain separately covered. A directly set synthetic current room is illustrative, not proof of an admitted navigation or connected-call transition.

D-212: message-view tests cover literal markup in complete qualified sender identities, identical formatted measurement/painting under narrow and enlarged desktop metrics, readable secondary address/parent text, stable square avatar bounds and readable initial discs. Normal high-contrast desktop palettes retain near-Base fields (field/Base contrast below 1.35:1), while body and secondary metadata retain at least 4.5:1 foreground contrast. Existing root assignment, selection, reply/reference, outgoing-state, draft and action tests remain required. Screenshot fixtures retain native disabled-state ink rather than presenting unavailable controls as enabled.

D-211: native layout tests cover wrapping call controls at compact widths and enlarged fonts, a long connected-call destination/account status at 320/560 pixels and 9/16/24-point fonts in both text directions, complete visible action geometry, compact initials with wrapped identities, metadata reflow, unchanged message-body geometry through hover, native focus/selection and protected-draft retention. Navigation pixel/disclosure tests cover continuous gutter colours and actual pointer collapse/keyboard expansion in both directions. Navigation tests cover 170/245-logical-pixel sidebars at 9/16-point fonts in both text directions, complete channel names and qualified presence addresses, non-overlapping access/handset controls and actual child-surface text activation. Channel metadata reflows below its full name when needed; text measurement and painting use the same wrapping policy. The inspection-button reservation follows its actual desktop/touch size and keeps clocks separate at 9/16/24-point fonts. Avatar pixel regressions cover first-line alignment and text clearance at 9/16/24-point fonts in both directions. Caller-shaped sender regressions supply an ordinary nickname plus separate username/domain fields, including punctuation and equal names on different Homes, and require complete qualified headings and parent inspection/accessibility. Parent-band regressions cover exact signed targets on headed and headerless replies at compact/enlarged metrics, full qualified inspection/copy/accessibility data, inline/stacked caption and self-marker separation, literal markup, safe focused-widget teardown, contrast on the actual band and separation from body text. Heading regressions cover current parent-font inheritance, point/pixel sizes, reparenting, live changes, plain accessible text and the existing artwork/narrow fallback. Composer regressions cover explicit/wrapped lines, four-line scrolling, growth/shrinkage, live fonts and unchanged text/selection on resize; existing inline-error and protected-draft cases remain required. Keyboard inspection regressions cover plain literal identity/reference text, selectable information, at least 4.5:1 contrast independent of low-contrast disabled-command roles, and wrapped labels at 9/16/24-point fonts in both directions and light/dark palettes. Generated authenticated HTTPS captures additionally verify ordinary enabled Join/disabled Share states, real signed/decrypted messages and retained drafts. Generated synthetic whole-window light/dark, compact, empty, differing text/call-context and dialog evidence supplements the unit/widget tests; it is not physical-platform or live-call acceptance.

D-209: `tests/bug-reports.test.ts` covers the shared-interface bug-report logic and rendered form, and `native-client/tests/bug-report.cpp` the Qt dialog and Help menu, as listed in [SPEC-026](026-bug-reports.md#testing).

Web audit units/components cover omitted account flags, exact collection expiry with retained replies/drafts, twelve consecutive retention horizons, immutable read reuse and context invalidation, incremental/revision/backlog loading, coalesced reads, hidden/unverified Recent and read suppression, streamed UTF-8/overflow/cancellation, large supported history, and per-recipient direct accounting for one/two/nine receivers. Run `tests/client-audit-browser.mjs` and `tests/screen-direct-budget-browser.mjs` explicitly in addition to auto-discovered TypeScript tests. Physical throughput/CPU/RSS claims require separate measured fixtures.

Native sender regressions exercise blocked and healthy direct recipients in either order, one/two/nine writable recipients at the same selected per-recipient rate, queue-pressure retirement, expiry, returning watch/key readiness and unchanged failed-send token accounting. Real encoder-to-Qt-to-sender tests consume dependency IDs for overflow, stale GUI delivery, replacement cancellation and sender rejection; already-produced deltas remain gated until an admitted recovery keyframe. The fixed five-second periodic fallback shares one constant with encoder GOP configuration, while explicit startup/feedback/recovery remains immediate. Per-target progress reuses signed fragments within existing total memory/work bounds; no separate numeric aggregate direct-upload preference is selected.

Native audit regressions exercise real central message readers across original, copied, recovery, Home, visitor and frozen-history paths; signed encryption/policy substitution fails before decryption and legacy exceptions remain original-Home-only. Real loopback transport covers expanded 50-record signed history, exact/one-byte-overflow decoded budgets, gzip, explicit destination dispatch, public/error limits and matching JSON parsing. A real visitor widget crosses an original expiry with unchanged history/trust while preserving an eligible neighbour and draft. Register `native-message-context`, `native-history-transport` and `native-visitor-expiry` in the release/sanitizer CTest matrix.

Desktop packaging regressions execute the real builders with isolated generated dependencies to reject stale/missing provenance, altered runtime/archive bytes, existing outputs and a late competing publication. Distinct ZIP/NSIS metadata must select the matching independently versioned update manifest through the real application-info handler. Actual pinned-runtime execution, real installer qualification and public artifact verification remain separate release checks. See `tests/desktop-packaging.test.ts`.

Native managed RTP regression tests repeatedly create publisher offers before sending any frames, for video alone and video with sound. Every primary media section must identify its nonzero RTP source, and video/audio sources must differ. The composed private-provider fixture requires signaled video identification and incoming video before subscription succeeds; missing source media returns the typed partial-track failure rather than pretending negotiation proves delivery. Real Cloudflare reception remains a separate compatibility check.

D-207 Qt unit/widget tests also cover independent public/private versus encryption labels, text-only/denied handset availability, accessible keyboard controls, exact active target/disconnect matching and preserved text navigation. D-207 Qt unit/widget tests cover authorized, empty and unavailable channel rosters; qualified deduplication; nested channel ordering; self/remote and muted labels; participant arrival/departure; stable expansion/selection; informational activation; and server/channel/person foreground/background distinctions across light, dark, monochrome and low-contrast palettes. Verify native selection, wrapping, font changes and 200% scaling with generated isolated widgets. Existing workspace tests retain connection/account scope; no real account or call is needed.

D-206 native message-view units cover continuous root/reply/missing-original/local-echo fields, distinct same-author roots, stable assignment across refresh/expansion, singular counts and actual parent labels, hidden table chrome with retained time/status details, live light/dark/high-contrast palettes and normal text contrast. Widget tests exercise body-only hover, opaque rounded controls, stable geometry, pointer transfer, focus/escape/menu access, compact/narrow and enlarged-font layouts, permission changes, local statuses and retained inline drafts. Generated Qt renders qualify appearance separately from protocol/HTTPS regressions; no real profile or call is needed for presentation checks.

Source-packager units reject invalid versions, changed upstream checksums, precompiled payloads and source symlinks; check deterministic archives, allowlist exclusion of unrelated private files, immutable-output refusal and launcher argument/environment preservation. D-202 packaging validation performs real empty-cache Portage source/crate fetch and Manifest verification, offline configure/compile/install into an isolated image, exact release-version and helper/plugin checks, launcher/desktop syntax, system-library resolution and normal upgrade selection in both repositories. Check source archives for precompiled payloads and private data; verify Cargo crates against the checked-in lockfile and retained licences. These are packaging integration checks, with no new application unit. Existing native units remain applicable to the compiled client.

D-199 native regressions construct the window before runtime startup, complete generated password sign-in, verify the protected selected connection and every permitted channel, and open an existing contact without a chooser error. The primary account action must expose qualified-address discovery on another Home. D-205 status units measure the rendered Server: position as client upload/download change from zero through the eight-character reservation, including proportional desktop fonts and enlarged scaling; verify the reduced rendered width and fully readable overflow through the existing maximum; retain narrow-to-wide wrapping/shrinkage checks. D-203 status units verify consecutive RTT and upload/download pairs in owner summaries, explicit Client/Server section labels and unchanged client ordering, including partial aggregate fields, unavailable voice and accessible text. D-201 status units verify distinct metric accents and spacing, labels/units and plain accessible descriptions, live light/dark palette changes with readable contrast, literal rendering of unavailable/error text, and styled-text wrapping/shrinkage at normal/enlarged fonts. D-200 status units verify always-visible local/voice metrics independent of legacy preference data, owner-only aggregate reads, actual text-height sizing and narrow-to-wide shrinkage, placeholders and retirement of the original context, with no statistics checkbox, Conversations button or statistics popup. Actual single-click widget/HTTPS tests verify channel-tab creation, reuse and focusing, denied/failed selections, preserved drafts and unchanged voice. Existing account-selection cancellation, denied-state, protected-write, draft and independent-call fixtures continue to apply.

Native invitation units cover trimmed raw keys, named account links, explicit loopback development, mounted services, wrong origins/paths/purposes, queries/userinfo, duplicate encoded keys/names, malformed/oversized input and unknown fields. Generated window/service checks cover cancellation, invalid links without credential/ticket requests or key changes, successful scoped admission, original-source loss, account-name mismatch, explicit channel-leave cancellation/confirmation and existing membership/voice revocation behavior.

Native adoption units cover all-or-nothing multi-account/connection conversion, exact keys/credentials/pending/draft preservation, invalid private/public keys and signed rosters, wrong authority/account/device, Home-token refusal at visitor destinations, duplicate accounts, malformed preferences, unsupported fields, changed source snapshots and failed atomic writes. Generated Electron/keyring/helper-to-native restart fixtures verify unchanged source bytes, no new source entries or device keys, retained zoom metadata, original-authority resumption and explicit cancellation. Migrated opaque-visitor tests exercise a valid original token and server-side expiry/revocation without fabricated session times or bypassing public discovery/request proofs.

Native history-browser units cover first/next/previous cursor navigation, exact page bounds, monotonically ordered unique positions, malformed pages, failure retry, one pending read, cancellation, scope invalidation, expired content and bounded page memory. Generated Home, foreign ordinary and canonical direct/group fixtures verify older eligible text beyond 250 records, immutable original authority, closed-history access, unchanged live cursors/drafts/voice and refusal after credential/context replacement.

Native statistics units cover monotonic rate/RTT windows, invalid samples, bounded sample/context eviction, availability reset, shared aggregate counts/ranges and malformed values. Widget fixtures cover default-off without an initialization write, independent reporting, owner/open/enabled aggregate reads, context destruction and failed preference persistence. Generated service/window checks exercise the actual saved preference and aggregates, original selected Home/Host/private routing, conditional notice publication/clear/expiry, unchanged drafts and call ownership, cancellation and no reporting after context retirement. Managed RTP fixtures qualify counters after the final pacing/authority gate alongside existing epoch/mute/expiry and packetization checks; private native/managed composition must retain media behavior.

Native deletion units cover confirmation digests, target/name substitutions, duplicates, unrelated/cyclic descendants, hidden-type substitution, receipt validation and idempotent connection-scoped cleanup preserving sibling/private edits and credentials. Composed original-service/window checks must additionally prove explicit cancellation/confirmation, changed-tree refusal, failed-save/exact retry, active-call retirement, clean draft/tab removal and accessible/empty-server fallback.

Native management units cover the existing action/scope allowlist, strict retained command fields, integer revisions and unsupported payloads. Original-service fixtures must prove committed-but-lost results, exact retry/restart and authorization failure retention, original-target creation/renaming without text selection, owner cancellation before dispatch and atomic failed protected writes. Foreign-moderator fixtures use a generated Home member promoted only at its Host, reject Home-token forwarding, retain exact commands through restart/401, and exercise the actual Host-bound form without changing the Home text, credentials, draft or voice requests. Closing the original destination retires the form. Qt form fixtures cover retained edits, applied authoritative values, permission/role gating and unchanged call/input ownership; pending enforcement remains distinct from effective/failed status.

Native outgoing units cover immediate/accepted/definite/ambiguous states, exact history identity matching, repeated identical text, reply roots, context retirement and late acknowledgement after clear. Application checks must exercise actual pending-command failure/retry, owner context and visible status without advancing the history cursor or granting canonical actions.

Native pinned-comment interoperability compares browser/native moderator content and encrypted copies in both directions, including regular-member forwarding to a future device. Reject altered content, invalid signatures/roles, wrong recipients/channels/servers, changed original digests, expired pins and oversized text; cover server-readable pins without an encrypted delivery. Original-service integration must additionally cover current membership/trust, bounded automatic copying and rejection recovery, pin replacement/clear, no surrounding-history entitlement and call/input continuity.

Native thread-call checks validate the derived descriptor and original Home/foreign request scopes. A generated-account real-relay fixture exercises distinct thread audio isolation, same-thread reception, parent-channel separation, unchanged selected text, explicit movement and fresh-press PTT. Participant-status updates must retain an open inline draft and disappear with the original status. Derived thread calls do not qualify for automatic ordinary-channel identity continuation.

Native people/Recent units cover bounded snapshots, qualified deduplication/self exclusion, newest encounter ordering, 30-day/50-entry limits, future/invalid/legacy records, clear cutoff and pinned-display filtering without deleting records. View/voice fixtures separately cover verified displayed text, account-owned active voice encounters, unchanged calls on person selection and no directory admission or presence inference.

Native update units compare numeric stable/alpha/Android version fields, validate complete platform manifests and reject substituted URLs, paths, formats, sizes and digests. Widget checks cover unknown-version wording, run-local dismissal, newer offers and late completion after destruction. A generated private-CA/proxy integration checks the exact anonymous official URL, no cookie/authentication reuse, MIME/size/redirect refusal, the absolute deadline under a slow stream and widget-owner cancellation; it never contacts the production release host.

Native screen foundations reuse SPEC-023's existing signed packet/recipient framing, strict header/chunk validation, replay window, token accounting and bounded authenticated assembly. SPEC-024 owns the independent presentation clock and completed-video ordering/recovery bounds. C++ units cover tampering, canonical bytes, exact fields/dimensions, recipient substitution, duplicate/old counters, rate changes/clock regression, partial-frame context/expiry/memory bounds, microphone-independent timing, sound drift and dependency recovery. Native/TypeScript interoperability compares exact signed packet and recipient-wrapper bytes in both directions. These primitive tests do not establish capture consent, decoding/rendering, sound/SFU integration or the complete screen-sharing client; those integrations retain their existing acceptance requirements.

Native capture-mix units verify explicit source/replay/time/size guards, per-source queue bounds, timestamp alignment, continuity through small clock jitter/known gaps, stereo summation/clipping, silence for late/missing input, no stale catch-up after stalls and actual Opus decoding. Publication/runtime fixtures must still verify the composed capture-to-network path and consent/call cleanup.

Native audio-helper fixtures use the private synthetic PipeWire graph to verify inventory/selection scope, generated PCM framing, one-use/expired offers, byte/time bounds, heartbeat expiry during a blocked Qt loop and owner/source cleanup. Existing filtered-output tests retain own-process/unknown-identity and no-microphone-fallback coverage. No agent test may select real audio sources.

Native capture fixtures use a private PipeWire/session-policy service with synthetic video source nodes and generated session descriptors. Verify multi-source composition, bounded raw delivery, monotonic timestamps, final expiry while Qt delivery is blocked, source loss and no old-context revival. No fixture may read the real desktop, microphone, camera or active account profile.

Native encoder fixtures use generated raw frames, decode the actual output through the verified receiver, and exercise pixel/metadata preservation, pending bounds, keyframes, stale input and disposal/replacement. Report supported/fallback factories and actual timing; generated software checks do not establish hardware use or physical desktop capture.

Native portal fixtures run on a private D-Bus service, exercising capabilities, exact consent/session paths, stream validation, no restored permissions, source cancellation/late completion and descriptor/session cleanup without accessing the real desktop. Profile tests exercise resolution/cadence bounds, no capture backlog, deduplicated pressure, idle versus successful progress, bounded rollback/retry, feedback expiry and independent stream adaptation. Standard viewer fixtures verify above-picture controls remain reachable at narrow widths. Physical portal/PipeWire and encoder-output qualification remain separate acceptance evidence.

Native presentation sound tests cover real stereo Opus decoding, timestamp order, queue/schedule bounds, partial-frame deadline gating, mute/removal, single-envelope ducking ramps, generated playback and idle worker retirement. Real encrypted relay fixtures must additionally verify presentation sound/voice coexistence, independent PC-audio mute and output expiry; no generated sink result establishes physical device latency or desktop capture.

Native viewer tests exercise standard controls, shared pixels, held-image cleanup, expiry, immutable source scope, revision changes and late grants after Stop. Receiver fixtures generate signed VP8 frames without accessing a desktop, camera or microphone, then verify explicit watch acknowledgment, replay/source/path isolation, decoded pixel delivery, key/lease expiry, old-revision rejection and moderator-muted video/sound separation. Call-level relay reception and visible embedded integration require additional generated service/media fixtures; primitive or decoder tests alone do not qualify those paths.

Native managed RTP units offer unsupported video codecs ahead of VP8 and verify that answers retain only the supported VP8/Opus profile and negotiated payload numbers. Native decoder units use real generated VP8/VP9 encoders and decoders to verify pixels, source/timing metadata, stale/scope rejection, replacement/destruction with already queued output, failed replacement and authenticated-versus-decoded geometry. A guard-page regression places a lone VP9 superframe marker, a lone keyframe header byte and every truncation of a real keyframe directly against inaccessible memory; each must be handled without a fault, and inputs shorter than a minimal keyframe header are rejected by validation and real decoder admission. The same guard-page placement replays fuzzer-found AV1 units (a truncated sequence header, and inter units after a partial-refresh key unit) plus every truncation of a real AV1 key unit; none may fault and the unprimed sequence is refused. They use synthetic video only; physical portal capture, hardware acceleration and the integrated viewer require separate evidence.

Native unread units cover exact protected position validation, own-message exclusion, direct/group separation, account/Host collisions, legacy summary fallback, deduplication and monotonic loaded-cursor bounds. Native view fixtures separately verify static counts, summary/hidden/failed-history behavior, explicit visible selection, protected-write failure/restart and unchanged voice/drafts.

Native voice cue units cover exact settings/defaults/types, silent volume/disabled cues, synthesis frequencies/gain/duration/envelopes, initial/repeated/stale/disconnected roster observations, self/device changes, batch coalescing and actual PTT-gate transitions. Playback and integration qualification separately cover preview isolation, bounded output, active-call account ownership and no cue bytes in outgoing media; pure synthesis tests do not establish audible or device acceptance.

Native picture-view tests cover actual visible Qt person rows, independently verified foreign Home mapping without admission or credential forwarding, missing/malformed/replaced references, initials fallback, bounded concurrent reads/cache and cancellation/account changes without affecting text or calls.

Native profile tests cover Unicode nickname normalization and forbidden characters, bounded PNG/JPEG/WebP source decoding, crop/zoom, canonical metadata-free thumbnail encoding and malformed/oversized PNG rejection. Integration tests cover the exact Home endpoint while foreign text is open, original account/device ownership, optimistic conflicts, protected-write failure, retained unknown outcomes, explicit exact retry and unchanged identity keys/drafts/call ownership.

Native conversation recovery tests cover expired/revoked visitor credentials, exact Home/Host/device/pending binding, old API retirement without handover, atomic failed writes, owner cancellation, no navigation/history/media side effect, unchanged command bytes and a separate explicit retry after recovery, including encrypted message replay.

Native cross-authority group invitation tests use accepted contacts whose direct pair authority differs from the new/existing group's Host; verify exact capability/command endpoints and original account ownership through text/account navigation, failed/canceled preparation, protected failure and explicit invitee admission without old history or voice movement.

Native foreign call tests cover exact Host/room control and completion, real encrypted audio between a Home participant and a visitor, ring/decline without media, explicit direct/group answer, unchanged independent text selection, Home reservation ordering and fresh input after movement/ending.

Native foreign inbox/presence tests cover checked incoming locators without navigation/admission/media, exact-host merge and stale/failed replies, colliding room IDs on different authorities, retained private connection restart, bounded batch cancellation/account loss and group presence/closure while another text view is selected.

Native foreign-conversation integration tests exercise actual Client/Workspace opening and typed encrypted send, protected-write failure, committed lost replies/restart/exact retry, rejected changed credential/Host and unchanged Home keys, selection and unrelated drafts.

Native conversation-session units/integration cover fixed qualified account/device/checked Host/session ownership; canonical peer opening, fixed-room view/list and exact immutable operation dispatch; changed Home/device/Host, cancellation, bounded jobs/deadlines and 401 retirement; mandatory encrypted direct/group state and recipient proof validation. A two-authority HTTPS fixture places the native account on the lexically later Home so the DM authority is genuinely foreign, and checks that its Home bearer never reaches that authority. This gateway alone does not establish UI, persisted command, media or full replacement completion.

Native conversation-summary units cover checked Home/foreign pins, canonical direct-pair authority, membership/type/account substitution, temporary fixed-host/retention rules, malformed timestamps and call answering-device bounds.

Native scoped-connection HTTPS tests cover new hidden admission, atomic save failure, valid private/ordinary-session reuse without rotation, unchanged selection/drafts/keys, cancelled owner and changed saved authority.

Native endpoint-borrowing HTTPS checks cover no new grants/logins/history/selection, fixed private/ordinary visitor sessions, capability/pin refusal, owner cancellation and rejection of changed credentials.

Native conversation-scope storage units cover boolean/omission compatibility, rejected Home scope, token-free metadata, hidden ordinary navigation/browsing hints, refused ordinary selection, exclusive ownership and preservation across restart/failed writes.

Native conversation-admission HTTPS tests cover public visitor admission closed, distinct direct-purpose proof, successful scoped login with no ordinary channel/directory access, ordinary-join refusal, cancellation and unchanged Home credential/private keys.

Native Join-as tests cover immediate filtered membership/selection, cancelled authentication and stale preparation, failed selection persistence, unrelated server/channel calls, same-identity no-op, exact captured-call identity movement and fresh input using generated accounts/real relay audio.

Prepared native membership tests verify already-admitted no-op, denied/missing/foreign-conversation targets, exact qualified destination proofs, cancellation before dispatch, unchanged visible view/drafts/keys, failed protected writes, retained lost replies/restart/exact retry and account-owned completion after chooser closure.

Native call-runtime integration checks cover cross-source cancellation, bound stale confirmations, same-account Home/Host fences, different-account replacement, original-context termination, pending-command cancellation and fresh PTT/VAD after movement. Use generated authorities and real encrypted relay audio; ordinary text navigation must preserve the active source.

Native window/relay tests exercise actual Qt Join voice and Hold to talk controls against two generated authorities, then switch the displayed account during an active foreign call. Assert decoded audio, unchanged attendance, qualified original account/Host footer, protected drafts and named Guest sign-out ending only its call without a spurious failure alert. Setup uses generated profiles/audio and does not qualify physical platform input.

Native foreign-controller relay tests cover declining a Home-to-Host move with unchanged original attendance/transmission, confirmation of the exact observed Home call, the four-second fence, no pipeline before reservation readiness, fresh input on the new attendance, mismatched controller/media rejection, refusal of Home direct commands from a foreign controller, encrypted audio through text navigation/Home renewal, original-token retirement and rejection of an in-call encryption/binding change. UI orchestration and automatic identity movement remain separate gates.

Native frozen-context HTTPS tests cover exact original server/account/device binding, wrong room/authority/device rejection, no transcript reads for eligibility, cancellation after dispatch, replacement of the browsing controller, original-token retirement without credential fallback, detached cleanup after controller destruction and sign-out affecting only the named connection. Production call/relay wiring remains a separate acceptance gate.

Native Home-reservation units cover exact immutable context, initial/fresh-renewal gating, movement timing, non-overlap, malformed/substituted replies, expiry/clock regression, cancellation/account-owner destruction, renewal failure and bounded cleanup. Generated multi-authority integration must still prove matching Home inspection and destination/relay media.

Native named-Rejoin tests cover a modeless exact-target confirmation, inactive saved profiles, signed-out/expired retained sessions, unchanged outgoing view during preparation, Home reauthentication at the verified authority, cancellation/supersession, pending-operation refusal before grants, and denied target reads/failed protected selection after successful admission. Assert preserved keys/drafts, no other-account credential replacement and no voice action.

Native transport tests use generated HTTPS services to verify one serial-control HTTP/1 socket across concurrent requests, a separate interactive pool, and successful exact control requests while the interactive connection is forcibly closed. Existing TLS, no-redirect/cookie/auth, owner cancellation, response/deadline bounds and scoped proof tests remain required. Generated relay regression exercises renewal through text/account navigation, tab closure and named-account sign-out without relaxing the three-second media authority.

Native named-sign-out generated HTTPS/window tests use two accounts at the same server, inactive/lazily restored destination sessions, exact owner credentials, cancelled metadata preparation, rejected logout, protected-save failure, pending-command refusal and unchanged selected profile/connection/drafts/keys. No history or call admission may result from resolving the management target.

Native tab-resource tests retain QPointer references to closed pages/editors and require immediate destruction, no reappearance after background changes, draft restoration after verified reopen and unchanged tree contacts. Failed-save closure preserves the page and edit. Generated HTTPS tests cover no foreground history polling after the last close, continued inbox and model-owned closed-group draft cleanup including failed persistence. Real relay checks close/reopen text tabs while PTT is held and verify unchanged attendance and continuing decoded audio.

Native direct/group preparation tests cover verified empty contacts, accepted history, unaccepted invitations without history/admission, wrong peer/authority/conversation/type, failed protected commits, cancellation/supersession and exact pending-operation restoration. Actual window tests verify failed tab/tree opens retain the committed page and draft, success commits its own cursor/selection, and no voice or membership command is caused by opening.

Native ordinary Home selection integration must cover denied/wrong-room responses, rejected atomic saves with unchanged view/protected state, cancelled and superseded reads, account-left continuations, failed tab switching, successful tree/tab activation, scoped draft restoration and persisted room/cursor. A channel open cannot issue membership or voice commands; generated relay checks retain the original call across text changes.

Native account-runtime and window integration uses generated qualified profiles and HTTPS services to cover stable key/controller ownership, prepared selection, cancellation/supersession, denied channels, no accessible channels, advisory readiness, chooser actions, independent draft restoration and closure of stale management dialogs. Protected-store units must verify that destination state and profile/connection selection commit together, including failed-write preservation. Generated relay integration switches accounts while holding PTT and verifies unchanged attendance/call IDs and continuing decoded audio; text selection cannot replace the call account. These fixtures do not establish foreign-call movement, installed-profile migration or full platform acceptance.

Native account-discovery units cover delegated service hosts, normalized usernames, bare-name authority context, malformed inputs, changed retained pins/bases, cancellation/supersession and failed protected writes without selection or key generation. Generated HTTPS/window integration opens the chooser through verified public discovery and checks the displayed Home and qualified identity before credential submission; anonymous discovery must never include credentials.

Native saved-tree tests cover two accounts on one server, multiple server groups, full pin grouping rather than UUID alone, protected browsing hints, credential-free projection, account-qualified room/status scope, cross-account root/channel activation and failure preservation. Context-menu tests refresh metadata while a menu is open and verify that the chosen action resolves its saved locator without using a destroyed tree item or another account's current context.

Native destination-account integration tests cover the actual server/channel chooser, bare-name destination context, retained Home and visitor reuse without a second admission, new scoped visitor admission, changed destination/Home pins before credentials, original-owner authentication, cancelled/superseded/edited/closed-dialog continuations, denied target channels and failed protected writes. Compare unchanged original keys/drafts/call ownership and verify that another account's connection ID is never reused as the chosen profile's authority. Admission retains SPEC-015's credential boundaries and existing 45-second total bound.

Native call-input lifecycle tests use the real adapter against a private fake portal: call/account/attendance ownership, no idle registration, restored saved binding, first-release arming, unchanged observation across ordinary settings, rejection of another account's input edits, recorder-scoped suspension/restoration, failed-registration no-retry, explicit retry and cleanup after call/test/dialog destruction. Widget/relay checks preserve call ownership and fresh-input behavior while Preferences and recording controls change. These fixtures never register shortcuts in the human's session or open a real input device; physical platform qualification remains separate.

Native recorder widget tests check modeless/nonblocking controls, completed key release updating only an unsaved candidate, cancellation on focus/Preferences/account loss and destruction of recording observers. Generated relay/window integration verifies that ordinary Preferences preserves held PTT, recording stops publication, cancellation retains the saved binding, and subsequent transmission requires a fresh release through the private shortcut portal. Generated-device mode must not enumerate or read the human's input devices.

Native saved-server window tests use generated HTTPS authorities and offscreen Qt controls to cover metadata-only expansion, encrypted tab dispatch, scoped draft switching, failed-selection preservation, an eight-second canceled status read, saved-sign-in reuse and whole-workspace uncertain-command restart/exact retry. Runtime visitor sign-out/rejoin checks must additionally cover isolated home credentials/keys, retained drafts, no signed-out restart traffic, failed logout/save and owner cancellation of the mutation guard.

The native destination context integration uses real generated HTTPS home/host services and protected native-store views to verify metadata-only startup, permission-filtered explicit open, bound encrypted send/decrypt, missing-trust refusal, exact committed-command loss/restart/retry without duplication, independent draft/selection/keys, wrong room/server/own-root responses without state replacement, failed draft/pending persistence without dispatch, canceled opens, and destination text authorization after home-bearer logout. Home helpers preserve their own role/proof and account context. No actual profile/keyring/capture is used; full multi-account navigation and cross-host media remain separate acceptance.

Retained destination-session units distinguish saved historical proof restoration from a fresh regressing login, preserve destination member role under a home owner, advance public proof only from the verified extending home head, and reject forks, changed devices or removed approval. Existing real HTTPS persisted-session restoration must use the explicit protected-source path and retain its credential-bound request behavior.

Native saved-sign-out units remove destination credential/session bytes while retaining exact account keys and scoped drafts/cursors, reopen the public record after restart/device-proof advancement, reject sign-out combined with active credentials or pending/home state, and restore a newly verified destination login without replacing drafts. This storage state does not by itself prove runtime sign-out/rejoin or remote membership behavior.

Native session integration uses a generated account/service and fake-key protected profile to cover wrong password without old-session loss, failed prepared/final writes, committed activation reply loss, malformed protected candidates without candidate dispatch, restart reconciliation, active-token use after old retirement, preference-save preservation, modeless controls/password clearing, warning/expiry/reauthentication with unchanged keys/drafts/selection, and owner destruction before password dispatch. The actual relay widget fixture must renew while PTT is held and decoded audio is flowing, retaining attendance IDs, keys, selected conversation/draft and the held gate without a session-ending event. These are generated integration checks; no physical capture or real profile/keyring is used.

Native session-clock units cover exact account/device binding, finite/Unlimited/retiring states, pending rejection, safe millisecond values and unknown fields, failed-observation preservation, request latency, short/long warning thresholds, exact expiry, clock regression and maximum supported dates. Integration must still prove signed token validation, minute/focus refresh, protected handover/restart and unchanged drafts/calls.

Native home-authority units cover exact UUID/domain/base pins, name-only changes, request-start cache boundaries, delayed replies, clock rollback, transient outage without stale fallback, shared reads, pending bounds, cancellation/destruction and permanent changed-authority rejection. Generated account integration must verify protected pin persistence before restricted operations; request snapshots cannot forward credentials after changed metadata or owner/account loss.

Native saved-connection storage units cover interleaved account/connection writes, same UUID across home domains, exclusive view ownership, metadata privacy/no duplicated private keys, unknown command/draft/cursor retention, expired session retention, immutable server/account/profile references, replacement-root refusal, display-only browsing fallback/pruning, same-account home fallback on removal, home/open-view removal refusal, persistence failure, invalid roots and owner destruction. Generated HTTPS integration must persist a real native visitor session, reopen it through the same qualified account, revalidate authority and issue a correctly signed destination request with unchanged account keys. These tests do not establish complete server/account navigation or cross-server voice.

Run all three interrupted recovery modes (normal completion loss, committed-expired and uncommitted-expired) from both an empty and a retained signed-out installation profile. Retained profiles must preserve old keys before activation, keep the same pending keys/completion across restart, and recover eligible history after verified activation.

Native sync regression uses generated valid-but-substituted own roots and wrong channel IDs; neither may replace usable state or protected identity. A valid signed device-roster extension advances both the runtime/protected own proof with identical keys/token. Existing channel/direct/group and media flows remain regression gates.

Home-startup regression uses a generated protected profile and loopback info endpoint with a changed UUID; assert only one credential-free info request, blocked authenticated calls, unpublished info, visible failure and unchanged vault. Generated account/link/recovery/QR flows verify valid server UUID/audience handling and protected home-pin persistence.

Native visitor admission uses generated HTTPS home/destination services with real signed grants, joins and destination sessions; verify qualified account/device binding, no home credential leakage, fresh signed destination requests, rejoin after public admission closes, changed authority/identity rejection, invalid grants, owner/account cancellation and bounded pending jobs. Only test binaries trust generated CA/proxy settings.

Native ordinary-channel movement fixtures exercise a held direct/group call, selection of unrelated channel text, declined movement with retained input, successful fenced movement with no carried press, target playback, cancellation, and a second ordinary-to-ordinary move. Existing direct/group invitation and media tests remain regression gates.

Legacy UI-scale units cover missing/valid items, exact decimal/range/step boundaries, both Chromium string encodings, origin/mounted scope, ambiguous records, unsupported/corrupt databases, owner/type/symlink/FIFO/size/count rejection, changed inventories and source preservation. A pinned Electron 44.9.1 integration fixture writes actual temporary localStorage, closes it, and verifies native extraction and unchanged source bytes. No real installed profile or keyring is used.

Native account-store units cover empty/default state, unchanged native-v1 upgrade, exact device/pending/preference preservation across restart, independent accounts with colliding UUIDs on different domains, interleaved writes to different profiles, exclusive view ownership, stable service/account binding, local selection, persistence failure rollback, token-free metadata and unsupported roots/owner destruction. Fixtures use the same authenticated Vault with ephemeral test keys or a fault-injecting C++ adapter; no runtime input selects an insecure store.

Legacy migration decoder units compare independently generated ciphertext vectors, preserve Unicode/JSON bytes and reject unsupported prefixes, unavailable/wrong keys, malformed lengths/padding and oversized ciphertext. These are format checks only; actual installed-Electron/keyring interoperability, full private/public key and roster validation, unchanged source/profile snapshots, successful protected import/restart and zoom metadata handling remain separate required migration acceptance.

Generated migration fixtures run pinned Electron with a private fake wallet and no host service activation, then read/decode its ciphertext through the native KWallet reader. Locked, missing-folder, missing-entry and wrong-type cases must refuse without mutation or activation. Source-file units use independently calculated wrapper hashes, current/legacy profile precedence, stale versus live/unknown process locks, changed bytes, replaced inodes, symlinks, FIFOs and size bounds. Verify source data/locks remain unchanged; these tests use only temporary generated profiles. Both original application names and private KWallet/Secret Service backends are integration fixtures; complete installed-profile adoption remains separate work.

Native public-discovery units cover direct and shortcut resolution, identity substitutions, invalid URLs, owner destruction, late replies and a single overall deadline across hops. Generated-certificate HTTPS integration checks the production public reader's certificate/hostname validation, cookie/credential/redirect refusal, content type/status, exact 16 KiB bounds, strict UTF-8/duplicate-key parsing, per-request deadline and cancellation without accessing real services or credentials. Native/browser interoperability compares descriptors and join/direct/request device-proof contexts in both directions, including expiry boundaries and tampering. Destination-session units validate signed-login/account/device/server binding, queued request cancellation, fresh per-request nonces, monotonic verification-cache expiry/regression, unchanged mounted URLs, local-versus-foreign proof behavior and refusal to dispatch credentials after substitution. These fixtures do not establish saved multi-account orchestration or complete multi-server UI acceptance.

Native recovery tests cover browser/native seed derivation and code/roster validation, explicit save acknowledgment, exact signed setup retry, eligible history copies, password plus recovery proof, lost committed completion and restart reconciliation, old-device/session revocation, retained recovery-box/share reading and rejection of consumed/wrong-service/substituted keys. Fixtures use generated accounts and temporary protected profiles.

D-197 native checks use different desktop font metrics and display scale factors, verifying readable standard controls, keyboard access and no application zoom. Migration units cover valid 75/100/200 values, missing, malformed and unreadable source values; retained metadata never changes Qt rendering and source data remains intact. Until migration exists these are required acceptance tests, not completed evidence.

Native implementation units exercise the JSON/crypto/vault/navigation foundation, rollback-safe current roster pins versus historical authors, protected local preference validation, Opus envelopes/PTT/activity/replay/bounded playout, generated-device pipeline lifecycle, WebRTC binary channels and selected SCTP candidate pairs, and a private fake GlobalShortcuts portal's response race, refusal, arming, session and stall fences. Generated-account integration retains/retries an unknown channel command and a committed direct request across process restart, accepts same-home contacts and exchanges encrypted DM text, preserves pin chronology and clears blocked conversation state. Native voice integration uses the current service and Go relay with generated audio: authenticated private direct routing, two successful heartbeats and non-relay candidates, held-input continuation across an additive rekey without sending old-context packets, text navigation, same-call relay-only fallback, and capture stop on renewal failure. Native/browser crypto and Opus waveform interoperability are separate from physical listening, input permissions, controller/game-context and complete replacement qualification. GStreamer message ownership and repeated graph shutdown are checked with leak detection enabled.


Native foundation integration includes a service-accepted encrypted send whose HTTP response is deliberately lost, native restart from the protected profile, retry of the original persisted command, and exactly one retained message. Crypto tests reject a signing secret whose public-key suffix is correct but whose seed has been changed. Native UI tests preserve tree expansion/selection across unchanged and changed projections. A second isolated fixture starts from an approved TypeScript source, submits a native manual-link request, restarts the native client while approval is pending, explicitly approves it in the simulated source, verifies the signed bootstrap/login, reads eligible shared history and sends new text; the source session remains valid. Forty-four interoperability cases cover canonical JSON, text/reply policies, rosters, signatures, signed login, manual binding/approval and history copies, including substitution failures. These checks do not establish QR/recovery, media, full migration or package-release completion.

D-195 native foundation tests cover canonical JSON/number compatibility and duplicate/UTF-8 rejection, service/route validation, signature/box interoperability with the existing implementation, signed device-roster and recovery transitions, signed-login endpoint/account/device bindings, encrypted vault corruption/locking/preservation, contact sort and separate tab drafts. Actual Qt tests verify the selected roots, native context actions, tab close/reopen and absence of a toolbar/right pane. Real loopback service integration must exercise the actual native transport, account proofs, signed login, encrypted text/history and logout/re-login; mocks cannot establish protocol compatibility. No foundation test is a substitute for the remaining native media/platform/upgrade/package gates.
D-194 native units must cover the union of conversations and pinned contacts, qualified-identity deduplication/account isolation, recent unpinned conversations before older pinned conversations, pinned-only entries, equal-message pin-date ties, equal/missing pin-date alphabetical fallback and deterministic duplicate-name ties. Opening/reading/closing/reopening a tab cannot change message recency, unpin a contact or move voice. Native integration must exercise both roots' right-click and keyboard menus, creation/cancellation through existing authority-aware flows, independent root disclosure, pinned contacts without tabs/messages, and useful narrow layouts without a toolbar or right pane. Existing members/trust/admin/listening/voice/sharing actions remain reachable. Sketch-only checks are design evidence, not application conformance.

D-193: native units and interoperability fixtures must cover the responsibilities ported from the current client, including canonical serialization/signatures, envelope compatibility, approved-device trust and protected persistence, scoped authentication, stale asynchronous results and independent text/voice context. Native UI integration must exercise keyboard navigation, standard menu/dialog actions, modeless settings during a call, input recording/fresh-press safety, capture consent, explicit call movement, theme/font changes and constrained windows. Existing delivered functionality remains an acceptance obligation; unit tests or a Qt window alone do not establish a completed replacement.

Resource validation must compare the released Electron client and native candidate on the same recorded system and equivalent generated fixtures: signed-in idle, minimized idle, joined silent voice, transmitting/receiving voice and supported presentation workloads. Record whole-process-tree CPU time, resident/proportional memory, cold/warm startup, archive size and installed size. Report application bytes separately from missing system/runtime dependencies and avoid counting shared system Qt as free disk usage. Use event-driven idle checks and inspect actual wakeups; preserve media/authority deadlines when optimizing scheduling. No percentage or absolute saving is claimed before measurement, and numeric pass thresholds remain unselected. Physical KDE/GNOME capture/input and package-upgrade evidence remain distinct from headless fixtures.

D-172: service/crypto tests and real SQLite workerd checks cover pin authority, persistence, original retention, context/signature verification, future-member access without surrounding history and invalid-copy recovery. Actual application browser checks verify Pin/Unpin, placement and automatic redistribution by an ordinary member with moderator copying blocked.

Unit coverage for D-173–D-180 checks strict public-mode scope and signed rosters, bounded update manifests and version ordering. Browser checks verify settings tab keyboard navigation and retained drafts, saved PTT during ordinary settings, exclusive recorder ownership and cancellation on hidden tabs, permitted handset join/leave, statistics opt-in and malformed aggregate isolation, fixed footer geometry through long-list scrolling, expanded admin aggregates and collapsed/narrow/200%-scale People views, conditional notices and update dismissal. Native generated-audio fixtures cover Wine missing-host-PID discovery while preserving own-call exclusion; physical application acceptance remains separate.

D-171 foreign-home iOS tests exercise the bundled client’s default-service scan, automatic verified selection/restricted submission, no extra password or submit action, pending and completed restart, preserved profiles and no token leakage to the default service. Malformed/expired payloads, discovery substitution and delayed completion after cancellation fail without submitting. SPEC-011 owns the unchanged approval and roster authority.

D-171 scanner units/integrations cover explicit consent, denial, both rendered QR directions, malformed/foreign input, delayed permission, all exit/background paths and stopped tracks. Native origin/main-frame gates reject unarmed or combined audio/video requests. Legacy manual linking/recovery and current sessions remain regression gates; physical camera scans and installed mobile upgrades are separate acceptance evidence.

Check the voice-disconnection notice's top-right dismissal control at narrow and wide widths, increased interface scale and both colour modes. It must remain clear of the notice text and Download voice log action, retain its accessible name and dismiss only the notice.

Viewer layout checks cover inline/expanded native and SFU pictures, one-row controls at desktop widths, wrapping at narrow/scaled widths, keyboard access, zoom and immediate Stop watching/inline reopening. Verify Show chat/Larger view keeps the picture playing while the existing composer accepts typing/sending and retains an unsent draft. Layout changes must not replace the playing video element or reset its attachment on Expand/Shrink or docking.

The screen-view lifecycle component regression covers asynchronous watch termination with the offer retained, source removal/reappearance, call-session replacement and explicit Stop in expanded/docked canvas and SFU layouts. Each exit removes the expanded panel and docked viewer, retains the chat draft and reopens inline at Fit. A retained-watch delivery stall does not collapse the viewer; Stop remains usable during pending Watch initialization. Run in Chromium and Firefox; these generated component checks do not consume real-SFU trial allocations or establish physical streaming performance.

D-170 website checks validate the Android manifest against the exact APK, render an Experimental Android download and installation/checksum details, and fit at 320px and desktop widths. HTTP unit tests cover APK MIME/attachment metadata, HEAD, conditional/ranged reads, unknown keys and mismatched objects; live publication verifies a full-download hash. Existing emulator evidence applies to the unchanged APK; publication does not establish hardware acceptance.

SPEC-025's managed trial uses the existing share/watch controls with standard RTP video/Opus sound, authenticated encoded transforms and a backend-only signaling API. Unsupported transforms report unavailability without plaintext or duplicate native publishing. A single captured screen/window feeds RTP directly with resolution/cadence ceilings; all-screen sources feed one combined canvas track. Selected Linux application/output PCM uses an uncompressed bounded worklet into a MediaStream destination, avoiding an application Opus encode/decode bridge. Listener mute/gain/ducking and final authority gates remain effective independently of PTT. Native video elements retain the last good authorized picture during delivery stalls; Stop watching clears and releases local resources immediately. Unit/integration coverage must exercise encrypted delivery, delayed control/key readiness, increasing context revisions, expired authority, cancellation, source end, provider failure and no silent fallback. Canonical profile/defaults remain in SPEC-025/008/023/024.

iOS D-163: unit-test origin/asset validation, build-input validation, vault encryption/corruption/bounds, lifecycle ownership/late starts, background permission, watchdog expiry and system-mute persistence across heartbeats/visibility changes. Preserve Android bridge/call regressions while reusing the mobile layout. An unsigned macOS build runs the native core units and a simulator WebKit smoke check for secure context, Ed25519, Web Locks, AudioWorklet, WebRTC and native bridge isolation before signing. Platform acceptance must measure bidirectional media and successful authority renewals while locked/backgrounded, with the debugger detached, rather than infer continuity from an active indicator or declared background mode. Include permission denial, explicit leave, interruption, network/authority loss, fresh PTT after return, application restart and TestFlight upgrade identity retention. Record iPhone XS compatibility independently from iPhone 13 mini results.

Mobile B composition regressions (`tests/mobile-layout.mjs`) exercise authenticated iOS and Android bridge profiles at 375×812 (100% and persisted 200%), 375×420 and 812×375, repeating chat, disclosure, detail return and settings at each allocation: no desktop region switcher, usable options navigation, retained chat draft, full-width category picker, visible focus after selection, unsaved nickname retention across categories, measured call-action targets, pointer hit testing, composer/bar containment, persistent account bar and no document horizontal overflow. The account bar is outside the scrolling task allocation; long notices/headings scroll above it, preserving an eight-rem task allocation. Stub bridge and reduced viewport results do not establish native keyboard, safe-area, active-call or physical background acceptance.

D-161 emulator integration checks cover the initially collapsed controls, visible bottom identity/config bar, absence of disconnected/connecting microphone controls, menu expansion/collapse, navigation to settings, and an active call with Hold to talk in the bottom bar. Verify full-height chat and no horizontal overflow in portrait/landscape, with the keyboard visible, and call continuity while toggling options. Existing microphone state/lifecycle units retain authority; no new protocol unit is introduced.

D-208 unit tests (`tests/linux-isa-gate.test.ts`, run by `npm test`) cover the ELF note gate. A synthesized ELF declaring `x86-64-v4`, `v3` or unknown ISA bits is rejected, while baseline and absent notes are accepted. Non-x86-64, non-ELF and truncated inputs fail closed. Fixtures agree with binutils `readelf -n` when it is available. The instruction classifier accepts baseline SSE2, `rep bsf`/`tzcnt` encodings and register-form `pextrw`. It classifies SSSE3/SSE4/POPCNT/CRC32 as v2, VEX/YMM/BMI/MOVBE as v3, EVEX/ZMM/mask registers as v4, and AES/RDRAND/XGETBV as extensions. Packaging integration gates run inside both packagers. Every staged ELF passes the note gate before and after stripping. A pre-strip `objdump` inventory attributes non-baseline instructions to symbols and DWARF compilation units, and fails on any instruction outside a reviewed dispatch rule. The inventory and measured archive floors are written to `isa-report.json`. Release qualification runs `scripts/package-qt-qemu-smoke.mjs` under QEMU TCG with CPU models Opteron_G1 (baseline), Nehalem (v2), Westmere (AES-NI without AVX) and Haswell (v3 without AVX-512). Each run uses the KDE runtime's glibc and the packaged bytes. It covers libsodium primitives with known answers (SHA-256, BLAKE2b, Ed25519, box/seal/secretbox, XChaCha20-Poly1305, kx, scalarmult, Argon2 and ipcrypt round trips), Snappy, LevelDB open/put/compact/reopen/get with Snappy, `--version`, helper start-up, `gst-inspect` of packaged plugins and an offscreen client launch with a generated temporary profile. These are platform qualification checks; physical old-CPU hardware is not claimed.

D-160 package validation verifies source archive hash, bundle metadata/runtime/permissions, executable dependency resolution, install/update with retained disposable profile, sandboxed Electron launch, renderer sandbox and fail-closed secure-storage behavior. Verify native helper startup in the actual runtime. Website unit tests cover Flatpak manifest selection, HEAD, ranges/conditions and object mismatch; live checks verify full bundle SHA-256 and publication. Use disposable profile data; do not import or alter the human’s existing device vault.

Renewal scheduler units cover subsecond requests, responses longer than one second, no overlapping or accumulated requests, serialization behind publication, cancellation while waiting/in flight, and failure stopping further attempts. Browser handler fixtures exercise both control and relay failures arriving after intentional leave, alongside an active relay rejection that must still count and disconnect. These fixtures cannot establish production network latency or a particular relay rejection's server-side cause.

D-157 message-composer correction (2026-10-24): successful server acknowledgement completes sending without waiting for the subsequent history synchronization. Preserve keyboard focus with a read-only rather than disabled editor while a send is pending; restore focus after a successful button send only if focus is still within the composer or on the document body. Never steal focus from another control, clear a different context’s draft, or erase a draft edited since submission. Apply the same focus-preserving pending behavior to inline replies. Ignore repeated held-Enter events and overlapping sends. One definitive `409 revision` rejection may refresh state and retry automatically only when server/channel, sender device, encryption/conversation policy and the complete account/device/recovery recipient set are unchanged and still trusted/admitted. Re-encrypt for the refreshed revision; any changed audience, permission/approval failure, second conflict or uncertain outcome retains the draft and existing error/reconciliation behavior. Unknown outcomes keep their original command ticket and payload under SPEC-009; no new command is issued for them. No new settings or polling intervals. Tests cover delayed acknowledgement/history, retained focus, immediate next typing, one-Enter revision recovery, no duplicate acceptance and context/audience/failure boundaries.

D-155 package inspection checks ZIP integrity, Windows x64 executable headers, exact bundled desktop source/helper/notices, public default origin and absence of user profiles/secrets. Website checks validate all three release manifests and hashes, render installer/portable choices and verify extraction/profile instructions at desktop and narrow widths. Existing HTTP tests extend to the ZIP route, HEAD, ranges, conditional reads and mismatched objects. These packaging/integration checks do not establish Windows hardware acceptance.

D-152 units cover Android origin/path validation, bridge origin/main-frame rejection, bounded native vault requests, lifecycle ownership and stale stop/start responses. Integration tests exercise real WebView loading and Keystore read/write persistence, microphone denial/grant, explicit join/leave, foreground-service notification/end action, Home/screen-off continuity, fresh PTT after return, failed service start, audio focus/renderer loss and no automatic reconnect. Shared TypeScript/build tests remain required. Emulator checks must measure actual protocol renewal and media progress while backgrounded, not merely an existing service or successful APK compilation. Record any unverified hardware/platform acceptance explicitly.

D-151 needs no new application unit for static copy/layout. Validate both release files through the existing site build, run existing download-handler tests, and inspect rendered home/download pages at desktop, narrow and enlarged-text sizes. Confirm equal visible platform cards, functional setup/checksum anchors, keyboard navigation and absence of unavailable-platform advertising. Check copy against SPEC-015/022 and current deployment limitations.

D-204 native heading fixtures cover whole-word/mixed-case/punctuation/repeated matching, substring and direct/group exclusions, exact accessible text, local/foreign rename transitions, native font/palette changes, narrow wrapping and unchanged adjacent controls. Inspect generated light/dark and enlarged-font renders. Verify no network or animation ownership is added.

D-149 is a presentation-only change and needs no new application unit. Render the actual heading with ordinary, mixed-case Lobbyster, punctuation, repeated matches and long names; confirm unchanged accessible text and no decoration for substrings or Messages/server-only context. Check light/dark, forced colours, narrow widths and 200% scale, wrapping and reachable header controls.

D-147 units cover private-call scope, local connection/attendance, qualified identities and account mismatch. Browser integration exercises current-DM highlighting through open/summary/settings/channel/group navigation, private-call connection/departure, unchanged channel-call icons, pin/unpin persistence, duplicate directory entries and independent unread state. Render both palettes, forced colours, keyboard focus, narrow and scaled layouts; verify icon/background contrast and filled/outline distinctions.

D-144 Linux application-sound tests follow SPEC-023: explicit stream selection, bounded native PCM capture and multiple-source mixing, own-process exclusion, source/lease loss and cleanup through the real desktop boundary.

D-142 reuses the sidebar sizing/unread/navigation units and requires no presentation-only unit. Render populated and empty sidebars in both palettes, including long qualified identities, nested channels, selected server/channel, voice badges, counts, pinned/unpinned thumbtacks and unread messages. Check focus visibility, search/filter, independent server expansion, context actions, manual resize/reset, narrow People expansion and enlarged UI. Check control/text contrast and horizontal overflow; distinguish visual component fixtures from live media verification.

D-141 is a presentation-only change with no new application unit. Render User settings in light, dark and forced colours, at narrow widths and increased interface scale. Check distinct heading/body boxes, nested grouping, text contrast, wrapping, visible keyboard focus and absence of horizontal page overflow. Exercise existing scale/reset, Back/Escape focus return and settings control access; keep existing settings behavior tests as regression coverage.

D-138/D-139: cover missing-default alphabetical selection and no-access empty state, owner confirmation/cancellation and deleted-channel draft cleanup, public/private link settings and clipboard failure feedback. Native Electron integration checks actual sanitized writes while denying reads/foreign frames; browser checks retain the accessible handset indicator and never auto-join voice on fallback.

Screen chooser regression coverage includes old/partial desktop bridges, supported browser capture, permission denial followed by retry, and cancellation without publication. Browser checks verify a full-width readable alert in light/dark themes and narrow dialogs, and no capture request on an incompatible wrapper. Native permission tests retain selected-origin/main-frame restrictions, camera denial outside D-171’s scanner and single-use source consent. Physical platform capture remains a separate acceptance gate.

R-117–R-121 future client units cover chooser cancellation/source loss, composite geometry and consent, capability/codec failures, bounded synchronized playback and independent listener ducking. Browser/desktop integration must verify actual rendered audiovisual output, mixed-route fallback, different listener settings and same-channel identity movement. SPEC-023 defines the scenarios and unresolved measurement thresholds; these tests have not been implemented by the specification draft.

D-112 browser regression checks verify the mode checkbox is inside PTT configuration without a call, saves across reload, and never starts capture. Disconnected and settings-paused states disable the held fallback and show no PTT retry action. D-113 browser coverage clears the binding, exercises pointer and keyboard fallback, release/cancellation/focus-loss shutdown, no automatic resume and restored configured PTT. Existing connected PTT, voice-activation and input-gating scenarios continue to pass. This is rendered integration coverage, not a new input-policy unit.

D-110 units cover width preference parsing, absent/default/invalid/blocked storage, independent reset, viewport budgets and manual priority. Browser checks cover two expanded server roots with colliding room IDs, account-correct selection/context actions and stale/unavailable background lists; pointer and keyboard resizing, reset and reload persistence, name-driven growth versus manual lock, light/dark presentation, UI scale and narrow-window clamping without horizontal overflow.

D-108/A-45: browser-test the real relocated controls, actual transmission, failure persistence, context independent of selected text/server, explicit call actions, keyboard/pointer access, scale 75–200%, narrow/short windows and light/dark/forced colours. Existing media and input unit tests remain required; no new media gate or configuration is introduced.

D-103 units cover warning boundaries, token verification, request identity freezing and family-scoped credential adoption. Browser integration covers policy editing, wrong passwords, secure-store failure, lost activation responses, other-window reconciliation, restart, warning accessibility and continued real fixture voice/drafts beyond old-token retirement. Report native platform testing separately.

D-100 unit coverage validates default, exact scale boundaries/steps, malformed persisted values and read/write failures. Browser coverage changes scale through settings, checks reload and same-origin-window persistence, independent browser-context defaults, reset and invalid-storage notice, menu geometry/focus at minimum and maximum scale, authentication and channel/direct/settings views, and narrow layout without horizontal overflow. Verify 56-pixel circles at 100% and proportional display at other scales, preserving 256-pixel source bytes. Check voice state transitions and composer separation in both palettes, text contrast and forced colours; existing transmission colouring and manual voice transitions remain regression checks.

Validate the component responsibilities and failure paths for PTT inheritance (SPEC-004/012), profile pictures (SPEC-019) and voice sound settings (SPEC-020).

D-084 units and browser coverage are specified in Local voice diagnostics below, including strict selected-stats projection and fresh-call reset.

SPEC-015's message-host extension tests signed destination/domain binding, encrypted inner/outer consistency, refusal to relabel copied history, and legacy history only on its home connection. The main and inline-reply composers preserve drafts and disable Send while the server reports D-078's E2EE verification pause; eligible history remains visible. Connection-specific device and history requests retain their API base and authorization snapshot. Main and inline drafts are protected per connection/channel/thread. Background saved connections use SPEC-015’s bounded rotating read, while an active call retains its original account’s PTT binding and trust/preferences. The server menu reports unavailable or expired background connections; selecting an expired connection opens ordinary sign-in/reconnect in the main workspace.

For an unchanged ordinary E2EE channel, text synchronization owns the displayed posting status. Voice snapshots refresh call state but do not replace that status: a voice lease does not inspect every text recipient. Retain it only for the same server/domain, channel, account/device, membership revision and admission state; direct conversations retain their separate policy behavior. A failed chat check stays paused until a successful chat check, and every actual send still requires the server's fresh recipient verification under SPEC-015. No approval lifetime or network scheduling changes. Regression tests alternate chat and voice responses across directory-cache expiry, then exercise a genuine home outage, recovery and context/revision changes.

SPEC-015's connection foundations add unit coverage for immutable API destinations, credential/room snapshots, concurrent different-server requests, rejected route escapes and account changes during asynchronous proof preparation. Vault tests deliberately reuse an account UUID on two domains and verify separate archives/trust pins, correct legacy home trust and no foreign fallback to a local namesake's keys. Browser device-link, recovery and chat/voice regressions must still pass after migration. The multi-server browser fixture additionally checks shortcut and direct joins, target-local accounts, expired sessions, independent drafts/history, foreign Pinned navigation and the D-078 pause. A two-relay browser fixture checks actual E2EE audio and home/foreign call movement; its loopback/fake-microphone scope does not establish physical or hosted latency acceptance.

D-070 browser checks verify Back precedes the workspace title at desktop and narrow widths, remains keyboard reachable, and returns to the channel. Focus may leave the ordinary workspace in either direction; Escape and focus restoration remain unchanged. This placement change needs no new application unit.

D-065/D-066 unit coverage checks the retained KDE parser bounds/precedence and verifies that the renderer accepts only a boolean appearance hint, ignores native colour values, removes stale overrides and yields to forced colours. Navigation data authorization and expiry tests belong to SPEC-008/012. Browser integration covers nested room rosters, independent text/voice targets, context action targeting, personal-versus-moderator effects, keyboard tree/menu/workspace navigation, viewport placement, inline confirmation cancel/commit, identity review without a sidebar, settings persistence, live system light/dark and forced colours, and narrow layouts. Verify paired rendered palette colours and text contrast in both modes, live switching, and native-mode precedence over an opposing browser preference. A controlled KDE fixture must select the application mode without copying its RGB values; physical Windows/KDE OS-theme acceptance is reported separately. Existing voice, nickname, recovery and linking tests remain regression gates.


D-064 unit tests cover nickname validation/defaults and identity-label fallback. Browser integration verifies right-click, keyboard entry, Escape/focus return, volume/mute persistence and audible suppression, participant removal, nickname save/clear/conflict, cross-client display and literal markup rendering. Personal controls must not alter shared moderation.

The shared web/desktop media receiver owns the D-062 playout buffer in SPEC-004. Authentication/replay checks precede scheduling; the worklet receives the authenticated sequence and session identity instead of discarding all reordered frames at the main thread. Test rendered startup, resumed speech, gaps and revocation; defaults and limits remain owned by SPEC-004.

P-028 client tests cover qualified/bare account input, full-address presentation, a different room host while retaining the home suffix, blocked foreign login before network credential dispatch, prefix-safe navigation and explicit reconnect after endpoint changes. A-40 covers browser/native discovery and existing-device regression; SPEC-010 owns the shared parser/transport cases.

D-054 units check immediate disconnect status while remote cleanup is pending, the hour boundary and final-five-minute warning. Desktop integration measures renewal timing in a hidden/minimized Electron window for at least three minutes, including failure/stop behavior; a full-hour human soak remains separate acceptance.

For D-053, test source/button validation, local-display restrictions, XInput2 version/pointer failures, query deadline, initial-held suppression, press/release, cancellation, display loss and no automatic fallback. Test the C bridge against a disposable X server, with selected-button simulation explicitly distinguished from real hardware. Physical button 4, foreground Wayland and XWayland applications, lock/suspend and release safety remain A-37 platform checks.

For D-052, unit-test key/full-URL normalization, malformed/ambiguous keys and wrong-origin/purpose rejection. Browser integration uses disposable accounts to verify ordinary login, setup navigation, logout/relogin with retained keys, invitation registration and click-to-join after a grant. See A-38; SPEC-008 owns authoritative permission tests.

Site build checks verify release-manifest validity and installer hash before rendering. Browser checks cover both pages, desktop/mobile layouts, working links, visible keyboard focus, details/checksum disclosure and absence of horizontal overflow. These do not establish native app or hardware acceptance.

Planned successor client units cover pending/approved/revoked device screens, history coverage/gaps, recovery-key handling without logging, shared permission updates and explicit voice movement. Binding-recorder units must ignore the click that opens recording and pre-held inputs; capture fresh keyboard/mouse/joystick presses; ignore repeat/axes/scroll; require release; and handle Save/Cancel/Clear, failed registration/persistence and legacy-string migration. Mock disconnect, ambiguous device re-enumeration, helper failure, stale polling, focus loss and reconnect while held; assert no capture/transmit during configuration or automatic resumption. Check mouse navigation suppression only where APIs allow it; real hardware and game focus remain separate gates.

Cloudflare client lifecycle units exercise cancellation while microphone permission is pending, closure warnings on the five-minute boundary, media closure at the shared deadline and refusal to resume PTT without a fresh join/press. Browser integration exercises real capture-worklet encryption and playback through both approved TURN transports; fake clocks/media APIs alone do not establish audible quality or regional latency.

Unit tests for client controllers, preferences, capability presentation, and administrative settings should cover:

- Missing preferences resolve to approved defaults; invalid bindings/devices/scales and unsupported values produce an explicit error without discarding unrelated preferences.
- Hotkey registration/revocation and OS/browser lifecycle events reach the correct media gate; mock platform adapters expose press and release separately.
- Local controls dispatch only local playback changes; moderator controls send the correct target, scope and revision and require the advertised capability.
- Capability presentation respects the server's effective decision, scope and revision; unknown or expired grants do not enable actions, and account/domain display labels are not interpreted as roles.
- Capability updates invalidate stale display state; a rejected server action does not remain represented as successfully applied in the UI.
- A mocked stale-revision response preserves unsaved input and displays a conflict rather than success; inherited/effective values and server/provider-rejected values are shown accurately.
- Account changes and active voice-session switching select the intended identity and never leak pending messages or start capture in another context; text-view navigation alone preserves the voice target.
- Error presentation does not disclose hidden room names, secret settings, or private role details; secret-store failure does not cause plaintext preference fallback.
- View-model/component tests verify descriptive control labels, keyboard focus state, and accessibility names without treating them as proof of platform screen-reader compatibility.
- Text navigation versus active voice changes, second-active-device rejection/replacement, and key-loss presentation; eligible ciphertext must not be presented as decryptable without keys.
- Historical encrypted-operation evidence verification, role-revision replay and invalid snapshots without duplicating the server's permission evaluator.
- Pending/effective/failed media enforcement, post-commit timeout reconciliation, duplicate action responses and stale results arriving after newer actions; a queued result cannot display “muted for everyone” as fully enforced.

OS global input, native capture, actual screen readers, installer behaviour, and browser media compatibility require separate platform acceptance runs.

Native source-device integration verifies explicit approval before new-device login, independently generated keys, a dropped committed approval reply, manager recreation and exact retained-operation reconciliation, retained DM/closed-group history, future recipient expansion and revocation. The actual Devices dialog is exercised for fingerprint rendering and protected state. Cross-language tests verify browser secretbox binding proofs in C++, native roster signatures against the browser implementation and native encrypted history shares read by the browser. Repeat these fixtures under memory/undefined-behavior sanitizers. No real OS keyring/account profile or capture device is used by these generated fixtures.

Native SPEC-018 integration covers distinct DM/group identities, no pre-admission group history, the fixed group retention, text-navigation-independent presence, explicit rejoin after restart, closed-group draft cleanup and eligible read-only history. Actual native-to-native call tests use the current relay and generated audio to check that ringing/decline starts no media, acceptance precedes capture, moving an existing call requires explicit confirmation plus the server fence/fresh input, and ending a call while another text tab is selected preserves that text selection. Run these paths with address/undefined-behavior sanitizers; generated capture does not establish physical device or cross-home call acceptance.

## Acceptance criteria

- D-227/D-228: the applicable SPEC-028 library, logical ownership, default projection and publication acceptance conditions pass; no logical-server media/client-navigation capability is claimed.

- D-226: right-clicking an owned saved server exposes **Invite or create user…**, opens its Invitations page, creates a usable new-account link or grants an existing account propagating server membership. Capability/role refusal is visible, and original account, text selection, keys and voice ownership remain unchanged.

- D-225: new native chat messages remain visible when the transcript was at bottom; incoming and outgoing refreshes preserve the exact scroll position when above bottom. Returning to bottom resumes following, including burst updates and wrapped messages.

- D-224: successful outgoing Qt screen sharing closes setup and shows a compact main-window pane with the owning account/call, status and Stop; text navigation leaves sharing active. Setup remains a dialog through consent/layout/error handling. Stop or call/owner termination removes the pane and releases capture without ending otherwise valid voice.

- D-223: Enter sends ordinary and inline-reply messages through the existing enabled action without adding a newline; Shift+Enter inserts a newline without sending. Blocked/pending/repeated keys retain drafts; input-method preedit cannot submit an unfinished composition.

- D-221: with hints available, a new message in the selected channel starts a read within 1.1 s of commit at the median on the budget fixture and the local browser fixture; with the socket unavailable, behaviour and cadence equal the previous two-second polling.
- D-221: two signed-in devices of one account produce no hint-attributable HTTP `429` and stay within 240 requests per fixed minute in every within-budget budget scenario; messages in unwatched public channels start no hint read. With a foreign channel selected, Home requests per fixed minute do not exceed the pre-hint polling plan by more than 2 on the composed foreign-budget fixture; scenarios already over budget before hints are reported separately and gain no hint-attributable Home requests.
- D-221: an authority whose `/info` lacks `event-hints/1` receives no ticket request, including native Qt destination and conversation authorities on `native-capability-federation.mjs`; a refused capability lookup is retried after 30 s without user-visible error; after an iOS no-call background, the foreground event reconnects within 1 s.
- D-221: browser, Electron and Android use the shared WebSocket path; iOS uses `SloppyNative.EventSocket` or polls only; native Qt Home, destination, conversation-session and cross-home inbox consumers use `QWebSocket` against the same contract. Unavailable platform qualification is reported separately rather than claimed.
- D-221 native Qt: `native-event-hints` passes in CTest. The service, federation and capability fixtures pass from `scripts/test-qt.mjs` on the release build and on an ASan/UBSan-instrumented build with zero sanitizer reports. Every recorded upgrade carries exactly `sloppy-events.1, ticket.<43>` and no Origin, cookie, Authorization or proof. Hinted Home, foreground-destination and foreign-conversation messages each become visible within 1.1 s of commit, socket-refused Home messages within 2.6 s, and a message committed during a held in-flight read becomes visible within 1.5 s of its release with at most two sync requests from hold to visibility.
- D-221 native Qt: an account holds at most one Home socket, one foreground-destination socket and four conversation-authority sockets. Each watches only its open view, a background destination has no socket, and a Home `inbox` hint starts no `/contacts` read. After sign-out the service sees no owner socket and no further owner request for 3 s. A revoked visitor session closes `4401` without the hint path ending the `ConversationSession`; the next ordinary read does.
- D-221 native Qt budget: two native clients on one account (same device credential, separate stores, six synthetic senders) record zero `429`s and fewer than 240 owner requests per minute, extrapolated from each 30 s window, with and without the second client's text view active. With `SV_NATIVE_EVENTS_VOICE=1` the same holds while one client keeps a real call active with its actual lease-renewal timer and the same attendance throughout. Hinted latency is not a condition in that mode, because SPEC-008 pacing may withhold hints (`hintsDropped.budget`) once the projected account load reaches its reserve line. Statistics-footer requests are outside this fixture, and the evidence labels them not measured. Acceptance does not substitute arithmetic for them.
- Expanding saved-server navigation before initial Qt startup cannot produce “The account runtime was already started.”
- A failed ordinary saved visitor restore attempts recovery once before reporting an error; success retains drafts/channel and requires no manual rejoin. Explicit sign-outs, unresolved commands and authority substitution remain protected.

- Mobile connected-state acceptance remains **unverified** for this UI-feedback candidate: connected PTT stays reachable through details/settings; Presentation Watch/Stop is reachable from ⋮; connected Leave and connecting Cancel meet 44×44 targets. A release must distinguish this gap from passing disconnected layout checks.

- Mobile B adaptation: both native bridge profiles retain reachable full-width chat, ⋮ channel/People navigation, mounted settings forms and detail Back at portrait, reduced-height and landscape allocations; the account bar remains reachable and primary navigation/call actions measure at least 44×44 CSS pixels at 100% application scale. Enlarged settings remain operable at persisted 200% scale. Stub-renderer checks do not establish native keyboard/background acceptance. Actual call context is independent of viewed chat/account; enabled base statistics remain outside disclosure during settings/details and options navigation.


- D-215: Electron/shared web exposes selected B categories with original independent policy commands and consent semantics; C controls and study selectors are absent. Core live state, enabled base statistics, readable notices and sharing Stop remain reachable alongside meaningful Task content at validated sizes. Detail return preserves the exact draft, focus and scroll. Changed authority cannot knowingly retain a stale role claim. Testing alpha publication verifies exact assets, both existing authorities, configured and observed rollout, and retained compatible Gentoo fetch/digests without claiming the separate visual target complete.

- A native output-only scheduling discontinuity discards stale playback and rebases its timeline while retaining the original valid call and healthy capture gates; generated idle/encrypted-call fixtures keep attendance and subsequent media, while genuine device/control failures still close the call.

- D-213/D-214: permanent navigation and native movable/closable tabs remain; heading, transcript and composer share the full available page width with only native style margins at wide and compact sizes, following live resize/font/style/direction changes without surplus gutters.
- D-213: complete current-call identity and explicit microphone state read together with their controls in one wrapping bottom session area; selected-text Join/Move intent remains explicit and does not change current-call ownership.
- D-213: all applicable full identities, thread metadata/fields, native selection, actions, drafts, held-input safeguards and always-visible statistics retain their accepted contracts through layout changes; unrelated prototype proposals remain unselected.

- D-212: the selected lighter native fields, quieter sender bands, bold display names and complete secondary qualified addresses render with the fixed weights above; literal identity markup stays plain text.
- D-212: compact initial discs match navigation presentation, retain the current-user native Link marker, and keep readable ink and stable square bounds at wrapped/enlarged layouts. No reference, age, status, permission, action, draft or native font setting is removed.

- D-211: all native call actions remain reachable with complete labels at the validated compact and enlarged-font widths; controls use natural sizes and the call/status areas occupy their content height.
- D-211: wrapped message identities retain square initials, unobscured body text, exact metadata and keyboard inspection; navigation remains complete and desktop-themed.
- D-211: the conversation title follows its current desktop font owner at 1.25 times the size, including live changes and reparenting; complete plain text and the existing artwork fallback remain available.
- D-211: main and inline reply editors grow with wrapped text through four visual rows, then scroll; resizing and clearing restore compact height without losing draft text or selection.
- D-211: compact reply captions show the actual signed parent number; inspection, Copy details, tooltips and accessible text retain the complete qualified parent identity. Inspection information is readable, selectable plain text rather than disabled-command text, within the current display width.
- D-211: at most four active redesign variants remain under evaluation; material unselected specification alternatives stay visibly proposed while subsequent review/refinement continues.
- D-211: before/after screenshots and each council member’s actual score are recorded in the UI overhaul PR, with no invented score or claim that a subjective rating proves functional acceptance.
- D-211: a provenance-recorded blind comparison includes Discord, TeamSpeak, Ventrilo, KDE System Settings, Windows Control Panel, Trillian Messenger, Microsoft Teams, Webex, Slack, Zoom and the professionally recognized references; each current council member gives the final SloppyVoice candidate at least 9/10 and ranks it highest using the shared rubric. Source identities and external awards are withheld from the scoring brief; recognizable image content and screenshot-only limits remain explicit.

- D-209: every client exposes Report a bug, shows the public-posting notice and the attached client kind/version/platform before sending, keeps diagnostics and account address off unless selected, posts through a Home server advertising `bug-reports/1`, and otherwise opens (or, on iOS, copies) a prefilled GitHub new-issue link meeting [SPEC-026](026-bug-reports.md#acceptance-criteria).

- D-207: admitted channels display their current authorized voice occupants beneath the correct channel, with qualified identity and explicit voice/muted state; unavailable rosters do not claim emptiness and departures remove rows.
- D-207: each channel shows its authoritative Public/Private discriminator, independently of encryption. Voice-capable channels expose an accessible permission-aware handset using the existing exact-target call/movement safeguards; text-only channels have none.
- D-207: servers, channels and people have distinct theme-aware foreground/background treatments, with at least 4.5:1 text contrast, desktop scaling, wrapped identities, native selection and keyboard access. Presence interaction has no text/account/admission/media side effect and ordinary refresh preserves surviving keyed selection/expansion.

- D-206: adjacent originals, including the same author, have distinct further-muted full-width fields; loaded replies, dates, drafts and active voice status retain their root’s field through expansion and refresh.
- D-206: the transcript has no visible table header or separate Time/Status columns; readable sender bands, exact inspectable timestamps, age, actual parent labels, counts, missing markers and outgoing statuses remain available.
- D-206: compact opaque rounded hover controls and keyboard/touch menus expose only permitted actions without a full empty action row or hover-induced text movement; message selection, copy and protected drafts survive.
- D-206: live desktop palette/font/scaling changes preserve readable contrast and fitted controls, with no application palette picker or hover-debug preference.

- D-202: the current Gentoo package fetches public immutable sources with verified digests, compiles all project application executables/helpers and its GCC plugin offline, installs no downloaded application binaries, and passes isolated install/version/plugin checks plus normal upgrade selection with matching project/local overlays. System PipeWire declares its GStreamer USE dependency; historical published packages remain intact and no system merge occurs during validation.

- D-199: normal startup sign-in commits the verified workspace, shows the full permission-filtered channel projection and allows DM opening without requiring another account selection; the primary account action accepts another qualified Home address.
- D-200: a single left click opens/focuses the exact permitted Home/foreign channel tab, reuses an existing tab, preserves outgoing drafts and never joins/moves voice; denied/failed preparation retains the previous usable tab.
- D-205: at a fixed viewport/font and unchanged other fields, each client bitrate reserves eight numeric characters (one third less space); changes through 999999.9 kbps leave Server: at the same rendered position. Larger values remain fully readable by expanding naturally; values/units/accessibility remain accurate and narrow layouts still wrap and shrink.
- D-203: owner statistics use consecutive service/voice RTT and upload/download pairs and preserve this order when optional fields are absent; client ordering is retained, Client/Server section labels distinguish the measurements, and accessible text exposes the same labels/order.
- D-201: statistics components have distinct category colours, horizontal gaps and separators in light/dark desktop palettes; labels, units and accessible text retain meaning without colour, live theme changes remain readable, and styled content still wraps/shrinks without clipping.
- D-199/D-200: local and owner-authorized aggregate statistics always remain visible in the bottom status bar, without a display checkbox, Conversations button or statistics popup. The bar fits the actual text height and shrinks on widening/shorter content; unavailable context uses placeholders, owner data remains private and legacy showStatistics values are retained without affecting display.

- Native account and older-room invitations accept valid existing raw/link forms locally, refuse substitutions before credential dispatch, and retain original service/account scope through cancellation or navigation. Native nonowners can explicitly leave their named admitted channel through a standard consequence confirmation; lost replies use the original retained command.

- Importing a closed supported Electron profile preserves its accounts, device/private/history keys, original credentials, pending operations, saved connections, drafts and supported preferences in authenticated native storage, or leaves the complete source and prior native state unchanged with a visible reason. Generated helper/restart/failure checks demonstrate this; source scale remains metadata only.

- Native History can traverse retained eligible text beyond the live 250-record window with bounded memory and standard keyboard-accessible controls. Generated original Home/Host/private tests verify source fences, cancellation, unchanged drafts/call state and no ineligible plaintext.

- Native Recent remains protected and account-local, contains only eligible verified encounters, honors SPEC-014 limits/clear behavior and stays independent of pins, memberships, text tabs and call attendance.

- Native unread counts stay local to the exact account/Host/conversation and clear only after eligible loaded content is shown and its monotonic read position is saved; summary/background/hidden views preserve unread state and call attendance.

- Native voice cue settings, event selection and synthesis match SPEC-020; playback-only previews and active-call cues preserve microphone permission, encryption, call ownership and explicit profile conflict/reconciliation behavior.

- Visible native person rows load only bounded validated pictures from the correct verified Home, keep a neutral fallback on failure and cancel account-scoped image work without changing credentials, membership or media.

- Native profile changes use the original verified Home account and preserve keys, independent text/call selection and unsaved conflicting edits; bounded cropped images satisfy SPEC-019 and unknown saves reconcile only through explicit exact retry.

- Native Home and foreign conversation summaries use the same strict type/account/membership/call validation bound to their original checked authority; a different or noncanonical direct host is rejected.

- A missing native private-conversation connection is saved only after validated scoped admission and successful protected persistence, while a valid existing Host session is reused without rotation or ordinary navigation.

- A borrowed native conversation endpoint preserves its exact existing account/Host credential with no navigation or fresh sign-in, and cancellation or changed preparation cannot expose a replacement endpoint.

- A saved conversation-only visitor retains its protected account/session state across restart but appears in no ordinary Servers projection or background ordinary-channel read, and ordinary selection cannot use it without explicit policy-checked admission.

- Native conversation-only admission uses the existing distinct direct-connect purpose and verified Home/Host bindings while ordinary visitor admission remains closed, with generated HTTPS checks proving no ordinary channel/directory/media privilege.

- Native Join as immediately joins/opens the named ordinary channel as its chosen identity and continues only the unchanged captured call in that exact server/channel; cancellation/failure preserves the prior usable view and unrelated calls, and selecting the existing call identity never toggles voice.

- Native prepared membership retains the old view until checked selection, sends only an explicitly requested eligible ordinary-channel join to its exact account/server, and preserves unknown outcomes for exact explicit retry across owner closure and restart.

- Native explicit cross-source voice changes retain the original call until cancellation or checked movement permits its termination, use the exact account/server contexts, reject stale confirmation/continuation and require fresh input on the replacement; generated real-relay tests cover both movement directions and unrelated-account preservation.

- Native saved-server Rejoin verifies and explicitly confirms its named account/server, refreshes only that connection’s credential, and publishes only after checked state plus protected selection. Cancelled/failed preparation preserves the prior view and keys, protected pending commands prevent replacement, and no call starts or resumes.

- Native voice control has a separate account-bound transport with at most one HTTP/1 connection per host; unrelated interactive socket closure cannot fail its queued requests. Generated HTTPS/control and real relay checks retain TLS verification, exact request/account binding, cancellation, pending limits and existing media deadlines.

- Native server-row Sign out affects only its named account/connection and matching call, including while another account is browsed. Preparation cancellation/pending commands prevent logout; errors do not claim remote success. Selected text identity, unrelated credentials, drafts and keys remain intact.

- Closing a native tab saves its draft before destroying page widgets and rendered history, and a failed save retains the usable page/edit. Background changes cannot recreate it; verified reopen restores its draft. Last-tab closure stops foreground history reads without altering inbox, group presence, pins or call attendance. Known closed-group draft clears persist independently of widgets and survive failed-save retry.

- Native direct/group tree, tab, invitation and new-contact opens publish only verified prepared state after a successful protected selection commit; failure/cancellation keeps the previous usable view and draft. Returning to an account with a retained operation exposes only its exact context for explicit retry without dispatching or changing the saved command.

- Native account selection retains the previous usable text view and protected selection on cancellation, supersession, failed authentication/state validation or a failed atomic save. A generated denied/failed-write fixture checks unchanged selected profile, connection, draft and destination snapshot.
- A retained account with no currently accessible ordinary channels opens an empty channel view after a valid account/permission read, without issuing a channel history request or implying lost account keys. Explicit conversation and call actions retain their own authorization.
- A generated relay call continues with the same account, attendance and call IDs and held input across text-account switching; personal input/listening controls remain bound to the call owner until an explicit voice movement.

- Native saved-connection fixtures retain independent sessions, drafts, cursors and pending operations across interleaved profile saves and restart; no connection record/list duplicates private account keys or leaks session material through metadata. Removal keeps the same account profile and selects only its retained home connection. Fresh authority/session validation precedes authenticated use of a restored visitor session.

- Native SPEC-011 recovery requires a saved separate key plus the password, verifies the original root and exact signed transition, survives completion interruption without replacing pending keys, revokes prior sessions and keeps eligible retained copies readable. The key cannot authorize media or a second recovery; setup and unreadable-history status are explicit.

- D-197: the native client inherits desktop fonts/display scaling and has no separate application zoom. Migration retains the original saved percentage as metadata, with missing/invalid-source handling and unchanged source data verified. Other clients retain their scale controls.

- D-193/R-124: the released Linux successor uses Qt with native C/C++ or Rust application code and does not require Electron; applicable existing account, encryption, text, voice, sharing and administration behavior passes native/interoperability validation. Report remaining gaps explicitly rather than declaring a partial port the replacement.
- D-194/R-125: native navigation has Servers and Direct Messages root items, root creation context menus with keyboard equivalents, conversation tabs, no toolbar/ribbon and no right pane. Pinned-only contacts remain visible after closing their tabs, and sort fixtures pass last-message/newest-pin/alphabetical precedence without navigation changing message times or voice.
- P-037 is selected within D-194, D-197 and D-198's explicit scopes; other presentation/workflow amendments remain proposed. Approved amendments identify their Linux-only predecessors and retain security, permissions, call-target and input safeguards; other clients keep their current presentation contracts.
- D-193: a comparable resource report records CPU, memory, startup and application/dependency disk costs for the old and new Linux implementations; release claims cite measured workloads and limitations.

- D-184: an ebuild or installed packaging-file update supplies a strictly higher Portage version/revision in both repositories; a normal update plan selects it over the installed older version. A same-archive revision preserves the original URL, size and digests, and passes fresh-cache fetch plus isolated prepare/install without a system merge.

- D-183: alpha.48 desktop packages use Electron 44.9.1, reject the incident test chains through actual Node and Chromium certificate validation, and pass ordinary HTTPS plus applicable native/application regressions. Published package bytes match their manifests/checksums; project/local Gentoo metadata and fresh-cache Portage fetch/digests pass. Existing device profiles, permissions and certificate checks remain intact.

- D-182: enabled statistics remain inside the visible right/People panel and keep their position while a long people list scrolls. Collapsing People does not hide enabled statistics; expanded aggregates and the opt-out checkbox remain reachable at narrow widths and 200% interface scale.

- D-172: current and future admitted channel members receive the moderator-approved pin; encrypted copying is automatic, independently authenticated and bounded by original retention/current membership, with explicit offline-holder waiting. Surrounding history and thread eligibility remain unchanged.

- D-173–D-180: saved PTT remains usable during ordinary settings; recording owns input until save/cancel, and leaving its tab restores the saved binding.
- Each voice-capable channel exposes a permission-aware handset with distinct available/connected/disconnect-hover states, accessible names and keyboard operation.
- Statistics appear at the bottom of the people panel only when enabled; an owner can expand bounded per-user aggregates, while malformed/unavailable responses preserve the rest of the interface.
- System status is absent during healthy unannounced operation; active announcements expire or clear, and repeated request failures show connection guidance.
- Public mode applies only to verified public servers and public channels; required encryption and own-account/private-context checks remain effective.
- Native clients offer a validated newer official package with Later and explicit download handoff; checking and dismissal preserve the current call.

- D-171: either device can show a QR, the other scan it and the approved device explicitly confirm admission without a new-device password; unsupported cameras retain manual entry or scanning from the other device. Camera frames stay local and tracks stop on the specified exits; browser/native permission checks and physical results are reported separately.

- The voice-disconnection notice places its Close control at the top-right, with readable text and a usable Download voice log action at narrow/scaled widths.

- Remote screen viewers place all viewing controls above the picture in a compact row that wraps when necessary; zoom, stop and expand/shrink remain usable in native and SFU views without horizontal page overflow.
- Show chat keeps a watched screen visible above the conversation while messages can be read and composed; switching layouts preserves the picture, subscription, zoom and current draft.
- Automatic watch termination, source removal and call-session replacement leave no expanded/docked empty screen panel; a subsequent Watch starts inline at Fit with the chat draft intact in Chromium/Firefox canvas and SFU component fixtures.

- D-170: `/download` visibly labels Android Experimental, links the exact published APK, and gives matching version/size/SHA-256, installation guidance and validation limits. The complete public download matches the local artifact, and desktop download links remain valid.

- D-163: a Codemagic-produced signed build installs through TestFlight on the iPhone 13 mini; its source revision, app version, build number, OS version and signing/upload outcome are recorded. Required iOS configuration choices are resolved before the corresponding implementation, and signing secrets are absent from source and logs.
- D-163: the first delivered iOS build retains the Android chat-first controls and a previously joined call while locked/backgrounded, with observed two-way media and protocol renewals. Held PTT stops, background activation retains existing policy, expiry/revocation still stops media, explicit Leave cleans up, and process loss does not auto-rejoin. A foreground-only prototype does not satisfy this acceptance criterion.
- D-163: the exact iPhone XS OS version and separate compatibility results are recorded before advertising that device as supported. Missing hardware evidence remains explicit.

- D-161: Android shows channel chat and its composer above the persistent user/config bar. Three-dot expansion exposes navigation, voice controls and people, and closes on channel/settings selection. Hold to talk/voice activation appears in the user bar only for a connected local call; toggling options preserves that call. The layout fits a narrow emulator screen and software keyboard without obscuring the composer or bottom controls. Desktop layout remains unchanged.

- D-208: every ELF in the published Linux x64 archive and Flatpak has no `GNU_PROPERTY_X86_ISA_1_NEEDED` level above `x86-64-baseline`. None has a non-baseline instruction outside a reviewed runtime-dispatched third-party function, and the release record includes the inventory. QEMU TCG Opteron_G1, Nehalem, Westmere and Haswell smoke runs pass with no SIGILL or loader ISA refusal. They cover bundled libraries, executables, plugins and an offscreen client launch. No host-copied library or host-native Rust standard library is packaged. The source archive, Gentoo ebuilds and `native-client/CMakeLists.txt` carry no ISA flags.

- D-160: public home/download platform copy uses Linux; a real x86_64 Flatpak bundle is downloadable with matching manifest hash and installation/update/profile instructions. Actual installation/launch and native dependency checks pass in the declared runtime, approved permissions are bounded, and existing archive/Windows downloads remain valid. Hardware gaps are stated separately.

- D-158: the homepage browser-entry section and download-page browser option visibly state that browser use requires local storage on the device for encryption keys, with no layout overflow at 320px.

- A 1037 ms renewal starts its overdue successor immediately after completion rather than waiting for the old 2000 ms interval boundary; fast renewals retain the nominal one-second cadence. Intentional leave cancels further attempts and ignores late failure responses; actual active-call rejection still closes media under the existing deadline rules.

- D-154: the approved Editorial homepage offers a public server as an alternative to self-hosting, accurately separates access from encryption, names sloppyvoice.com invitation-free admission only while D-153 is enabled, and qualifies direct bandwidth by eligible private encrypted routes. Home/download support system light/dark appearance and working keyboard navigation; no preview controls or PTT promotional highlights ship.

- D-155: the public page links a complete Windows x64 portable ZIP at a new immutable URL; full download matches its manifest size/SHA-256, extraction exposes `sloppy-voice.exe` and its native helper, and the page states launch steps and normal-profile persistence. Installer/Linux links remain valid.

- D-152: a signed test APK installs and opens the bundled Sloppy Voice client on the named emulator, with documented build/install commands and exact artifact hash.
- Explicitly joined voice continues with Home and screen off; observed renewals and media progress retain the same session. Notification End call stops capture and service. Held PTT does not survive focus loss; background voice activation requires prior explicit activation and permitting policy.
- Native vault ciphertext survives an app restart/upgrade, rejects tampering or unavailable keys without plaintext fallback, and cannot be read by foreign origins/subframes. Backup excludes device identity.
- Permission denial, failed call setup, renderer/process loss and audio-focus interruption cannot leave a claimed active call or silently restart capture. Narrow-screen navigation keeps channels, conversation/settings and people reachable.

- D-151: `/download` shows Windows and Linux with equal prominence side-by-side on a desktop and without horizontal overflow at 320px; each has its correct manifest-backed link, size, version and checksum. Unavailable desktop/mobile platforms have no public entry or placeholder. Homepage copy explains self-hosted accounts joining permitted channels across compatible servers and states the current technical setup/source-access limits.

- D-204: Qt ordinary channel titles containing whole-word Lobbyster show the existing static lobster behind the title, with readable original text/accessibility; light/dark themes, desktop scaling, rename transitions and narrow wrapping keep account labels and controls reachable. Direct/group, navigation and tab labels remain undecorated.
- D-149: the current channel heading renders at 24 CSS pixels at 100% scale; whole-word Lobbyster matches, regardless of case, have a static cartoon lobster behind the word. The title remains unchanged and readable, artwork is inaccessible/non-interactive, other contexts have no decoration, and narrow/scaled/forced-colour layouts keep text and controls reachable.

- D-147: Pinned replaces Friends throughout the people UI; existing saved people and synchronization are retained. Filled amber and muted outline thumbtacks, accessible Pin/Unpin state, active green private-call handsets and lavender current-DM buttons remain distinguishable in light/dark/forced colours. Ordinary channel/thread co-attendance never activates phone/message buttons. Private activity remains account-qualified, clears with its actual local state, and does not alter contact acceptance or voice movement.

- D-144/D-145: the Linux share dialog names the selected game/music streams, captures only those streams, and releases its native capture helpers on every stop/failure path, as specified in SPEC-023.

- D-142: both sidebars use the approved rounded section hierarchy while keeping compact rows, full identity/access labels, selected channel/server distinction and existing voice/unread meaning. Populated, empty, long-name and narrow/scaled fixtures retain reachable controls, search, expansion, context actions and resize/reset without horizontal page overflow. No automatic call, new permission or saved configuration change is introduced.

- D-141: User settings has solid, rounded heading boxes and softer matching rounded settings panels, with quieter nested groups; other workspaces retain their compact treatment. Light/dark text and controls remain readable, forced colours retain visible section boundaries, and narrow/scaled layouts keep controls reachable without horizontal page scrolling. Existing section order, settings values, Back/Escape, focus return and PTT safety are preserved.

- D-138/D-139: Channel settings shows the canonical selectable public link; desktop Copy writes it successfully. Confirmed deletion follows SPEC-012 and missing defaults recover without voice movement. The active voice channel uses a compact handset icon with tooltip and accessible meaning.

- D-136: a denied preview displays an accessible reddish panel spanning the dialog's content width, with recovery guidance. An old desktop wrapper explains the required update before attempting capture; supported wrappers and browsers retain explicit source permission, preview and Start sharing.
- Screen-sharing delivery satisfies R-117–R-121/A-49 and SPEC-023 on each claimed platform, including one combined all-screen view, explicit source consent, route-aware bitrate, microphone-only PTT, synchronized playback and local configurable game-sound ducking. Physical capture/audio and measured capacity gaps must be disclosed before claiming platform completion.

- Without a voice call, user settings offers the editable mode checkbox within Push-to-talk configuration, saves it across reload, and leaves capture off. Neither disconnected state nor open settings permits on-screen transmission. Disabled PTT shows an explanation and a held Click to talk fallback in eligible active calls, with no Re-enable PTT action and no shortcut re-enabling.

- A-46: expand two servers without switching the selected conversation or moving voice; navigate and act on either branch under the correct account/server.
- Both sidebar boundaries resize with pointer and keyboard, retain manual width on reload, and reset independently to automatic; content changes do not enlarge a manual side.
- Automatic sizing accommodates ordinary names on one line when space permits; long names wrap at the cap and small/scaled windows keep conversation and sidebar controls usable.

- R-112/A-45: three separate bottom-left bars replace the center voice strips, with reachable context, diagnostics, call actions, microphone controls, failure notice and identity actions at supported scales.

- D-104: saved servers appear as roots with Add server and named context actions; the bottom-left Messages icon opens an unread summary, right-sidebar DM indicators agree across qualified lists, and neither removed top-bar control remains. Reading one DM clears only its local indicator, without moving voice.

- D-103/A-42: early renewal preserves workspace/drafts and voice, shared windows adopt the stored credential, and the subtle warning obeys the fixed threshold without appearing for Unlimited.

- R-102/R-106: circular sidebar pictures are 56 CSS pixels at 100%; changing UI scale to 75%, 125% and 200% proportionally changes text, controls, pictures and menus across shared screens while keeping navigation and reset accessible.
- R-106: a valid scale survives reload/sign-out and updates other windows on the same origin, without changing another device/account’s server profile; missing values use 100%, invalid values/storage failures show the specified notice, and reset restores 100%.
- R-107: voice connection states have distinct subtle surfaces and explicit labels; message-entry surfaces are separate from voice/chat, readable in light/dark mode and retain system-colour boundaries in forced colours. PTT transmission colouring is unchanged.

- D-098 unexpected disconnection produces a persistent accessible notice identifying channel, time and the available reason; polling cannot erase it and the client never rejoins automatically. Intentional leave does not show a failure alert.

- Complete the applicable PTT inheritance, profile picture and audio cue acceptance criteria in SPEC-004/012/019/020.

- D-094 displays text-labelled green Private/red Public channel badges with rounded borders and softer fills, independently of encryption and readably in light/dark/forced-colour modes.
- D-094 people rows show identity, icons and recorded context in that order; saved friends are absent from Recent but remain eligible in Server Members, and unfriend/Clear preserve the existing Recent data contract.

- D-084: Connection details expand inline, show only local aggregate call metrics, reset on a new call and neither record nor upload audio, keys, credentials or ICE addresses.

- R-083: user, server and channel settings, member management, creation and help workspaces place Back at the top-left before the title at desktop and narrow widths; Back/Escape return to the channel with appropriate focus.

- R-077: the main interface has one room/voice tree, no persistent member sidebar, and the same channel actions through `+`, right-click and keyboard.
- Personal and permitted moderator controls appear in one participant menu; local controls never alter room policy and moderation never bypasses server capabilities.
- Shared web/mobile/released Electron configuration and management occupy the main workspace without modal backdrops or focus traps; consequential actions wait for inline confirmation. D-198 supersedes this placement for the Qt successor with standard modeless native dialogs and ordinary consequential confirmations.
- R-078: the shared UI uses the application light/dark palettes selected by live system appearance; KDE RGB values cannot replace them. Forced colours take precedence, and neither OS settings nor stored account/device preferences are changed.
- Tree/menu/workspace keyboard, narrow viewport and existing text/voice/identity/linking/recovery regressions pass; platform evidence and browser palette limitations are stated explicitly.


- A participant context panel works with mouse and keyboard, keeps volume/mute together, persists only personal playback settings and never unmutes or changes another listener.
- Saving a nickname updates other signed-in clients while the full account address stays visible; clearing restores address-only display. Drafts survive polling/conflicts and profile changes do not alter keys, permissions or voice leases.

- A minimized desktop client continues renewing voice authority for a test exceeding the reported two-minute failure window. At the shared 60-minute deadline it closes, reports the reason and requires explicit rejoin; a deterministic clock fixture checks the deadline separately from real-time soak. D-054.

- D-053’s explicitly selected side-button source works without evdev access, uses no keyboard event subscription/injection/grab, and passes interruption/fresh-press checks. Actual foreground/hardware verification is reported separately under A-37.

- A-38 passes for the D-052 workflow without changing existing owner credentials or sessions.

- D-051's public `/download` page works on desktop/mobile and by keyboard, links to the verified installer and checksum, and states alpha/signing/account limitations without claiming completed hardware validation.

- D-050 produces an alpha.3 Windows x64 installer containing the matching application/helper and notices, with per-user installation and an uninstall entry; device data survives install/update/uninstall. The evidence distinguishes compiler/extraction/Wine results from actual Windows acceptance.
- D-050's web deployment serves the matching built assets while retaining the existing domain, EU authority, owner and media binding. The refreshed Gentoo Manifest matches its release archive. Package origin overrides and generic no-default behavior pass the SPEC-002 precedence checks.

- The successor completes A-33/A-34/A-35/A-36 on the same account across KDE, Windows and web, with separate keys, server-owned permissions, honest history/recovery coverage and explicit voice movement. These are pending feature gates.
- Record and save a keyboard key, the physical ProtoArc mouse button 4 used for Discord, and a real joystick button from the configuration page. Verify held/released indication and persistence; no audio is sent while configuring. Repeat actual PTT while another application/game has focus on KDE Wayland and Windows; test focused-browser behavior separately. A-37; D-047/D-048.
- Before leaving the testing phase, complete joystick press/release, disconnect/reconnect and foreground-game tests on both target desktop platforms. An unplugged/unavailable joystick is recorded as untested, never a passing mock-only result. D-048.


- Both generated desktop archives contain the project licence and attribution at the specified paths, declare `Apache-2.0` in application metadata and preserve Electron/Chromium/godbus notices. The Gentoo application licence expression has no `all-rights-reserved` placeholder and its Manifest matches the packaged Linux archive. D-035.
- Run one shared interface on the declared KDE Wayland and Windows first-test matrix; complete sign-in, room text, voice, global PTT, and moderation with the optional D-053 XWayland mouse adapter explicitly identified when used. Record GNOME/macOS as incomplete until their required integrations are demonstrated. See A-20/A-23.
- Exercise the browser client on its declared browser/version matrix and verify focus-only PTT, stop-on-focus-loss, and no false claim of global PTT. See A-24.
- Inspect and operate local versus moderator mute/gain controls; labels and resulting scope remain unambiguous to the user and correct in recorded actions. See A-09/A-10.
- Revoke a user's capability while their interface is open; the UI updates and a request using stale rights is rejected by the server. See A-11.
- Have two admins edit the same setting revision; the accepted update is shown as saved and the stale client's input remains available alongside the server's conflict response.
- Configure the reference server's supported PTT/media settings through an authorised client and verify the effective configuration and required session propagation without routine provider-console changes.
- Complete the supported keyboard-only and screen-reader workflows; all actionable controls have accessible names, focus indication, and a non-colour-only status representation.
- D-181/D-202: each client release records project/local-overlay agreement with the published compatible native source archive; a new package passes empty-cache Portage fetch/digests before delivery is declared complete, with system installation remaining a separate human action.
- D-061/D-202: Portage downloads the current native source archive and pinned crate sources from an empty cache without authentication or manual file staging and validates their Manifest digests.
- Validate the Gentoo package metadata, launcher and staged installed files under D-032; no credentials, automatic service startup or sandbox-disabling flags are installed.
- Inspect client-visible settings, diagnostics, and credential persistence and verify that provider secrets are absent and local credentials use the selected protected storage contract.
- Open another room's text while holding desktop PTT, then switch the active voice session; verify the original target is preserved for navigation and a new press is required for the session switch. See A-07.
- During delayed or failed relay revocation, display incomplete mute enforcement; display effective enforcement only for the corresponding confirmed revision. Reconcile a timed-out command without creating another effect. See A-29.

## D-063 configuration and keyboard interface

Use channel terminology in the shared interface without renaming protocol IDs. A bottom-left cog opens user settings; the server button has context-menu and keyboard access plus a visible settings action. Group related supported properties on a scrollable panel, including readable scope/default/constraint explanations. D-065 supersedes modal focus containment: use the main-workspace and non-modal menu behaviour in the D-065 section, retaining labelled headings, Escape dismissal (except during input recording), focus restoration and visible focus. Provide a discoverable shortcut list: Ctrl+, user settings; Ctrl+Alt+S server settings; Ctrl+Alt+C channel settings; Ctrl+Alt+M member management; Ctrl+K channel search; Ctrl+Alt+H shortcut help. Shortcuts must not consume recorder input or IME composition. Hold-to-talk supports held Space/Enter with release/blur cancellation. Existing PTT safety rules apply while configuration is open. User/device linking remains available without logging out. Polling results and command tickets are bound to the initiating token/channel; discard obsolete results. Prefer SPEC-012 sync/1 and load management data only when visible. Desktop microphone permission checks and requests admit microphone audio only from the selected service main frame; screen capture follows the explicit source-consent contract above. Camera access stays denied except for the explicit D-171 QR-scanner session above. Redirects obey the same service boundary as navigation.

Member management displays pending account invitations with username, expiry and an explicit cancel action. Copy is available for an invitation just created on that client; existing bearer secrets are not retrieved from the server. A pending invite does not appear as an active member until registration succeeds.

Device-directory and recovery responses update verified account authority on the current vault; they must not replace local input/listening preferences with an earlier request snapshot. A delayed result from another account/device is rejected. Saving an input binding reports completion only after persistence. Test a delayed directory response across a binding save and reload. This is same-client isolation; cross-tab vault ownership remains a separate unselected design.


## D-064 participant controls and account nickname

D-065 supersedes the original modal listening panel and separate channel-member sidebar. Right-clicking a participant in the room tree or channel-member workspace opens the combined context menu specified in the D-065 section. Provide a focusable visible entry/button, Enter/Space activation and Shift+F10/Menu access, Escape/outside dismissal, focus return and bounded viewport placement. Show local volume and `Mute for me` together; their persisted values and scope remain SPEC-004's existing per-client controls. Changes affect current playback immediately and report persistence failures. Personal controls never issue moderation commands. D-065 permits separately labelled, capability-checked moderator actions below them in the same menu. A participant cannot locally adjust their own received voice; their entry directs them to User settings. Close a stale panel when its account/channel/participant context disappears. D-189 supersedes menu-wide input suppression: opening or using this panel preserves authorized microphone input; recording a replacement binding still suppresses input.

User settings includes an account Profile section with a labelled Nickname field, explicit Save, preview and clear-to-username behavior. Explain that it is shared with other users and across approved devices; its canonical validation/defaults are in SPEC-008. Do not replace unsaved input when a poll updates the account. A conflicting profile revision preserves the draft and requires an explicit review/reload before retrying. Display errors and success within the panel. Older services without `account-profile/1` expose no editable nickname control.

Display a nonempty nickname in bold with the full `username@domain` beneath in smaller text, including voice/channel lists, the self card, member management and message authors. Without a nickname retain the full address as the primary label. Never truncate away the only way to read/copy the full address, interpret labels as markup, or use them for login, identity trust, permissions, message authorship or media routing. Current participant profile data may label previously fetched messages; otherwise use the message's retained author profile. Changing a nickname never rewrites historical author evidence.

## Local voice diagnostics (D-084)

D-108 moves **Connection details** into the non-modal panel above the bottom-left connection bar, collapsed initially. Show current codec, selected UDP/TCP transport when available, local-to-relay RTT, sent/received wire rate, adaptive target/queued delay, arrival jitter, missing/late/discarded frames, decoder failures, FEC attempts, PLC slots, underruns, renewal failures and encryption pauses. Unknown metrics say unavailable; zero is not a substitute for unavailable RTT/path data. FEC attempts do not assert successful recovery. Delivery gaps cannot establish actual network loss: late packets, browser scheduling and local drops can also cause them.

D-099 and [SPEC-021](021-voice-diagnostics.md) add a bounded, memory-only event journal across calls with explicit JSON download in Connection details and disconnect notices. This component records client lifecycle, renewal, scheduling and transport events under that shared contract. Metrics remain memory-only aggregates for the current call, sampled once per second. Starting another call resets them; no new storage, upload or telemetry endpoint exists. Never collect audio, packet contents, keys, SDP, ICE addresses, credentials or a per-person history for diagnostics. SPEC-004 owns codec/playout constants. Unit tests cover counter aggregation/reset and a strict selected-stats projection; browser tests open the inline details and verify local-only values. Acceptance requires useful diagnostics for encrypted and readable calls without weakening mute, capture or authority rules.

Human presentation refinement, 2026-10-25: place the voice-disconnection notice's Close control at its top-right, reserving space so it cannot overlap the heading or download action at narrow widths or increased interface scale. Preserve the named keyboard-accessible dismissal action, persistent notice and explicit diagnostic download. This adds no configuration or behavioral change to calls or logging.

### D-164 Linux output-device sound selection

The screen-sharing popup offers Applications and Output devices under SPEC-023’s capture contract. Applications remains the initial mode; output capture requires the separately advertised outputAudioVersion 1 capability and explicit device selection. Display the full-output/call-echo scope before preview. Refresh and mode changes clear selection, with controls disabled during capture. Older wrappers show desktop-update guidance for output capture. SPEC-023 owns source limits, consent, defaults and lifecycle. Unit and native integration tests verify mode isolation, exact output selection, scope disclosure and no microphone/default-device fallback. Acceptance requires named-output and all-listed selection without silently broadening application capture.
