Skip to main content

Native desktop GPUI workbench

desktop/ contains two related Windows-native GPUI contracts: the normal interactive EXEPERT workbench and the isolated renderer gate used for benchmark evidence. The interactive executable is a native Rust/GPUI client with no Electron, WebView, browser canvas, Three.js, WebGL, wgpu bridge, custom DirectX surface, or runtime browser asset loading. Its optional Chat client and read-only backend health probe are separate from the local Brain renderer.

The renderer gate remains a closed, deterministic proof of GPUI painting EXEPERT's low-LOD fixture. Benchmark mode disables interactive diagnostics, ambient activity, backend probes, and network access so those features cannot change the evidence contract.

Architecture boundary

The nested Cargo workspace pins its own Rust toolchain, MSVC target, Zed/GPUI revision, dependency graph, and lockfile. The release executable embeds and validates the canonical OBJ, generates 1,811 neurons and 2,312 axons, runs a bounded deterministic worker, projects geometry on the CPU, and submits native GPUI paths and quads. The report wrapper launches that exact binary in a restricted environment and samples process RSS and CPU every 100 ms.

The desktop client deliberately duplicates only the deterministic fixture behavior needed by the native workbench and renderer gate. It does not extract brain_core, import brain_sim, or change the current browser/WASM product.

Interactive workbench

The normal release executable is a complete native workbench. GPUI owns the titlebar, activity rail, panels, Brain canvas, telemetry views, controls, inspector, and detached Runtime Log window in one Rust process.

Workbench geometry and navigation

The wide layout preserves the 48 px activity rail, 224 px control panel, flexible Brain stage, and 288 px right-side panel. Interactive mode switches to a stacked layout below 1,200 px: the right-side surface moves below the Brain stage and remains 300 px tall and internally scrollable. The minimum native window is 1,024×640. Benchmark mode always keeps its side-by-side contract.

The rail destinations are Dashboard, Prompts, Observability, Arcade, Research Runs, Journals, and Settings. Dashboard restores the internal Dashboard, Virality, Brain, and Chat tabs. The other destinations currently render a truthful native placeholder labeled NATIVE MODULE NOT YET PORTED; they do not invent prompts, traces, research runs, journals, or settings data.

Local Brain activity

After the interactive worker is ready, the client sends an opt-in ambient command. Ambient frames use deterministic native fixture propagation with 256 low-intensity signals, reduced alpha, and reduced size. Selecting a V/A/L/T/G stimulus temporarily uses the full 2,048-signal preset workload. Completion and reset return to ambient mode; pause freezes propagation and resume continues it. Retry reinitializes the worker and starts ambient activity after readiness. No renderer-only timer or fake visual pulse is used.

Benchmark mode never sends the ambient command and retains the existing worker, paint callback, timing, and evidence behavior.

Connectivity semantics

The status rows distinguish the local Brain from the optional backend:

  • BRAIN / STARTING, AMBIENT, ACTIVE, PAUSED, READY, IDLE, and ERROR describe the local worker.
  • BACKEND / ONLINE, CHECKING, and OFFLINE describe Supabase/Chat reachability.

The Brain does not require the backend to animate or render. Backend status is derived from the configured public Chat values using only a read-only GET /auth/v1/health request with a three-second timeout. It retries periodically and immediately after Chat configuration is saved or cleared. Chat bootstrap and Playground provisioning are deliberately excluded from the probe. Missing configuration, timeout, or failure is reported as offline. Credentials, tokens, URLs, and Chat content are not included in diagnostics.

Native render telemetry

The compact brain-render-telemetry card lives below the Brain canvas. The detailed render-telemetry-section lives in the right telemetry panel. Both read a shared native store and refresh independently so telemetry updates do not become Brain canvas invalidations.

PAINT FPS and PAINT FRAME describe natural canvas paints. WORKER FPS and WORKER FRAME describe simulation publication cadence. Additional native fields include snapshot time, GPUI primitive draw time, static geometry build time, cache hit/miss, view size, DPR, estimated buffer size, camera yaw/pitch, distance, zoom, FOV, native target, and painted signal counts.

The display uses GPUI/CANVAS, VIEW, and BUF EST terminology. BUF EST is only the logical view multiplied by DPR; it is not a claim about GPU swapchain allocation. The client does not copy browser-only WEBGL2, CSS dimensions, web target coordinates, or web bearing labels.

Runtime Log and Inspector

The OPEN RUNTIME LOG button and Ctrl+Shift+L open one detached native Runtime Log window. It keeps a bounded 2,048-entry session buffer with DEBUG, INFO, WARN, and ERROR levels across APP, BRAIN, RENDER, WORKER, CAMERA, INSPECTOR, UI, and NETWORK categories. The window refreshes at roughly 10 Hz and supports level/category filters, pause, follow-bottom, clear, and SAVE LOG. Pausing freezes the view while collection continues; rows remain single-line and truncate visually.

Saved exports retain the retained diagnostic messages and exclude chat prompts, responses, tokens, credentials, and secrets. SAVE LOG tries %LOCALAPPDATA%\\EXEPERT\\logs\\exepert-runtime-<timestamp>.log first and falls back to %APPDATA%\\EXEPERT\\logs. Window geometry is persisted under %LOCALAPPDATA%\\EXEPERT\\runtime-log-window.json or its %APPDATA% fallback. The native element inspector remains available through SELECT ELEMENT or Ctrl+Shift+E.

Interactive versus benchmark mode

CapabilityInteractive modeBenchmark mode
Ambient activityEnabled after worker readinessDisabled
Runtime LogEnabledDisabled
Backend probeEnabledDisabled
ResizingEnabledLocked benchmark geometry
Benchmark paint recorderDisabledEnabled
NetworkOptional Chat/health onlyDisabled

This separation keeps user-facing diagnostics useful without changing the renderer-gate workload or certifying behavior.

Development and troubleshooting

Run Cargo from desktop/, because it is a nested workspace. Running cargo run --package exepert-desktop from the repository root produces a package-not-found error.

Set-Location 'C:\xampp\htdocs\exepert-prod\MASTER-exe\desktop'
& '.\scripts\run-dev.ps1'

For the release executable:

Set-Location 'C:\xampp\htdocs\exepert-prod\MASTER-exe\desktop'
cargo build --target x86_64-pc-windows-msvc --release -p exepert-desktop --locked
& '.\target\x86_64-pc-windows-msvc\release\exepert-desktop.exe'

If the Brain is active but BACKEND / OFFLINE is shown, the local renderer is still healthy; check the saved public Supabase URL/key and wait for the next health probe. If Runtime Log is empty, confirm the executable was launched in interactive mode rather than benchmark mode; the log store is intentionally disabled for benchmark runs. After source changes, rebuild or relaunch the release executable because Rust/GPUI does not hot-reload.

P0 evidence isolation

renderer-gate.v3 separates benchmark behavior from ordinary interactive behavior. Benchmark windows are non-resizable at a 1280×720 client size; interactive windows keep normal resizing. The report records client width, height, and scale in a fixed seven-checkpoint sequence covering READY, active start/end, pre-minimize, restored paint, and Idle start/end. Any missing, reordered, duplicated, or drifted checkpoint is a software failure. Sizes are recorded as unrounded logical pixels and checkpoint times must be strictly increasing. Every scale-factor observation must exactly match READY; a positive but changing DPI scale is still invalid evidence.

Scripted input still enters through GPUI's public keystroke dispatcher and real bindings, but each dispatch receives a one-shot authorization. The report must contain the exact 104-action phase ledger (camera 1, stimulus 81, pause 10, reset 12). Unarmed keyboard, pointer, wheel, and control input is rejected and recorded as contamination from root-level guards covering the panels and canvas. Authorization alone is insufficient: an entry is appended only after the handler executes, and every worker-backed action must return a command sequence.

The fixed pre-Idle delay is replaced by a reset barrier: the worker must acknowledge the reset sequence and GPUI must paint a READY frame carrying it. The app then drains pending events, disarms recurring paint notifications, uses the publication count carried by that drained READY frame as its exact baseline, and starts Idle. The coalescing asynchronous worker wake listener and active render cadence are both cancelled by generation; the worker counter sampled at Idle end still exposes any late publication without authorizing another paint. Paint invalidations, worker publications, and worker-triggered notifications are independently required to remain zero. The wrapper advances from each preceding 100 ms deadline, and the native finalizer rejects any skipped scheduled slot. The initial Idle paint must itself be observed before recurring invalidations can be reported as zero.

The focused p0_probe Rust test validates viewport stability and every Idle work source without running the certifying workload. It only reports isolation failures; it cannot produce PASS or modify the 60-second gate requirements.

