notnessie

Concepts

This page explains what NotNessie remembers, how memory flows through a Claude Code session, and the one rule that governs all of it: current code wins over memory.

Memory types

Every memory has a type. The type drives how a memory is captured, how it is ranked, and how it is shown back to you. NotNessie defines ten:

Type What it captures Typical source
project_fact A durable fact about the project (β€œthe API base path is /v1”). Saved or summarized
decision An architectural or implementation choice (β€œwe use Redis for refresh-token metadata”). notnessie_save_decision, summaries
preference A coding/style preference (β€œprefer service classes over fat route handlers”). notnessie_save_preference
constraint A hard rule Claude should not violate (β€œnever edit generated files”), with an optional severity. notnessie_save_constraint
verified_command A command confirmed to work in this repo (β€œpnpm test”). notnessie_save_verified_command, PostToolUse hook
task_summary A post-task recap: what changed, commands run, outcome, new TODOs. notnessie_save_task_summary, Stop/PreCompact hooks
bug_note A note about a bug and its context. Saved or summarized
failed_attempt An approach that was tried and did not work β€” so it is not retried. Saved or summarized
todo A follow-up task to remember. Summaries
open_question An unresolved question the team or assistant should be aware of. Summaries, notnessie_get_open_questions

Each memory also carries metadata that retrieval uses: a confidence score (a heuristic baseline from the source kind and memory type), tags, the files it applies to, pinned and deleted flags, and a source record describing where it came from (MCP tool call, a specific hook, a session, or a task).

How memory flows

A typical session moves through three stages. The hooks do the automatic work; the MCP tools do the explicit work.

1. SessionStart β€” context in

When a Claude Code session starts, the SessionStart hook builds a context pack for the repository and injects it, so the assistant begins with the most relevant decisions, constraints, verified commands, and open questions already in view. UserPromptSubmit can refresh task-specific context as you work.

2. During the session β€” saves

As you work, memory is captured two ways:

3. Stop & PreCompact β€” summaries out

When a session ends (Stop) or Claude Code is about to compact the conversation (PreCompact), the hook summarizes the session into memory: decisions made, files changed, commands verified, failed approaches, and new TODOs. Summaries are produced with the Claude Agent SDK, with a heuristic fallback when the SDK is unavailable. Hooks honor your configuration (for example, they skip auto-saving task summaries if you turned that off) and never store full transcripts or raw output.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   inject    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SessionStart β”‚ ──────────► β”‚  Claude Code session β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                         β”‚ save tools + PostToolUse
                                         β–Ό
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚   PostgreSQL memory   β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                         β–² summarize
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚   Stop / PreCompact   β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Retrieval: hybrid, re-ranked

When NotNessie builds a context pack or answers a search, it does hybrid retrieval:

  1. A SQL candidate pool scores each memory on full-text keyword rank and pgvector cosine similarity to the query embedding.
  2. JavaScript then re-ranks that pool using a normalized keyword score, the semantic similarity, recency (a 30-day half-life), confidence, a per-type weight, pinned status, and overlap with any files mentioned in the task.

With no query (a general project pack), ranking falls back to pinned, then confidence, then recency β€” a sensible default. When embeddings are disabled or unavailable, the semantic term drops out and ranking is keyword-only; nothing breaks. See Architecture for the storage details.

Authority: code beats memory

Memory is background context, not instructions to obey blindly. This rule is baked into the generated CLAUDE.md block and the skill:

Current code is more authoritative than old memory. If memory conflicts with the codebase, mention the conflict instead of following the memory.

That is why the dashboard exists: memory captured by an AI is never perfect, so a human reviews, corrects, pins, and deletes it. Pinning a memory makes it rank first; deleting is soft by default (restorable) with a --hard option for permanent removal.

Privacy is part of the model

Capture is deliberately conservative and secret-aware:

See Configuration for the redactSecrets and memory-mode settings that govern this.