Native response timing and alignment delivery
This document records the native Rust/GPUI response-timing and geometry work
developed from baseline commit
b4ecd6bd1b13461cc4f3982afa6cdb44d3e572c9. It covers two connected
increments:
- reusable Worked and conditional Thought disclosures across EXEPERT, Codex, and DSH Chat; and
- corrected ZED active-response/footer alignment plus a compact shared scroll-to-bottom control.
The change is presentation and read-only timing projection inside the native
desktop boundary. It does not change the hosted EXEPERT SSE contract, the
Codex App Server protocol, the exepert.dsh.v1 sidecar protocol, Supabase,
database schemas, reference repositories, settings schemas, dependencies, or
transcript ownership.
Delivered behavior
| Area | Delivered contract | Surfaces |
|---|---|---|
| Whole-response timing | A live Working for … label freezes as Worked for … when an exact terminal duration exists | EXEPERT, Codex, DSH Chat |
| Stopped timing | Exact failed or cancelled terminal durations display Stopped after … | EXEPERT, Codex, DSH Chat |
| Reasoning timing | Thinking for … and Thought for … appear only for recorded provider-visible reasoning spans | DSH Chat when trustworthy records exist |
| Missing data | Missing, malformed, backwards, truncated, or partially paged timing produces no timer | All three sources |
| Disclosure interaction | Full-width stacked buttons start collapsed, expose expanded state, support keyboard activation, and animate height, opacity, and chevron direction over 150 ms | All three sources |
| Safe expanded content | Timing facts are bounded, cards stop at 360 px and scroll internally, and reasoning content is already redacted and bounded | All three sources |
| Live repaint | One visible-surface 1 Hz ticker updates running labels without rekeying or remeasuring rows on each tick | All three sources |
| ZED row geometry | The active response uses the centered 760 px assistant shell and 20 px inset; the 720 px footer shares the same center | EXEPERT ZED presentation |
| Standard geometry | Existing 720 px standard EXEPERT alignment is unchanged | EXEPERT presentation |
| Tail control | One 32 px button with a centered 16 px chevron grows from 28 px to 32 px over the existing 140 ms appearance animation | EXEPERT, Codex, DSH Chat |
| Reduced motion | Disclosure and tail-control appearance resolve directly to their final geometry | All three sources |
Timing model and truth boundary
ResponseTiming contains one required Worked measurement and one optional
Thought measurement. Each TimingMeasurement carries:
- metric kind: Worked or Thought;
- state: Running, Completed, or Stopped;
- optional exact duration and source start/end timestamps;
- provenance identifying the authoritative source or provisional local clock;
- at most twelve bounded source-supplied detail rows; and
- optional bounded provider-visible reasoning content.
The provenance order prefers an explicit source duration over a valid source timestamp difference, and either over a process-local monotonic live anchor. The local anchor exists only to paint a smooth live counter. It is not saved as canonical source timing, and it cannot create a historical timer when the source data is incomplete.
Durations render as whole seconds (57s), minutes and seconds (7m 17s), or
hours, minutes, and seconds (1h 02m 03s). Values below one second therefore
display 0s; no false decimal precision is introduced.
EXEPERT timing
EXEPERT starts the provisional clock when ChatEvent::Started identifies the
active native response. Completion prefers the response metadata's persisted
total_latency_ms; a valid local terminal duration is retained only when the
backend did not supply one. The existing bottom latency chip is removed, and
the timing surface is placed above the assistant response.
Expanded Worked facts can include source-provided provider, model, token usage, start/end, and provenance. Throughput is never calculated from total wall time. EXEPERT's value is backend request latency, not private model thinking time, so native-only EXEPERT responses do not receive a Thought row.
Regeneration and deletion continue to follow message identity. Completed timings are pruned with removed messages, while persisted metadata restores canonical latency for resident history.
Codex timing
The Codex reducer retains startedAt, completedAt, and durationMs in a
turn-keyed timing map. Live turn/started state receives a local monotonic
anchor. A terminal durationMs wins when present; otherwise a non-negative
startedAt/completedAt difference is accepted. Exact failed or cancelled
turns use Stopped state.
One synthetic timing transcript row is inserted before the first agent item in each qualifying turn. When a turn is active but has no output, the row occupies the turn tail until the first agent item arrives. Stable identity includes the server, task, turn, and metric rather than a loaded-list index.
Read-only mirrors retain timing already supplied with turn data. When the
primary resident item window lacks timing, the runtime performs a bounded
supplemental thread/turns/list hydration for matching resident turns. The
request is source-qualified, epoch-checked, bounded, and fail-closed. It does
not replace last-good transcript content, weaken the existing item-list to
turn-list to capped-read fallback, or claim ownership of external history.
Codex 0.149.1 exposes no reasoning duration. Existing authorized
ReasoningSummary content therefore remains in its separate safe disclosure;
it is never converted into a Thought timer, and raw reasoning remains excluded
before UI state.
DSH timing
DSH timing is a read-only projection over already-redacted canonical
DshTrajectoryRecord values. Worked requires a resident turn/start plus a
matching terminal turn/end or turn/error. An explicit terminal duration
wins; otherwise a valid source-timestamp difference is used. Only the newest
live turn can receive a provisional monotonic anchor, and incomplete paged
boundaries remain untimed.
Thought timing opens and closes spans from recorded reasoning block and delta boundaries. The projection:
- qualifies spans by model step and block index;
- terminates spans at recorded block, message, model, tool, approval, or turn boundaries as appropriate;
- merges overlapping spans so concurrent blocks are not double-counted;
- sums separate model steps;
- excludes tool and approval gaps; and
- refuses a Thought timer when no complete or live recorded span exists.
The Thought card aggregates only already-redacted provider-visible reasoning, bounded to 32 KiB before rendering. Records consumed by this presentation are suppressed from DSH Chat to prevent duplicate text. Every original record, cursor, timestamp, hierarchy, and payload remains unchanged in Trajectory.
Disclosure rendering and lifecycle
The shared renderer places two possible full-width rows above output in Worked, then Thought order. Each row has a clock or thinking glyph, source-qualified stable ID, hover and focus-visible treatment, right/down chevron, accessible label, and native expanded state. Enter and Space use the normal GPUI button activation path.
Expansion state is process-local and defaults collapsed. It is keyed by source, owner, turn or message, and metric. The 150 ms cubic ease-out transition retargets from the current progress during rapid toggles instead of restarting from an endpoint. Height, opacity, and chevron progress use the same generation; reduced-motion mode settles immediately. Expanded content is clipped during the transition and capped at 360 px with its own vertical scrolling.
One asynchronous ticker is armed only while a running measurement is visible. It requests a repaint once per second and stops when no visible timing is running. Stable transcript revisions exclude the displayed second, so each tick paints new text without invalidating cached variable-row measurement. Opening or closing a disclosure does change its row revision; reconciliation preserves the current stable bookmark or pinned tail.
Assistant-row and footer geometry
The completed ZED assistant response already owned a centered 760 px reading column with a 20 px content inset. The active streaming/timing row and response footer previously bypassed that geometry and appeared left-shifted.
A private assistant-row shell now centralizes the existing widths:
- ZED shell: 760 px;
- standard EXEPERT row: 720 px; and
- ZED content inset: 20 px on each side.
native-streaming-row-* remains the stable ID on the 760/720 px inner row.
chat-response-footer remains a 720 px child centered within the 760 px ZED
shell. IDs, callbacks, wrapping, semantic roles, message ownership, virtual-row
keys, and tail-follow behavior remain unchanged. Switching between EXEPERT and
ZED presentation explicitly invalidates the affected native transcript row
measurements before restoring the stable reading anchor.
The pre-existing ZED failure card is deliberately not moved by this increment.
Its separate alignment follow-up is recorded in
_bmad-output/implementation-artifacts/deferred-work.md.
Compact shared scroll control
EXEPERT, Codex, and DSH Chat continue to use source-specific transcript views and callbacks, but their conditional tail control now consumes one shared geometry contract:
- final circular control size: 32 px;
- compact chevron size: 16 px;
- appearance start: 28 px;
- appearance end: 32 px; and
- appearance duration: the existing 140 ms.
The helper clamps progress before interpolation, which prevents overshoot when an animation is retargeted or sampled late. Flex layout centers the even-sized chevron without coordinate nudges or SVG changes. The unseen-content badge is offset from the control edge so it does not cover the smaller glyph. Stable IDs, tooltip, role, accessible name/description, focus, Enter/Space activation, and source-specific scroll callbacks are preserved.
Privacy, persistence, and compatibility invariants
- Worked means source-specific whole request or whole turn wall time; it never claims private model thought duration.
- Thought means recorded provider-visible DSH reasoning-channel wall time only.
- Raw or private hidden reasoning is never rendered, timed, persisted, or added to diagnostics.
- Expanded-state and animation state is process-local and not written to any transcript or settings store.
- EXEPERT response metadata remains the source of completed backend latency.
- Codex App Server remains authoritative for Codex history and turn metadata.
- DSH Trajectory remains the unmodified canonical event view.
- Token throughput is displayed only if explicitly supplied; it is never derived from whole-turn wall time.
- Existing EXEPERT, Codex, DSH, Supabase, sidecar, schema, paging, retention, approval, and transport contracts are unchanged.
- Benchmark and renderer-probe modes retain their existing lifecycle boundary.
Verification record
The final native source candidate was checked with the pinned Windows toolchain:
cd desktop
cargo +1.96.0-x86_64-pc-windows-msvc fmt --all -- --check
cargo +1.96.0-x86_64-pc-windows-msvc test --workspace --all-targets --locked --target x86_64-pc-windows-msvc
cargo +1.96.0-x86_64-pc-windows-msvc clippy --workspace --all-targets --locked --target x86_64-pc-windows-msvc -- -D warnings
cargo +1.96.0-x86_64-pc-windows-msvc build --package exepert-desktop --release --locked --target x86_64-pc-windows-msvc
cd ..
pnpm.cmd --dir docs-site exec docusaurus build
git diff --check
Observed results on 2026-09-03:
- Rustfmt passed;
- the complete locked all-target workspace suite passed; its library portion reported 515 passed and four intentionally ignored native harnesses, and all enabled integration suites passed;
- strict workspace Clippy passed with plain
-D warnings; - the target-specific optimized Windows release build passed and produced
desktop/target/x86_64-pc-windows-msvc/release/exepert-desktop.exe(39,613,440 bytes in the recorded local build); - all seven ignored Windows GPUI harnesses passed when run explicitly and serially, including the 32 px scroll-control bounds proof, Codex layout and virtualization, workbench motion, checkpoint preview, auto-scroll, and width-reflow bookmark restoration; and
- the Docusaurus optimized production build passed with this delivery record registered in Desktop navigation; and
git diff --checkpassed with line-ending conversion notices only.
The optimized application was launched against existing local transcript data. The shared tail control remained exposed as Scroll to bottom, its callback restored the tail, and the native inspector measured the chevron at 16 × 16 px. Switching ZED to standard EXEPERT presentation and back reflowed the resident transcript cleanly. Existing timing rows expanded and collapsed through native mouse and keyboard paths during the timer delivery check.
No fresh provider request was sent during the final alignment smoke. Live streaming/footer placement therefore remains supported by source contracts and native layout harnesses rather than a new network-backed interaction. A manual normal/scaled-DPI comparison of active row, completed response, footer, and button centers remains an optional physical-display release check, not an automated claim.
Repository change inventory
This is the exhaustive path inventory relative to baseline commit b4ecd6b.
At documentation finalization Git reported exactly 29 changed paths: 7
additions, 22 modifications, and no deletions or renames. Generated Cargo and
Docusaurus output remains ignored and is not part of the commit.
Implementation records
| Status | Path | Responsibility |
|---|---|---|
| M | _bmad-output/implementation-artifacts/deferred-work.md | Records the intentionally deferred pre-existing failure-card alignment |
| A | _bmad-output/implementation-artifacts/spec-native-gpui-worked-thought-timers.md | Approved timer intent, constraints, acceptance criteria, verification, and review map |
| A | _bmad-output/implementation-artifacts/spec-align-native-chat-rows-compact-scroll-control.md | Approved alignment/control intent, review fixes, verification, and follow-up boundary |
Native desktop source
| Status | Path | Responsibility |
|---|---|---|
| M | desktop/exepert-desktop/src/app.rs | Shared disclosure rendering, expansion/ticker lifecycle, EXEPERT/Codex/DSH projection, row placement, centered assistant shell, pruning, and presentation reconciliation |
| M | desktop/exepert-desktop/src/chat.rs | Persists source start/finish metadata used by native completed latency |
| A | desktop/exepert-desktop/src/response_timing.rs | Shared timing types, provenance, formatting, bounded content, and reversible disclosure animation |
| M | desktop/exepert-desktop/src/lib.rs | Exposes the internal response-timing module to the desktop crate |
| M | desktop/exepert-desktop/src/codex/protocol.rs | Parses and bounds persisted per-turn timing fields from App Server responses |
| M | desktop/exepert-desktop/src/codex/runtime.rs | Performs bounded supplemental turn-timing hydration with fallback and epoch safety |
| M | desktop/exepert-desktop/src/codex/state.rs | Retains, reconciles, prunes, and projects live/terminal Codex turn timings |
| M | desktop/exepert-desktop/src/dsh/mod.rs | Registers the DSH timing projection module |
| M | desktop/exepert-desktop/src/dsh/product.rs | Inserts DSH timing rows and suppresses only consumed reasoning rows in Chat |
| A | desktop/exepert-desktop/src/dsh/timing.rs | Derives exact DSH Worked/Thought measurements from canonical source records |
| M | desktop/exepert-desktop/src/ui/chat.rs | Centralizes 32/16 px scroll-control geometry and clamped 28-to-32 px appearance sizing |
| M | desktop/exepert-desktop/src/ui/codex_transcript.rs | Adds synthetic Codex timing-row identity and consumes shared tail-control sizing |
| M | desktop/exepert-desktop/src/ui/dsh_transcript.rs | Adds synthetic DSH turn-timing rows and consumes shared tail-control sizing |
| M | desktop/exepert-desktop/src/ui/native_chat_transcript.rs | Preserves EXEPERT row identity while consuming shared tail-control sizing |
Native desktop tests and contracts
| Status | Path | Responsibility |
|---|---|---|
| M | desktop/exepert-desktop/tests/chat_presentation_ux_contract.rs | Locks ZED/standard geometry and presentation-reconciliation behavior |
| A | desktop/exepert-desktop/tests/chat_control_render.rs | Native GPUI proof for the centered 32 px tail control |
| M | desktop/exepert-desktop/tests/codex_replay.rs | Covers supplemental Codex timing hydration in deterministic replay |
| M | desktop/exepert-desktop/tests/codex_ux_contract.rs | Updates Codex transcript/control contracts for synthetic timing rows and compact sizing |
| M | desktop/exepert-desktop/tests/emoji_ux_contract.rs | Locks cross-source 32/16 px geometry, 28-to-32 px animation, and badge clearance |
| M | desktop/exepert-desktop/tests/message_actions_ux_contract.rs | Preserves response action/footer geometry after top timing placement |
| A | desktop/exepert-desktop/tests/response_timing_ux_contract.rs | Covers timing semantics, placement, provenance, accessibility, motion, hydration, DSH spans, and row alignment |
Maintained documentation and navigation
| Status | Path | Responsibility |
|---|---|---|
| M | docs-site/docs/architecture/native-codex-client.md | Documents Codex whole-turn timing, bounded hydration, and compact tail geometry |
| M | docs-site/docs/architecture/native-dsh-integration.md | Documents DSH exact turn/reasoning projection and Chat-versus-Trajectory visibility |
| A | docs-site/docs/architecture/native-response-timing-delivery.md | Provides this complete delivery, verification, and repository inventory |
| M | docs-site/docs/frontend-modules/native-desktop-chat.md | Documents user-visible timing, accessibility, alignment, scrolling, and validation contracts |
| M | docs-site/sidebars.ts | Adds this delivery record to the Desktop documentation navigation |
Maintainer reading order
- Read the two completed implementation specifications for the approved intent and review history.
- Review
response_timing.rsfor the source-independent truth and motion model. - Review
app.rsfor lifecycle, rendering, stable disclosure state, ticker, centered row shell, and source-specific projection boundaries. - Review
codex/{protocol,runtime,state}.rstogether for live events, authoritative precedence, hydration, fallback, and pruning. - Review
dsh/timing.rs, thendsh/product.rs, for span derivation and the Chat-only deduplication boundary. - Compare the three transcript views with
ui/chat.rsbefore changing shared tail-control sizing or source callbacks. - Read the contract tests and native renderer harness before changing stable IDs, row revisions, expansion motion, virtualization, or accessibility.
Build and launch
Build the target-specific optimized executable from PowerShell:
Set-Location 'C:\xampp\htdocs\exepert-prod\MASTER-exe\desktop'
cargo +1.96.0-x86_64-pc-windows-msvc build --package exepert-desktop --target x86_64-pc-windows-msvc --release --locked
Test-Path -LiteralPath '.\target\x86_64-pc-windows-msvc\release\exepert-desktop.exe'
Start-Process -FilePath (Resolve-Path -LiteralPath '.\target\x86_64-pc-windows-msvc\release\exepert-desktop.exe')
To see the timer, send a new request in EXEPERT Chat. The top row begins as Working for … and freezes as Worked for …. DSH also shows Thought for … only when its recorded reasoning boundaries are complete. Existing historical EXEPERT responses show a timer only when their persisted metadata contains canonical latency.
Git delivery boundary
The delivery branch is codex/native-response-timing-alignment. The commit
containing this record is the complete source delivery. No deployment, hosted
request, release upload, or binary distribution is part of the GitHub merge;
the optimized executable remains a local ignored build artifact.