Repository navigation
Description
Problem
In pkgs/chat (main.go, main 4b0f9ceb), every client's model keeps its entire chat history forever and rebuilds the whole viewport content on every message:
case chatMsg:
m.messages = append(m.messages, m.senderStyle.Render(msg.id)+": "+msg.text)
m.viewport.SetContent(strings.Join(m.messages, "\n"))
m.viewport.GotoBottom()(main.go:177-180; the field is declared at :113 and initialised at :144.)
Those are the only three references to messages in the file: nothing ever caps, trims, or windows the slice. The viewport is 5 lines tall (viewport.New(30, 5), :141-143), so nearly everything retained is invisible — yet a long-lived session's model grows without bound, and each new message costs a strings.Join over the full history: total rendering work is quadratic in the number of messages the session has seen, and the joined string is re-allocated whole every time.
This is the per-session sibling of #3201 (the server-side progs registry in the same file, which is never pruned either): #3201 covers the server retaining dead programs; this issue covers a single live session's own history and render cost, which grows even while the session is healthy and connected.
Evidence (verified this run)
- Code:
grep -n messages pkgs/chat/main.goreturns exactly three sites — field:113, init:144, append+Join:178-179. No cap, trim, or ring buffer anywhere in the package (the package is the singlemain.go, 197 lines). - Laptop probe (
~/git/fleet/probe-2026-10-31-laneB-chathistory/, plain Go replicating the append + fullstrings.Joinperformed perchatMsg;pkgs/chat/main.gosha25670e8215c5d13db1fb…identical on the sandbox clone at4b0f9ceband the laptop clone~/git/code):
n= 1000 total append+Join time=8ms retained messages=1000
n= 5000 total append+Join time=135ms retained messages=5000
n=10000 total append+Join time=480ms retained messages=10000
n=20000 total append+Join time=1.898s retained messages=20000
Doubling the history roughly quadruples the total work — the per-message Join dominates, exactly as the code shape predicts.
Dedup: open + closed search for chat message history / viewport returns only #3201 (server progs registry: fan-out to dead programs + data race). No existing issue covers the per-model messages slice.
Why it matters
The chat server is a long-running SSH service: a busy room or a client left connected for days steadily eats more memory per session and gets visibly laggier with every message, because each keystroke-era message re-renders history the 5-line viewport will never show. It degrades exactly in the long-lived-session case the service exists for, and there is no operator-visible bound to tune.
Acceptance criteria
- A session's retained history is bounded by a named cap (sized relative to what the viewport can show / scroll back, and documented in the code), or the viewport content is built incrementally without re-joining the full history per message.
- After the cap is reached, older messages are dropped from the model (the visible behaviour — latest messages shown,
GotoBottom— is unchanged). - Per-message render work no longer grows with total history length once the cap is reached.
- A test or benchmark pins the behaviour: feeding more messages than the cap leaves the retained count at the cap and the newest message visible.
Activity
dezren39 commentedon Nov 1, 2026
🤖 Agent note · filed
pkgs/chat/main.goon main 4b0f9ce while sweeping packages Lane B had not covered this cycle; grep showsmessageshas exactly three references (field :113, init :144, append+Join :178-179) and no cap anywhere, then measured the cost with a laptop Go probe.dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up
155 remaining items
dezren39 commentedon Nov 4, 2026
🤖 Agent note · parked task 5697 for 30 minutes. Same-fix PR #3284 is still OPEN and draft, authored and assigned to @dezren39; no competing branch or PR was created. Resume after #3284 merges/closes or Drew explicitly hands off the work.\n\n
dezren39 commentedon Nov 4, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 4, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 4, 2026
agent-note:v1
event: handed_off
task: 5697
lane: code-j
worker: repo-worker-code
execution_lane: opencode
issue: #3268
kind: small_fix
state_checked: 2026-11-04T12:00Z — issue #3268 OPEN, no held/user-owned/do-not-merge/do-not-auto-edit labels; labels synced to queue/claimed + status/in-progress + work/assigned.
next: opencode claimant launches the bound session for task 5697.
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off