Skip to content

Repository files navigation

GRIND

A pure STUDY + GRIND Obsidian vault — a cognitive gym, not a note app.

spec v2.4 · template_version 2.4 · min_supported 2.0 · validator: deterministic


Every file in this vault is one of five things: input for learning, a permanent knowledge atom, a practice problem, a review item, or a measurable progress record. Nothing else gets in. No journals, no to-dos, no life admin.

The operating model is a split of labor:

Claude Code racks the weights, writes down the reps, and keeps the gym spotless. You show up and lift.

Claude Code does the structural and generative work — scaffolding notes, drafting concepts, generating quizzes and flashcards, applying mastery math, regenerating plans. The human does the only part that can't be outsourced: the actual recall, problem-solving, and rating.


Table of Contents


Why this exists

Most knowledge vaults rot because they optimize for capture. This one optimizes for retrieval under pressure. Three design decisions follow from that:

Decision Consequence
Mastery is evidence-weighted, never subjective You can't feel your way to a 4.5. Only solved problems and rated recalls move the number.
Every right/wrong answer is logged forever A rolling mastery score tells you the score; the Review History tells you which questions cost you points.
Generated artifacts are overwritten, never hand-edited Plans and queues always reflect current evidence, not a stale opinion from three weeks ago.

Quick start

# 1. Open this folder as an Obsidian vault.
#    All 8 plugins + the Minimal theme + hardcore.css are already committed and
#    configured — just click "Trust author and enable plugins" when prompted.

# 2. Confirm the vault is structurally sound:
python3 _scripts/validate.py     # must exit 0

# 4. Drop in your first source, then let Claude Code do the scaffolding:
claude "From SRC-20260731-CLRS-Ch22, propose the atomic ideas, then draft one Permanent
note per idea using 06_Templates/permanent.md. Classify each via _ClassificationRules.md,
set generated_by: claude-code and verified: false, and create 2-3 starter flashcards per
note with deck set to the topic."

Important

Claude Code's drafts land at verified: false with mastery capped at 2.9. Only a human flips verified: true. Claude never self-verifies its own work — that gate is the whole reason the mastery number means anything.


Folder structure

GRIND/
├── 00_Inbox/                  # Raw capture only. Must be EMPTY by end of day.
├── 01_Sources/                # Immutable source material. Never edit after import.
│   ├── Books/  Papers/  Courses/  Lectures/
├── 02_Permanent/              # Atomic evergreen notes — the core of the vault.
│   ├── Concepts/  Theorems/  Algorithms/  Definitions/  Frameworks/
│   │   └── _Mastered/         #   proven-mastered notes, moved off the active surface
├── 03_Practice/               # Deliberate practice.
│   ├── ProblemSets/  WorkedExamples/  Flashcards/
├── 04_Projects/               # Time-boxed campaigns with real end criteria.
├── 05_Progress/               # Metrics, reviews, trackers.
│   ├── DailyLogs/  WeeklyReviews/  MasteryMaps/
│   └── Plans/                 #   PLAN-*.md + MISSED-Queue.md  (generated)
├── 06_Templates/              # Canonical templates + controlled vocabularies.
├── _scripts/                  # validate.py + flashcards.html (Trainer)
├── 99_Archive/                # Cold storage. Move here — never delete.
├── CLAUDE.md                  # Operating rules for Claude Code
└── GRIND-Obsidian-Vault-Specification-v2_4.md

Every file has exactly one correct location, name pattern, and template. If you hesitate about where something goes, the system is broken — not your judgment.


The six note types

Only these six exist. MAP- and PLAN- are machine outputs, not note types.

Type Purpose Lives in Owns mastery?
Source Immutable reference to original material 01_Sources/<Type>/
Permanent One atomic concept, theorem, algorithm, definition, or framework 02_Permanent/<Type>/ only here
Practice A problem with attempt, solution, and reflection 03_Practice/ProblemSets/ ✗ (feeds it)
Flashcard Spaced-repetition item; SRS state only 03_Practice/Flashcards/ ✗ (feeds parent)
Daily Log One study day's effort and outcomes 05_Progress/DailyLogs/
Weekly Review Aggregate, prune, plan 05_Progress/WeeklyReviews/

Classification is mechanical. A Permanent note's type comes from _ClassificationRules.md, applied in order — stop at the first match:

Theorem  →  formally provable result, has a proof
Algorithm →  a procedure; answers "how do I compute this?"
Definition →  a precise term with no further derivation; answers "what is X?"
Framework  →  organizes multiple concepts; composite rather than atomic
Concept    →  (default) any other single coherent idea

