Skip to main content
Glama


The problem

You tried Redis for session storage. It failed at 8 seconds during a regional outage, so you moved to Postgres.

Three weeks later, in a new session, your agent suggests Redis.

You explain again. A month after that you switch from Claude Code to Codex, and explain a third time. Six months later you no longer remember why Redis was rejected — and neither does anyone else on the team.

Code remembers what you chose. Nothing remembers what you rejected.

Memory tools record what happened. That is already in your commits, your pull requests, and the code itself. whynot records the other half: the options you ruled out, and the reason, in a file your agent reads before it proposes anything.


Related MCP server: CommitLore

Install

npx whynot-cli init

Nothing to install globally, no account, no telemetry. Node 20+ is the only requirement.


Quick start

1. See what will never expire

audit is read-only. It scans your existing AGENTS.md, CLAUDE.md, and .cursor/rules for absolute rules that state no condition — the ones that will be obeyed forever.

npx whynot-cli audit
Scanned 2 agent config files:
  AGENTS.md  (last changed 412d ago)
  CLAUDE.md  (last changed 8d ago)

3 rules look like permanent constraints:

  AGENTS.md:3
    "Never use TypeScript in this repo."
    → absolute rule with no stated condition; unchanged for 412 days

2. Create the store

npx whynot-cli init

This creates .decisions/ and adds *.md text eol=lf to .gitattributes.

3. Record a rejection

npx whynot-cli add \
  --title "Sessions do not go in Redis" \
  --why "Single-writer Redis took 8s to read during a us-east outage; the SLO requires p99 < 500ms" \
  --type rejected \
  --revisit "Redis supports cross-region strong consistency" \
  --evidence pr:412 \
  --tags infra,session
---
id: 0001
title: Sessions do not go in Redis
type: rejected
status: live
created: 2026-09-21
expires_on: 2026-12-20
revisit_when: "Redis supports cross-region strong consistency"
evidence:
  - "pr:412"
tags: [infra, session]
---

## Conclusion
Sessions must not be stored in Redis.

## Why
We tried Redis with a single writer region. During a us-east outage, reads took
8 seconds; the SLO requires p99 < 500ms. The Postgres table approach was
selected instead.

4. Give it to your agent

Add the MCP server:

{
  "mcpServers": {
    "whynot": {
      "command": "npx",
      "args": ["-y", "whynot-cli", "mcp"]
    }
  }
}

Then paste the block from AGENTS.snippet.md into your AGENTS.md or CLAUDE.md. The MCP server gives the agent the tools; the snippet is what makes it actually use them.

If MCP is unavailable, the format still works. .decisions/ is plain Markdown, so the agent can read and grep it directly. This was observed in the real-agent test, not assumed.


How it works

Every entry expires

Type

Default lifetime

rejected

90 days

decision

180 days

constraint

365 days

When an entry lapses it stops reaching your agent. Not annotated, not warned about — absent. whynot stale lists it, and you either renew it or retire it.

This is the core of the design. Telling an agent "this note is old, be skeptical" was tested and does not work. Removing the note from view does.

Three entry types

Type

Use it for

rejected

An approach you tried and abandoned. The most valuable kind — nothing else in the repository remembers it.

decision

A choice between viable options, with the reason

constraint

A hard requirement the project must satisfy

Written for humans, by design

  • Markdown in git. Read it, diff it, review it, revert it. If this tool disappears, grep still works.

  • No vector store, no embeddings, no model call on write. Each of those is a failure mode: index staleness, write-path cost, and results nobody can audit.

  • No daemon, no telemetry, no hosted service. Your reasoning about your own codebase stays on your machine.


What the evidence says

Six experiments, three model families, mostly n=20 per cell.

Question

Result

Does the age of a decision matter?

No. 30 days and 7 years were obeyed at the same rate (0/12 each). Expired → 12/12.

Does recording a rejection change the answer?

Yes. 78–87 percentage points, p < 0.0001.

Does an irrelevant record distort unrelated work?

No. 0/30.

Does a real agent use it across sessions?

Yes. Codex respected the decision in 9/9 sessions.

Two qualifications worth knowing before you install:

  • About one in five responses resisted a stale record — by attacking its stated reason. A reason that names a condition ("the team did not know TypeScript") invites re-checking; one that states a property ("this project changes constantly") does not.

  • With real code in context, some agents infer the answer from the repository and ignore the record. Records matter most for what code cannot express: the option you rejected.

Full results, methods, and reproduction scripts: docs/findings.md.


Docs

Design

Why the tool looks like this

Findings

Every experiment, what it found, what it did not

Validation

Index of the detailed write-ups

Pre-registration

Decision rules fixed before the data

Contributing

The four design constraints that are not negotiable

AGENTS snippet

The block that makes your agent use this


CLI reference

whynot init                     Create .decisions/ and the .gitattributes rule
whynot add --title T --why W    Record an entry
      [--type rejected|decision|constraint]
      [--revisit "condition"]   When to reconsider
      [--ttl N]                 Days until it expires
      [--expires never]         Explicitly permanent
      [--evidence pr:412]       Repeatable
      [--tags infra,session]
whynot list [--all]             List live entries
whynot check "<query>"          Show live entries matching a query
whynot stale                    Entries needing a human decision
whynot renew <id> [--days N]    Extend an entry's life
whynot retire <id>              Archive an entry (never deletes)
whynot audit [--days N]         Scan agent config files (read-only)
whynot doctor                   Validate the store
whynot mcp                      Run the MCP server on stdio

License

MIT. No account, no telemetry, no paid tier, no closed binary. There is nothing to upsell you.


Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Self-hosted decision memory for AI coding agents. Captures decisions with the alternatives you rejected, and warns before an agent re-proposes a rejected approach.
    4
    81
    Apache 2.0
  • A
    license
    A
    quality
    A
    maintenance
    Git-native decision memory for coding agents: stores constraints, ruled-out alternatives, and warnings as git trailers and refs/notes, returning only records still in force for the file path being edited.
    8
    18
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Gives AI coding agents persistent, branch-aware memory and a dependency-tracked task graph by storing decisions, lessons, and tasks as plain JSON and Markdown committed directly into the repository. Agents can record and fuzzy-search past decisions, dump instant project context, and create, claim, complete, and query tasks whose completion automatically unblocks downstream work.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Persists your coding decisions, rules, bugs, to-dos and dead ends into a repo file and automatically brings the relevant ones back into later AI coding sessions. It also checks commands and file edits against those saved rules before they run, flagging anything that might break them.
    848 npm
    MIT