Repository navigation
perf(tray): parse hgs output off the GUI thread (event data plane M1) - #367
Merged
Merged
Conversation
Owner direction 2026-10-27: data parsing and similar processing run outside the GUI thread. First milestone of the event data plane (zerus-604d.1). - ProcessRunner passes every result through one serial preparation thread, hgs-prepare, keeping completion order. run(request, owner, prepare, apply) and post(owner, prepare, apply) shape values there; the owner's thread only applies them. - Every HgsClient reply, the connector panels, the speech client, the update feed and startup fleet discovery are parsed in prepare steps. The task parse pool and the 8 MiB worktree snapshot re-parse per lookup are gone. - JsonParse is the tray's only JSON parser and reports a parse on the GUI thread; every Qt suite runs with ZERUS_GUI_THREAD_CHECKS=fatal. check-source.py rejects QJsonDocument::fromJson elsewhere and limits JsonParse::local() to a listed, shrink-only set of small local values (owner: "согласен, оставляем исключения до M2"). - SettingsJson parses QSettings JSON values once per change, warms the large keys at startup and records what writers stored, so per-poll read-mark reads no longer re-parse settings. - IdentityHash remembers per-row SHA-256 identities, 3.9 % of the Mac GUI thread in a 2026-10-27 sample. Design: docs/superpowers/specs/2026-10-27-event-data-plane-design.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First milestone of the event data plane (epic zerus-604d, task zerus-604d.1). Owner direction 2026-10-27: an event-driven data channel is mandatory, and parsing and similar processing must run outside the GUI thread.
What changes
hgs-prepare, before reaching its owner, in completion order.run(request, owner, prepare, apply)andpost(owner, prepare, apply)shape values there; the owner's thread only applies them.hgs, connector and network output is off the GUI thread. This covers all ~50 HgsClient replies (listings, inspections, git-status, task, swarm, worktrees, receipts and the direct-QProcess flows), the connector panels, the speech client, the update feed and startup fleet discovery. The task parse pool and the per-lookup re-parse of the 8 MiB worktree snapshot blob are removed.JsonParseis the tray's only JSON parser. A parse on the GUI thread of a GUI application counts as a violation, and every Qt suite runs withZERUS_GUI_THREAD_CHECKS=fatal.check-source.pyrejectsQJsonDocument::fromJsonoutsideJsonParse.cpp. It lists the files that may still callJsonParse::local()(small values the tray wrote itself) and how often; the list only shrinks and is empty at the end of M2 (owner: «согласен, оставляем исключения до M2»).SettingsJsonparses QSettings JSON values once per change. It warms the large keys on the preparation thread at startup and records what writers stored, so the per-poll read-mark reads no longer re-parse settings.IdentityHashremembers per-row SHA-256 identities. In a 2026-10-27 Mac sample these took 3.9 % of the GUI thread, through OpenSSL digest setup on each call.Design and baseline:
docs/superpowers/specs/2026-10-27-event-data-plane-design.md. API v1, the hgs CLI, status semantics and on-disk settings are unchanged.Verification (arch, local)
ctest(Release, offscreen,ZERUS_GUI_THREAD_CHECKS=fatal): 83/83 suites passed; JUnit shows 3000 test functions executed, 0 failed, 23 skipped (platform-only).test_jsonparse(violation detection, worker parses, local limit, HgsClient listing and inspection parsed off the GUI thread) and threetest_processrunnercases (preparation thread, completion order across prepared and plain results, destroyed owner drops a prepared value).python3 -m unittest discover -s tests -p 'test_source_*.py': 26 tests OK, including the new JSON rule tests. Privacy guard: 0 findings on the changed files.requestProjects, the startup discovery, synchronous draft-store reads, the download-cache index), and they are fixed here.What remains on the GUI thread after each listing (unread passes, rebuild, organization serialization) is M2 (zerus-604d.2).
🤖 Generated with Claude Code