Naming conventions

Type Pattern Example
Source SRC-YYYYMMDD-ShortTitle SRC-20260315-CLRS-Ch22
Permanent PERM-{Type}-ShortTitle-NN PERM-Algorithm-Dijkstra-01
Practice PRAC-YYYYMMDD-Domain-ShortTitle PRAC-20260320-Graph-ShortestPath
Flashcard CARD-Domain-Concept-NN CARD-Algorithms-BellmanFord-01
Project PROJ-ShortName-YYYY PROJ-CS229-2026
Daily Log LOG-YYYY-MM-DD LOG-2026-03-20
Weekly Review WEEK-YYYY-Www WEEK-2026-W12
Mastery Map MAP-Domain MAP-Algorithms
Study Plan PLAN-ShortName PLAN-CS229-2026

Alphanumeric, hyphens, underscores only. The zero-padded -NN suffix is mandatory on Permanent notes and Flashcards — it disambiguates same-titled atoms and lets one concept own several cards. Every domain value must already exist in 06_Templates/_Domains.md; inventing one on the fly is a validation failure.


Mastery: the scoring engine

mastery is a float in [0.0, 5.0] stored on Permanent notes only. Cards and problems are evidence that moves it — they never store it themselves.

Level Meaning Behavior required
0.0 Unknown Cannot explain or apply
1.0 Recognition Recognizes it when seen
2.0 Basic recall States the definition with effort
3.0 Working understanding Explains intuition + formal statement + an example
4.0 Fluent application Solves medium problems, explains edge cases
5.0 Mastery Teaches it, derives variants, spots subtle errors

How evidence rolls up

Practice problems are primary evidence — the delta applies to every Permanent note linked under ## Related Concepts:

base        = {"easy": 0.3, "medium": 0.5, "hard": 0.8, "expert": 1.0}[difficulty]
time_factor = 1.0 if solved_under_expected_time else 0.6
hint_penalty= 0.0 if not used_hints else 0.4
delta       = base * time_factor * (1 - hint_penalty)

correctmastery = min(5.0, mastery + delta)
partialmastery = min(5.0, mastery + delta * 0.4)
incorrectmastery = max(0.0, mastery - base * 0.7)

Flashcards are secondary evidence — the delta applies to the card's parent note:

Rating again hard good easy
Δ mastery −0.50 −0.25 +0.05 +0.15

Guardrails

  • No unweighted ±1. Ever. The rating is the evidence.
  • ±1.0 per session cap on any single note, summed across all its cards and problems.
  • Unverified Claude drafts cap at 2.9 until a human flips verified: true.
  • Decay: unreviewed for 60 days while active → −0.2 per additional 30 days (max −1.0), then status: reviewing + forced review.
  • focus_score never touches mastery. It's a subjective self-report, nothing more.
  • Mastered promotion (mastery ≥ 4.8 + verified: true + no live project deadline) moves a note to _Mastered/ — off the active surface, cards still cycling on longer intervals.

Missed-item tracking

A single rolling number tells you the score, not which questions cost you points. So every individual result is logged, permanently:

  • Every card review appends a line to that card's ## Review History (date | rating | correct). Wrong → misses_in_a_row += 1; right → reset to 0. At 3 consecutive misses the card is flagged leech: true, cleared only by two consecutive correct reviews.
  • Every practice attempt appends to ## Attempt 1 or ## Retry Log with an explicit outcome. A later correct retry does not erase the earlier failure — each attempt is its own piece of evidence and applies its own delta.
  • MISSED-Queue.md is regenerated after every session: all leech cards + every problem whose latest outcome was incorrect or partial, grouped by domain.

Note

Mastery must never move without a matching history line. Evidence with no paper trail is a validation failure (rule 11), not a shortcut.

Remediation then targets exactly what you keep missing, instead of "review everything again":

claude "Read 05_Progress/Plans/MISSED-Queue.md. Generate a practice set covering ONLY those
problems' related concepts. Before writing, check each Retry Log: if I've failed a concept
twice, make this attempt easier and add a worked hint in the Key Insight section."

The Flashcard Trainer

_scripts/flashcards.html — a self-contained, zero-dependency review surface. Open it in any browser; it needs no plugin and no server.

Key Action
Space Flip the card
1 2 3 4 Rate Again / Hard / Good / Easy
Previous card / mark Good and advance

Plus deck filtering, shuffle, and a progress bar. On finish it emits a per-card results block — not just a summary — because §5.9 needs each individual outcome:

CARD-Algorithms-BellmanFord-01 | rating: hard | correct: false | parent: PERM-Algorithm-BellmanFord-01 | 2026-07-31

