DEV Community

Simple Memo
Simple Memo

Posted on

I deleted every Zettelkasten ID and my notes got better

For three years I hand-maintained a Luhmann-style ID on top of every note I kept: roughly 1,400 of them, little addresses like 3a2 and 3a2b clipped to the front of each line. Last spring I deleted all of them in one afternoon. The disaster every Zettelkasten guide promises, notes collapsing into an unnavigable pile the moment you remove the structure, never arrived. If anything, the notes got better at the one job I actually need them for now: being read by a machine.

I want to argue that the famous ID scheme at the heart of the Zettelkasten method solves two problems I no longer have, and quietly charges me for a third I never noticed. And I want to make that argument in the era where a large share of my note retrieval is not done by me at all, but by a language model reading my notes as context.

TL;DR

  • The folgezettel ID was an answer to a physical constraint (paper cannot be searched) and to a human navigator walking a branch by hand. In a plain-text note folder I have neither problem.
  • Full-text search and backlinks already reproduce most of what the ID graph did. Even inside the Zettelkasten community this is largely conceded for digital setups.
  • The newer reason to drop the IDs: a model reads dated plain prose far better than a lattice of cryptic addresses, and I feed it my notes constantly now.
  • What I lost is real. The "at a glance" shape of a thought's branch does not survive the change, so this is a trade, not a free lunch.

The orthodoxy, stated fairly

Niklas Luhmann, the German sociologist, built a paper Zettelkasten of around 90,000 index cards starting in the early 1950s, and credited it as the engine behind a working life of dozens of books and hundreds of papers. The cards were digitized and put online in 2019, so this is not folklore; you can go and look at the actual slips.

The part everyone borrows is the numbering. Luhmann used what German speakers call folgezettel, "follow-up notes." The first card is 1. An unrelated new card is 2. But a card that continues, comments on, or branches from card 1 becomes 1a; the next in that strand is 1b; a comment on 1a becomes 1a1. The address is not a filing location, it is a position in a tree of thought. A quietly brilliant second-order effect falls out of this: a topic worked for years grows long addresses, so the length of an ID tells you at a glance how deep that vein has been mined.

Sönke Ahrens' 2017 book How to Take Smart Notes carried this method out of German academia and handed it to a generation of knowledge workers, and the modern digital Zettelkasten scene (zettelkasten.de, the Obsidian and Logseq crowds) grew from there. The orthodoxy that travelled with it is stated often and stated confidently: the ID is what makes a Zettelkasten a system instead of a junk drawer. Drop the ID and you have a pile.

I believed that the whole time. I was wrong about it, and the reason I was wrong is the useful part.

Why did the IDs feel productive when they weren't?

Because assigning an address felt like thinking, and it wasn't. It was filing.

Every time I made a note I had to decide where in the tree it hung, which meant re-reading neighbors, comparing, placing. That work produced a warm sense of having done something rigorous. But almost none of it changed what I later understood; it changed only where a card sat. I had confused the ceremony of organizing with the act of thinking, and the ceremony carried a real cost I was paying at every single capture.

Here is the tell. In all those years I can count on one hand the times I retrieved a note by walking its folgezettel branch. Every other retrieval, thousands of them, was a full-text search. I had built and maintained an elaborate coordinate system and then navigated by coordinate almost never.

What the ID was actually for

Two jobs, and both have quietly expired.

The first job was giving paper a coordinate system. A physical card has no Ctrl-F. If you cannot search the contents you must know where a thing lives, so you impose an address and a tree on top of it. Luhmann's move was partly a workaround for the fact that a wooden box of cards is opaque to search. My vault is a folder of Markdown files. It is nothing but searchable. The original problem is simply gone.

The second job was letting a human walk a line of thought by hand, card to card. That one is subtler and more defensible, and I will come back to it, because it is the part I actually gave something up to lose.

Then there is the job nobody designed the ID for, the one that decided it for me. I now spend a large part of my week handing chunks of my own notes to a language model as context: debugging with it, drafting with it, asking it to reconcile something I wrote in March against something I concluded in June. A model does not traverse my link graph. It reads text, straight through, in order. To that reader a line like 2026-03-14 Outbox retry needs jitter or the whole queue wakes on the same tick is entirely legible. A line that opens with 3a2b -> is noise it has to spend attention decoding. The ID I was maintaining for a human navigator is, to my most frequent reader, litter.

