#20533: fix: strip resolvedSkills from session store to prevent snapshot bloat
agents
size: XS
Cluster:
Skill and Session Management Fixes
## Problem
Fixes #20528
`buildWorkspaceSkillSnapshot()` stores full `Skill` objects (name, description, filePath, etc.) in `resolvedSkills`, which gets serialized to `sessions.json`. With 3,138 built-in skills this adds ~2.9 MB per session entry, causing `sessions.json` to grow to hundreds of MB/day with frequent cron jobs.
## Solution
1. **`normalizeSessionStore()`** now strips `resolvedSkills` from each session's `skillsSnapshot` before persisting to disk. The lightweight `skills` array (`name` + `primaryEnv`) remains — sufficient for cache-hit checks.
2. **`shouldLoadSkillEntries`** in both `attempt.ts` and `compact.ts` now checks `skills.length > 0` as a fallback when `resolvedSkills` is absent (i.e. session restored from disk), so skill env overrides still work correctly without re-scanning the filesystem.
## Impact
- Session snapshots go from ~2.9 MB → ~18 KB per entry
- No behavioral change for in-memory runtime (resolvedSkills still populated during the session)
- Existing bloated sessions.json files are cleaned up on next write
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Strips the heavy `resolvedSkills` field (full Skill objects with name, description, filePath) from session snapshots before persisting to disk, reducing session storage from ~2.9 MB to ~18 KB per entry. The lightweight `skills` array (name + primaryEnv) remains sufficient for cache-hit checks and environment overrides.
**Key changes:**
- `normalizeSessionStore()` now removes `resolvedSkills` before disk persistence
- Updated fallback logic in `attempt.ts` and `compact.ts` to check `skills.length > 0` when `resolvedSkills` is absent
- No behavioral changes for runtime (resolvedSkills still populated during active sessions)
- Existing bloated sessions.json files automatically cleaned on next write
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The changes are surgical, well-scoped, and address a clear performance issue. The logic correctly preserves the lightweight `skills` array for cache checks and env overrides while removing only the redundant heavy `resolvedSkills` field. The fallback condition properly handles all three scenarios: fresh sessions, in-memory sessions with resolvedSkills, and restored sessions with only the lightweight skills array.
- No files require special attention
<sub>Last reviewed commit: dba2024</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#12209: fix(skills): refresh stale skill snapshot after gateway restart
by mcaxtr · 2026-02-09
81.6%
#22568: fix(gateway): bump skills snapshot version on startup so sessions r...
by zwffff · 2026-02-21
81.3%
#21883: fix: guard against undefined snapshot.skills in applySkillEnvOverride…
by felipedamacenoteodoro · 2026-02-20
80.9%
#16654: fix: refresh skills snapshot when managed skills change
by PhineasFleabottom · 2026-02-15
80.2%
#11250: fix: expand skills watcher ignore list and improve session repair l...
by zhangzhefang-github · 2026-02-07
79.7%
#22525: [Bug]: Session snapshot not reloading skills after gateway restart ...
by zwffff · 2026-02-21
79.2%
#9221: fix(skills): use skillKey for env config lookup in snapshots
by gavinbmoore · 2026-02-05
78.9%
#21521: fix: re-resolve skill paths at runtime for cross-machine portability
by mmaghsoodnia · 2026-02-20
78.3%
#15115: fix: pre-load skill docs in cron sessions to prevent hallucinated syn…
by joaolcorreia · 2026-02-13
76.3%
#14023: fix: filter skills watcher to relevant file types to prevent FD exh...
by funmerlin · 2026-02-11
76.0%