Skip to content

fix(workspace): bound in-memory workspace cache - #306

Merged
Waishnav merged 2 commits into
mainfrom
fix/bounded-workspace-cache
Sep 6, 2026
Merged

fix(workspace): bound in-memory workspace cache#306
Waishnav merged 2 commits into
mainfrom
fix/bounded-workspace-cache

Conversation

@Waishnav

@Waishnav Waishnav commented Sep 6, 2026

Copy link
Copy Markdown
Owner

#218 correctly identified a second retention layer after the MCP transport work: WorkspaceRegistry kept every opened workspace context resident even though workspace sessions are already persisted. This caps the persisted-backed cache at 32 entries with LRU restoration by workspaceId, so old contexts can leave memory without invalidating workspace handles.

Skill reads are now derived directly from the current advertised skill catalog: files within an advertised skill directory are readable without tracking a hidden per-workspace activation state. That keeps cache eviction semantically invisible and avoids adding any new database migration or persisted skill state.

This intentionally leaves #218's heap snapshots, health metrics, stale-binding cleanup, and old MCP-session timers out; #201 already removed retained MCP transport sessions.

Summary by CodeRabbit

  • New Features

    • Improved workspace caching performance while preserving skill resource paths after cache eviction.
    • Files within advertised skill directories can now be read without first reading the skill’s SKILL.md.
  • Documentation

    • Updated skill-reading guidance to reflect the revised file access behavior.
  • Tests

    • Added coverage for workspace cache eviction and skill resource path restoration.
    • Updated skill path resolution tests.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Team

Run ID: 24119aec-e4ea-4973-aa04-86967715a61e

📥 Commits

Reviewing files that changed from the base of the PR and between 5d2cfda and af27987.

📒 Files selected for processing (1)
  • src/workspaces.test.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

The change removes skill-read activation tracking and allows reads within advertised skill directories. It also adds a 32-entry LRU cache for workspaces and a regression test for resource resolution after eviction.

Changes

Skill read resolution and workspace caching

Layer / File(s) Summary
Skill read resolution contract
src/skills.ts, src/server.ts, src/skills.test.ts, docs/...
Skill path resolution no longer requires activated directories or returns isSkillFile. Server instructions, read handling, tests, and documentation use the updated rule.
Bounded workspace cache
src/workspaces.ts, src/workspaces.test.ts
Workspace registration uses a 32-entry LRU cache. Cache hits refresh recency, and eviction is covered by a resource-resolution regression test.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to af279

This change bounds persisted workspace caching with LRU eviction and allows reads from advertised skill directories. The supplied regression coverage and cleanup update indicate no remaining merge-blocking risk.

Sequence Diagram(s)

sequenceDiagram
  participant ReadTool
  participant WorkspaceRegistry
  participant SkillResolver
  ReadTool->>WorkspaceRegistry: resolveReadPath(inputPath)
  WorkspaceRegistry->>SkillResolver: resolveSkillReadPath(skills, inputPath)
  SkillResolver-->>WorkspaceRegistry: matching skill and absolutePath
  WorkspaceRegistry-->>ReadTool: resolved read path
Loading

Poem

I’m a rabbit guarding paths in the green,
Skills open their folders, clear and clean.
Caches hop in an LRU line,
Thirty-two slots keep order fine.
Evicted workspaces return anew,
Their resource paths still point true.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 9 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: bounding the in-memory workspace cache in WorkspaceRegistry.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/bounded-workspace-cache

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Sep 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR bounds the persisted-backed workspace context cache to 32 LRU entries and preserves activated skill-directory state when an evicted workspace is restored.

  • Adds a versioned SQLite column for activated skill directories.
  • Persists skill activation and rebuilds workspace contexts from stored sessions.
  • Refreshes cache recency on workspace lookup and evicts the oldest resident context.
  • Adds regression coverage for eviction followed by skill-resource access.

Confidence Score: 4/5

The PR should not merge until concurrent activation persistence can no longer discard a successfully loaded skill directory.

The cache and restoration flow is otherwise coherent, but replacing a shared JSON activation list through an unprotected read-modify-write can lose durable state across concurrent store connections; legacy migration coverage is also missing.

Files Needing Attention: src/workspace-store.ts, src/oauth-store.test.ts

Important Files Changed

Filename Overview
src/workspaces.ts Implements LRU cache refresh and eviction while restoring persisted skill activation into reconstructed contexts.
src/workspace-store.ts Adds durable skill activation, but its JSON read-modify-write can lose concurrent updates across database connections.
src/db/migrations.ts Adds the activation-state column for fresh and existing databases through migration 7.
src/db/schema.ts Extends the typed workspace-session schema with non-null JSON activation state.
src/workspaces.test.ts Verifies eviction and restoration retain access to resources belonging to an activated skill.
src/oauth-store.test.ts Updates the expected migration ledger but does not exercise the legacy upgrade path.

Sequence Diagram

sequenceDiagram
    participant C as Client
    participant R as WorkspaceRegistry
    participant DB as SQLite store
    C->>R: Open/use workspace
    R->>DB: Persist session
    R->>R: Insert as most-recent cache entry
    R->>R: Evict oldest entry above 32
    C->>R: Read advertised SKILL.md
    R->>DB: Persist activated skill directory
    C->>R: Use evicted workspace ID
    R->>DB: Load session and activations
    R->>R: Rebuild context from current configuration
    R-->>C: Restored workspace
Loading

Reviews (1): Last reviewed commit: "fix(db): tolerate partial legacy workspa..." | Re-trigger Greptile

Comment thread src/workspace-store.ts Outdated
Comment on lines +132 to +145
.select({ activatedSkillDirsJson: workspaceSessions.activatedSkillDirsJson })
.from(workspaceSessions)
.where(eq(workspaceSessions.id, id))
.get();
if (!row) return;

const activatedSkillDirs = parseActivatedSkillDirs(row.activatedSkillDirsJson);
if (activatedSkillDirs.includes(skillDir)) return;
activatedSkillDirs.push(skillDir);
this.database.db
.update(workspaceSessions)
.set({ activatedSkillDirsJson: JSON.stringify(activatedSkillDirs) })
.where(eq(workspaceSessions.id, id))
.run();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Concurrent activations get lost

When two registry or store instances sharing a state directory activate different skills for the same workspace concurrently, both can read the same JSON value and the later update can overwrite the earlier activation. After cache eviction or restart, a successfully loaded skill may lose its persisted activation, causing later resource reads to be rejected. Serialize this read-modify-write operation or store activations in a form that supports atomic updates.

Knowledge Base Used: Local persistence

Comment thread src/oauth-store.test.ts Outdated
@Waishnav
Waishnav force-pushed the fix/bounded-workspace-cache branch from bdf6353 to 5d2cfda Compare September 6, 2026 06:26
@Waishnav
Waishnav merged commit 321d09e into main Sep 6, 2026
4 checks passed
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