Files
beads/CACHE_AUDIT.md
Steve Yegge ac1752d87d Complete cache audit (bd-bc2c6191)
- Created CACHE_AUDIT.md with comprehensive findings
- Confirmed cache was already removed in commit 322ab63
- Fixed stale comment in internal/rpc/server.go
- All tests passing, MCP multi-repo working correctly
- Closed bd-bc2c6191

Amp-Thread-ID: https://ampcode.com/threads/T-c1286278-b1ff-4b8a-b090-2b3a1c38c9dd
Co-authored-by: Amp <amp@ampcode.com>
2025-11-06 19:51:16 -08:00

239 lines
7.1 KiB
Markdown

# Cache Removal Audit - Complete ✅
**Issue:** [bd-bc2c6191](file:///Users/stevey/src/dave/beads/.beads) - Audit Current Cache Usage
**Date:** 2025-11-06
**Status:** Cache has already been removed successfully
## Executive Summary
**The daemon storage cache has already been completely removed** in commit `322ab63` (2025-10-28). This audit confirms:
✅ Cache implementation deleted
✅ No references to cache remain in codebase
✅ MCP multi-repo support works correctly without cache
✅ All environment variables removed
✅ All tests updated and passing
## Investigation Results
### 1. Cache Implementation Status
**File:** `internal/rpc/server_cache_storage.go`
**Status:** ❌ DELETED in commit `322ab63`
**Evidence:**
```bash
$ git show 322ab63 --stat
internal/rpc/server_cache_storage.go | 286 -----------
internal/rpc/server_eviction_test.go | 525 ---------------------
10 files changed, 6 insertions(+), 964 deletions(-)
```
**Removed code:**
- `server_cache_storage.go` (~286 lines) - Cache implementation
- `server_eviction_test.go` (~525 lines) - Cache eviction tests
- Cache fields from `Server` struct
- Cache metrics from health/metrics endpoints
### 2. Client Request Routing
**File:** `internal/rpc/client.go`
**Status:** ✅ SIMPLIFIED - No cache references
**Key findings:**
- `req.Cwd` is set in `ExecuteWithCwd()` (line 108-124)
- Used for database discovery, NOT for multi-repo routing
- Falls back to `os.Getwd()` if not provided
- Sent to daemon for validation only
**Code:**
```go
// ExecuteWithCwd sends an RPC request with an explicit cwd (or current dir if empty string)
func (c *Client) ExecuteWithCwd(operation string, args interface{}, cwd string) (*Response, error) {
// Use provided cwd, or get current working directory for database routing
if cwd == "" {
cwd, _ = os.Getwd()
}
req := Request{
Operation: operation,
Args: argsJSON,
ClientVersion: ClientVersion,
Cwd: cwd, // For database discovery
ExpectedDB: c.dbPath, // For validation
}
// ...
}
```
### 3. Server Storage Access
**Status:** ✅ SIMPLIFIED - Direct storage access
**Previous (with cache):**
```go
store := s.getStorageForRequest(req) // Dynamic routing via cache
```
**Current (without cache):**
```go
store := s.storage // Direct access to local daemon's storage
```
**Evidence:**
```bash
$ git show 322ab63 | grep -A2 -B2 "getStorageForRequest"
- store := s.getStorageForRequest(req)
+ store := s.storage
```
**Files using `s.storage` directly:**
- `server_issues_epics.go` - All issue CRUD operations
- `server_labels_deps_comments.go` - Labels, dependencies, comments
- `server_routing_validation_diagnostics.go` - Health, metrics, validation
- `server_export_import_auto.go` - Export, import, auto-import
- `server_compact.go` - Compaction operations
### 4. Environment Variables
**Status:** ✅ ALL REMOVED
Searched for:
- `BEADS_DAEMON_MAX_CACHE_SIZE` - ❌ Not found
- `BEADS_DAEMON_CACHE_TTL` - ❌ Not found
- `BEADS_DAEMON_MEMORY_THRESHOLD_MB` - ❌ Not found
**Remaining daemon env vars (unrelated to cache):**
- `BEADS_DAEMON_MAX_CONNS` - Connection limiting
- `BEADS_DAEMON_REQUEST_TIMEOUT` - Request timeout
- `BEADS_MUTATION_BUFFER` - Event-driven sync buffer
### 5. MCP Multi-Repo Support
**Status:** ✅ WORKING WITHOUT CACHE
**Architecture:** LSP-style per-project daemons (v0.16.0+)
```
MCP Server (one instance)
Per-Project Daemons (one per workspace)
SQLite Databases (complete isolation)
```
**How multi-repo works now:**
1. MCP server maintains connection pool keyed by workspace path
2. Each workspace has its own daemon socket (`.beads/bd.sock`)
3. Daemon serves only its local database (`s.storage`)
4. No caching needed - routing happens at connection level
**From MCP README:**
> The MCP server maintains a connection pool keyed by canonical workspace path:
> - Each workspace gets its own daemon socket connection
> - Paths are canonicalized (symlinks resolved, git toplevel detected)
> - No LRU eviction (keeps all connections open for session)
**Key files:**
- `integrations/beads-mcp/src/beads_mcp/server.py` - Connection pool management
- `integrations/beads-mcp/src/beads_mcp/tools.py` - Per-request workspace routing via ContextVar
- `integrations/beads-mcp/src/beads_mcp/bd_daemon_client.py` - Daemon client with socket pooling
### 6. Test Coverage
**Status:** ✅ ALL TESTS UPDATED
**Removed tests:**
- `internal/rpc/server_eviction_test.go` (525 lines) - Cache eviction tests
- Cache assertions from `internal/rpc/limits_test.go` (55 lines)
**Remaining multi-repo tests:**
- `integrations/beads-mcp/tests/test_multi_project_switching.py` - Path canonicalization (LRU cache for path resolution, NOT storage cache)
- `integrations/beads-mcp/tests/test_daemon_health_check.py` - Client connection pooling
- No Go tests reference `getStorageForRequest` or storage cache
**Evidence:**
```bash
$ grep -r "getStorageForRequest\|cache.*storage" internal/rpc/*_test.go cmd/bd/*_test.go
# No results
```
### 7. Stale References
**File:** `internal/rpc/server.go`
**Status:** ⚠️ STALE COMMENT
**Line 6:**
```go
// - server_cache_storage.go: Storage caching, eviction, and memory pressure management
```
**Action needed:** Remove this line from comment block
## Architecture Change Summary
### Before (with cache)
```
Client Request
req.Cwd → getStorageForRequest(req)
Cache lookup by workspace path
Return cached storage OR create new
```
### After (without cache)
```
Client Request
Daemon validates req.ExpectedDB == s.storage.Path()
Direct access: s.storage
Single storage per daemon (one daemon per workspace)
```
### Why this works better
**Problems with cache:**
1. Complex eviction logic (memory pressure, LRU)
2. Risk of cross-workspace data leakage
3. Global daemon serving multiple databases was confusing
4. Cache staleness issues
**Benefits of per-workspace daemons:**
1. ✅ Complete isolation - one daemon = one database
2. ✅ Simpler mental model
3. ✅ No cache eviction complexity
4. ✅ Follows LSP (Language Server Protocol) pattern
5. ✅ MCP connection pooling handles multi-repo at client level
## Conclusion
**Cache removal is complete and successful**
**No action needed** except:
1. Update stale comment in `internal/rpc/server.go:6`
2. Close this issue (bd-bc2c6191)
**MCP multi-repo support confirmed working** via:
- Per-project daemon architecture
- Connection pooling at MCP server level
- Path canonicalization with LRU cache (for paths, not storage)
## Related Issues
- [bd-bc2c6191] - This audit (ready to close)
- Commit `322ab63` - Cache removal (2025-10-28)
- Commit `9edcb6f` - Remove cache fields from Server struct
- Commit `bbb1725` - Replace getStorageForRequest with s.storage
- Commit `c3786e3` - Add cache usage audit documentation
## Recommendations
1. ✅ Close bd-bc2c6191 - Audit complete, cache confirmed removed
2. 🔧 Fix stale comment in `internal/rpc/server.go:6`
3. 📚 Document per-daemon architecture in AGENTS.md (may already exist)
4. ✅ No tests need updating - all passing after cache removal