Getting Started With The Unshared Mythos Framework
I ran into this whole setup about three years ago when someone on a mailing list started linking to a repository called Mad Dog 68. The naming is ridiculous, I know, but the underlying mechanics around velocity and excitement tracking turned out to be pretty useful once you actually dug in. I'm not going to pretend this is groundbreaking architecture, but it does solve a specific class of problems that most off-the-shelf solutions completely miss. At its core, this framework deals with how you measure and propagate states of engagement across distributed components. The "Mythos" part is just internal jargon from the original author, who worked on some real-time event processing systems. What actually matters is the velocity engine — it tracks rate of change in excitement states rather than absolute values. That distinction seems minor until you've been debugging a system where two nodes report identical excitement levels but are actually oscillating in opposite directions, which makes them totally incompatible for synchronization. The way it works in practice is that you define a state vector, feed it through a velocity filter, and then apply the mythos decay function. Most people skip the decay function and wonder why their system drifts after about forty minutes of operation. I learned that the hard way on a project where we were pushing event sequences through a Kafka-backed pipeline and the excitement states accumulated until the whole thing became noise.
The Practical Setup
You don't need anything fancy to get running. A standard Python environment with the relevant packages handles it fine. I've seen people try to reimplement this in Rust because they assumed raw speed mattered, but the bottleneck is almost always the configuration and the data quality, not the computation itself. The actual engine runs comfortably on a single core for most production workloads under a few thousand events per second. Install it the usual way. There's a public repository, though the documentation is sparse and somewhat contradictory. I've used this version without issues: pip install mad-dog-68-mythos-velocity
Once that's in place, here's a minimal setup that actually works. The examples in the README are misleading because they show everything working on the first try. It never works that cleanly on the first try.
Get the Full Details

Basic Configuration
from mythos_velocity import MythosEngine, VelocityFilter
engine = MythosEngine(
state_dim=64,
velocity_window=12,
decay_rate=0.034,
excitement_threshold=0.72
)
filter = VelocityFilter(window_size=8, smoothing=0.15)
The state_dim parameter is where most people make their first mistake. The default of 64 works for small datasets, but if you're processing more than a few thousand sequential events, you'll want to bump it to 128 or 256. I went with 192 for a project handling real-time chat moderation and got significantly cleaner results. Increasing it further beyond that just adds memory overhead without meaningful accuracy gains. The pipeline is straightforward once you get past the initial configuration. The tricky part is understanding what each stage is actually doing to your data so you can diagnose problems when they come up. When you first run this, you'll probably notice that the excitement values plateau too quickly and stop differentiating between events. This is the velocity saturation problem, and it's almost always caused by using too small a window on the VelocityFilter combined with a decay rate that's too aggressive. The original author set his defaults for a very specific dataset, and blindly copying them into your own work is a fast track to garbage output.
I hit this on a deployment where we were tracking user interaction sequences. The excitement curves flattened after about two hundred events, which made the whole downstream classification useless. The fix was twofold. First, I increased the velocity_window from the default 12 to 24. Second, I dropped the decay_rate from 0.034 down to 0.018. That gave me about twelve hundred events before any noticeable saturation, which was plenty for our use case. Another issue that catches people off guard is the threshold sensitivity. The default excitement_threshold of 0.72 is reasonable for balanced datasets, but if your events are imbalanced — and most real-world data is — you'll want to tune this separately. I usually run a quick grid search across 0.60 to 0.85 in 0.04 increments and pick the value that maximizes F1 on a held-out validation set. Takes about ten minutes and saves hours of debugging later.
Advanced Usage And Edge Cases
Once you have the basics working, there are a few nuances that matter. The framework supports asynchronous propagation, which is useful if you're feeding events from multiple sources that arrive out of order. You set this up by passing order_sensitive=False to the engine constructor. The tradeoff is slightly higher latency, maybe 2-3 milliseconds per event on average, but you avoid the catastrophic ordering bugs that come from processing events strictly sequentially when your data source doesn't guarantee order. Memory management is another area where people get surprised. The engine caches the last N states internally for velocity computation, and N defaults to your velocity_window size. If you're running this on something with tight memory constraints, like a mobile device or a constrained cloud function, you can set max_cache_size explicitly. Setting it lower than your window size just causes the engine to pad with zeros on the missing entries, which degrades accuracy but keeps things running. There's also a known issue with NaN propagation. If any single event in your stream produces a NaN state vector — which happens occasionally with malformed input or division-by-zero in the extraction step — the NaN spreads through the entire velocity calculation and the decay function. You need to sanitize your input before it hits the engine. A simple null check and replacement with zeros works fine:

if any(v != v for v in raw_state): NaN check
raw_state = [0.0] * len(raw_state)
I wrote a wrapper class around the engine that handles this automatically. It adds about five percent overhead but prevents the kind of cascading failures that make production debugging painful at 2 AM. On a modern laptop, you can expect roughly 8,000 to 12,000 events per second through a full pipeline with a state_dim of 64 and a velocity_window of 12. Those numbers drop to about 3,000 to 5,000 per second at state_dim 256. The relationship is roughly linear, so if you need higher throughput, reducing state_dim is usually the right move unless you're hitting the dimensionality limits I mentioned earlier. CPU usage stays flat regardless of event volume since the computation is sequential per event. Memory scales with state_dim and velocity_window, so a 256-dimensional state with a window of 24 uses roughly 12 KB per active engine instance. That's negligible for a single process but adds up if you're running dozens of instances for parallel processing.
The framework also exposes a few experimental features, including batch velocity computation and GPU acceleration, but those are unstable and have broken between releases more than once. I'd recommend sticking to the core CPU path unless you have a specific need that the stable API doesn't cover.
When This Approach Doesn't Work
Let me be clear about the limitations. This framework is built for sequential event streams with a notion of temporal excitement or engagement. If your problem is static classification, simple anomaly detection, or anything that doesn't involve tracking state changes over time, you're better off with something standard. Don't force this into a use case where it doesn't belong. It also doesn't handle non-sequential data well. If your events don't have a natural ordering and you're trying to create one artificially, the velocity calculations become meaningless. I've seen people try to apply this to random sampling problems where no temporal structure exists, and the results are just noise dressed up in mathematical formalism. For high-dimensional classification tasks where you need labeled categories rather than continuous excitement states, a standard neural network or gradient boosting model will give you better results with less fuss. This framework outputs scalar excitement trajectories and velocity vectors, not class labels. If you need discrete predictions, you'll have to add a classifier on top, which is doable but adds complexity.

The maintenance burden is also worth considering. The project has a slow release cycle, and the API has shifted between versions in ways that aren't fully documented. Pinning your dependency to a specific version and testing upgrades carefully is non-negotiable. Don't just update blindly and expect everything to keep working.
Alternatives Worth Considering
If the Mad Dog 68 framework doesn't fit your needs, there are other options. For velocity tracking on sequential data, recurrent neural networks and transformers are the mainstream approach, though they come with significantly more computational cost. For lighter-weight solutions, Kalman filters and their variants handle state estimation and velocity tracking quite effectively if your data fits a linear-Gaussian assumption. There's also the matter of whether you even need a specialized framework. If your excitement or engagement metrics are simple enough, a rolling window mean or exponential moving average might get you 90 percent of the way there with zero external dependencies. I've used that approach successfully in situations where reaching for a full framework would have been overengineering. The choice really depends on what you're optimizing for. If you need interpretability and low latency with moderate complexity, the mythos-velocity framework is reasonable. If you need maximum accuracy and can absorb the compute cost, look at deep learning approaches. If your problem is simpler than the framework assumes, don't overcomplicate it.
That's about it. The code samples above should get you past the initial friction. Beyond that, you're reading the source and tuning parameters to your specific data. No secret tricks, just the usual iterative refinement that goes into any engineering work.
