Editor has no MAX_HISTORY cap on its undo stack — workspace caps at 50 (#172) but the editor's undo/redo grows unbounded across a long session #196
Labels
No labels
blocked:commit-ready-failed
blocked:gate-fetch
blocked:gate-lint
blocked:gate-plan
blocked:gate-research
blocked:needs-attention
blocked:needs-decision
blocked:needs-human
blocked:no-changes
blocked:verify-failed
bug
deferred
feature-request
in-progress
needs-decompose
needs-triage
quickfix
security/medium
triage-approved
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Mark/Kimi_Agent_Brother_10_Digitizing_App#196
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Finding
src/components/workspace/useWorkspace.ts:198definesMAX_HISTORY = 50and enforces it on line 213:if (newHistory.length > MAX_HISTORY) newHistory.shift();. The workspace's undo/redo never grows past 50 entries.src/pages/Editor.tsx(the editor's main page) has no such cap.grep -n 'MAX_HISTORY' src/pages/Editor.tsxreturns 0 matches. ThepushHistorycallback at line 670+ appends tohistoryindefinitely.A user who opens a long-lived editor session and edits a design for hours can have a
historyarray of 10,000+ snapshots. Each snapshot is aJSON.parse(JSON.stringify(paths))deep copy — for a 30-path design with 12 nodes each, that's 360 nodes × ~200 bytes = 72KB per snapshot × 10,000 = 720MB of heap.historyIndexis a single number, so navigation is fine. But memory growth is real.Where
src/components/workspace/useWorkspace.ts:198(the reference implementation)src/pages/Editor.tsx:670(pushHistoryappends without limit)Suggested fix shape
Apply the same pattern the workspace uses:
Note: the workspace increments
historyIndexonly on the user explicitly pushing (not on undo/redo). The editor'spushHistoryis called on every state-changing dispatch, so the cap should preserve the same "you can always redo" behavior —historyIndexstays at the end of the trimmed stack.Severity
Medium. Memory growth is real; the user feels it after a long session. The workspace side already has this fix; the editor side is the gap.
Discovered by
Gap analysis (2026-10-02) of editor memory safety.
Related
Stale. Bug does not reproduce on main — the editor's
pushHistoryalready caps bothhistoryandhistoryIndexat 50. The constant is namedHISTORY_LIMIT(notMAX_HISTORY), which is why the gap-analysis grep missed it.Evidence:
src/pages/Editor.tsx:265—const HISTORY_LIMIT = 50;src/pages/Editor.tsx:472-482—pushHistorytrims the array toHISTORY_LIMITvianext.slice(shiftCount)and capshistoryIndexatHISTORY_LIMIT - 1so it can never point past the trimmed end.The cap was added in commit
674ad11(Apply changes from kilo-gsd.py run for #67, 2026-09-13), which is older than this gap analysis (2026-10-02). The implementation is even slightly stronger than the suggested snippet: it also boundshistoryIndextoHISTORY_LIMIT - 1, defending against the array-trim/index-update race.Closing as already-resolved. Reopen if a regression is found.