Lessons Keeper
Give sessions a memory: durable lessons live in a plain markdown file,
versioned with the project, written and parsed by
scripts/lessons.py so the format is enforced mechanically.
Recall — before starting non-trivial work
- Run:
python scripts/lessons.py list(filter with--tag <topic>, e.g.--tag build). - Read every returned lesson. Lessons cite evidence — a file path, command, or error. If the evidence no longer exists in the code, the lesson may be stale: verify against the code before obeying, and prune it (see below) if outdated.
- Memory is advisory. Code, tests, and CI win any disagreement with a lesson.
Record — after finishing a task
Record a lesson when you learned something durable that a future session would otherwise rediscover the hard way: surprising behavior, a workaround, a user correction, a decision with its rationale.
Run: python scripts/lessons.py add "<lesson>" --tag <topic>
and include the evidence inside the lesson text: (evidence: path/file.py)
or (evidence: command that reproduces).
What qualifies
| Record | Don't record |
|---|---|
"Staging API requires X-Org-Id even on GETs (evidence: api/auth.py)" |
"Added a function to auth.py today" |
| "Docker build needs HTTPS_PROXY build-arg behind the VPN" | "Tests are red right now" |
| "Chose Postgres over Mongo for multi-region reads (decision + date)" | Anything transient about the current conversation |
Rules
- One idea per lesson, one line. Merge related findings.
- Never record secrets, tokens, credentials, or personal data.
- Never record transient context ("what I'm doing now") — that's conversation, not memory.
- Prefer pruning over accumulating:
python scripts/lessons.py prune --keep 100whencountgrows large, and whenever a lesson's evidence has vanished from the codebase. .lessons/lessons.mdis committed and reviewed in pull requests like any other file — expect humans to read it.
Script reference
add "<text>" [--tag t] [--scope project|user] [--date YYYY-MM-DD]— append a lesson; exact duplicates are refused with exit 0 (idempotent). Scopeprojectwrites.lessons/lessons.mdin the repo (default);userwrites~/.lessons/lessons.md.list [--tag t] [--scope …]— print lessons (newest last).prune --keep N— keep the N most recent lessons.count— number of lessons.- Exit codes:
0ok ·1storage error ·2bad arguments. The entry date defaults to today; pass--dateto reproduce runs exactly.