I stopped being my second brain's scheduler
Cadences that surface what's due, habits that flag a slipping streak, and a live HUD that watches the vault — and it ships without a single background cron. SMRITI v2.1.

Search for a command to run...
Cadences that surface what's due, habits that flag a slipping streak, and a live HUD that watches the vault — and it ships without a single background cron. SMRITI v2.1.

No comments yet. Be the first to comment.
I'm building an open-source system to interrogate the AI-research firehose — RAG now, a multi-agent researcher by the end, in public over five parts. Part 1 is the foundation: the architecture, the ingestion, and the eval bug that would have shipped meaningless numbers.
A sub-agent that writes to your system will tell you it succeeded. It's reporting what it intended to do, not what actually landed — and the gap is where silent data corruption lives.
You can plan a day around what you can do, or around what you can decide. Until recently those were the same plan, so it never mattered which you meant. Parallel sub-agents pull them apart — and the i
When a team sets out to add AI to something, the first real argument is usually about the model. Which provider, which version, this one or the one shipping next month. It feels like the decision ever
Deepak Goyal
10 posts
Architecture decisions, not opinions. AI systems, system design, and what actually works in production.
On this page
Cadences that surface what's due, habits that flag a slipping streak, and a live HUD that watches the vault — and it ships without a single background cron. SMRITI v2.1.
The system I'd built was good at holding structure. It was terrible at reminding me the structure existed.
Every month there was a review I was supposed to run per area. Every week, a backlog to groom. There was a walking habit I'd sworn to keep. And while I worked inside Claude Code all day, the state of my vault — what's due, what's done, what's slipping — lived somewhere I had to go and look.
So I became the scheduler. I remembered the monthly review three weeks late. I noticed the walking streak had already collapsed. I context-switched out of my terminal to check what today's tasks even were.
Quick context: SMRITI is an open-source second brain that pairs Obsidian with Claude Code. v1.0 gave it daily-companion behaviours. v2.0 gave it architecture — skills + agents, per-area Projects, Standards. Both gave me structure. Neither made the structure surface itself.
v2.1 is the release where the system starts watching for me. Three pieces — recurring-work cadences, a habit tracker, and a live statusline. And one deliberate call about what to ship: no crons, no background jobs — you'll see why in a minute. Here's what hurt, what I built, and the lesson that shaped all three.
Some work isn't a one-off task. It recurs: a monthly area review, a weekly content-backlog grooming, a quarterly retrospective. In my Project files these lived as recurring Initiatives with a planned date.
Nothing watched that date.
So the monthly review would come due on the 31st, and I'd notice it around the 20th of the next month — if I noticed at all. The Initiative sat there, quietly overdue, because the only thing that could catch it was me remembering to scroll the project list. A recurring cadence that depends on human memory isn't a cadence. It's a hope.
Two pieces of plain bash — no network, no daemon.
cadence-scan.sh → "which recurring Initiatives have planned <= today?"
cadence-roll.sh → advance a completed one's planned by its interval
cadence-scan globs the Projects folder, reads frontmatter, and surfaces anything whose planned date has arrived. It runs inline inside /start-my-day — so the morning brief now carries a Cadences Due section:
### ⏱️ Cadences Due
⏱️ area-review — Monthly area review · monthly · 2d overdue · opens on next close
When the iteration is actually done, /close-my-day runs cadence-roll: it advances planned by one interval (monthly → +1 month, quarterly → +3) so the cadence stops nagging, bumps the iteration counter, and — if the Initiative is marked auto_scaffold: true — opens the next iteration's task list automatically.
Two new frontmatter fields carry the behaviour:
auto_scaffold: true — open the next cycle without asking.
nth_weekday: "4 Sat" — snap each roll to the 4th Saturday of the month instead of a fixed calendar date that drifts across weekdays.
The date became the trigger, not my memory. A recurring review now surfaces itself the morning it's due, rolls itself forward the evening it's done, and re-opens its own next iteration. I went from remembering to check to being told — and the only thing that changed is that a 90-line script reads a frontmatter field I was already writing.
I had a daily walking target. I'd log my step count in the day's note and… that was it. The number went into a file and never looked back at me.
So the failure mode was invisible. One low day is noise. Two in a row is the start of a collapse — but I only ever noticed the collapse after a week of it, when the habit was already gone. There was no moment where the system said hey, that's two.
Each habit becomes its own small file with a check-in spec in its frontmatter:
phase_65:
capture:
type: number
source: frontmatter
key: steps
low_threshold: 5000
miss_rule:
window_days: 2
counts_as_miss: below-threshold
flag: "⚠️ Daily Steps: {miss_count}-day streak break"
Now /close-my-day does a habit check-in. It reads today's step count from the daily note, flags a same-day low, then walks back the window and counts consecutive misses. Two days under the floor and it surfaces the flag — the night it becomes two, not the week after.
The detail I'm proudest of is the ramp-up clamp: a habit you promoted three days ago can't fire a "2-day streak break," because it clamps the look-back to min(window, days_since_promoted). New habits get a grace period instead of a false alarm. The tracker meets you where the habit actually is.
It handles two capture types — number (steps, weight, hours slept) and event (did I journal today? did I log a decision?) — so the same machinery covers "how much" and "did I at all."
A single disruption shouldn't be able to snowball into a collapse. The whole value of the miss flag is catching the second day, while recovery is still one walk away. The system now holds the streak's memory so I don't have to — and tells me at the exact moment intervention is cheap.
I live inside Claude Code. And while I'm there — heads-down, building — the state of my second brain is somewhere else. What's due today? How many quests have I closed this week? How's the project load across areas? Every one of those questions was a context switch: stop, go look, come back.
The information existed. It just wasn't where my eyes already were.
v2.1 ships a native Claude Code statusline — a five-row heads-up display that renders live, right under the prompt:
⠹ SCANNING THE ATLAS…
🪔 SMRITI │ 🌍 YOUR CITY │ Sun Aug 2 🕔 09:50
⚔️ PROJECTS WORK Σ24 ✓9 ▶6 │ LEARNING Σ8 ✓2 ▶3 │ HEALTH Σ4 ✓1 ▶1
📥 INBOX 2 │ ⚔️ 3 🎯 1 │ 📅 Mo 5/5 Tu 4/4 … ▸Su 2/3
🛞 SARATHI Claude │ SK 6 · AG 8 │ ●●●●●●········ 42%
Top to bottom: a rotating activity line; identity and clock; per-area project counts (total / done / active); today's inbox, quests, and bounties with a weekly Mon–Sun rollup; and the model, skill/agent counts plus a live context-window bar.
The engineering that matters is underneath. The slow parts — scanning folders, counting projects, rolling up the week — are precomputed into a small cache by /start-my-day and /close-my-day. The live render does zero folder-walking; it reads the cache and prints. So it's instant on every refresh, not a lag spike.
And here's the part I reworked before release: it reads entirely from your vault. The per-area counts come from your Project folders. Today's quests and the whole weekly rollup come straight from your daily notes' checkboxes. There's no service it has to phone. Early on I'd wired the weekly row to my task manager; that was a leak of my setup into everyone's. The final version derives every row from plain markdown you already have — so the HUD works the same whether or not you use any external tool.
The areas aren't hardcoded either. It reads whatever sub-folders live under your Projects directory, so your HUD shows your domains, not mine.
Ambient awareness beats on-demand lookup. I stopped leaving my terminal to ask "what's the state of things," because the state of things is now a glance away, updating as I work. The vault went from a place I visit to a thing I can feel in my peripheral vision.
Here's a confession that complicates the story: on my machine, some of this is scheduled. I have launchd jobs that run quiet maintenance while I sleep. I like them. They earn their keep.
So why does v2.1 ship with zero crons?
Because a schedule is a commitment I shouldn't make on your behalf. A second brain that installs background jobs the moment you clone it is a second brain you now have to operate: processes to monitor, failures that happen while you're not looking, a machine that has to stay on. That's a fair trade for me — on my setup, with my tolerance for babysitting infrastructure. It's a lousy thing to force on a stranger who just wanted to try it out.
So every piece of v2.1 hooks into a moment you already show up: the morning brief, the evening close, every statusline render. Cadences surface when you open the day. Streaks get checked when you close it. The HUD updates because you're typing anyway. Nothing runs behind your back, nothing needs babysitting, and it works the first minute after you clone — no scheduler, no daemon, no setup.
And if you do want it hands-free? The scripts are built for exactly that. cadence-scan and the habit check take no arguments and touch nothing but local files — point your own cron or launchd at them and you've got the scheduled version, on your terms, when you decide you want it. I left it as your choice instead of my default.
Making that opt-in — clean, documented, and yours to toggle — is where the next release starts.
v2.1 is additive and drop-in over v2.0. Same six skills, same eight agents, no vault migration. If you're on v2.0, you pull and you're done.
Cadence engine — cadence-scan + cadence-roll, new auto_scaffold / nth_weekday fields, wired into start/close-my-day.
Habit system — file-per-habit with a daily check-in, streak walk-back, and miss flags, plus a worked example.
Native statusline — the five-row HUD, vault-sourced, auto-configured by setup.sh.
No crons. No new skills or agents. The whole automation layer is skill-invoked local bash.
What's next. The opt-in scheduling layer is the headline candidate for v2.2: wire these same scripts into cron/launchd with a one-command installer, a clean on/off switch, and setup docs — so the fully hands-free version is a deliberate choice you make, never a default you inherit. If that's the piece you want, say so on the repo (an issue or a star) — reader signal is genuinely what decides what ships next.
It's open source — clone it, run setup.sh, and it'll offer to wire the statusline for you: github.com/deepakgoyal-ai/smriti.
The throughline across v1.0, v2.0, and now v2.1: a second brain shouldn't ask you to remember it exists. v2.0 made it coherent. v2.1 made it look up and wave when something needs you — without ever running behind your back, and without asking you to run anything behind yours.
Built by Deepak Goyal. Follow the journey: GitHub · LinkedIn