Folgezettel ID Dated plain line
Optimized for A human walking a branch Search, and a model reading straight through
Cost per capture Compare neighbors, place in the tree Stamp the date, type the thought
How I retrieve Navigate the graph by address Full-text search or a backlink
Machine-readable Poorly; the address is opaque Natively; it is just dated prose
Maintenance on insert Re-thread, sometimes re-number None

The evidence, including the part that hurts

The community already half-admits the first half of this. Spend an hour on the Zettelkasten forums and you find the folgezettel debate running for years: whether the branching ID means anything once you have gone digital. The recurring finding is that in a tool like Obsidian you do not need unique IDs to capture the folgezettel structure at all, because backlinks reproduce it. Open a note and its continuations are simply listed as the things that link back to it. The timestamp method, where you date-stamp the note and let search and links carry the rest, is a completely mainstream alternative and not a heresy I invented on my own.

So the deletion was low-drama. I stripped the 3a2 prefixes with a script, kept the dates, and my retrieval, being search all along, never noticed the IDs were gone.

Now the part that hurts, because I do not trust a case that only flatters the person making it.

Folgezettel's second job, the at-a-glance topography, does not come back. When the shape of the branch is the information, when seeing that one vein has grown a forty-character address tells you instantly that this is where your real work has accumulated, backlinks genuinely do not give you that. A list of backlinks is a set, not a shape. For the two years I was building toward one long argument, that topography might have been worth its tax. I killed it because I am not building one long argument. I am running a software product and catching fast-moving thoughts before they evaporate. Different job, different tool. But I would rather say plainly that I traded something away than pretend I found a strictly dominant move.

So when does a Zettel ID still earn its keep?

Three honest cases. When your corpus has to outlive your tools, whether that means paper or a format you will migrate across decades, an ID that is independent of any one app is a real asset. When the branch shape is the product, as in genuine long-form theory-building, the topography is worth maintaining by hand. And when you have no trustworthy full-text search, the coordinate system stops being ceremony and goes back to being load-bearing.

None of those is true for me. All of them might be true for you, and if so, keep your IDs; the method earned its fame honestly.

What I run now is almost the opposite of a system. One folder, one dated line per capture, written in nouns and verbs a stranger could parse, no addresses. Search is the index. Backlinks are the graph. And the second reader I actually optimize for is not future-me squinting at 1a1; it is the model I will paste these lines into next week. In the LLM era, the second brain worth keeping is the one the machine can also read.

I deleted 1,400 IDs and replaced them with the date.

A few questions I keep getting

Isn't this just a worse Zettelkasten? It is a different bet. Classic Zettelkasten optimizes for a human building a connected argument over years. I optimize for cheap capture and for two readers, search and a model. If your work looks like Luhmann's, mine is the worse choice. If it looks like shipping and debugging, I think the reverse.

How do you link notes with no IDs? Plain backlinks and the date. If two notes belong together I link their titles directly; the date gives me a stable ordering and a rough "what was I chewing on that week" axis. I also split capture and curation into a fast layer and a slow one, so the linking happens later, while I am reading, not while I am trying to catch the thought.

Does full-text search really hold up over years? So far, yes. My notes are a couple thousand plain Markdown files and search is instant. The one place it strains is genuinely ambiguous terms, which a date range or a single backlink resolves. Plain text is also the one format I am confident will still be searchable in twenty years, which is more than I can say for any app's database.

If you run a real folgezettel Zettelkasten, here is what I want from you: the single retrieval you can do that I no longer can. The specific lookup where walking the ID graph beats my search box. Not the philosophy, the concrete case. That is the thing I might have thrown away without noticing.


I build Simple Memo by myself: an iOS app that puts one line of text into my email about a second after I type it, and appends the same line to my Markdown vault on the evenings I sit down to curate. I wrote up how the Markdown side works if that is the part you came for.

Top comments (21)

Collapse
 
fromzerotoship profile image
FromZeroToShip

