A Clock That Listens
An engine that gives software a sense of its own time.
Every running program has a clock, but almost none of them have a tempo. They tick at whatever rate the CPU allows, and every tick weighs the same. A flood of low-stakes events and a single critical signal pass through the same pipe at the same speed, occupying the same slice of attention. This is fine for most software. It is conspicuously wrong for any software that is supposed to think.
Temporal Gradient is a small Python framework I built to take that wrongness seriously. The idea is simple enough to fit in a sentence: when something important happens, the system’s internal clock should slow down, and the things it remembers should fade according to that same inner time rather than the wall clock. One signal, salience, governs both when the machine considers and what survives consideration. Most systems treat those as two separate engineering problems. Temporal Gradient asks what happens when you treat them as one.
The shape of the thing
The mechanism is not exotic. A stream of text events comes in. Each event gets a salience score, written Ψ, the product of two components. Novelty (H) measures how unlike the recent past the event is; the default scorer is a rolling Jaccard distance over tokens, which is to say, a very simple bag-of-words check. Value (V) is a weighting term, scored in the default implementation by counting hits on imperative keywords: critical, never, urgent. The defaults are crude on purpose. They are placeholders for whatever real scorer you would bring to a real domain.
Salience then feeds into a clock-rate modulator. The math is one line:
dτ/dt = clamp(1 / (1 + α·Ψ), min_rate, max_rate)
In English: high salience reduces the rate at which internal time τ advances. A loud event compresses the system’s experience of duration; a quiet stretch lets the inner clock keep pace with the outer one. The clamp prevents pathological cases: the clock cannot stop entirely, cannot run away.
Memory then decays along τ, not along wall time. Each remembered item has a strength S that falls exponentially with internal duration. Access reconsolidates the item, bumping its strength back up, bounded by a ceiling. Items that fall below a threshold get swept out. Downstream compute is gated by a cooldown expressed in τ: the system is only allowed to do expensive work after enough internal time has passed, which by construction means enough lull in salience.
That’s the whole engine. Five modules, about thirty test files, formal interface contracts so the salience scorer or the decay function can be swapped without rewriting anything else. Every cycle emits a validated telemetry packet: internal time, salience, clock rate, memory strength, depth, meant to be logged and replayed and analyzed cold, the way you would analyze the output of a sensor rather than the output of a service.
What the unification buys you
The instinct to keep “when to think” and “what to remember” as separate concerns is so strong that it’s almost invisible. Production agent systems route around the problem with rate limiters and vector databases and LRU caches, and the seams between those layers are where most of the operational pain accumulates. You tune the rate limit to keep costs down, and now the agent misses things during bursts. You tune the cache to keep recall fast, and now it forgets the important rare event because the recent noise crowded it out. Each layer is reasonable in isolation. Together they fight.
The argument for unifying them under a salience-modulated clock is that the two problems are actually the same problem viewed from two angles.
What deserves more thinking and what deserves to be remembered are both answers to the question what mattered? If you have a defensible signal for mattering, and salience, however crudely scored, is at least an honest attempt, then you can drive both behaviors from it and get a system whose tempo and whose memory move together. Quiet periods accelerate the clock and let stale items decay. Loud periods dilate the clock and reinforce what’s being attended to. The machine’s experience of its own past is shaped by what it cared about, in proportion to how much it cared.
This is not a new instinct. Cognitive scientists have argued for decades that subjective time is salience-modulated: that the long minutes of a car accident and the vanished hours of an absorbing conversation are the same mechanism in two directions. Bergson called the inner experience of duration durée, distinct from the spatial, divisible time of the physicist. Attention research in machine learning has explored salience weighting in narrower forms. Temporal Gradient does not claim to model any of this.
It borrows the shape of the idea: that time is a function of what’s happening, and renders it as a small, testable, deterministic engine you can wire into other code.
What it is not
It is not, to be blunt about it, a product. There is no integration with any real event source, no persistence layer for the memory store, no deployed caller anywhere. The default salience scorers are toys. To get useful behavior from it you would need to write your own novelty function, probably using embeddings rather than Jaccard, and your own value function appropriate to your domain. The framework gives you the bookkeeping, not the meaning.
It is also not a cognitive model. The README says this explicitly and the documentation repeats it: the dynamics make no claim about how minds work, no claim about consciousness, no claim about anything beyond the state variables and equations defined in the code. The temptation to overclaim is real, and the discipline of refusing to is part of what makes the project worth taking seriously instead of being filed away with the long tradition of software that promises more than it can deliver.
What it is is a primitive. A piece of mathematical machinery that does one specific thing: reparameterize time by salience and decay memory along the result, and does it cleanly enough that you could build something on top of it without rewriting the foundations. Whether anyone will is the question I don’t yet have an answer to.
Where it might earn its keep
Three applications make obvious sense to me. The first is incident response: an agent monitoring a stream of alerts should think slowly and remember vividly during a breach, then accelerate and forget routine noise during calm. The second is long-form assistive tools, a journaling companion, a research notebook, whose recall of past entries should be biased toward what was novel or charged rather than what was recent. The third is adaptive monitoring more generally: any system whose appropriate cadence depends on what’s happening, where a flat rate limit will either oversample the boring or undersample the critical.
None of these are theoretical. Each one is a real problem that real teams handle today with awkward stacks of unrelated layers. None of them currently use anything like Temporal Gradient, which is either an opportunity or evidence that the framing doesn’t matter to the people who could use it.
The honest finish
I have a small, clean engine and an open question about whether the world has a use for it. The temptation is to keep polishing the engine, because that’s the part I know how to do. The harder thing is to pick one of those three applications and force it to be real: wire it to an actual stream, write a salience scorer that understands the domain, hand the output to a downstream consumer that actually does something with it, and see whether the result is visibly better than the naive alternative.
That’s the test. Not whether the math is elegant, or the code is well-tested, or the documentation is honest. Those things are already true. The test is whether a system that has a sense of its own time does something a system without one cannot.
I don’t know yet. The fact that I can frame the question this precisely is, I think, the point of having built the thing in the first place.
Take a look below:




