nexus/.planning/phases/33-persistent-memory/33-01-SUMMARY.md
Nexus Dev 1d222e3e8a docs(33-01): complete persistent-memory memory-service plan
- SUMMARY.md with 17 passing tests, 2 deviations documented
- STATE.md advanced to plan 2, progress 80%
- ROADMAP.md updated: Phase 33 1/3 plans complete
- REQUIREMENTS.md: ASST-01 and ASST-02 marked complete
2026-04-04 03:55:49 +00:00

82 lines
3.7 KiB
Markdown

---
phase: 33-persistent-memory
plan: 01
subsystem: server/services
tags: [memory, sanitization, file-backed, rest-api, credentials]
provides:
- File-backed assistant memory service (get/append/clear per companyId)
- Credential sanitizer scrubbing sk-/ghp_/AIza/JWT/key=value patterns
- REST endpoints GET/PATCH/DELETE at /api/assistant-memory/:companyId
affects: [33-persistent-memory, chat-routes, assistant]
tech-stack:
added: []
patterns: [file-backed JSON service, FIFO eviction, write-time sanitization]
key-files:
created:
- server/src/services/memory-sanitizer.ts
- server/src/services/assistant-memory.ts
- server/src/routes/assistant-memory.ts
- server/src/__tests__/33-memory-sanitization.test.ts
- server/src/__tests__/33-assistant-memory.test.ts
modified:
- server/src/app.ts
key-decisions:
- "Removed zod dependency from assistant-memory.ts — zod is not installed in the worktree node_modules, replaced with manual type guard parsing"
- "GitHub PAT regex changed from {36} to {36,} to handle tokens longer than expected minimum length"
duration: 4min
completed: 2026-04-01
---
# Phase 33 Plan 01: Persistent Memory Foundation Summary
**File-backed assistant memory service with write-time credential sanitization and REST endpoints mounted in app.ts.**
## Performance
- **Duration:** 4 minutes
- **Tasks:** 2 completed
- **Files modified:** 6
## Accomplishments
- `sanitizeMemoryFact` scrubs OpenAI (sk-), GitHub PAT (ghp_), Google API (AIza), JWT-shaped tokens, and key=value credential patterns at write time
- `assistantMemoryService` provides file-backed get/append/clear scoped per companyId at `data/assistant-memory/<companyId>.json`
- 50-fact FIFO cap enforced in append()
- REST routes at `/api/assistant-memory/:companyId` with assertBoard + assertCompanyAccess auth on all three verbs
- 17 unit tests pass (10 sanitizer, 7 service)
## Task Commits
1. **Task 1 (RED): Failing tests** - `378d1c11`
2. **Task 1 (GREEN): Memory sanitizer + service** - `fb3c1578`
3. **Task 2: Routes + app.ts wiring** - `eba57c5c`
## Files Created/Modified
- `server/src/services/memory-sanitizer.ts` - `sanitizeMemoryFact` with CREDENTIAL_INLINE_RE and SENSITIVE_KEY_VALUE_RE
- `server/src/services/assistant-memory.ts` - `assistantMemoryService()` with get/append/clear, resolveMemoryPath, 50-fact cap
- `server/src/routes/assistant-memory.ts` - `assistantMemoryRoutes()` GET/PATCH/DELETE with auth guards
- `server/src/app.ts` - Added import + `api.use(assistantMemoryRoutes())` mount
- `server/src/__tests__/33-memory-sanitization.test.ts` - 10 sanitizer tests
- `server/src/__tests__/33-assistant-memory.test.ts` - 7 service tests with os.tmpdir() isolation
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] GitHub PAT regex too strict**
- **Found during:** Task 1 (TDD GREEN)
- **Issue:** `ghp_[A-Za-z0-9]{36}` matched exactly 36 chars, leaving trailing chars unredacted (`[REDACTED]k`)
- **Fix:** Changed to `{36,}` to match minimum 36 chars
- **Files modified:** `server/src/services/memory-sanitizer.ts`
- **Commit:** fb3c1578
**2. [Rule 3 - Blocking] Zod not resolvable in worktree vitest context**
- **Found during:** Task 1 (TDD GREEN)
- **Issue:** Worktree's server `node_modules` has no zod symlink; vitest cannot resolve `zod` during test collection
- **Fix:** Removed zod import from `assistant-memory.ts`, replaced schema validation with manual type guard
- **Files modified:** `server/src/services/assistant-memory.ts`
- **Commit:** fb3c1578
## Known Stubs
None — all data paths are fully wired.
## Next Phase Readiness
- `assistantMemoryService` ready for injection into chat route (`server/src/services/chat.ts`) in Plan 02
- Routes already mounted; API is live on server start