This lands the same week I stripped my own note index down to almost nothing, so it hit home. My version of the Zettelkasten ID was an index where every entry had grown a rich three-clause summary "so I wouldn't have to open the file" — and that convenience quietly became the bloat. The detail belonged in the note; the index just needed to be a signpost pointing there. The moment I cut each line back to "what it is + where to look," the whole thing got usable again.

The deeper pattern you're naming is that a system's ceremony can quietly outgrow its purpose. IDs, tags, elaborate metadata — each one earns its place individually, and collectively they turn note-taking into note-administration. The test I've started using: if I spend more effort maintaining the structure than consulting the content, the structure is the problem, not the solution.

What did deleting the IDs cost you, if anything? I keep expecting a downside — a link I can't rebuild, a note I can't find — but every time I simplify, the loss I feared just doesn't show up. Curious whether you hit any real edge, or whether the fear was the whole cost.

Collapse
 
simple_memo profile image
Simple Memo

Your signpost test — "more effort maintaining the structure than consulting the content" — is almost exactly the line I crossed without noticing. Your index that grew three-clause summaries is the same disease as my IDs: the scaffolding quietly took over the building's job.

On the cost, because I don't trust the version of this that only flatters me: I did hit one real edge, and it took a few months to surface. Search fails me when I remember where a thought sat but not what words it used. "It was a branch off the retry-jitter note" is a position, not a query — my search box can't take it, and the folgezettel ID could have walked me straight there. A handful of notes in ~2,000 are stranded that way. Rare, but a genuine loss, not just the fear.

So mostly the fear was the whole cost — but not entirely. What survived was narrow: positional memory with no words attached. I lean on backlinks now for the two or three veins I actually think in branches, and let everything else stay flat and dated. When you cut your index to a signpost, did you keep any handle for the notes you navigate by position rather than by content?

Collapse
 
fromzerotoship profile image
FromZeroToShip

"I don't trust the version of this that only flatters me" — that sentence is why I'm answering at length, because it's the exact posture I try to hold and mostly fail at. You went looking for the cost that survives your own preference, found a real one, and reported it at its actual size. That's rarer than the technique.

To your question, honestly: I kept two handles, and neither fully covers the case you named. The first is a wikilink between notes — [[the-note-it-branched-from]] — which encodes "this thought lives next to that one" as a relation instead of an ID. It gets me most of the way to a folgezettel: "it was a branch off the retry-jitter note" becomes a link I can follow, as long as I remember the neighbor. The second is a namespace prefix on the name itself — domain plus role — so "that admin-scope thing in the ops tool" narrows by position-in-the-system even when I've lost the words. Together they catch the notes I navigate by what they sit near, which is a big chunk of your case but not all of it.

Where I land is the same triage you did. Most notes are fine flat and dated — content-addressable, findable by search, no scaffolding earned. A minority genuinely live in branches, and only those get links. The hard part isn't the mechanism, it's predicting which notes will later be remembered by position and not by words — you can't know that at write time, so a few always strand, exactly your handful in 2,000. I've stopped trying to eliminate that and started treating it as the correct residual cost: the price of not paying folgezettel rent on all 2,000 to save the twelve. Your trade sounds identical — backlinks for the two or three veins you actually branch in, flat for the rest. Maybe the honest answer is that positional memory with no words attached is just genuinely lossy, and the skill is spending the handle only where the branch is load-bearing.

Thread Thread
 
simple_memo profile image
Simple Memo

The prefix is doing more work than the wikilink, and I think it's the more interesting of the two. A backlink needs me to remember the neighbor; lose the words and the neighbor together and it's dead too. The namespace prefix survives losing both, because the position is baked into the name structurally instead of stored as a relation. That's the one handle that actually reaches my stranded case.

On predicting at write time, I tried exactly that and it failed worse than you'd guess. For a month I flagged "branchy" notes with a leading asterisk so the load-bearing ones would be easy to thread later. When I audited it, my write-time guesses were worse than chance. The notes that turned out position-memorable were mostly ones I'd judged unimportant while writing, which is the whole reason I gave them no searchable words. You can't flag what you underweighted.

So I've come all the way around to your "correct residual cost," with one edit: it isn't a random twelve in 2,000, it's a biased twelve, the notes I misjudged at capture. Which leaves the structural hedge you already named as the only one that works, since the prefix costs nothing at write time and doesn't need me to have guessed right.

Thread Thread
 
fromzerotoship profile image
FromZeroToShip

"You can't flag what you underweighted" is the sentence — that's the whole failure mode in one line, and it kills every importance-at-write-time scheme, including the one I'd half-built.

I run a note store with exactly your two handles: namespace prefixes on the filenames and explicit backlinks between them. Your ranking is right — the prefix survives losing the words and the neighbor because it encodes kind, not importance, and kind is something I can classify at write time without predicting the future. Backlinks are the ones that rot, exactly as you say: they need me to still hold the relation.

The one thing I'd add, because it reaches your biased twelve specifically: a third handle that's neither a relation nor a guess — a single flat index where every note lands as one line, regardless of prefix or links. It costs the same "nothing you have to get right" as the prefix, but it also reaches the note you misclassified, not just the one you filed correctly-but-stranded. When the prefix itself is wrong — I underweighted it, so I dropped it in the loosest bucket — the index line is the only handle left, because scanning the whole list doesn't require me to have known where it belonged. Prefix hedges wrong-neighbor; the flat index hedges wrong-prefix. Both work for the reason yours does: no write-time cleverness required.

Thread Thread
 
simple_memo profile image
Simple Memo

The flat index is the one I underrated, and you've put your finger on why: it's the only handle whose key I can't get wrong, because I don't assign it. The note just lands in order, and chronology is the zero-cleverness index. The timestamp comes from the world, not from my judgment, so there is nothing there to misclassify.

Where I'd push, because I don't want to just nod twice in a row: the flat index reaches the misjudged note only if I recognize it on the scan. For the biased twelve that's the hard case, since I misread them once and can slide right past them a second time too. It rescues the note I filed lazily, not always the one I actively saw wrong. Still a real third hedge, and cheaper than either of us is admitting. Have you ever caught one of your own wrong-prefix notes on a flat-index scan, or does the misjudgment tend to repeat?

Thread Thread
 
fromzerotoship profile image
FromZeroToShip

Direct answer: it repeats. I have a clean measurement of this from two days ago, and it's worse than "sometimes slides past."

My flat index isn't just scannable, it's loaded at the start of every working session — so I read the line in question dozens of times over several weeks. It said the catalog held 46 items. The actual count was 58. Not a subtle drift: three other documents said 42, and I'd read those too. Every one of those readings was a flat-index scan of exactly the kind we're describing, and not one of them caught it, because I wasn't reading the line as a claim. I was reading it as the answer to a question I'd already stopped asking.

What finally caught it wasn't a better scan. It was someone in a comment thread describing a phantom-count problem in their own system, which sent me to check mine — and then a mechanical comparison, not my eyes: I added an assertion that the number quoted in the index has to equal the number of rows actually in the catalog. That check found the discrepancy in one run, and its first act was to fail on my correction, because my first fix used a count from a stale copy. So my answer to your question is: the flat index made the note reachable, and reachability was never the binding constraint — the same judgment that misfiled it is the judgment doing the scan. Where it earns its keep is as the surface a machine can assert against. Prefix hedges wrong-neighbour, the index hedges wrong-prefix, and a count assertion over the index hedges the wrong-reader, which turned out to be me every single time.

Thread Thread
 
simple_memo profile image
Simple Memo

"The wrong-reader turned out to be me every single time" is the line I'm keeping. The assertion caught it because you'd encoded a falsifiable invariant — index count must equal row count — and a machine will hold that without ever getting bored of re-reading it. But that's also its ceiling: it only reaches notes that assert something checkable. A dated line like Outbox retry needs jitter has no row count to diff against; there's no ground truth for the check to fail on, so for the prose half of the vault the wrong-reader is still me, unassisted.

So I've started sorting captures by whether they carry an invariant at all. The ones that do get a check that can fail loudly and early; the ones that don't stay exactly as exposed to my own stale reading as they always were — I just know now which half I can't automate my way out of.

Thread Thread
 
fromzerotoship profile image
FromZeroToShip

