# Tasks: enterprise-server-cache-memory **Change ID**: enterprise-server-cache-memory **Package**: `@suaveplan/cache-memory` **Target path**: `server/data/cache-memory` **Prerequisite packages on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/logger` --- ## 0. Pre-flight (non-negotiable) - [ ] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each) - [ ] 0.2 If any worktrees exist under `.claude/worktrees/`, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (`git worktree remove`) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - [ ] 0.3 Confirm the package set in `MANIFEST.md` matches `find packages -maxdepth 3 -name package.json` count. Drift here means a prior change archived without regenerating the manifest. ## 1. Scaffold - [ ] Create directory tree per `proposal.md` layout. - [ ] Write `package.json` at `0.1.0`, `"sideEffects": false`, exports map for `"."`, `adapter`, and `lru`. - [ ] Add dependencies: `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/logger workspace:^`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`, `tslib catalog:build`. - [ ] Add devDependencies: `vitest catalog:testing`, `@vitest/coverage-istanbul catalog:testing`, `fast-check catalog:testing`, `@suaveplan/testing workspace:^`. - [ ] `tsconfig.json` extending `library.json`; `vitest.config.ts` using `createTestConfig()`. - [ ] Scripts: `lint`, `typecheck`, `test`, `test:coverage`, `build`, `docs:check`. ## 2. Types and errors - [ ] Define `MemoryCacheOptions`, `CacheStats`, `MemoryCacheOptionsSchema` in `src/types/cache-memory.types.ts`. - [ ] Write `cache-memory.types.md` (≥200 words, both examples, API reference). - [ ] `src/error-codes.ts`: `MemoryCacheErrorCode`, metadata, `registerMemoryCacheErrorCodes()`, eager call. ## 3. LRU data structure - [ ] Implement `src/lru/lru-cache/lru-cache.ts`: - Doubly-linked list + Map, O(1) get/set/delete. - `LruCache` with `maxSize`, `get(k)`, `set(k, v)`, `delete(k)`, `has(k)`, `keys()`, `size`. - On capacity exceeded: evict LRU (tail) entry; increment eviction counter. - No external deps. - [ ] Write `lru-cache.test.ts`: LRU ordering, capacity eviction, re-access promotes entry, delete middle node, size tracking. - [ ] Write `lru-cache.md` (≥200 words). ## 4. Memory cache adapter - [ ] Implement `MemoryCacheAdapter` in `src/adapter/memory-cache-adapter/memory-cache-adapter.ts`: - Owns an `LruCache<{ value: Uint8Array; expiresAt?: number }>`. - `get(key)`: check expiry using `clock.now()` (or `Date.now()` when no clock); on expiry call `delete(key)` and return `undefined`; increment hit/miss counter. - `set(key, value, ttlMs?)`: store entry with `expiresAt = clock.now() + ttlMs` when TTL supplied; evict if `maxSize` exceeded (handled by LRU internally). - `delete(key)`: remove entry; return `true` if existed. - `has(key)`: get + check expiry; return bool. - `list(prefix?)`: iterate keys, skip expired, filter by prefix. - `clear()`: reset LRU; reset stats. - `ttl(key)`: `expiresAt - clock.now()` or `undefined`. - `size()`: current entry count. - `stats()`: return `CacheStats` snapshot. - OTel: counter `cache_memory.ops_total` (operation, hit); histogram `cache_memory.duration_ms`. - [ ] Export `createMemoryCacheAdapter(options?)`. - [ ] Write `memory-cache-adapter.types.ts` with internal types. - [ ] Write `memory-cache-adapter.test.ts` (≤500 lines): all CRUD, TTL expiry with FakeClock, LRU eviction order, stats accuracy, concurrent access (synchronous — no real concurrency needed), logger invocations. - [ ] Write `memory-cache-adapter.md` (≥200 words, simple + advanced, full API reference). ## 5. Property-based tests - [ ] Write `tests/property.test.ts` (≤500 lines, `{ timeout: 30000 }` on each): - **Get/set round-trip**: for arbitrary keys + values, `set` then `get` returns the same bytes. - **Delete removes**: after `set` + `delete`, `get` returns `undefined`. - **TTL expiry consistency**: entries with `ttlMs = 0` never returned on next `get` with advanced clock. - **LRU ordering**: inserting N+1 entries into a size-N cache results in the oldest-accessed entry being evicted. - **Stats accuracy**: `hits + misses === total get calls` for arbitrary call sequences. ## 6. OTel + docs - [ ] Counter `cache_memory.ops_total`; histogram `cache_memory.duration_ms` as specified. - [ ] All `.md` files per layout; root `README.md` with quick-start, FakeClock testing example, API table, deps table. ## 7. Verify and publish - [ ] `bunx turbo lint --filter=@suaveplan/cache-memory` — zero errors. - [ ] `bunx turbo typecheck --filter=@suaveplan/cache-memory` — zero errors. - [ ] `bunx turbo test --filter=@suaveplan/cache-memory` — all tests pass. - [ ] `bunx turbo test:coverage --filter=@suaveplan/cache-memory` — 100%. - [ ] Confirm `"sideEffects": false` set; no `TODO`/`any`/`.skip` in `src/`. - [ ] `bun scripts/publish.ts --package @suaveplan/cache-memory`. - [ ] Update `CLAUDE.md`; archive to `openspec/archive/2026-04-24-enterprise-server-cache-memory/`.