--- name: memex-best-practices description: Zettelkasten best practices for building a high-quality knowledge graph. whenToUse: When the user asks about how to write good memory cards, naming conventions, linking strategies, or general Zettelkasten methodology. Also useful as a reference when writing or reviewing cards. --- # Zettelkasten Best Practices A reference guide for writing high-quality memex cards that compound in value over time. Covers card format, naming conventions, tagging, linking strategy, and graph health maintenance. This is NOT a workflow skill (see `memex-recall`, `memex-retro`, `memex-organize` for those). This is a **quality standard** — consult it when writing or reviewing cards. ## Card Quality Checklist Before writing a card, verify: - [ ] **Atomic** — one insight per card. If you can split it, do. - [ ] **Own words** — distill and rephrase, don't copy-paste. This is the Feynman method: if you can't explain it simply, you don't understand it well enough. - [ ] **Non-obvious** — would this change how you approach a similar task in the future? If not, skip it. - [ ] **Linked in context** — `[[wikilinks]]` are embedded in sentences explaining *why* the relationship exists. ## Card Format ```markdown --- title: "Short Noun Phrase ≤60 chars" created: "YYYY-MM-DD" source: "" tags: [domain-tag, type-tag] category: "" --- One atomic insight, written in your own words. This relates to [[other-card]] because . ``` ### Required Frontmatter | Field | Required | Format | |-----------|----------|---------------------------------| | `title` | ✅ | Noun phrase, ≤60 chars | | `created` | ✅ | ISO date `YYYY-MM-DD` | | `source` | ✅ | Auto-filled by MCP/CLI client | ### Optional Frontmatter | Field | Format | Notes | |------------|-------------------------|------------------------------------------| | `tags` | YAML list | See [Tag System](#tag-system) below | | `category` | Single string | See [Categories](#categories) below | | `links` | YAML list of slugs | Explicit links (in addition to wikilinks) | | `status` | `conflict` / `draft` | Set by organize skill when needed | ### Body Rules - Write in **plain Markdown** - Use `[[slug]]` wikilinks inline, within natural sentences - Keep cards concise — aim for a few paragraphs, not an essay - Code examples are fine, but the insight should stand without them ## Slug Naming Slugs are permanent identifiers. Choose them carefully. ### Format - **kebab-case**, all lowercase English - **3–60 characters** - Descriptive but concise ### Examples | ✅ Good | ❌ Bad | Why | |---------|--------|-----| | `docker-compose-port-binding` | `note-1` | Descriptive vs. meaningless | | `jwt-revocation-blacklist` | `docker` | Specific vs. too broad | | `nextjs-app-router-caching` | `how-to-fix-the-bug-we-found` | Noun phrase vs. sentence | | `vitest-mock-timer-gotcha` | `vitest_mock_timer` | kebab-case vs. snake_case | ### Special Slug Prefixes Use these prefixes to signal card type at a glance: | Prefix | Use | Example | |-------------|------------------------------------|--------------------------------| | `adr-*` | Architecture decision records | `adr-monorepo-vs-polyrepo` | | `gotcha-*` | Pitfalls, traps, surprising behavior | `gotcha-yaml-date-auto-parse` | | `pattern-*` | Reusable patterns, best practices | `pattern-retry-with-backoff` | | `tool-*` | Tool-specific tips and configs | `tool-gh-cli-pagination` | These are conventions, not enforced constraints. Use them when they fit naturally. ## Categories Assign one category per card to indicate its domain: `architecture` · `backend` · `frontend` · `devops` · `tooling` · `security` · `workflow` · `testing` · `data` Categories are broad. Use tags for fine-grained classification. ## Tag System Tags serve two purposes: **domain** (what technology) and **type** (what kind of knowledge). ### Domain Tags Use the specific technology or concept name: `docker` · `nodejs` · `typescript` · `react` · `nextjs` · `postgres` · `redis` · `git` · `api` · `css` · `linux` · `aws` · `azure` ### Type Tags Classify the kind of insight: | Tag | When to use | |-------------|----------------------------------------------| | `decision` | A choice was made between alternatives | | `gotcha` | Surprising behavior, easy-to-miss pitfall | | `pattern` | Reusable solution or approach | | `howto` | Step-by-step procedure | | `reference` | Factual lookup (config format, API shape) | | `debug` | Root cause analysis of a specific bug | ### Tagging Guidelines - Use **1–3 tags** per card (one domain + one type is ideal) - Prefer existing tags over creating new ones - Tags are lowercase, single-word or hyphenated (`rate-limiting`, not `Rate Limiting`) ## Linking Strategy Links are the most valuable part of a Zettelkasten. They create a network that surfaces unexpected connections. ### Link in Context Every `[[wikilink]]` should appear in a sentence that explains the relationship: ```markdown This contradicts what we found in [[jwt-migration]] — stateless tokens can't be revoked without a server-side blacklist. Related: [[jwt-migration]] ``` ### When to Link - **Contradiction** — "This conflicts with [[X]] because..." - **Extension** — "This builds on [[X]] by adding..." - **Example** — "[[X]] is a concrete instance of this pattern" - **Alternative** — "We chose this over the approach in [[X]] because..." - **Prerequisite** — "Understanding [[X]] is necessary context for this" ### Avoid Over-Linking Not every card needs to link to every related card. Link when the connection would **surprise** someone or **change how they read** either card. ## The Keyword Index The `index` card is a curated entry point to the entire knowledge graph — inspired by Luhmann's *Schlagwortregister* (keyword register). ### Purpose - Provides structured entry points for the `memex-recall` skill - Groups cards by concept, not by chronology - Each card appears under 1–2 categories ### Format ```markdown --- title: Keyword Index created: source: organize --- ## Authentication - [[jwt-revocation-blacklist]] — Server-side revocation for stateless tokens - [[oauth2-pkce-flow]] — PKCE flow for public clients (SPAs, mobile) ## Docker - [[docker-compose-port-binding]] — 0.0.0.0 vs 127.0.0.1 gotcha - [[docker-multi-stage-builds]] — Reducing image size with build stages ``` The index is maintained by the `memex-organize` skill. You can also update it manually after writing cards. ## The Recall → Work → Retro Loop The core memex workflow is a learning cycle: ``` ┌─────────────────────────────────────────────────┐ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ RECALL │───▶│ WORK │───▶│ RETRO │ │ │ │ │ │ │ │ │ │ │ │ Search │ │ Do the │ │ Distill │ │ │ │ existing │ │ actual │ │ insights │ │ │ │ cards │ │ task │ │ to cards │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ ▲ │ │ │ └───────────────────────────────┘ │ │ Cards feed future recalls │ └─────────────────────────────────────────────────┘ ``` - **Recall** (task start) — search for relevant prior knowledge before starting work. Avoid repeating past mistakes. - **Work** — do the actual task, informed by what you recalled. - **Retro** (task end) — reflect on what you learned. Write cards for non-obvious insights only. This loop is implemented by the `memex-recall` and `memex-retro` skills. The key insight: **retro is not just documentation — it's how you learn**. Writing in your own words forces deeper understanding than simply bookmarking a Stack Overflow link. ## Graph Health Maintenance A knowledge graph degrades without maintenance. The `memex-organize` skill handles this, but here are the principles: ### Orphan Cards (0 inbound links) An orphan is a card that nothing links to. It may be: - **Genuinely standalone** — fine, leave it alone - **Missing connections** — search for related cards and add contextual links ### Hub Cards (≥10 inbound links) A hub card is referenced by many others. It may be: - **Appropriately central** (e.g., a foundational concept) — fine - **Too broad** — consider splitting into smaller, more atomic cards ### Contradictions When two cards disagree, this is valuable signal — not a bug. The organize skill flags contradictions with `status: conflict` for human resolution. Don't auto-resolve conflicting beliefs. ### Staleness If a card's information is outdated: - **Update it** if the new info is a simple correction - **Write a new card + archive the old one** if the new understanding is significantly different ## Importing from External Sources (e.g., Flomo) When importing notes from external tools like flomo, the bar is **higher** than session retro: - **Digest, don't copy.** External notes are raw material, not Zettelkasten cards. Read them, identify the genuine insight, and rewrite as an atomic card. - **Tag with `source: flomo`** (or the appropriate source). This enables anti-loopback guards in bidirectional sync. - **Merge related notes.** 5 flomo memos about the same topic → 1 card with the distilled insight. - **Skip garbage.** Short fragments, bookmarks without context, copy-pasted quotes with no personal insight — these don't make it in. - **Quality checklist still applies.** Imported cards must be atomic, in your own words, non-obvious, and linked. ### Anti-Loopback Rule Cards with `source: flomo` are **never pushed back to flomo**. This is enforced in code and must not be removed. The same principle applies to any future external source: never echo content back to its origin. ## Anti-Patterns | ❌ Don't | ✅ Do Instead | |----------|---------------| | Write a card for every task | Only capture non-obvious insights | | Copy-paste error messages as cards | Distill the root cause and fix | | Create cards with no links | Always link to at least one related card | | Use vague slugs like `notes` or `misc` | Use descriptive slugs: `postgres-connection-pool-sizing` | | Write essay-length cards | Keep cards atomic — split if needed | | Hoard tags (5+ per card) | Use 1–3 tags: one domain + one type | | Link without explaining why | Every `[[link]]` needs a surrounding sentence | | Mechanical 1:1 import from external tools | Digest and curate — external notes are raw material | | Push source: flomo cards back to flomo | Anti-loopback: never echo content to its origin | ## Quick Reference Card For easy lookup, here's the complete format in one block: ```markdown --- title: "Descriptive Noun Phrase ≤60 chars" created: "2025-01-15" source: "" tags: [typescript, gotcha] category: "backend" --- ``` **Slug**: `kebab-case-english-3-to-60-chars` **Tags**: 1 domain + 1 type, lowercase **Links**: in sentences, not in lists **Length**: a few paragraphs, not an essay