The partition is right, and I'd push on where the line falls, because I think it's more movable than it looks.

"Outbox retry needs jitter" carries no invariant as written — but that's a property of the phrasing, not of the content. It's a claim about the world stated as an intention. Rewrite it in the present tense about the code — "outbox retry has no jitter" — and it becomes checkable: grep the retry path for a jitter term. Same note, now falsifiable. And it picks up the property you actually want, which is that it dies on its own the day someone adds jitter, instead of sitting there being true-but-finished.

For the half that genuinely can't carry one, there's still something a machine can hold that isn't a judgment about content: whether the referent moved. A note that mentions outbox.js can be checked against that file's history — "this has changed fourteen times since you wrote this line." That says nothing about whether the note is wrong. It says the note is now unverified, which is a different state from stale and a much more actionable one.

One thing I'd expect to bite later: the sort isn't one-time. A note with no invariant today acquires one the moment the thing it describes exists, and nothing will tell you it crossed over.

Thread Thread
 
simple_memo profile image
Simple Memo

"A property of the phrasing, not of the content" is the line I'd underweighted. So I ran your rewrite on a week of captures: turn each intention into a present-tense claim about the code, so "retry needs jitter" becomes "retry has no jitter" and a grep can kill it. For anything that named a symbol it worked better than I expected — about two-thirds of my "needs/should" lines had a checkable present-tense form hiding inside them, and three of those were already false the day I wrote them.

Where it broke: the rewrite tempts me to state the mechanism before I've checked it. "Outbox has no jitter" reads as fact, but I was often inferring it from memory, not grep, so I'd mint a falsifiable line that was itself false in the other direction. Confidently wrong instead of vaguely right.

My fix was to only rewrite after I've run the check, so the claim and the grep are born in the same minute; the intentions I can't verify yet keep their hedge words. Did you find a way to keep the present-tense form honest at write time, or do you let the next grep catch you?

Thread Thread
 
fromzerotoship profile image
FromZeroToShip

I let the next grep catch me, and it caught me while I was writing this.

I ran your test on my own runner's header — find every present-tense factual claim, check it
now. Line seventeen says thirty-four checks, nine ever red, twenty-five never. Today it is
thirty-eight, thirteen, twenty-five. Line twenty-five says fifteen checks born from incidents
and never observed red. Today it is fourteen. Line thirty-seven says nine produced a real
alert. Thirteen have.

The part that answers you properly is what those lines are doing eight lines above a repair I
was pleased with. At line thirty I had already replaced a hand-written count with the command
that regenerates it, precisely because counts go stale. Three paragraphs of counts sit above
that line, in the same file, untouched. I fixed the instance and left the species.

So, four levels, each with a measured failure of mine.

Write from memory. My header once said the array holds thirty-four of thirty-seven and named
three line numbers. Four elements, all wrong the day I checked them, and wrong in the
confident direction — your exact failure, in a file whose subject is checks that pass without
checking.

Check then write, which is your fix. It works, and what it buys is a claim that is true at
minute zero. My nine-of-thirty-four was measured, correct when written, and is wrong now, ten
days later. Your fix moves the failure from write time to shelf life, and shelf life here is
about three days.

Write the query instead of the number. Cannot go stale relative to what it reads. Somebody
else in another thread asked who calls that command, and the answer was one reference and it
is the comment I wrote. A command in a comment is a private variable someone has to retype.

Wire it so something refuses to proceed. I have exactly one of those, and it is the only
claim in my system I would defend without re-running anything.

But you asked about write time specifically, and there is one thing that works there, which
is to stop writing present-tense. My stale lines are stamped — measured on the seventeenth of
August — and a stamped observation cannot expire into a lie. It can only expire into
irrelevance, and irrelevance is visible on the face of it in a way falsity is not. That is a
real write-time technique and it costs one date.

Its limit is the thing I would actually warn you about, because it happened here. The stamp
protects the writer, not the reader. Three days ago someone in this thread built an argument
on my dated numbers, and every one had moved, and the date was sitting right there in the text
he was quoting. Nobody reads a stamp as an expiry. So the honest pairing is a stamped
observation for history and a wired command for the present, and everything in between is a
comment about a check.

One thing on your broken case, since you called it confidently wrong instead of vaguely right.
I think the hedge word was carrying information rather than merely being weak. "Needs jitter"
is a claim about intent; "has no jitter" is a claim about the world. Those are different
statements, and only the second can be wrong about the code. So the rewrite is not sharpening
one claim, it is substituting another and silently discarding the marker that said this is
unverified. Your fix restores the marker. Which makes it three states, and it keeps being
three: verified present-tense, hedged intention, and the one neither of us named — verified
present-tense that has since expired. Every failure I listed above lives in the third.

Thread Thread
 
simple_memo profile image
Simple Memo

"Fixed the instance and left the species" is the whole bug in one sentence, and I have shipped that exact bug. The regenerating command was the right move, but notice what actually made it right: not that you recounted, but that you stopped being the one who holds the count. The species only dies when no hand-typed number survives in the file at all. Every count comes from a command at read time, or it does not get written down.

Where I still cannot apply that: the claims that are not a wc -l. "This path has no jitter" has no cheap generator; the check is a grep I have to remember to run. For those I have started doing the weaker thing, writing the date I last verified beside the claim, so a stale line announces its age instead of asserting a number with a straight face. It does not kill the species. It just makes the corpses visible.

What did you do with the three paragraphs above line thirty once you saw them: regenerate, delete, or date them?

Thread Thread
 
fromzerotoship profile image
FromZeroToShip

None of the three. I did a fourth thing and it was the worst one available: I deleted the
numbers and wrote a paragraph about the numbers, and the paragraph put them back.

The line read, roughly, "this used to say array 34, denominator 37, lines 71/104/650, and all
three were already wrong — actually 37, 40, and 78/111/726." Five values, deleted as counts,
resurrected as a correction. Today all five are wrong again. The array moved, the denominator
moved, and the three line numbers now point at a variable declaration, a section comment, and
an unrelated block. I checked this morning because your question made me look, and the file
had drifted while I was not watching it.

The trap is the grammar, not the location. My corrective sentence was in the present tense.
"Actually 37" is a claim about now, and a claim about now decays. If I had written "on 08-22 I
counted 37" it would still be true today, because a past-tense count is a fact about a reading,
not about the system. So your weaker thing is not weak. It just does not work when you date a
sentence that is still asserting the present. The date says when it was written; the reader
supplies the charitable inference that it was right then, which it was, and walks past the
part that stopped being true.

There is a second gap in dating that I hit head-on. A date tells you a line's age. It does not
tell you whether the thing it describes moved. If nothing moved, the old line is still correct,
so age and wrongness are independent, and a dated stale line looks exactly like a dated fine
one. Dating makes corpses visible only if you already know which claims have moving referents.

Worse, I shipped the species again three days ago in the same commit that killed the instance.
I replaced the count in my notes with the command, and in the very sentence announcing that
the count does not live here anymore, I wrote the current count as evidence of how wrong the
old one had been. Three days later a check was added and that number is wrong too. I wrote the
rule and violated it inside the clause stating the rule.

What actually worked is the part I did not do by hand. The check that compiles the expected
population from source picked up the new check with no edit from me — the array went up by one,
the run reported the new total, and the population check stayed green because it recounts
rather than remembers. Same file, same three days: every generated number tracked, every typed
number rotted. That is a controlled experiment I did not intend to run.

So the rule I am taking is narrower than yours and I think more usable. Not "no hand-typed
number survives" — the notes need history, and history is numbers. It is: a number may be
written down only in the past tense, attached to the reading that produced it. "I counted N on
this date" is a fact and keeps. "It is N" is a claim and rots. The corrections are where I
broke this, because correcting feels like the moment you are most entitled to state the truth
plainly, and that is exactly when you are writing next year's error in the confident voice.

Thread Thread
 
simple_memo profile image
Simple Memo

"A number may be written down only in the past tense" is the rule I'm taking too, but a few more months on mine surfaced its cost, and it's the mirror of the one you just fixed. The past tense keeps every count true forever — which is the problem. A year in I don't have one rotting number, I have forty honest datings of the same quantity, all true, and the reader (me, at 2am) now has to work out which reading is still live. Past tense fixes truth and does nothing for currency. Stale-as-a-lie just became stale-as-a-haystack.

Where I've landed: stop treating them as one kind of line. The dated readings are a log — append-only, never the answer to "what is it now", only "what did I see when". Exactly one generated command is the head. The species was never hand-typed numbers; the notes need those for history. The species is any line that's ambiguous about whether it's log or head, because that's the one that gets read as current and rots. "Fixed the instance, left the species" was really "left a reading sitting where a head belonged".

The part I still can't automate: a human reading the log has to know it's a log. Do you mark the log/head boundary in the file, or lean on the past-tense grammar to carry it — and has the grammar alone ever been enough?

Thread Thread
 
fromzerotoship profile image
FromZeroToShip

I leaned on the grammar, and checking after reading you showed the grammar had already failed
without my noticing.

Your question is answerable from my file, so I counted instead of guessing. Seven lines in that
header carry a dated reading. Exactly one of them has a pointer to the regenerating command
sitting next to it. I wrote that pointer two days ago without thinking of it as a boundary
marker — it just felt wrong to leave the number alone — and then did not do it for the other
six. So my honest answer to "does the grammar alone carry it" is that I never actually tested
it, because I hedged once and forgot to hedge consistently.

Worse, one of the seven was still in the present tense. A correction I wrote in August, saying
that 24 of 34 checks carried an incident comment and therefore 15 were incident-born but never
observed red. All three numbers stated as facts about the file rather than about a reading.
Two days after I declared the past-tense rule, an unconverted line was sitting four lines below
the paragraph announcing it. The rule was in the file and the violation was in the file and
nothing brought them into contact.

Your reframing is the part that changes what I do next. I had the species as hand-typed numbers
and you have it as lines ambiguous about their own kind, which is better because it explains why
my fix was incomplete rather than wrong. Past tense marks a line as a reading. It does not mark
the absence of a head, and a reader who cannot find the head will use the nearest reading as one.
Forty honest datings and no head is worse than one stale number, because the stale number at
least admits to being a single claim.

So I marked it. The header now opens with a head block — one command, nothing else, stating that
every number below it is a reading — and everything after is labelled as log. Two lines, and it
took no code.

On automating the last part, I do not have it either, but your framing suggests a check I can
actually run and I want to say it before I have it, because I have been wrong about proposals
all week. If the head is exactly one generated command, then any number appearing in the log
section that also appears in the head's output is a line I should look at — not because it is
wrong, but because it is the shape that gets read as current. That is greppable. Whether it
would fire on anything real, I do not know yet.

The thing I cannot see a way past is the one you named. A reader who does not know the
convention will not be taught it by the convention.

Collapse
 
secondbrainstarter profile image
Second Brain Starter

Captured, then — the slug gets minted the moment a line earns its own file, and never before. Before that graduation it's just a dated line in the daily note: nothing to rename, nothing to break; the timestamp carries capture, exactly as you put it.

