A complete guide: install it, run it, understand what it made, keep it honest, and share it.
If you read one section, read The daily loop. That is the whole thing in practice.
granth is two files. SKILL.md is the skill — it carries the procedure and every file it
emits, verbatim. HOW-TO-USE.md is this guide. There is nothing else to install.
- What granth actually does
- Install
- Your first run
- What you get
- The daily loop
- The other verbs
- The rules, and why each one is there
- Customising it
- Troubleshooting
- Sharing your curriculum
- FAQ
You say:
/granth initiate Rust systems programming
You get a repository set up to teach you Rust systems programming over a fixed number of days, in a shape that makes it hard to fool yourself.
Not a folder of notes. A repository with:
- a master plan that assigns every concept to exactly one day, so gaps are visible;
- append-only ledgers that record what happened, including what went wrong;
- ADRs for structural decisions, so "why is it like this?" has an answer in six months;
- a depth contract that says what "covered properly" means;
granth.py— one dependency-free file that checks the contract and refuses to let a half-finished day look finished;- a
CLAUDE.mdand a project-specific day skill, so the next session already knows the rules.
A study plan is a list. Nothing in a list can go wrong, which means nothing in it can be checked.
granth's output can go wrong, loudly:
| The failure | What catches it |
|---|---|
| A day covered thinly | depth — missing sections, no failure part, unexplained code |
| A concept quietly skipped | index — the traceability table shows it open |
| A day written out of order | brief N — exits non-zero and names the day that is next |
| An invented version or citation | No ledger row, and depth fails on it |
| "This should take about 2 hours" creeping in | depth — no clocks, anywhere |
| A half-finished day committed | done N — refuses on an unticked checklist |
Anyone teaching themselves something substantial and wanting a record they can defend afterwards: a language, a framework, a field, a protocol, a discipline with no code in it at all. Also useful for teams writing internal onboarding curricula, where the ledgers matter more than usual because several people write days.
granth is a Claude Code skill: a folder with a SKILL.md at its root.
For every project on your machine
git clone https://github.com/<you>/granth ~/.claude/skills/granthFor one project only
git clone https://github.com/<you>/granth .claude/skills/granthFrom a local copy — it really is just two files:
mkdir -p ~/.claude/skills/granth
cp SKILL.md HOW-TO-USE.md ~/.claude/skills/granth/Then start Claude Code and check:
/granth
If the skill does not appear, confirm ~/.claude/skills/granth/SKILL.md exists and that its
frontmatter is intact — the name: field must be granth.
- Claude Code (or any harness that loads Claude Code skills).
- Python 3.11 or newer, for the toolchain in the repositories it makes.
tomllibis stdlib from 3.11, and that is the only reason for the floor.python3 --versionto check. - git, if you want
done Nto commit for you.
No other dependencies, ever. The toolchain is stdlib-only on purpose: a repository that teaches you something should not need a package install before it can check itself.
/granth initiate Kubernetes in production
What happens, in order:
- Preflight. It checks whether the directory is empty, is a git repository, or already holds a curriculum. It will not scaffold over existing work — if it finds a plan, it stops and asks.
- Research. It looks up the shape of the field so the interview offers proposals instead of open questions.
- The interview. Up to two rounds, up to four questions each:
- How many days? Short (20–30), standard (60–100), or deep (150+).
- What gets built? The one artifact everything is tested against.
- What are the constraints? Budget, tools, platform, anything that must stay free or offline.
- Is there code that lints and tests, or is this reading and writing only?
- The design. Tracks and IDs, phases and gates, and the complete day map — every day, one row. It shows you this before writing anything. Correct it here. Changing a day map after twenty days exist means renaming twenty folders.
- Writing. The tree in §4 below.
- Verification. It runs
doctor,indexandstatus, proves the order guard works, and fixes anything red before showing you.
Then:
python granth.py brief 0 # or 1, whichever your plan starts at
/day-<slug> 0 # the project's own day skill writes day 0Scope. Pick by concept count, not by ambition. If your topic has roughly 120 things worth knowing and you want 1–3 per day, that is 40–90 days. A 200-day plan for a 60-concept topic produces padding, and padding is what kills these projects.
The artifact. Be concrete. "A web app" is not an artifact; "a link shortener with auth, rate limiting and a metrics endpoint" is. The artifact is what makes "is this concept load-bearing?" a mechanical question rather than an opinion.
Constraints. Say the real ones. "Free tiers only", "must run offline", "Windows, no admin rights", "two hours a week" — that last one shapes scope, not the documents, because no document carries a clock.
your-repo/
├── CLAUDE.md the operating rules — every session reads this first
├── README.md
├── granth.toml identity, paths, and the contract's knobs
├── granth.py THE WHOLE TOOLCHAIN — one file, stdlib only
├── .gitignore secrets excluded before the first secret exists
├── docs/
│ ├── 00_MASTER_PLAN.md THE CONTRACT — vision, principles, tracks, phases, day map,
│ │ the depth contract (§11) and the style guide (§12)
│ ├── PROGRESS.md append-only · one row per completed day
│ ├── PINS.md append-only · every version and limit, with the date observed
│ ├── SOURCES.md append-only · every citation, with the date the record was checked
│ ├── GLOSSARY.md append-only · every term, defined once
│ ├── PROVENANCE.md append-only · every dependency, audited before it runs
│ ├── CHANGELOG_PLAN.md append-only · every amendment to the plan
│ ├── adr/ one file per structural decision, never rewritten
│ ├── TRACEABILITY.md GENERATED · every ID and whether it is closed
│ ├── CURRICULUM_INDEX.md GENERATED · where do I learn XX-14?
│ ├── TRACKER.md GENERATED · what is written, how thick, what is pending
│ └── WIKI.md + wiki/ GENERATED · one row per day, one page per day, entity index
├── days/
│ ├── README.md
│ └── _TEMPLATES/ blank hub, checklist, part and source documents
└── .claude/
├── settings.json
└── skills/day-<slug>/ the project's own day-writing skill
Never edit the five generated files by hand. The next index overwrites them. If a generated
index disagrees with a day, the day is right and the index is stale.
days/day-07-tools-by-hand/
├── LESSON.md the hub — orients and assembles; it never teaches
├── CHECKLIST.md the definition of done
├── parts/
│ ├── 01-what-a-tool-is/
│ │ ├── 1.1-the-shape-of-a-call.md
│ │ └── 1.2-when-the-schema-lies.md
│ └── 02-the-result-turn/
│ └── 2.1-handing-the-answer-back.md
├── sources/ one document per primary source, read AFTER the parts
└── lab/ your own work — gitignored
Every part carries eleven sections in a fixed order: the one-line answer, the story, the idea in plain language, why this project needs it, the source behind it, the mechanism, line by line, the source in one demo, when it breaks, in production, check yourself. The three in italics are conditional.
Five commands. This is the whole practice.
python granth.py brief 7 # 1. what day 7 must cover — and whether day 7 is allowed yet
/day-<slug> 7 # 2. write it
python granth.py depth 7 # 3. check it against the contract
# 4. do the work: the build brief, the reps, the check that goes red
python granth.py done 7 # 5. finish: refuses unless ticked and the row is pastedPrints the assignment, the phase gate, any ID left open by an earlier day, the sources already taught, and the order guard.
If it exits non-zero, stop. It means day 7 is not next. That is not a warning: the plan's ordering is the curriculum, and a day written early is a day whose prerequisites were never taught. Skipping or reordering needs an ADR, and the ADR is the point — it makes you notice the cost before paying it.
The project's own skill writes the day: the hub, the parts, any source documents, the checklist.
It will not solve the TODO(me) exercises. Those are yours; that is the difference between a
curriculum and a tutorial.
Read the planned part list it prints before it writes. If it looks thin, say so then — that conversation costs one message now and twenty documents later.
Never argue with a depth failure. Every rule it checks exists because its absence produced a document nobody could learn from. It checks:
- the folder shape and the numbering, with no gaps;
- every required section, in the contract's order;
- a walkthrough after every code block that carries logic;
- a declared level, and a day that climbs;
- citations that are well formed and in the ledger, and no source taught twice;
- a part declaring
failure: true— the deliberate failure every day owes you; - no clock, anywhere;
- a hub that assembles rather than teaches;
- the hub's IDs matching the plan exactly.
Read the parts in order. Run each Check yourself. Do the build brief. Break the thing on
purpose and watch the check go red, then fix it. A check nobody has seen fail has verified
nothing.
Refuses unless the checklist is fully ticked and the PROGRESS.md row is pasted. Then it
regenerates the indexes, runs the whole gate, and commits.
The refusal is a feature. It is the only thing standing between you and a repository full of days that look finished.
| Command | What it does |
|---|---|
status |
days complete, days written, what is next |
brief N |
the assignment, the gate, open IDs, sources taught, the order guard |
start N |
the hub path and every document in reading order |
parts N |
list the subtopic documents |
new N [slug] |
scaffold an empty day folder from days/_TEMPLATES/ |
depth [N] |
the depth contract, for one day or all written days |
depth --list |
print the contract as configured |
index [--check] |
regenerate the derived documents, or fail if stale |
check |
lint + format + tests + depth + index freshness |
done N |
refuse, then check, regenerate and commit |
doctor |
config, plan markers, ledgers, duplicate IDs |
Writes the next day. Identical to /day-<slug> N inside a granth repository; use whichever you
remember. It reads the project's own skill so the standard stays project-specific.
Records a structural decision. Use it when someone six months from now would ask "why on earth is
it like this?" Not for a version bump (that is PINS.md) or a wording change (that is
CHANGELOG_PLAN.md).
An ADR is never rewritten. A decision that turns out wrong is superseded by a later ADR, and the original stays exactly as it was. That single rule is the whole value: an ADR set you can edit always looks like it was right from the start.
Reality moved — a renamed API, a superseded specification, a tool that no longer exists.
The order is fixed and it matters: verify what actually moved → state the cost → ADR if structural → edit the plan and bump its version → append the changelog entry → only then touch days or work.
Amending after the fact leaves no trace that the world changed, and six days later someone hits the same wall and works around it differently.
For any curriculum repository, granth-made or not. Runs the mechanical checks, then reads for what
a script cannot see: whether the stories are scenes a reader has actually lived, whether In production sections are real, whether error text is pasted or reconstructed, whether each day
climbs. Reports; changes nothing unless you ask.
Wiring only: config present, plan markers intact, ledgers there, no ID assigned to two days. Run it when a tool behaves strangely, before blaming a day.
Every rule exists because its absence produced something unusable. The three that carry the most weight:
No duration, no "estimated hours", no "this should take about", no pace — in any document, in any field.
A duration field looks harmless. What it actually does is silently authorise the worst edit in technical writing: cutting an explanation because the day is running long. Remove the field and that edit has no justification left, and the day gets another part instead.
A topic is finished when it is understood, in one sitting or in five.
Versions, interfaces and citations are looked up live on the day they are used, with a dated
ledger row. A lookup that fails leaves a TODO containing the exact command — never a guess.
Citations are the strictest case, because they fail the most quietly. A wrong version pin breaks the next install. A plausible identifier attached to the wrong title survives for years, gets copied into other people's notes, and is never caught. Cite by title and identifier, never by author.
Every part opens where someone who has never met the idea can stand and ends where a professional stands: what breaks at scale, what a senior reviewer says, what an interviewer probes.
In production is the section that gets dropped, and dropping it halves the document. A part that
shows the idea working on one small case and never says what happens at ten thousand has taught
half the subject.
- The story carries no jargon and must be a scene you could have been standing in. If the reader must first be told what the setting is, the analogy is carrying the explanation instead of hooking it. One metaphor family per day.
- Every code block gets a walkthrough. An unexplained line is a bug in the document: the reader can copy it but cannot change it.
When it breakscarries real, pasted error text. If you have not seen the error, cause it.- Every day has one deliberate failure.
- A source is taught once in the whole curriculum; every later day cites and links it.
- Sources are read after the parts. Build the mechanism by hand, then read the proposal.
- No person names or brand names in any generated document. Tool names are required and fine.
[contract]
require_sources = false # a subject with no citable primary sources at all
require_failure_part = false # almost never right; think hard first
[toolchain]
lint = "" # empty means: skip that step in `check`
test = ""python granth.py depth --list prints the contract as configured — the fastest way to confirm a
change landed.
Keep the slot, change the pattern:
[contract.section_patterns]
"why this project needs it" = "why .{0,40}(needs?|matters to) it"Tracks, phases and the day map live in the plan, between <!-- granth:...:start --> markers —
never in granth.toml. That is deliberate: a person reading the plan and a script parsing it
cannot then disagree.
To add a day: amend the plan, add the row inside the markers, write the changelog entry, and write
an ADR if the numbering shifts. doctor will tell you if an ID ends up on two days.
Set lint, format_check and test to "". check then runs the depth contract and the index
freshness, which is exactly right. Everything else is unchanged — music theory and Rust get the
same contract, because the contract is about explanation, not about code.
| Symptom | Cause and fix |
|---|---|
/granth does nothing |
The skill is not where Claude Code looks. Check ~/.claude/skills/granth/SKILL.md. |
granth: needs Python 3.11 or newer |
tomllib is stdlib from 3.11. Upgrade, or run a newer interpreter explicitly. |
the plan carries no <!-- granth:day-map:start --> block |
The markers were deleted or renamed. Put them back around the day tables. |
brief 12 exits non-zero and you disagree |
It is doing its job. Days 1–11 are not in the ledger. If the reordering is deliberate, write the ADR. |
index --check fails right after index |
Something rewrote a generated file — usually an editor plugin or a formatter. |
plan_version 'v2.0.0' but granth.toml says 'v1.0.0' |
The plan was bumped without updating written hubs. Update them, or revert the bump: a wording fix is not a version. |
A day passes depth but reads badly |
Working as designed. The checker is a floor, not a standard. Run /granth audit. |
done N refuses and you are sure it is finished |
Read the refusal. It is one of: an unticked box, or a missing PROGRESS.md row. |
Day titles print as ? or � |
An old Python on a legacy Windows code page. granth.py sets UTF-8 itself on 3.7+; if you see this you are below the floor. |
The repository is standalone. Anyone who clones it gets the plan, the ledgers, granth.py and the
project's own day skill — granth itself is not needed to read it, write days in it, or check it.
Before publishing:
python granth.py check # everything green
git ls-files | grep -i env # only .env.example should appear
grep -rn "{{" --include="*.md" . # no unsubstituted placeholdersThen check by hand: no real secret in .env.example, and no person or brand names anywhere — the
contract forbids them, and a public repository is where that gets noticed.
docs/PROGRESS.md is the honest part of the repository. Leave the bad days in it, with the notes
saying what went wrong. A ledger with no failures in it is a ledger nobody has been honest in, and
readers can tell.
Why is SKILL.md so large?
Because it carries every file it emits — including granth.py — verbatim, so that granth is two
files and a generated repository is never missing a piece. The cost is that the skill loads a lot
of context when invoked, and each initiate reproduces the toolchain once. If that ever becomes a
problem, Part 2 of SKILL.md can be split back out into a templates/ directory without changing
anything else.
Do I have to use all eleven sections? Yes, and three are conditional, so most parts carry nine. If a section feels like padding, that is usually a signal the part is two parts — the one-idea test catches it.
Can I use it for something with no code?
Yes. Set the toolchain commands to "". The contract is about explanation, not code.
What if I miss a day?
Nothing happens. There are no clocks and no streaks. brief N still says what is next.
Can I change the day count later? Yes, with an ADR. Adding days to the end is cheap. Inserting one in the middle renumbers everything after it, which is exactly why it needs a written decision.
Does it need an internet connection? The toolchain does not. Writing days does, because facts are verified live.
Can two people write days in the same repository?
Yes, and this is where the ledgers earn their keep. One rule: the PROGRESS.md row is appended by
whoever finishes the day, and done N will not commit without it.
Why "granth"? ग्रंथ — a treatise: a work that carries a whole subject, in order, and can be handed to someone else. That is the artifact this skill is trying to produce.
Can I apply the contract to a repository I already started?
Yes. Run /granth audit first to see where it stands, then ask it to adopt the existing plan — it
keeps your content and adds the markers, the ledgers and the toolchain rather than overwriting
anything.