ZD Ultimate Legend Wrapper — technical architecture
Current as of v2.6.2 (2026-07-19). This is the repo’s technical architecture document.
What the app is
A local Windows configuration and lifecycle tool for the ZD Ultimate Legend controller. It reads and writes the controller’s onboard settings over standard USB HID feature reports, and layers a controller-health/lifecycle surface on top (restore points, health reports, wear ledger, module passports). It is deliberately NOT a remapper, virtual device, overlay, or background service.
Constraint architecture (enforced, not aspirational)
Ten product constraints define the design space: HID-only writes (MI_02 feature
reports), no drivers, no virtual devices, no input injection, no game-process hooking,
no background service, no automation (no macros/turbo/scripting), no network calls,
honest write reporting (every write reports its outcome; profile Apply then reads back
and compares every readable field it attempted, refreshing on-screen state; Restore /
Safe Import / inline-deadzone writes perform their own read-back checks; individual
setting writes have narrower verification, while step-size and lighting writes inside
profile Apply use field-specific verify/retry paths;
back-paddle bindings are write-only), local-only data
(%APPDATA%\ZDUltimateLegend\, plain JSON/JSONL).
Enforcement lives in the test suite, not in promises:
- Forbidden-phrase gates — per-surface tests fail the build if user-facing copy
overclaims (e.g. “calibrated”, “ban-safe”); claim-boundary paragraphs live once
per subsystem in
boundary.pymodules and are the only whitelisted denials. - Field-registry drift gate (
tests/test_field_registry_drift.py) — theControllerSnapshotdataclass is the source of truth; key-set parity and category values are pinned across every registry that mirrors it. - i18n parity gate —
set(en) == set(zh-CN) == set(ko)over entire locale files; no empty values. - Honest write reporting — every controller write reports its write outcome:
whether the synchronous
WriteFilecall succeeded for the full report (not a device ACK — a plain write call does not wait for one). The AppShell profile Apply job then reads the device back and compares every readable field it attempted, reporting each field as matched, mismatched, or could-not-verify in the Apply details — a field that cannot be re-read (unreadable, or skipped by the read budget) is disclosed as could-not-verify, never presented as verified — and refreshes on-screen state from that read. Read-back verification — re-reading a field and comparing it to what was sent — thus runs in profile Apply and in the Restore, Safe Import, and inline-deadzone flows. The flows differ in reach: Restore compares every field it attempted and uses read provenance to classify write-only or unreadable fields as could-not-verify; Safe Import runs its whole-snapshot compare only when every write reported success (any failed write downgrades the audit to “sent” and skips the compare) and classifies write-only entries as unverifiable, though a readable entry missing from its read-back is reported as a mismatch rather than unverifiable; the inline-deadzone panel confirms the settled value of each change and reports a confirm read it couldn’t complete as sent-unverified. Within profile Apply, step-size and lighting writes additionally go through read-back-and-retry setters. Those setters are best-effort: a confirmed mismatch (a successful read returning a different value) is surfaced as not-committed once the retry budget is exhausted, never as a false success — and a setter read-back that could not be read at all collapses to the plain write outcome. When that setter runs inside profile Apply, the post-apply sweep still reports the field’s verify state separately. Other individual setting writes do not implicitly inherit the profile-wide sweep. Write-only surfaces (back-paddle bindings) have no read path and are reported as sent, not verified.
Package map (zd_app/)
protocol/— stable HID protocol layer: interface enumeration (hid_transport), preflight visibility checks, trigger-interface coordination. Production code, shipped in dist.services/— business logic, zero UI imports (enforced by structure + tests):settings_service.py— raw HID transport + per-field read/write codecs on the1055aaXXfeature-report family; singleWriteOutcomeenum; batch reads carry a deadline budget and per-field provenance.settings_apply_coordinator.py— write pipeline with per-field trailer writes (the firmware silently rejects some fields inside multi-field bursts; trailers + settles + retry-once mitigate the documented quirk family). Each write reports its own outcome; step size and lighting zones additionally use field-specific verify/retry setters (best-effort — an unreadable setter read-back collapses to the plain write outcome). The AppShell profile Apply job composes this pipeline with a post-apply sweep over every readable field it attempted (per-field matched / mismatched / could-not-verify, surfaced in Apply details). The restore/Safe-Import/inline-deadzone paths keep their own apply-then-compare verification.restore_point_service.py+storage/restore_point_store.py— full-state capture/restore with provenance-honest reads (_do_fresh_readreturns snapshot + read_success + read_errors), per-entry restore verification, retention pruning, atomic temp-then-replace persistence.snapshot_diff.py— pure differ behind the Device-vs-Profile screen; three-way (device / selected profile / last-applied) with drift detection, 8-point sensitivity rider folding, and unreadable-vs-absent honesty driven by provenance maps.health_report/,wear_ledger/,module_passport/,diagnostic_bundle/— the lifecycle layer: guided measurement workflows, append-only maintenance log, per-side stick-module fingerprints, and operator-triggered, path-sanitized export bundles.device_service.py,xinput_poll_service.py,preflight_service.py— presence polling, live XInput diagnostics, transport preflight.
storage/— JSON/JSONL stores: wrapper profiles, app settings, restore points, last-applied record (last_applied_store.py), snapshot codec. Writes use temporary files plus atomic publication: updates replace the destination, while new wrapper profiles use collision-safe hard-link publication so an existing profile cannot be overwritten. Corrupt files degrade to disclosure cards or logged no-ops, never crashes.ui/— DearPyGui screens + theAppShellcoordinator (app_shell.py). One screen module per sidebar entry underui/screens/. Two load-bearing seams live here:- Threaded HID-job seam — long device flows (profile apply, restore, full read,
Safe Import apply+verify, retry bursts) run as jobs on a worker executor;
_run_hid_jobowns a busy flag, completions drain at the top of_tickon the render thread, and every device-touching UI entry point refuses (with status) while a job is in flight. Sync mode (no executor) preserves byte-for-byte legacy behavior for tests and headless paths. - Deferred-UI / modal-swap seam — DearPyGui never renders a modal created in the
same pass another modal was showing (empirically benched, thread-independent; see
tools/diag_dpg_modal_thread_visibility.py). Modal chains therefore route through_defer_modal_swap(teardown pass → rendered frame → create pass, with coalescing keys); two modals never show stacked — lower modals hide and re-show instead.
- Threaded HID-job seam — long device flows (profile apply, restore, full read,
Safe Import apply+verify, retry bursts) run as jobs on a worker executor;
i18n/— locale loader +en.json/zh-CN.json/ko.json(full-file parity gate).
Entry point: main_zd.py (wires real stores/services/executor; AppShell accepts
injected fakes for tests). Version constants: zd_app/version.py.
Data directories
%APPDATA%\ZDUltimateLegend\— settings, wrapper profiles, restore points, wear ledger, module passports, diagnostic bundles, logs (rotating), crash reports.- Source runs use a local
zd_data/directory instead (gitignored).
Test architecture
The public maintenance gate is a unittest suite. Services and most screen behavior
are tested headlessly against a patched DearPyGui that records widget calls. The
always-on Tier-1 font-pressure matrix is different: every cell launches a fresh
subprocess with a real DearPyGui context and viewport; ZD_RENDER_MATRIX=full adds the
broader Tier-2 cell set. Other real-DPG behaviors, including the modal law, also have
isolated subprocess gates and manual bench tools under tools/. Suite conventions:
system Python 3.12 with dearpygui installed (the release CI additionally runs the full
suite on Python 3.13 — the runtime the release binaries ship with — before building); exit
code 139 (or Windows’ signed/unsigned 0xC0000005 form after a complete OK
summary) on teardown is a known DPG artifact, not a failure. Skip totals vary by
environment: Tier-2 cells skip unless the full matrix is requested, and registered
rendering-stack variants skip only when their exact known-finding signature matches.
A timeout, unrelated assertion, changed signature, or unexpected success fails the
matrix gate. Drift/parity/forbidden-phrase gates run as ordinary tests so they fail the
build on violation.
Build & distribution
tools\build_release.ps1 → PyInstaller portable folder + ZIP + (when Inno Setup 6 is
present) an installer EXE, plus SHA256SUMS.txt; tools\install_local.ps1 mirrors the
freshest build to local-install\ and refreshes Desktop/Start-Menu shortcuts. Official
release assets (v2.5.0+) are CI-built on Python 3.13 from the release tag and carry
build-provenance attestations (gh attestation verify); there is no AuthentiCode code
signing yet, and every release publishes hashes. No auto-update, no telemetry —
matching the constraint architecture.
External tooling
The shipped app imports nothing outside zd_app/, main_zd.py, and the build tools — a
boundary enforced by tests.