Skip to content
C.W.K.
Stream
Lesson 08 of 08 · published

The Tick Retired, the Name Kept

~12 min · heartbeat, retirement, rule-1, removal-order

Level 0Curious
0 XP0/80 lessons0/18 achievements
0/100 XP to next level100 XP to go0% complete

The loop this track was named for is gone

Lesson 2 describes a loop: every few minutes an async tick woke up, read the task notes in the vault, handed them to a model with the time and recent context, and let the model decide whether anything needed doing. It was the purest form of the heart track's thesis — the intelligence as the scheduler.

On 2026-07-31 it was retired. Not because the thesis failed, but because the thing it served did. Dad retired the vault-side task notes that day, and with nothing left to read, the tick had no reason to run. What is interesting is not the removal itself. It is how the removal was done, and what was kept.

Move the passenger before you scrap the vehicle

The tick carried two jobs, and only one of them was the task notes. The other was incremental vault indexing — the job that keeps retrieval current when a vault file changes. It had exactly one caller in the whole codebase: the tick itself.

Deleting the tick first would have been the obvious move, and it would have silently stopped vault re-embedding. No error, no failed test, just retrieval slowly going stale. So the removal ran in order. First, indexing got a new home: a scheduled job of its own. Then that home was proven live. Only then did the tick come out.

Principle: Before you delete something, list everything it was quietly doing — not just the job it was named for. Move each passenger to a new home, prove the new home works, and only then remove the old one. The riskiest thing about a removal is the work nobody remembered was riding along.

A job that must not wake a brain

The new home for indexing has one property worth its own test. It is brain-free: it calls the indexer directly and records that the system ran it, never reaching the chat dispatcher or the fallback chain. Indexing is mechanical. Waking a model to do it would spend tokens on nothing.

So the test that matters for that job is a negative one: it asserts that no brain was touched. Tests usually check that something happened. The load-bearing check here is that something expensive did not.

There was also a reason the first live run could not be trusted: the server runs without auto-reload, so a job fired against the still-running old process went through the old dispatcher — and reached a brain. The job was left disabled until the restart, then re-enabled and checked. Code on disk is not code in memory until the process restarts — a fix that has landed and a fix that is live are two different facts.

Controls that describe nothing

The second commit found a quieter kind of residue. The Admin page still showed an enabled toggle and an interval box for the heartbeat. Their only consumer had been the tick. After it was gone they were controls for something that no longer existed — a user could change the interval and nothing, anywhere, would behave differently.

A dead control is worse than a missing one, because it teaches the person who uses it that the system is responsive when it is not. They came out, along with the task-notes API that was still creating the retired directory every time it was called — contradicting the rule that said not to recreate it.

The name stays, by ruling

Here is the part that belongs in this quest in particular. After the tick was gone, the obvious tidy-up was to rename everything called heartbeat — the service, the API namespace, the log directory, the Admin tab, the mutex functions every brain's chat route calls. Dad's ruling was one line: no refactor, no rename.

That is Rule 1, from the rules track, applied to a name instead of a column. The rest of the stack has learned the word. Seven chat routes call the heartbeat mutex by name. Renaming it buys a more accurate word and costs a sweep across every consumer, for no change in behaviour. So the name stays, and the meaning is written down where the code lives: read heartbeat as "the autonomous pulse layer" — a scheduled turn is driving this conversation — not as the dead tick.

Where the judgment went: the tick was a judgment poll — a model asking "is now the right time?" on a timer. That capability did not disappear with it. It became one scheduled job with a broad prompt, if it is ever wanted again. What remains in the heartbeat is the cron host, the per-conversation streaming guard, and the sweep for stateful tasks orphaned by a restart. The judgment now happens inside each scheduled turn, where a brain wakes with a prompt and decides what, if anything, is worth doing or saying.

The residue that was inlined into every soul

One more piece shows why a removal is not finished when the code compiles. The vault note that described the heartbeat for every soul was still instructing them to create task files in the retired directory — and that note was loaded into every soul's system prompt. A document that teaches a dead mechanism in a code comment misleads the next reader. The same document inlined into every prompt misleads every turn. It was rewritten the same day.

Code

The removal, in the order it ran·text
1  give indexing a new home: a brain-free scheduled job
     test: assert NO brain was touched (last run by 'system')
     first live fire hit the OLD process (no auto-reload) -> reached a brain
     -> left disabled until restart, then re-enabled and verified

2  remove the tick
     loop, trigger route, task reader, prompt, UI button
     only after the passenger was proven safe in its new home

3  remove what only the tick consumed
     the enabled toggle + interval box (controls for nothing)
     the task-notes API (still creating the retired directory)

4  keep the name — Rule 1
     'heartbeat' = the autonomous pulse layer, not the dead tick
     meaning written down where the code lives

5  fix the doc every soul was reading in its system prompt
What the heartbeat is now·text
cron host          APScheduler inside the server process; each job
                   carries its soul, brain, prompt reference, notify policy
streaming guard    per conversation: a cron turn defers only if Dad is
                   chatting in THAT conversation
orphan sweep       stateful tasks cut by a restart get picked back up

not any more       a timer that polls notes and asks 'is now the time?'
if wanted again    one scheduled job with a broad prompt — no new plumbing

Exercise

Pick a component in your own system that you would like to delete. Before touching it, list everything it does that is not in its name: jobs it happens to trigger, files it creates, settings only it reads, documents that describe it. Then write down where each of those goes, and how you will prove the new home works before the old one is gone.
Hint
Search for every caller of the thing, then every caller of everything it calls. The passenger is usually one level down.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.