code-yeongyu / code-yeongyu/senpi

bug(codemode): settled/detached eval result cards repaint at 1 Hz forever; missing dispose accumulates timers (idle CPU burn)

Closed
#1,696 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
429
Forks
98
Avg merge
5h 3m
Merged PRs (30d)
526

Description

## Summary
packages/senpi-codemode/src/tool/render.ts:

- syncLiveTicker arms a 1-second setInterval (line 95) whenever hasLiveCell(details) is true (line 929), and hasLiveCell treats detached cells as live. Detached/peek snapshots remain in detached state forever, so their cards keep repainting at 1 Hz after completion.
- PlainTextComponent has no dispose. Every transcript rebuild (interactive-mode.ts) creates fresh components with fresh tickers while old intervals can never be stopped, so timers accumulate over the session lifetime.

Measured: 9 idle sessions each sustained 2-8% CPU over 25 minutes (35-99 CPU-seconds each); sampling an idle 4-day-old session showed ~20% of main-thread samples in JIT JS execution — leaked repaint timers.

## Context
Root-caused during a profiling investigation of a long-lived macOS host (M4 Pro, 64 GB) running ~28 concurrent senpi/omo sessions for several days. Symptoms: load average ~150 with only ~50% CPU utilization (threads blocked on swap I/O), 20 GB swap in use, idle sessions each burning 2-8% CPU sustained, and idle session heaps growing to multiple GB (one 4-day-idle session: 648 MB resident JSC heap + 1.4 GB swapped, 3.3 GB peak footprint). All file:line references are against main (b19491745). Raw profiling evidence held locally.

## Expected (ideal state)
Terminal-state and detached snapshot cards are static (no ticker). Components own a dispose() that clears their interval, and transcript rebuilds dispose replaced components. An idle session's render path arms zero intervals.

## Acceptance criteria
- Unit tests: rendering a settled/detached cell card arms no interval; dispose() clears armed tickers; a rebuild cycle leaves zero live intervals.
- Idle-session CPU attributable to the render ticker drops to ~0.

## Related
- sibling eval-cell retention issue (same profiling run)

Contributor guide

Open the contributing guide

Research direction

Start in packages/senpi-codemode/src/tool/render.ts at syncLiveTicker and hasLiveCell, then inspect the transcript rebuild path in interactive-mode.ts. Add or update unit tests covering settled and detached cards, dispose(), and rebuilds; done means those cases leave zero live intervals and the render ticker no longer burns idle CPU.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.