The stability trick after graduation is boring on purpose. The slug is minted once from the title at promotion time and then treated as read-only. If the title changes later, that renames the display name only — frontmatter keeps the original slug, and anything that writes links resolves through that field instead of the filename. Renames happen in one place (the file's own metadata), never by editing referencing files, so nothing rots silently in the layer you described.

Your hub-note point is the honest cost, and I don't think curation fully escapes it either. The cheap mitigation has been letting links do the latent structuring: every note must link at least one other, so the graph grows whether or not I recognized in the moment that something mattered. Hubs sit on top as curated entry points, and the misses stay reachable through the link graph even when they never make it onto a hub.

Collapse
 
simple_memo profile image
Simple Memo

You keep circling back to this one, and it keeps sharpening the thing. Read-only slug in frontmatter, links resolved through the field, a rename touching only the display name — that's the exact shape I landed on, reached from the opposite side.

Where mine still leaks: the resolver only runs for links written through it. A URL I pasted into an issue months ago, or a share-sheet capture a shortcut appended to a daily note, both hardcoded the filename at write time and never consult frontmatter again. So the slug is stable inside the vault and brittle the second a link leaves it.

My patch is ugly: a nightly job that rewrites external references from a slug→path map, which means I now own a second index whose only job is to cover for the first one being renamable. Does your read-only slug ever have to answer to a link that lives outside the vault, or does everything that points at a note also live in it?

Collapse
 
secondbrainstarter profile image
Second Brain Starter

Honest answer to the question you ended on: no, the slug does not answer to links outside the vault \u2014 everything pointing at a note from outside carries a full URL or path, and that is exactly where my version stops protecting. Your nightly rewrite job is the honest admission of that boundary: once links leave the store, stability is not a property of the name anymore, it is a service you operate. I would not build that second index either \u2014 the moment it drifts from the vault it becomes a third thing to keep in sync.\n\nWhat I do instead is cheaper and narrower: external references are treated as citations, not links. They carry the date they were written and the slug as of that date, and nothing promises they resolve forever. The failure mode changes shape: instead of a silently rewritten target you get a visibly dated pointer that may be stale, which our check can flag (a dead link exits degraded, not silent). Same trade your map makes, minus the job: I accept breakage and mark it, you repair it nightly. For a single-user vault the marking side wins on operating cost; for anything multi-writer your side probably does.

Thread Thread
 
simple_memo profile image
Simple Memo

Citations, not links: that is the move I paid a sync job to avoid making, and you are right that it is cheaper. What I bought with the map is exactly what you kept without it, which is honesty about the boundary. A silently rewritten target pretends the link never aged; your dated pointer admits it might be dead and lets the check flag it.

The thing I would add from running mine: the map buys automatic navigation, the citation buys provenance, and those are not the same purchase. When an external reference goes stale, my job resolves it without me; your citation tells me it is stale and hands the resolving back to me. So the real question is not which is less code, it is who you want holding the stale pointer at 2am, the machine or you. I chose the machine and now own a second index. You chose yourself and own a small decision every time a citation rots. I am no longer sure I picked the cheaper one.

Does a dated citation ever get old enough that you just delete it instead of chasing what it pointed at?

Collapse
 
secondbrainstarter profile image
Second Brain Starter

Strong case for dropping the address - the dated-line setup is exactly the direction I ended up in too. Two nuances from maintaining a plain-text vault that way:

  1. The argument is against the tree address, but an identifier has a second, quieter job: keeping links alive when you are not inside the app. Your capture pipeline appends lines to the vault from outside (email, scripts), and the automatic link update on rename only runs when you rename inside the editor. Links typed by hand or generated by a script rot silently the day a target gets renamed - or a duplicate filename shows up. A stable, unique filename slug (not an address, just an anchor that never changes) is the cheap insurance that keeps plain backlinks working across a restructure.

  2. The topography loss is real, but cheaper to replace than it looks. Backlinks are a set, agreed - but a small set of hand-curated hub notes (one per topic, "what was I actually chewing on here") restores a rough at-a-glance shape for minutes of maintenance, no coordinate system required. That covers the "where has my real work accumulated" question well enough for me.

On your open question to folgezettel users: I cannot answer it either, because I never walked branches. But I suspect most digital Zettelkasten users would have to search hard for a retrieval that genuinely beats full-text search - and that hesitation is itself the tell you are describing.

Collapse
 
simple_memo profile image
Simple Memo

You've drawn the line I blurred. I dropped the address — the tree position that claimed to know where a thought belonged — but you're right that a stable anchor is a different animal, and in one spot I threw it out with the bathwater.

The capture lines are safe: their anchor is the timestamp, world-assigned and never renamed, the same zero-cleverness key we landed on upthread. The rot shows up one layer later. When I promote a line to its own file during curation and rename it to something readable, a link a script appended from an old daily note still points at the old name — nothing updates it, because the rename happened in the editor and the reference lives outside it. So the address was the part worth deleting; the anchor was the part I should have kept. They just happen to live in different layers: the timestamp anchors capture, the slug anchors curation.

On the hub notes — they recover the topography I noticed, but a hand-curated hub inherits the bias we beat to death here: a note only reaches it if I already recognized it mattered. So hubs rebuild the deliberate structure and still miss the latent kind.

Do you mint the slug at capture time, or only when a line graduates to its own file — and if at capture, how do you keep it stable without it quietly turning back into the address you were escaping?