Paste that back and Claude Code applies the deltas, appends the history lines, updates misses_in_a_row / leech, and regenerates the Missed Queue:

# Build a session from one topic...
claude "Collect all active CARD notes with deck = [Topic] and regenerate _scripts/flashcards.html"

# ...or from just the things you keep getting wrong
claude "Regenerate _scripts/flashcards.html from 05_Progress/Plans/MISSED-Queue.md instead of a topic"

# Then, after the session
claude "Apply these Trainer results using _MasteryScale.md: [paste results block]"

The Obsidian Spaced Repetition plugin remains the scheduler of record — both surfaces act on the same cards, and frontmatter interval/ease mirror the plugin.


Generated artifacts

These are derived outputs, overwritten on every regeneration. Hand-editing them is an anti-pattern — your edit will be silently destroyed, and worse, it desynchronizes the plan from the evidence.

Artifact Regenerated from
05_Progress/Plans/PLAN-Overall.md, PLAN-{Project}.md mastery, decay flags, deadlines, curriculum_cycle
05_Progress/Plans/MISSED-Queue.md leech cards + latest incorrect/partial outcomes
05_Progress/MasteryMaps/MAP-{Domain}.md domain-level mastery roll-up
_scripts/flashcards.html active CARD-* notes (by deck, or from the Missed Queue)

To override a plan, change the inputs — edit the Project or the curriculum_cycle in the Weekly Review — then regenerate.


Validation

Validation is the script, not prose. Run it before any commit or bulk change:

python3 _scripts/validate.py     # must exit 0
The 11 checks
  1. YAML completeness — required keys present; template_version >= MIN_SUPPORTED (2.0)
  2. Migration policy — a spec bump never invalidates old notes; below-minimum notes are quarantined, not failed
  3. Domain legality — every domain exists in _Domains.md
  4. Naming compliance — filename matches its type's pattern, -NN included
  5. Card–parent integrity — every parent resolves; cards: lists agree bidirectionally
  6. Link integrity[[wikilinks]] in required sections resolve; 30-day orphans flagged
  7. Mastery bounds & ownership — float in [0.0, 5.0], on Permanent notes only
  8. Inbox discipline00_Inbox/ empty at end of run
  9. Archive eligibility — archived notes satisfy the §5.6 conditions
  10. Verification gate — unverified Claude drafts capped at 2.9
  11. Review history presence — no reviewed item without a logged outcome

Generated artifacts (PLAN-*, MAP-*, MISSED-Queue.md) carry no frontmatter schema and are skipped by the validator, as are 06_Templates/, _scripts/, and 99_Archive/.


Daily & weekly rhythm

DailyWeekly
  1. Empty 00_Inbox
  2. Get today's queue from PLAN-Overall.md
  3. Study blocks: Source → Permanent → Practice
  4. Review ≥ 20 cards, rate honestly
  5. Solve the day's practice set
  6. Claude drafts the Log; you set focus_score
  7. Commit
  8. Close. Inbox must be empty.
  1. Aggregate 7 Daily Logs → WEEK-YYYY-Www
  2. Review weak notes (mastery < 3.0, stale, forced)
  3. Verify pending Claude drafts (or send them back)
  4. Run validate.py, promotion, archiving
  5. Regenerate Plans + MasteryMaps
  6. Accept or override next curriculum_cycle
  7. Commit and push

Claude Code command cookbook

# What should I study right now?
claude "Regenerate PLAN-Overall.md from current mastery, decay flags, deadlines, and the
latest curriculum_cycle. Give me today's prioritized queue with time estimates."

# Build a quiz (solutions hidden so you can't peek)
claude "Generate a 10-question practice set on [Topic] at mixed difficulty (3 easy, 5 medium,
2 hard). One PRAC note each, generated_by: claude-code. Put full solutions in a collapsed
>! callout. Link each to its related Permanent notes so mastery updates when I solve them."

# End of day
claude "Draft today's LOG from the notes, problems, and cards touched since the last commit.
Fill hours and sessions; leave focus_score for me."

# Weekly maintenance, one command
claude "Run weekly maintenance: 1) validate.py. 2) Aggregate the 7 Daily Logs into this
week's WEEK note. 3) Apply Mastered promotion and conditional archiving. 4) Regenerate Study
Plans and MasteryMaps. 5) List remaining Inbox files, unverified notes, and failures."

Autonomy model

🤖 Claude Code does — no permission needed

