The atom format
Everything in strands/ is plain markdown. Git is the source of truth; the CLI is one consumer of it. If the tool ever dies, the material is still readable and greppable.
A file
---
strand: countries
group: Europe / Nordic
tags: europe, nordic
---
Free prose before the first `###` is commentary and is ignored by the parser.
Use it to explain why a file is grouped the way it is.
### dk.capital
kind: capital
subject: Denmark
answer: Copenhagen
peg: A COPPER HEN roosting on a Danish pastry — copper-hen, Copenhagen.
peg_source: suggested
- Frontmatter between
---lines gives defaults inherited by every atom in the file. An atom may override any of them. - An atom starts at
### <id>. Ids are globally unique;lintenforces it. - Inside an atom,
key: value. A line that is neither blank nor a new key continues the previous value, so long answers can wrap. - A blank line ends a continuation.
Referring to another peg
An image built on a number peg writes {{89}}, not the word. The peg table fills it in when the corpus is loaded.
peg: Four o'clock. 89 = f-p = {{89}}. A {{89:lower}} cloud hanging across
the Bastille gate — the crowd walks straight through it.
{{89}} gives the word as stored (VAPE) and {{89:lower}} gives it lower case, because most images read "a vape cloud" rather than "a VAPE cloud".
This is not decoration. Before it, every image that used a peg carried its own copy of that peg's word — a second source of truth, and it drifted: eight pegs were quoting words the table had not said for months, and nothing noticed. lint now rejects a peg that writes a table word out in full.
What a reference cannot do is rewrite the prose around it. Change 89 from VAPE to FOB and "a fob cloud" is grammatical nonsense — but it is visible nonsense, and akasha peg prints every peg that builds on the one you changed so you know which images to look at.
Keys
| key | meaning |
|---|---|
kind | one of the keys in TEMPLATES — see the table below |
subject | what the atom is about — supplies {subject} to templates, and is the default answer for reverse cards |
answer | required |
ask | overrides the kind's question template; required for fact, contrast and causal |
reverse | overrides the reverse template; reverse: none suppresses the reverse card |
reverse_answer | overrides subject as the reverse card's answer |
peg | the mnemonic image; {{89}} references the peg table |
peg_source | suggested (written for you), own (yours), none (no image) |
span | a period, for era atoms — generates its own ~s card |
cue | a one-line description that identifies the subject without naming it — generates a ~c recognition card |
date_ask / span_ask | override the generated date / span question |
tags | comma-separated |
note | shown during review, never tested |
source | provenance, if worth recording |
Atoms versus cards
An atom is a fact. A card is a directional recall test, and scheduling state is keyed per card, because knowing "capital of Denmark → Copenhagen" does not mean you know "Copenhagen → which country". Those decay separately and so they are scheduled separately.
cards_for() expands one atom into up to five cards, one per direction:
| suffix | direction | generated when |
|---|---|---|
| (none) | forward | always |
~r | reverse | the kind has a reverse template, unless reverse: none |
~d | date | the atom has a date |
~s | span | the atom has a span |
~c | cue | the atom has a cue |
So dk.capital and dk.capital~r for a country, and E01, E01~r, E01~s and E01~c for an era. Each card tests exactly one thing. A compound question — the era card used to ask for the name, the span and the organising condition at once — cannot be caught decaying in one part, and in that case did not even answer one of the three.
Question templates
The files hold facts; the wording of questions lives in one place, TEMPLATES in akasha/parse.py:
| kind | forward | reverse |
|---|---|---|
capital | What is the capital of {subject}? | {answer} is the capital of which country? |
flag | Describe the flag of {subject}. | Which country flies this flag: {answer} |
location | Where is {subject}? Region, neighbours, coastline. | — |
population / area | Roughly what is the … of {subject}? | — |
era | Era {era}: what is it called, and what holds it together as one era? | Which era is {subject}? Give its number. |
event | {subject} — which era and slot, and what does it change? | Era {era}, slot {slot} — what sits there? |
deep | {subject} — how long ago, and what did it make possible? | — |
invention | {subject} — what did it make possible, and which era? | — |
person | {subject} — what did they change, and when? | Who is this: {answer} |
major | Major System: what is the peg for {subject}? | Major System: which number is {answer}? |
fact / contrast / causal / tour / ring | explicit ask: required | — |
Rewording every capital question is therefore a one-line change, not a 147-file sweep.
Adding a kind
Add an entry to TEMPLATES. Use (None, None) if the kind always needs an explicit ask:. lint will then accept it.
Ids
Convention, not enforcement:
- countries:
<iso2>.<facet>—fr.capital,fr.flag,fr.loc - contrast sets: a descriptive slug —
nordic.crosses,slavic.tricolours - causal chains:
<chain>.<NN>.<slug>—rome.04.diocletian-split, so the chain sorts into its causal order
Ids are the scheduling key. Renaming an id orphans its review history — akasha prune will show you the orphan; there is deliberately no rename command, because silently moving a decade of review history is worse than making you think about it.