P1 timing architecture

The simulation worker runs at a sustainable 50 Hz and retains a one-frame bounded snapshot channel. Its drop counter still measures real overwritten snapshots; the asynchronous wake signal only coalesces notifications and does not buffer render frames. GPUI consumes on each worker wake, while a separate generation-scoped active cadence requests a render every 8 ms. That cadence is cancelled for minimize and Idle. On Windows, a balanced 1 ms multimedia timer-resolution guard is held only for the live polling generation and is released whenever polling stops. Frame p95 remains a real inter-paint interval rather than a worker-tick, timer-request, or render-duration proxy. Active publication/drop deltas come from one coherent counter pair captured at the exact active boundary instants. The benchmark also establishes and verifies the native window as foreground before measured Active work, preventing Windows background pacing from contaminating those real paint intervals. Ready startup/retry, pause, and inactive resume use finite control frames. Ready/Paused/Idle acknowledgements stop wake and timer polling after their command sequence settles, including during benchmark phases. A READY lifecycle event cannot settle polling until its exact-generation READY frame is present.

Benchmark resume uses a dedicated command. The worker emits a Resumed event and an immediate control frame carrying that command sequence without changing the simulation tick or time, then holds later simulation frames until the qualified frame is painted. Before minimize, the benchmark explicitly yields native foreground to the Windows shell. On restore, the owning GPUI thread queues ShowWindowAsync(SW_SHOWNOACTIVATE) so the native size event can reinstall GPUI's request-frame callback without re-entering the foreground task that is waiting for the paint. It keeps both foreground ownership and the calling thread's active HWND away from the restored window; restoration cannot inherit either state and bypass the one authorized post-paint activation. While the canvas suppresses stale lifecycle painting, the benchmark consumes the qualified worker frame within a bounded 50 ms wait and grants that exact frame a post-visibility one-shot paint permit. Render errors, unready output, and anything other than the complete 2,048-quad Active workload cannot consume it. The recurring poller remains stopped during this held-frame wait. After both entity and window updates unwind, it marks GPUI dirty and issues one immediate RedrawWindow(RDW_INVALIDATE | RDW_UPDATENOW) outside every GPUI/App borrow. If that request has not painted after 16 ms, one bounded GPUI forced-update message is allowed. This preserves a real native WM_PAINT without re-entering borrowed state or letting a background paint wait beyond the limit. The first permitted paint carrying the exact resume sequence ends the unchanged 100 ms latency measurement. Foreground activation is one-shot authorized only afterward and recorded separately only when that specific native dispatch immediately proves the HWND is foreground and GPUI delivers its activation callback. A later unrelated foreground observation, unscripted activation, or activation-triggered lifecycle paint cannot qualify. The paint release also carries the resume command sequence so a stale release cannot unlock a later cycle. Evidence records every stage from restore request through frame, paint, and activation, the pre-suspend frame floor, generation/sequence, before/after simulation time, render timings, cache state, paint-time native visible/non-iconic/active flags, and an exact-one qualifying paint count. Native paint activity uses the GUI thread's GetActiveWindow; foreground ownership is retained as a separate post-paint activation proof.

Every success or failure finalizer cancels the active polling generation before consuming evidence, which also releases the Windows timer-resolution guard. Nested phase-transition results are flattened into runtime errors; they cannot silently continue in the wrong phase.

Static geometry is keyed by canvas origin and size, viewport width/height, scale factor, and camera. A hit reuses the four tessellated axon paths, 1,811 neuron bounds, which GPUI paints directly as native quads without a combined neuron path. Dynamic positions and exactly 2,048 signal quads are rebuilt for each active paint. Snapshot, draw, static-build, and cache measurements remain supplemental; they cannot replace or relax the 40 ms inter-paint p95 threshold.

Both Active boundaries require a real paint before execution proceeds. This keeps the paint interval span aligned with the full 10-second focused smoke and 60-second certifying phase without shortening either duration.

desktop/scripts/timing-probe.ps1 runs the separate renderer-timing-probe.v1 contract: a 10-second active smoke at the same 40 ms threshold plus five restores at the same 100 ms threshold. It additionally requires at least 450 real inter-paint intervals and 450 phase-bounded worker publications. It reports only OK/FAIL, writes an ignored artifact, and cannot certify the renderer. Its wrapper enforces full stage structure, report/process exit parity, chronological stage evidence, and every unchanged focused threshold. The final focused run, report SHA-256 2B5D8C42D453BBFA3030C3CC6CB202306BF452C969668E6D738CA43F9B9B916A, recorded 733 intervals over 10.3328 seconds of paint coverage, 22.5407 ms p95, 513 publications with 8 drops (1.559%), and restore latencies of 55.3448, 48.8332, 55.3169, 53.7071, and 54.0755 ms.

Active-RSS diagnosis and repair

The completed renderer-gate.v3 workload produced UNVERIFIED/3, report SHA-256 AC086DEFE390968525024708127241465D776114F19A57859B93C88E202E3C6C. Its only software failure was 227.031 MB peak Active RSS against the unchanged 200 MB limit. Timing and evidence isolation were already healthy: frame p95 was 20.6054 ms, restore was 11.471 ms, all seven viewport observations were exactly 1280×720@1, Idle paint/worker counts and unexpected inputs were zero, all 104 scripted actions were present, and Active cache misses were zero. The result is diagnostic, not certification.

The app-side repair compacts only the retained static representation. Four axon paths are built directly from the embedded fixture; projected construction vectors are not retained. Each nine-point projected axon is approximated by adaptive quadratic spans constrained through each span's endpoints and midpoint. A span is accepted only when its maximum error against the projected polyline is at most 0.25 logical pixels; otherwise it is bisected, with an exact line for an adjacent-point fallback. Lyon stroke tessellation remains at 0.25 pixels, so fit plus tessellation remains within 0.5 pixels. Each completed path vertex vector is shrunk to capacity. The default measured Active camera is required to use no more than 60,000 cached path vertices. The 1,811 neurons are retained only as cached GPUI quad bounds, while the 2,312 axons and exactly 2,048 dynamic Active signal quads remain unchanged.

Non-certifying memory evidence

renderer-memory-probe.v1 is separate from the gate and declares non_certifying: true and feeds_renderer_gate: false. The native process records a bounded checkpoint ledger at process start, fixture load, application and GPUI creation, window open, first READY paint, Active start/ten-second marks/end, both sides of five restores, and finalization. Each checkpoint uses Windows PROCESS_MEMORY_COUNTERS_EX plus resident working-set page classification to report working set, peak working set, private usage, pagefile usage, committed virtual memory, and private/shared resident bytes. Known fixture, static-path, frame-snapshot/channel, and benchmark-evidence capacities are exact Rust accounting. Changes in whole-process counters are labeled as inferred rather than exact ownership.

High-frequency sampling stays in memory-probe.ps1, outside the renderer. It samples the child every 100 ms, binds every sample and the native report to the same child PID/start time, carries the wrapper-observed child exit into final precedence, and reports the wrapper's own peak separately. Missing values use null plus an unavailable reason. A native threshold/runtime failure cannot be upgraded by clean wrapper samples. The native v1 report also requires nine chronological 1280×720@1 observations at READY, both Active boundaries, all five qualified restores, and finalization. Windows-generated stationary mouse-move notifications are blocked without entering the input ledger; any actual global cursor displacement remains unexpected and fails the probe.

The Short profile retains 10 seconds of Active work, at least 90 aligned samples, five qualified restores, the 40 ms frame-p95 threshold, 100 ms restore threshold, exact viewport/workload, zero Active cache misses, and the unchanged 200 MB RSS limit. Soak retains 60 seconds and at least 500 aligned samples. Both report only OK/FAIL with exits 0/2/4; neither can emit PASS or alter renderer-gate.v3. Readiness for a later certifying run additionally requires no more than 195 MB in every probe.

& 'C:\xampp\htdocs\exepert-prod\MASTER-exe\desktop\scripts\memory-probe-contract.ps1'
& 'C:\xampp\htdocs\exepert-prod\MASTER-exe\desktop\scripts\memory-probe.ps1' -Profile Short
& 'C:\xampp\htdocs\exepert-prod\MASTER-exe\desktop\scripts\memory-probe.ps1' -Profile Soak

Generated native, wrapper-sampling, and final reports remain ignored under desktop/artifacts/. Focused probe results are recorded only after the locked build and all three Short runs plus the Soak complete successfully.

The final 2026-08-20 sequence passed every focused requirement:

Combined reportActiveSamplesPeak Active RSSFrame p95Restore rangeSHA-256
Short 110.3537 s104117.594 MB24.5027 ms47.5280–63.5347 msCF315FE6F03FBD55488F84E7C212F8A2098D46EE46A113A2E16CFCF78FF1A751
Short 210.4429 s104117.367 MB24.3523 ms50.0515–79.1991 msFBB7DAC262F255BCB6DDB1A486CA40C263306436F17478D4AC7802AC9D83CB9C
Short 310.3810 s104117.938 MB26.4639 ms51.5645–73.2806 msBBB0E1F74E50C16053F08F35BA593EA2F607FE26E45F33B30046606221E48170
Soak61.1461 s611118.258 MB23.4117 ms49.7780–64.8757 ms1A9939909ECD37562D90F3B9583D25A8285E1B6D06D537DC956AAE318EC61991

All four reports contain the exact canonical geometry/workload, all required viewport checkpoints, five complete bounded restores with no simulation-time jump, zero unexpected inputs, and zero Active cache misses.

Final renderer gate

The single full gate for code candidate 7308fcd6ba9e7b9fdb12091809f7ec1ede887b99 completed as SOFTWARE-READY / UNVERIFIED, status UNVERIFIED, exit 3, never PASS. Its ignored report has SHA-256 75DA91A12587093CBC927E71332CC1E076DC0F35D384845DE8988249188903C4; the measured release binary has SHA-256 C1030C10AD3347D26B19B5088795866722D630DCB2CB21018CE6C0CB178295E9. The software failures list is empty.

The report records 1,339 exact 100 ms samples, 113.707 MB peak Active RSS, 23.8285 ms frame p95, and one 56.3968 ms qualifying restore paint with no simulation-time jump. The 104-action ledger is valid; Active cache misses, unexpected inputs, recurring Idle paints, Idle worker publications, and Idle poll notifications are all zero. Seven viewport observations remain exactly 1280×720@1, and the canonical 1,811-neuron, 2,312-axon, 2,048-signal workload is intact.

The remaining unverifiable reasons exactly equal the recorded floor-host classification: non-integrated GPU, 130,957 MB RAM rather than the 8 GB floor, unavailable SSD evidence, 1920×1080 display rather than 1366×768, 32 logical threads rather than four, and Ultra rather than Balanced power. This candidate still requires an unchanged run on the specified floor hardware for certification.

Evidence contract

The hard gate includes a 10-second warm-up, 60-second active phase, ten reset/replay cycles, minimize/restore, and 60-second Idle phase. Certifying evidence requires:

  • an exact 1280×720 client viewport throughout;
  • real GPUI-bound scripted input and nonzero activity for all five stimuli;
  • at least 500 clock-aligned active RSS/CPU samples on a 100 ms schedule;
  • active frame p95 at or below 40 ms;
  • restore request-to-qualifying-paint latency at or below 100 ms;
  • zero recurring Idle paints and zero Idle worker publications;
  • valid fixture, source, binary, environment, and raw-evidence hashes.

Exit 0 is PASS, 2 is a software threshold failure, 3 is an environment that cannot be certified, and 4 is a runtime or evidence error. A non-floor host may return UNVERIFIED/3 after every software requirement passes. That result is evidence, but it is never PASS. Software failures take precedence and force FAIL/2; the finalizer accepts UNVERIFIED/3 only with an empty failure list and reasons exactly equal to the recorded floor-host classification.

Diagnostic baseline and repair order

The first complete report was UNVERIFIED/3 and had SHA-256 F22B6124E6531CE9D6799EEB056669BA5945EEE3E65054F2FF34E74A6FC6487C. It observed a 1920×1009 final viewport, 817 recurring Idle invalidations, 136.169 ms restore latency, and 50.749 ms active frame p95.

Repair order follows causality:

  1. P0 locks benchmark geometry, authorizes only scripted actions, records phase-level observations, and enters Idle only after an acknowledged and painted reset with polling cancelled.
  2. P1 publishes and holds an immediate qualified resume frame without advancing simulation time, rejects stale restore paints, replaces periodic polling with worker wakes, and caches static axon/neuron geometry while retaining 2,048 dynamic signal quads.
  3. The full renderer gate runs once after the P1 source and documentation are committed. Short focused probes are non-certifying and cannot relax or replace the 60-second gate.

Generated reports remain ignored under desktop/artifacts/. Architecture, commands, and checkpoint history are maintained in desktop/README.md and desktop/spec-gpui-native-desktop-poc.md.