Scaffolds and names every note type · drafts Permanent notes, practice sets, and flashcards · refreshes the Flashcard Trainer · applies _MasteryScale.md deltas from your ratings · aggregates Daily Logs and drafts the Weekly Review · regenerates Plans, MasteryMaps, and the Missed Queue · runs validate.py and auto-fixes safe issues · empties the Inbox · promotes Mastered and archives conditionally — moving, never deleting

🧠 Only the human can

The actual recall, problem-solving, and rating — Claude writes the quiz; you take it · verifying Claude-drafted notes (verified: true) · setting goals, deadlines, and the curriculum_cycle

✋ Claude asks first before

Deleting anything (default: refuse — move instead) · editing Source note content · merging or splitting Permanent notes · changing any controlled file in 06_Templates/ · raising MIN_SUPPORTED


Plugins & theme

All eight plugins and the theme are committed to this repo, pre-configured. Clone it, open it in Obsidian, trust the plugins when prompted — everything is already wired to the vault's folders. Nothing to install by hand.

Maximum eight, hard cap. Nothing that adds sidebars, social features, entertainment graphs, or AI chat inside the vault.

# Plugin Role Pre-wired to
1 Templater Rigid note creation Folder templates: each folder auto-applies its own template on file creation
2 Dataview Query mastery, review queues, progress JS + inline queries enabled
3 Spaced Repetition Native SRS; the scheduler of record Reviews #card notes; ignores Templates, Archive, and generated artifacts
4 Obsidian Git Version control + backup Auto-commit and push every 30 min, pull on boot
5 Linter YAML + heading hygiene on save Whitespace/heading rules only — YAML rewriting is off (see warning below)
6 QuickAdd One-keystroke creation per note type Six commands: SRC ·, PERM ·, PRAC ·, CARD ·, LOG ·, WEEK · — each enforces the §3 filename pattern
7 Calendar Visual daily/weekly logs Daily → 05_Progress/DailyLogs/, weekly → 05_Progress/WeeklyReviews/
8 Style Settings Live theme tuning Exposes the whole GRIND palette in the UI

Warning

The Linter's YAML rules (yaml-key-sort, force-yaml-escape, insert-yaml-attributes) are deliberately disabled. They would rewrite wikilink-valued keys like source: [[SRC-…]] and parent: [[PERM-…]] into quoted strings and break card–parent integrity (validation rule 5). Leave them off.

Core plugins are trimmed to match the aesthetic: graph view, canvas, web viewer, and slides are off. Re-enable any of them in Settings → Core plugins if you want them.

Theme

Minimal (kepano) in dark mode, plus hardcore.css — a full snippet, not the six-line stub:

  • Pure black #0d0d0d, sharp red #ff3333, JetBrains Mono throughout
  • Mastery colour ladder — red at 0.0 climbing to green at 5.0, readable at a glance
  • Collapsed solution callouts are forced genuinely opaque and labelled "collapsed. Attempt first." — the peek-guard from rule 12 becomes visual, not just structural
  • 00_Inbox is styled loud (it must be empty by end of day); _Mastered/, 99_Archive/, and generated artifacts are dimmed or italicised so the active surface stays obvious
  • Every colour and toggle is exposed through Style SettingsGRIND Hardcore

The Flashcard Trainer ships with a matching palette, so both surfaces look like one system.


Anti-patterns

Strictly forbidden. Each one silently corrupts the signal the vault exists to produce:

  • Storing mastery on anything other than a Permanent note
  • Deriving mastery from focus_score or any subjective signal
  • Claude self-verifying its drafts, or an unverified note exceeding 2.9
  • Moving mastery without a matching Review History / Retry Log line
  • Inferring correct/incorrect from the solved date instead of the explicit outcome
  • Hand-editing PLAN-*, MAP-*, or MISSED-Queue.md instead of regenerating them
  • Deleting instead of moving to 99_Archive/
  • Editing Source content, or 06_Templates/ files without confirmation
  • Permanent notes containing more than one atomic idea
  • Free-form filenames, missing -NN, or domains not in _Domains.md
  • Leaving files in 00_Inbox past end of day
  • Personal thoughts, journals, to-dos, or life admin — anywhere
  • Skipping the Daily Log or Weekly Review

This vault is a training facility.

Every action is deliberate. Every file has a job. Execute the system exactly and it will compound your knowledge.

Full specification: GRIND-Obsidian-Vault-Specification-v2_4.md · Operating rules: CLAUDE.md

About

GRIND — a spaced-repetition study system built on Obsidian. Evidence-weighted mastery scoring, a deterministic validator, generated flashcards and study plans, and eight pre-configured plugins so a fresh clone runs as-is.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages