Skip to content

fix: keep large team and Activity overviews responsive - #1919

Merged
santoshkumarradha merged 5 commits into
devfrom
fix/teams-hover-scale
Oct 24, 2026
Merged

santoshkumarradha merged 5 commits into
devfrom
fix/teams-hover-scale

Conversation

@santoshkumarradha

@santoshkumarradha santoshkumarradha commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

What changed

All teams could stall every hover as membership grew. CPU profiling attributed about 98% of the overview's samples to repeated reporting-home membership searches. Background spend reads compounded the problem by reloading and repairing the same teams file once per pool.

This replaces repeated searches with indexed membership repair and one lazy reporting-home reading per paint. Summary counts and manager titles no longer construct full member rows. The global-manager card shares the same reading. Spend reads retain one immutable membership snapshot for the most recently used profile, invalidated by the current primary/legacy file stamp; ledger appends continue through the existing incremental ledger reader. Reporting policy and cap behavior are unchanged.

Activity/history had a related per-paint cost: unchanged task rows were copied on every filtering read, layouts were rebuilt for multiple readers of the same paint, and tree construction repeatedly walked parent chains. The reading now keeps row identities as indexes, copies task/chat slices only when deletion removes a row, pre-sizes sibling storage, memoizes ancestry validity, and shares filtered layouts during one body's paint. Paint scratch is discarded before the next input or engine update.

How it was checked

Paired actual terminal runs used the same mock data, a 160×55 terminal and 12 alternating pointer targets. Timings measure input delivery until the changed hover hint is visible. Fixture construction, the first overview frame and model latency are separate; latency runs made zero model calls.

Scenario Before (dev 502ed96) After
100 teams × 100 members: median hover 2,979 ms 36 ms
Same scenario: p95 hover 5,266 ms 51 ms
Same scenario: first overview frame 693 ms 116 ms
200 teams × 200 members: median hover Not measured 81 ms
Same larger scenario: p95 hover Not measured 220 ms

Fixture construction was approximately 0.46–0.54 seconds for 10,000 memberships and 2.30 seconds for 40,000. These are diagnostic observations, not machine-independent timing gates or a claim of constant-time rendering.

Separate CPU redraw benchmarks improved from 678 to 13 ms at 10,000 memberships and from 3,067 to 26 ms at 20,000. A selected team with 1,000 members redraws in approximately 4.7 ms.

  • Both actual terminal capacity scenarios passed. The separate live 120-member workflow passed twice consecutively with manager preview, a pointer burst, physical scrolling, resizing and opening a member. All 9 completed model requests across those two runs were verified as OpenRouter deepseek/deepseek-v4.1-flash, including auxiliary calls.
  • All teams store tests pass under the race detector. A deterministic 1,000-case comparison preserves the previous reporting/repair policy, including shared members, closed teams, cycles and duplicate flags.
  • Concurrent spend queries share one unchanged membership load. Tests cover membership changes, ledger growth, profile isolation and a newly appearing legacy file. Team navigation/geometry tests and the frame's no-filesystem/no-network law pass.
  • Final local make pr-ready and all final-head GitHub CI gates passed (build, vet, formatting, laws, backend and TUI tests). The local classifier reproduced the existing TestLowCreditReadSwapsOnlyAnUntouchedImplicitConversation failure on unchanged dev; this PR does not claim to fix that unrelated test.

Reproduce after make build:

go test ./internal/tui3 -run '^$' -bench 'BenchmarkTeamsAllScale|BenchmarkTeamsHover' -benchtime=3x -count=1
CODEAF_E2E_MODEL=deepseek/deepseek-v4.1-flash go test -tags e2e ./internal/e2e -run '^TestTeamsAllScaleTerminal(Latency|LargeCapacity)$' -count=1 -v -timeout 8m
CODEAF_E2E_MODEL=deepseek/deepseek-v4.1-flash CODEAF_BASE_URL=https://openrouter.ai/api/v1 go test -tags e2e ./internal/e2e -run '^TestTeamsLargeOverviewPointerAndLivePreview$' -count=1 -v -timeout 8m

The capacity tests use a local fixture endpoint and reject model calls. The live workflow requires a configured OpenRouter key. Before/after comparisons use the same capacity-test file with each revision's built application.

Activity/history was measured separately with 40 mock project histories and 5,120 tasks. Twelve alternating pointer targets wait for the selected row's distinct visible door hint. Navigation makes zero model calls.

Activity/history measurement Before After
Actual terminal median hover 120 ms 64 ms
Actual terminal p95 hover 267 ms 95 ms
CPU time per body paint 30.9 ms 10.1 ms
Allocated per body paint 155.1 MB 12.5 MB
Allocated per history rebuild/layout 75.8 MB 49.1 MB

Filtering to a uniquely named chat preserves its full family; clearing, folding, and resizing pass. New race-tested regressions cover unchanged-row sharing, deletion/restoration without mutating the held snapshot, paint lifetime, filtering, resize, and 300 malformed parent graphs compared against independent ancestry walks. Home hover already reuses its painted hit map; that path did not need a new cache. The existing teams live acceptance now waits for the narrow-screen navigation after resizing before clicking a member, preventing old wide-frame coordinates from being used against the new layout.

Additional reproduction:

go test ./internal/tui3 -run '^$' -bench '^(BenchmarkTasksConversationHistory|BenchmarkActivityScaleFrame)$' -benchtime=5x -count=1
CODEAF_E2E_MODEL=deepseek/deepseek-v4.1-flash go test -tags e2e ./internal/e2e -run '^TestActivityScaleTerminalLatency$' -count=1 -v -timeout 5m

Use the same benchmark/test fixture with each revision's built application for paired comparisons. Terminal setup and model time are excluded from hover measurements. Activity's first-page polling is too coarse to support an opening-speed claim; the measured hover samples use 5 ms screen polling.

Checklist

  • Numbered change entry added after PR allocation.
  • No user-facing command, key, limit, default or refusal changed; performance bounds documented in PERF.md.
  • Only task-owned paths staged.
  • Santosh authorized consolidating the remaining audit fixes, measuring them, and merging once validation passes. Final validation passed.

Merged into dev as a43c63bd7. The merged revision was built with clean revision metadata and passed the actual 5,120-task terminal workflow again. Post-merge median/p95 hover was 75/98 ms; timing variability is expected. Task worktrees and generated build files were removed after verification; measurement logs remain available locally.

@santoshkumarradha
santoshkumarradha marked this pull request as ready for review October 24, 2026 16:27
@santoshkumarradha santoshkumarradha changed the title fix: keep large teams overviews responsive fix: keep large team and Activity overviews responsive Oct 24, 2026
@santoshkumarradha
santoshkumarradha merged commit a43c63b into dev Oct 24, 2026
6 checks passed
@santoshkumarradha
santoshkumarradha deleted the fix/teams-hover-scale branch October 24, 2026 16:56
santoshkumarradha added a commit that referenced this pull request Oct 24, 2026
* Keep large teams overviews responsive with indexed membership reads

* Document large teams responsiveness fix for PR 1919

* Use supported chat surface in change entry

* Bound Activity history copies and share each paint reading

* Wait for resized terminal geometry before pointer acceptance
santoshkumarradha added a commit that referenced this pull request Oct 24, 2026
Takes dev's team/Activity scale fixes, Activity memory and store perf work,
multiline prompt history and keyboard copy, and the tidy passes. app/v3 keeps
its features: the teams spend result cache now reads membership through dev's
shared spendTeamsFile; the command table stays in internal/slashcat (dev's
comment tidy applied there); autonomyKinds keeps session.AutonomyKinds() under
dev's comment; PERF.md takes dev's trimmed guide plus app/v3's own bounds
(DisplayEntry 328, factory, process actions, harness list, media lookups).

dev's new comment law (internal/commentlaw) flagged five app/v3-only
comments (dated rulings, a vendor name, a home-like path); they now say the
behaviour only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant