A timestamp is not time.
Every note in an Obsidian vault carries a created date. So does every row in every database I have built. We are drowning in timestamps, and for years that fooled me into thinking my systems understood time. They did not.
The photograph and the video
A timestamp is a coordinate. It says when a fact was filed, the way an EXIF date says a moment existed. A video says something else: which way things were moving, how fast, whether the motion was picking up or petering out. Is this trend rising or dying? Almost everything worth acting on lives in that second description.
Personal knowledge management has this backwards, and so did I. Obsidian, Zettelkasten, the whole capture and link tradition: date everything, model nothing. You end up with a cross linked photograph album of your own past thinking, and you mistake having the dates for having the time.
spot-surfer.png1024 × 1024Near a turning point, size and speed point opposite ways
A knowledge base optimizes for magnitude, for how much. Intelligence about a moving world optimizes for motion, for how fast. Calculus makes that precise enough to build against.
How much is being said now. All a vault or a vector store can see.
The first derivative. How fast the level is changing, and which way.
The second derivative. Whether the change itself is intensifying.
Emergence lives in the second derivative. A trend being born and a trend that has plateaued can carry the same size and the same growth, differing only in whether that growth is speeding up. The conversation about your product that started last Tuesday is tiny. The one that dominated last quarter is huge and quietly dying. Rank by chatter and you surface the corpse over the newborn.
Which region of a corpus is densest?
Embedding is a deliberate choice: two things are close when their meaning is close. Cosine similarity has no time axis. Retrieval returns what sits nearest the query, and among near things it favors the densest region of the corpus. So which region is densest? The one that has had longest to accumulate mass. The freshest signal is a lonely point that loses every retrieval to last year's cluster. Similarity search is a popularity contest the past always wins, and a created_at column will not save it: a date lets you filter while the ranking stays pure cosine.
Half of my own product is a magnitude machine, and I would rather say so
Benchmates holds both kinds of layer, and one family reproduces the problem I just described. Semantic search orders by cosine distance. The typed knowledge graph is timeless too: its nodes carry a first seen and an updated stamp, and neither enters a score. Ranking is pure density. Which is the right place to start, because it means the interesting claim cannot be about the graph.
| Layer | Family | What decides the ranking |
|---|---|---|
| Semantic search | Magnitude | Cosine distance and nothing else. A date can filter the rows, it never ranks them. |
| Typed knowledge graph | Magnitude | Edge weight over mention count. No decay, no half life, no staleness term. |
| Snapshot to delta | Motion | The size of the change, week over week, decoupled from the level. |
| Squeeze and coordination | Motion | Burstiness and author concentration, weighted ahead of raw sentiment level. |
| Viral monitor | Motion | Acceleration first, velocity second, age used to favor the young. |
The knowledge base half measures mass. The monitoring half measures motion. That line is the design.
The delta was hardcoded to zero
Time awareness was not here at the start. The migration that added dated trend snapshots confesses the old behavior in its own header.
Until now research jobs OVERWROTE one living markdown per job … so there was no time series and the email's trend "delta" was hardcoded to 0.070_serp_trend_snapshots.sql
Zero because nothing was left to subtract from. Overwriting is amnesia, dated snapshots are memory, diffing them is the perception of change. The fix lives in a unique key: put the day a metric represents inside it, so a re run updates today and tomorrow appends.
- 070
- UNIQUE (project_id, provider, query, geo, metric_type, source_date)
- 082
- UNIQUE (platform, external_id, source_date)
Sort by the move and the small term wins
The digest ranks trending terms by the size of the week over week move, with the level along for the ride. A term at 15 out of 100 rising 9 beats one at 80 falling 12.
Two clocks on every row
Dated tables carry source_date, the day a metric represents, beside captured_at, the moment we wrote the row. A personal knowledge base has one, which fuses when a thing happened with when you heard about it and makes history impossible to rebuild.
Then the same amnesia showed up one layer down
We wanted to watch Instagram and TikTok for emerging virality, and the table already holding social posts was keyed so that re scraping a post overwrote its counts. It kept each post once, at its latest size, so it could say how big a clip was and never how fast it got there.
The fix was the move the trend layer had already made: stop overwriting, start snapshotting. Each post is recorded per day now, append only, the same clip measured Monday and Tuesday and Wednesday. Above it sits the first true second derivative in the system: day over day velocity, and the change in that velocity, ranked so young accelerating posts float up and old decelerating ones sink. Two rows from a real database:
| Post | Views | Age | Change in daily growth |
|---|---|---|---|
| The rocket | 20,000 | Two days old | Growth speeding up by 9,000 |
| The whale | 909,000 | Nine days old | Growth slowing by 1,000 |
One post is forty five times bigger than the other. Rank by size and the whale buries the rocket. Rank by acceleration and the rocket wins by a mile. That inversion is the argument, in two rows of output.
You can backfill a level. Recovering a derivative is another matter.
Where a source timestamps its own records, the past is reconstructable. Google Trends hands back interest going years deep, reviews carry real dates, a scrape of a hashtag returns posts stamped with when each was created, and historical search results are buyable from vendors archiving since 2021. All of that is a level, dated at the source.
What a post's view count was last Tuesday is gone, because nobody sampled it last Tuesday. Per post virality has no history. It starts the day you start watching, which is a decent argument for starting now.
Where the principle reaches, and where it stops
One rule decides where a piece of knowledge lives: match a layer's model of time to the temporality of the thing it holds. Search interest, social chatter, review sentiment, viral clips, all of it is inherently a trend, so it goes on the motion layer. Reading it as a static all time aggregate is a category error.
One thing is worth holding timelessly, and it is what the graph is for: who your customer is, how your brand sounds, what your product does, where you are trying to get. You would hate for who is my customer to decay every seven days, or lose its place to whatever spiked on Reddit last night. For self knowledge, magnitude is correct, so the graph gets no decay bolted on. Its defect is that it accumulates where it should supersede, retiring an old fact once a newer one contradicts it.
Two edges are open, and I would rather name them. The viral monitor runs but is still warming up, since velocity needs two samples and acceleration three. The outcome loop that re scores a claim by what happened afterward is built and validated but dormant, waiting on a live telemetry feed.
So this is not a claim that we solved time. It is a design principle I can point to in the schema and steer by, with a visible edge where it stops.
The magnitude half has its own write up. That is the knowledge graph, and the sources feeding the motion half are listed under integrations.
Request access