Winnex

Winnex Stack

WINNEX — Weighted Inference Neural Network Enhancement. A deterministic, training-free framework that improves a pretrained model using only the geometry it already learned.

What WINNEX is

Frontier models in regulated sectors cannot be retrained. You do not fine-tune a model that already passed validation, and you cannot ship a gradient step into a system under audit. WINNEX improves inference without touching the weights.

At the centre sits the Madhava bound engine: deterministic vector search in which every excluded document carries a Cauchy–Schwarz proof of exclusion. Around it sit a deterministic spectral tokenizer, a weight balancer that fuses multiple models without retraining, and native C++/OpenCL inference that runs without a GPU.

The core claim, stated precisely

An approximate index tells you "here are the nearest neighbours." It cannot tell you "and here is the proof that nothing relevant was missed." Madhava answers the second question — per document, with arithmetic the reader can re-run.

That is the entire value proposition. Everything else in this stack exists to feed it, wrap it, or run alongside it.

Two propositions, deliberately distinct

The stack serves two different buyers with two different problems. They should not be sold as one thing, because they are not one thing.

Proposal A

The gold standard for regulated RAG

Who. Legal, medical, financial and government organisations — anywhere a regulator, auditor or court can ask why a document was not returned.

The problem. "The search said there was nothing — but what if it was wrong?"

The stack. normalize → madhava → tracer.

The trade. You give up 20 to 100 times query speed above 50,000 vectors. In exchange you receive a mathematical and cryptographic certificate that no relevant document was lost.

The claim. The only stack that turns "we did not find it" into "we proved it does not exist."

Proposal B

Next-generation inference on restricted hardware

Who. Edge computing, startups with a limited GPU budget, and environments where security policy forbids PyTorch or CUDA.

The problem. A 7B model does not fit a 16 GB card with the standard stack, and PyTorch is a large, opaque binary.

The solution. winnex-nano — a PyTorch-free inference engine running on OpenCL for CPU and GPU, with bf16 memory management that runs models Transformers rejects with OOM, while keeping perplexity bit-exact with the reference.

The evidence. Qwen2.5-7B on a 16 GB card: 7.5 s against 69.8 s on CPU, perplexity 15.55171 against 15.55172. Identical output, 9.3× faster.

These do not compete. Proposal A is about proof. Proposal B is about reach — running models on hardware that would otherwise be unavailable. An organisation can adopt B to make the model run where it needs to, and A to make the retrieval defensible. The shared C++ core means adopting one does not double the footprint of the other.

Why holding both is an advantage

The usual vendor forces a choice: either a compliance product that cannot run where you need it, or an optimized runtime with no audit story. WINNEX built one kernel set and derived two products from it — a bound engine for proof and an inference engine for reach. That is not a positioning trick; it is the reason the same team could ship both in two years on no outside capital.

Why this matters commercially

In a bank, a hospital, a law firm or a government body, the question is not "how fast is the search?" The question is "can you prove the search was complete?" — asked by a regulator, an auditor, a judge or an opposing counsel. An answer of "we use a well-known approximate index" is not a defence. A per-document mathematical bound is evidence.

This reference covers every package Winnex publishes. Each entry states what the package does, how to install it, a working example, and what it deliberately does not do.

Read this before you choose

If you need the fastest possible approximate search and nobody will ever ask why a document was excluded, use FAISS or Pinecone. Above roughly 50,000 vectors they are faster at query time. WINNEX exists for the case where the proof is the product — and at that job it is the only option in this stack.

Overview

The stack is layered and every layer is independent. You can run the engine alone, add the audit trail later, and never touch the inference or embedding packages. Nothing here requires the rest.

This section explains what each component is for, in plain terms, before the reference sections go into detail.

winnex-madhava — the search engine

What it is. A vector index that answers a question ordinary indexes cannot: prove that the search did not miss a relevant document.

What it does. When you ask for the 10 nearest vectors, it returns those 10. For every other vector in the corpus, it computes a Cauchy–Schwarz upper bound on how similar that vector could have been. If the bound sits below the similarity of the 10th result, the vector provably could not belong in the answer — and the arithmetic is recorded.

Why you would want it. Because "we searched and found nothing" is not a defensible statement in a regulated process. "We searched, found nothing, and here is the proof that nothing was there" is.

What it costs. Query speed, above roughly 50,000 vectors. It is 20 to 100 times slower than HNSW at that scale. That is the trade, and there is no way around it.

What it gives back. Two things HNSW cannot match. The index builds 23 times faster — 1.45 s against 33.6 s for the same corpus of 99,800 vectors. And below 50,000 vectors, query time is better than HNSW, because the bound eliminates most of the corpus before any distance is computed. The crossover at 1,000 vectors: 0.55 ms against 0.69 ms.

winnex-tracer — the audit artifact

What it is. The layer that turns a mathematical proof into a document.

What it does. Takes the per-query proof from the engine and writes it into a tamper-evident record: write-once storage, Ed25519 signature, SHA3-256 hash chain linking each record to the previous one, and an audit commitment so the issuer cannot later deny having produced it.

Why you would want it. The engine proves something to a mathematician. The tracer proves it to a court, an auditor or a regulator — who need a file with a hash, a signature and a timestamp, not a formula.

Think of it as: the engine produces the evidence, the tracer produces the exhibit.

winnex-ai-normalize — the input adapter and quality gate

What it is. The piece that turns whatever you have — text, or vectors from another system — into the exact format the engine accepts, and then tells you whether that input is good enough for the guarantee to mean anything.

What it does. Embeds text through a provider of your choice, validates the result, applies the L2 unit-norm contract, optionally quantizes to uint8 — and runs a thirteen-flag audit over the corpus before it is ever indexed.

Why the audit matters more than the conversion. A bound proof is only as strong as the vectors it was computed on. The engine will happily index a corpus full of NaN and return bound_violations = 0, because the arithmetic is correct — the inputs were garbage. This package is what stops that from happening silently.

The flag system is the most useful part of this package and the part most people skip. It has its own section below.

The flag system — what it is for and why it exists

The purpose of signalling. Every quality defect produces a flag: a stable machine-readable code, a severity, a measured value and a threshold. Not a warning buried in a log — a structured object your pipeline can act on. The codes are stable across versions, so CI gates, monitoring rules and ingestion policy can key on them without parsing prose.

Three severities: pass, warn, fail. A report exposes fail_flags, warn_flags and has_fail, so the caller decides policy — abort ingestion, quarantine the batch, alert, or proceed with recorded risk.

The thirteen flags

CodeSeverityWhat it detects
dataset.nanfail NaN or infinity anywhere in the corpus. These overflow float32 and produce garbage scores with zero bound violations
dataset.degeneratewarn Zero or negligible variance — a corpus where every vector is nearly identical, so no search can separate them
dataset.foldablewarn The one that matters. How much of the corpus the bound actually eliminates. High coverage means the proof is doing real work; low coverage means you pay for the proof and get almost none of the benefit
dataset.recall_not_guaranteedwarn The returned top-K is the best within the candidate pool, not proven to be the global top-K — silent collapse with violations still at zero
embedding.resolutionwarn Gap between the top-1 and the k-th score is too small — the embedding cannot separate neighbours from noise
embedding.provider_driftwarn Same provider but the embedding space moved since the reference; old and new vectors are no longer comparable
embedding.cross_providerwarn Provider was switched. Two encoders produce two incompatible spaces — mixing them corrupts every query
embedding.dim_shiftwarn Dimension changed between batches
embedding.normwarn Norm distribution abnormal — typically a partially failed embedding call
embedding.anisotropywarn The uint8-quantization trap: vectors collapsed into a narrow cone, destroying the separability the bound depends on
integrity.corpus_alignmentwarn Corpus and reference misaligned — row i of the corpus does not correspond to row i of the labels
integrity.query_corpus_proximitywarn A query index collides with a corpus index — the benchmark is measuring the engine against itself
dataset.recall_not_guaranteedwarn Covered in its own section below — the flag that separates a report of success from a report of truth

Why dataset.foldable decides whether the proof is worth anything

The bound is only useful if it eliminates documents. If the corpus geometry lets the bound prune 80% of candidates before the exact path, the engine is doing its job. If it prunes 8%, you pay the cost of the proof and receive almost none of the benefit — and the report states the measured fraction instead of letting you assume.

The thresholds are calibrated against the engine, not guessed: bound_frac ≥ 0.50 is strongly foldable, below 0.20 triggers the probe gate. They are documented in source next to the constants.

Why dataset.recall_not_guaranteed exists

This flag was added after an honest discovery. A configuration can show zero bound violations and still not be globally guaranteed, because the violation count only covers the candidate pool. If stage-2 truncation dropped the true neighbour before it was ever considered, the bound never had a chance to be violated. The report says it plainly:

seed recall@K = 0.375 vs the motor's own search_exact (< floor 0.95);
8/8 seed queries are recall_guarantee=pool_only — the returned top-K is
the best WITHIN the pool, NOT proven the global top-K. viol=0 does not
cover this (silent collapse). For a global guarantee use
audit_exhaustive=True or k1=N.

This is the single most valuable output of the package. It is the difference between a system that reports success and a system that reports the truth.

How a pipeline should use the flags

from winnex_ai_normalize import audit_corpus, QualityGateError

report = audit_corpus(corpus, dim=384)

# 1. reject a corpus the engine cannot handle
if report.has_fail:
    for f in report.fail_flags:
        print(f"[{f.code}] {f.message}")
    raise QualityGateError("corpus rejected")

# 2. is the proof actually doing work on this corpus?
fold = next((f for f in report.warn_flags
                if f.code == "dataset.foldable"), None)
if fold and fold.metric < 0.2:
    log.warning("bound covers only %.1f%% of the corpus",
                100 * fold.metric)

# 3. never ship a config whose top-K is only pool-proven
recall = next((f for f in report.warn_flags
                   if f.code == "dataset.recall_not_guaranteed"), None)
if recall:
    raise QualityGateError("top-K is not globally proven")
Signalling is a contract, not diagnostics

Because the codes are stable identifiers, they belong in your CI and your alerting. A corpus that trips dataset.nan should never reach the index — and the flag carries the exact percentage so the alert can say how bad it is without anyone opening a log.

winnex-xfactor — the embedding shortcut

What it is. A way to get a usable embedding space from a model you already have, without training anything and without calling an external API.

What it does. Reads the model's own token-embedding table, computes the subspace where those embeddings actually live, and produces a projection basis. It derives this from the weights — it never runs the model.

Why you would want it. When you cannot send data to an embedding API (air-gapped, regulated, cost) and you do not want to train anything, this gives you a deterministic encoder derived from weights you already possess.

What it is not. A product on its own. It exists to feed the engine when a hosted embedding provider is not an option.

winnex-nano — the inference engine

What it is. A general-purpose LLM inference engine built on OpenCL. It runs on GPU and on CPU, without CUDA.

What it does. Loads the same weights and the same BPE vocabulary as Hugging Face Transformers and produces the same outputs — with memory management that lets larger models fit smaller cards.

It is bit-exact, not approximate. Measured on Qwen2.5-7B with 131 tokens: CPU path perplexity 15.55172, GPU path 15.55171 — a relative difference of 7×10⁻⁶. The checkpoint is already bf16, so the GPU reads exactly the numbers the CPU reads after widening them to f32. Nothing that was in the file is lost.

Where it wins. A 7B model in f32 is 26.1 GB against a 16 GB card — the standard Transformers path runs out of memory. WINNEX sized the weights in bf16 and streamed lm_head in 512-row blocks, taking that tensor from 2.18 GB down to 7.3 MB. The 7B fits a 16 GB GPU and runs 9.3 times faster than CPU — 7.5 s against 69.8 s for the same 131 tokens, with identical perplexity.

This is an infrastructure alternative, not only a search feature. The engine competes on correctness and memory efficiency against the standard stack — not merely on producing exclusion proofs.

What it is still not. It is not a training framework, and it does not replace fine-tuning. The spectral tokenizer path remains slower and less compact than BPE; it exists as an autonomous encoding, not a drop-in replacement. Use the standard BPE path when you need parity with your existing pipeline.

winnex-tracer-core — the shared base

What it is. The substrate the tracer family is built on: write-once storage, signing, hash chain, retention policy.

Why it exists as a separate package. So the four vertical domains (GOV, JUS, MED, GAP) reuse one audited implementation instead of four copies. You install it on its own only when building a new tracer domain.

winnex-madhava-sec — agent security

What it is. The same bound pruning, applied to a different problem: detecting prompt injection in an AI agent's input.

What it does. Prunes most of the candidate corpus with the bound before the expensive classifier runs. That pruning is where the saving comes from.

What it does not do. It does not improve detection accuracy. Measured F1 is 0.8183 with pruning against 0.8262 for a direct search — the difference is noise. Adopt it for cost, never for accuracy.

Weight balancing — improving a model you cannot retrain

The problem. A bank runs a frontier model that has been through validation. It cannot be fine-tuned: the weights are frozen by policy, and a gradient step would void the validation. But the model performs unevenly across the institution's actual documents.

The mechanism. WeightBalancer fuses the weight matrices of several models into one, without any training step:

W′ = Σᵢ αᵢ · R(qᵢ) · Wᵢ

Each source model contributes with a coefficient αᵢ and a rotation R(qᵢ) derived from its own geometry. The result behaves as a single model. No backward pass, no labelled data, no fine-tuning dataset.

What it is honest about. Weight balancing changes the geometry the model reasons over. It does not make a weak model strong, and it does not improve generation quality in the way fine-tuning would. What it does is let an institution combine models it already has and already trusts — a general model, a domain model, an internally trained model — into one inference path that serves all its document types.

Streaming — indexing 100M vectors without loading them

The problem. A large corpus does not fit in RAM. A 100M vector corpus at 128 dimensions is roughly 12.8 GB raw. Loading it to build an index means either a very large machine or a very long wait.

The mechanism. The corpus is memory-mapped, never read into RAM. The C++ core builds quantized projections in streaming blocks of 500,000 vectors at a time, then caps stage-2 survivors so the exact post-filter stays bounded regardless of corpus size.

The measured result. Building the index over 100M vectors took 342.6 seconds on 4 CPUs, with 0 bound violations. Peak memory 28 GB. That is a build that fits in a maintenance window instead of a weekend.

Why fast build changes what is practical

An index that rebuilds in seconds instead of tens of minutes unlocks patterns that are simply not viable otherwise: re-indexing per tenant, rebuilding nightly instead of weekly, running experiments across dozens of configurations, and continuous ingestion where new documents enter the index as they arrive.

The build advantage measured on 99,800 vectors: 1.45 s against 33.6 s for HNSW — 23 times faster. At 1M vectors the build completes in 1.69 s.

How the pieces fit

If you need…Install
Proof that a search did not miss a document winnex-madhava
That proof as a signed, timestamped artifact winnex-tracer
Text converted to vectors, without silent corruption winnex-ai-normalize
Embeddings without an external API call winnex-xfactor
A 7B model on a 16 GB GPU, bit-exact with Transformers winnex-nano
LLM inference without a GPU at all winnex-nano
Prompt-injection screening at lower inference cost winnex-madhava-sec
A new vertical domain on top of the tracer winnex-tracer-core

Installation

All packages are on PyPI and require Python 3.8 or newer. The C++ cores ship pre-built inside the wheels — no compiler, no build step.

# the core engine — start here
pip install winnex-madhava

# add-ons, install only what you need
pip install winnex-ai-normalize    # text → vectors, with failover
pip install winnex-xfactor         # manifold basis
pip install winnex-nano            # native CPU inference
pip install winnex-tracer          # audit trail
pip install winnex-madhava-sec     # agent security

Verify the install

python -c "import winnex_madhava as m; print(m.__version__)"
# expected: 1.9.23

Requirements by package

PackageRequires
winnex-madhavaPython ≥ 3.8, NumPy
winnex-ai-normalizePython ≥ 3.8, NumPy, httpx
winnex-xfactorPython ≥ 3.8, NumPy
winnex-nanoPython ≥ 3.8, NumPy, winnex-madhava ≥ 1.8.1
winnex-tracerPython ≥ 3.8, NumPy
winnex-tracer-corePython ≥ 3.8, NumPy
winnex-madhava-secPython ≥ 3.8, NumPy, scikit-learn, sentence-transformers, pandas

Architecture

  raw text                    raw vectors
      │                            │
      ▼                            │
 winnex-ai-normalize ◄────────────┘
   · provider failover (OpenAI / Qwen3 / nano / xfactor / direct)
   · validate dimension, NaN, norm — fails loudly
   · L2 unit-normalize (cosine contract)
   · quantize float32 → uint8
      │
      ▼
 winnex-madhava ──────────────────────►  top-K
   · Cauchy–Schwarz bound pruning              +
   · exact-L2 post-filter                 per-document proof
   · audit_exhaustive mode                 of exclusion
      │
      ▼
 winnex-tracer
   · WORM storage
   · Ed25519 signing
   · SHA3-256 hash chain
   · AuditCommitment — non-repudiation
      │
      ▼
 audit report — the artifact a regulator or court accepts

winnex-madhava

core engine v1.9.23

Deterministic vector search with mathematical guarantees.

What it solves

Approximate indexes answer "here are the k nearest neighbours." They cannot answer "prove you did not miss a relevant document." Madhava answers the second question.

For every vector excluded from the result, the engine computes a Cauchy–Schwarz upper bound on the inner product. That bound converts into a lower bound on squared L2 distance. If the lower bound exceeds the distance of the k-th result, the vector cannot be in the top-K — and the engine records the arithmetic that proves it.

Quick start

import numpy as np
import winnex_madhava as mad

# corpus: float32, L2-normalized, shape (N, D)
corpus = np.random.rand(10000, 384).astype(np.float32)
corpus /= np.linalg.norm(corpus, axis=1, keepdims=True)

engine = mad.build_engine(
    corpus,
    dim=384,
    metric="cosine",
    k=10,
    k1_fraction=1.0,        # keep all bound survivors
    postfilter=True,         # exact-L2 re-rank
    audit_exhaustive=True   # produce the proof
)

result = mad.retrieve(engine, corpus[0], k=10)

result["indices"]          # top-K
result["bound_violations"]   # must be 0
result["proof"]              # per-document bound record
Configuration matters

The default k1_fraction=0.05 keeps only 5% of candidates after the wide bound. On some corpora that discards correct neighbours. Set k1_fraction=1.0 with postfilter=True for exact recall. This was measured across configurations, not assumed.

When to use it

  • A regulator or court asks why a document was not returned
  • Missing a document carries a financial or legal consequence
  • You must hand an auditor a machine-checkable artifact
  • You want proof per query, not a sampling argument

When not to use it

  • You need sub-millisecond latency — use FAISS or HNSW
  • Billions of vectors and cost dominates everything
  • Nobody will ever ask why something was excluded
Measured on this stack

Top-1 agreement with exact cosine scan: 1.0000. setR@10 overlap: 0.9933. Bound violations: 0 across every configuration tested. 300 queries in 0.15 s.

winnex-ai-normalize

input layer v1.4.6

Turns any input into a valid float32 corpus for the engine.

The Madhava engine is agnostic — it consumes float32 vectors and nothing else. This package is the adapter: it embeds text through a provider, validates the result, applies the L2 unit-norm contract, and optionally quantizes to uint8.

What it guarantees

  • Provider failover — OpenAI, Qwen3, nano, xfactor or direct vectors, tried in order
  • No silent fallback — if every provider fails it raises. It never substitutes a placeholder vector
  • Validation — dimension mismatch, NaN and zero-norm are rejected before reaching the engine
Why the no-fallback rule exists

A zero vector or random placeholder passes validation in most pipelines and silently corrupts every downstream bound. The engine's guarantee is only as good as the vectors it receives. Fail loudly instead.

from winnex_ai_normalize import normalize

corpus = normalize(
    texts=["first document", "second document"],
    provider="openai",
    dim=384,
    quantize=False
)

winnex-xfactor

embedding v1.0.8

Training-free manifold basis extracted from a pretrained model's embedding table.

Given a model's embed_tokens matrix, X-Factor computes the orthonormal basis of the subspace where those embeddings actually live. It never runs the model — the basis is derived structurally.

Ē = E − mean(E)                    # center
C = ĒᵀĒ / V                        # covariance (D×D)
C = U Λ Uᵀ                         # eigendecomposition
r = min{r : cumsum(Λ₁..r)/ΣΛ ≥ τ}   # effective rank
X = U[:, :r]                       # manifold basis (D×r)
P = X·Xᵀ                           # orthogonal projector

What you get

  • Deterministic — identical model weights always produce an identical basis
  • No training, no sampling, no random seed
  • Dimension reduction that preserves the manifold where tokens live
Role in the stack — a utility, not the core

X-Factor is a shortcut, and it should be described as one. It gives you a usable embedding space without an API call, which matters when data cannot leave the premises. But the real engineering value in this stack sits in winnex-madhava for proof and winnex-nano for inference reach. Adopt X-Factor when you need embeddings offline; do not mistake it for the reason to choose WINNEX.

winnex-nano

inference v0.1.47

General-purpose LLM inference on OpenCL — GPU and CPU, no CUDA. Bit-exact with Transformers, with memory management that fits a 7B model on a 16 GB card.

Model-agnostic (Qwen, BERT, DeepSeek, GPT), built on the Madhava kernels — the same QKᵀ matmul and the same selective top-K with Cauchy–Schwarz bounds. No logic is duplicated between the search engine and the inference engine.

Correctness comes first

The engine loads the same weights and the same BPE vocabulary as Hugging Face Transformers. It is not an approximation of the model — it is the model.

PathPerplexityTime (131 tokens)
CPU15.5517269.8 s
GPU (device mode) 15.551717.5 s

Measured on RTX 5060 Ti 16 GB, 31 GB host, Qwen2.5-7B. Relative perplexity difference: 7×10⁻⁶. The checkpoint is already bf16, so the GPU reads exactly the numbers the CPU reads after widening to f32 — nothing that was in the file is lost. That is 9.3× faster with identical output quality.

Memory strategy — why this fits where Transformers does not

A 7B model in f32 is 26.1 GB against a 16 GB card. The standard path raises out-of-memory. Four decisions change that:

DecisionEffect
bf16 weights when f32 does not fit 26.1 GB → 13.1 GB. The dtype is chosen once for the whole model — mixing formats per matrix corrupts every launch after the first switch
lm_head streamed in 512-row blocks 2.18 GB → 7.3 MB for the largest single tensor (152064 × 3584)
Weights keyed by tensor name, not host pointer Without this the device cache never hits and the GPU re-uploads 14.2 GB per forward — measured slower than CPU (90.8 s against 67.0 s)
16×16 tiled GEMM in local memory The original kernel measured 1 FLOP/byte against a machine balance of ~26 — it waited on its own weight reads. Tiling cuts global traffic per MAC by ~8×

enable_gpu() picks one of three strategies automatically:

ModeWhat lives whereWhen
device Every projection on the GPU (bf16 when f32 does not fit); host keeps only norms and biases The model fits in VRAM
stream One layer at a time through a scratch buffer Half the model fits, the whole does not
cpu Nothing on the device The model does not fit even at bf16

Modules

ModulePurpose
ForwardEngine General-purpose LLM forward pass, bit-exact with Transformers
WeightBalancer Multi-model fusion: W′ = Σᵢ αᵢ·R(qᵢ)·Wᵢ
ChunkEngine Chunked generation with Madhava working memory
SpectralTokenizer Character → quaternion spectrum. Deterministic, no vocabulary. An autonomous encoding, not a BPE replacement
server_sse OpenAI-compatible /v1/chat/completions (stream and non-stream)

Selective attention — exact, not heuristic

The default is exact causal softmax. MADHAVA_TOPK_ATTN=1 enables a selective mode where keys are pruned while the mass they account for stays within MADHAVA_EPSILON_MASS of the full softmax mass, and the retained set is renormalised. The guarantee is exact rather than a score bound: ‖attn_full − attn_pruned‖₁ ≤ 2ε.

On Qwen2.5-0.5B over 80 LAMBADA items, quality is preserved across all three arms — CPU softmax 35.0%, CPU with ε=1×10⁻⁴ 35.0%, CPU with ε=0.05 36.2% — all inside the confidence interval.

pip install winnex-nano

# with the OpenAI-compatible server
pip install "winnex-nano[server]"
What it is not

Not a training framework and not a replacement for fine-tuning. The spectral tokenizer path is slower and far less compact than BPE — it exists as an autonomous encoding for the native engine, not as a drop-in replacement for a BPE-trained model. Generation quality through the spectral path is not yet demonstrated with standard metrics; the retrieval and the bit-exact Transformers-parity path are the load-bearing claims.

winnex-tracer

audit trail v1.1.3

Turns a proof into a document.

The engine produces a proof per query. The tracer turns those proofs into a tamper-evident record that survives outside the system — the artifact you hand to an auditor, a regulator or a court.

ComponentFunction
WORM storageWrite-once record of every query
Ed25519 signingEach record signed by the issuing node
SHA3-256 hash chainEach record commits to the previous — tampering breaks the chain
AuditCommitmentNon-repudiation: the issuer cannot deny producing it

Domains

Four vertical wrappers ship inside the same package:

  • Tracer-GOV — public sector audit and external control
  • Tracer-JUS — e-discovery and legal production
  • Tracer-MED — clinical retrieval and billing audit
  • Tracer-GAP — financial gap and reconciliation analysis
pip install winnex-tracer             # core only
pip install "winnex-tracer[med]"      # with the medical domain

winnex-tracer-core

shared base v1.0.2

The substrate the tracer family shares: WORM storage, Ed25519/ICP signing, tamper-evident audit log, retention policies and AuditCommitment. All four domains depend on it. Install it standalone only when building a new tracer domain.

winnex-madhava-sec

security v3.1.0

Agent security through the same bound pruning.

Uses Cauchy–Schwarz bound pruning to detect prompt injection and classify agent inputs. Pruning removes most of the corpus before any classifier runs — that is where the saving comes from.

pip install winnex-madhava-sec
Benchmark honesty

On published agent-security datasets, detection F1 is 0.8183 with bound pruning against 0.8262 for direct search. Accuracy is essentially equal — pruning does not make classification better.

What it saves is inference cost: the bound removes the majority of candidates before the expensive path. Do not adopt this package expecting higher accuracy.

Benchmarks as use cases

Benchmarks are only useful when they tell you what you can build. Each table below is a measured scenario — not a leaderboard entry, but a configuration with a concrete deployment behind it. Every number comes from code in this repository against external ground truth, and the notebooks are public on Kaggle (kleniopadilha).

Where the numbers come from

Ground truth is external in every case: BIGANN's reference, an exact cosine scan, or the ANS regulatory document itself. Nothing was annotated by hand, and nothing is a self-referential claim of the engine against itself. Where a published figure was found to be invalid — the BIGANN ground-truth file in one Kaggle dataset turned out to point at the wrong vectors — it was withdrawn rather than kept. That is why some older numbers you may find quoted elsewhere no longer appear here.

Scenario: a regulatory document store per tenant

The setup. Ten thousand to fifty thousand documents per department. Nobody outside asks how fast it is; the audit team asks whether the retrieval was complete.

What the numbers say. In this size range Madhava is not just competitive, it is faster at query time than HNSW — 0.99 ms against 1.18 ms at 10,000 vectors, 2.42 ms against 2.35 ms at 50,000. The bound removes most of the corpus before any distance is computed, so below the crossover the proof costs effectively nothing. Above it, HNSW wins on latency and Madhava wins on the artifact.

Scenario: a corpus that grows every day

The setup. New documents arrive continuously and the index must be rebuilt without stopping the service.

What the numbers say. A 1M-vector index builds in 1.69 s. A 100M-vector corpus builds in 342.6 s on four CPUs, memory-mapped, with 0 bound violations. Rebuilding is a maintenance loop, not an outage.

Scenario: a hospital billing dispute

The setup. An operator denies a claim. The hospital needs to show the procedure was covered under the contract's segment.

What the numbers say. Against the ANS Rol as ground truth, coverage is decided correctly 97.5% of the time. A bill that should be paid is wrongly denied 1.5% of the time; a bill that should be denied is wrongly covered 1.0% of the time. Identifying the exact procedure is harder — 63.4% — and that figure is stated here because a procurement team will ask.

Scenario: proving that a search missed nothing

The setup. An auditor asks which documents were excluded and why.

What the numbers say. Top-1 agreement with exact scan is 1.0000 across 300 queries. setR@10 overlap is 0.9933. Bound violations: zero in every configuration tested. Each exclusion carries its bound; the tracer signs the record.

Reference tables

The detailed numbers follow.

Every number below was produced by code in this repository and can be reproduced. Ground truth is external: BIGANN, the ANS regulatory document, or an exact cosine scan.

Search engine

MetricValueSource
Top-1 agreement with exact scan1.0000 cosine reference, 300 queries
setR@10 overlap0.9933same run
Bound violations0all configurations
Recall@10, 1536-d, 99.8k vectors1.0000 [128→256] configuration
Recall@10, 20k vectors1.0000GloVe / BIGANN

Against HNSW

MethodRecallLatency
Madhava [128→256]1.000054.0 ms
HNSW (ef=256)0.99951.38 ms
HNSW (ef=128)0.99900.84 ms
HNSW (ef=64)0.99500.48 ms
IVF (nprobe=40)0.96403.15 ms

Read this table carefully. HNSW is 20 to 100 times faster at query time. Madhava is not faster there and does not claim to be. What Madhava buys you is that HNSW at ef=64 returns recall 0.9950 without knowing which 0.5% it lost, while Madhava returns 1.0000 and can prove it per document.

Index build time — where Madhava wins by a wide margin

Query latency is only half the story. The other half is how long it takes to build the index — and this is where the comparison inverts.

Same corpus: 99,800 vectors at 1,536 dimensions.

MethodBuild timeRelative
Madhava [128→256] 1.45 s1×
IVF (nprobe=40)15.62 s10.7× slower
HNSW (ef=256)33.60 s23.1× slower
The build advantage is 23× over HNSW

This is not a marginal difference. It changes what is practical: re-indexing after a schema change, rebuilding per tenant, running experiments across dozens of configurations, or rebuilding nightly instead of weekly.

Build time scales linearly and stays fast

Corpus sizeBuild time
1,000 vectors0.019 s
10,000 vectors0.020 s
50,000 vectors0.093 s
200,000 vectors0.504 s
500,000 vectors1.21 s
1,000,000 vectors1.69 s

One million vectors index in under two seconds. For comparison, building an HNSW index over the same 1M corpus typically takes minutes.

And at small scale, query latency is competitive

Below roughly 50,000 vectors, Madhava's query time is close to HNSW and faster than exact scan — because the bound prunes most of the corpus before any distance is computed.

CorpusMadhavaHNSWExact scan
1,0000.55 ms0.69 ms0.27 ms
5,0000.62 ms1.17 ms0.73 ms
10,0000.99 ms1.18 ms1.58 ms
50,0002.42 ms2.35 ms7.29 ms
200,00010.03 ms1.85 ms18.30 ms
1,000,00047.72 ms3.37 ms67.87 ms

The crossover is around 50,000 vectors. Below it, Madhava is faster than HNSW and dramatically faster than exact scan. Above it, HNSW wins on latency — while Madhava stays far ahead on build time and keeps the proof.

This matters for the way real deployments work. Most regulated document corpora are per-tenant or per-department, and most sit in the thousands to tens of thousands of documents. At that size the proof costs almost nothing.

Domain benchmark — ANS regulatory corpus

Task: given a TUSS procedure term from a hospital bill, find the corresponding procedure in the ANS Rol and decide whether it is covered in the operator's segment. Ground truth is the ANS regulatory documents themselves, not human annotation. 3,401 procedures, 5,496 pairs, 800-pair sample.

MetricValue
Coverage decision accuracy97.5%
False covered — bill that would be denied1.0%
False denied — legitimate revenue lost1.5%
Exact procedure identification (top-1)63.4%

The 63.4% is weak and is stated here deliberately. Identifying the exact procedure is harder than deciding coverage. Anyone evaluating this product should know that before a sales conversation, not after.

Limitations

Design constraints, not bugs scheduled for later.

Latency

20 to 100 times slower than HNSW at equal recall target. Bound computation and the exhaustive audit path have a cost that cannot be removed.

Scale

Benchmarked to 100k vectors in the reference configuration. Streaming 100M vectors via mmap is documented at roughly 18.6 GB RAM. Beyond that is unexplored in public benchmarks.

The proof covers the vector space, not the encoder

Madhava proves a document could not be in the top-K given the vectors it was indexed with. It does not prove the embedding was good. A poor encoder produces a correct but useless proof.

It does not improve classification

On classification tasks the pruning gives no benefit and can cost up to one percentage point of F1. This is a retrieval engine.

Not a compliance certificate

The audit trail is evidence, not ISO/IEC 42001 certification. A notified body will not accept a Cauchy–Schwarz bound in place of a conformity assessment. It is the technical artifact underneath that assessment.

License

Packages are released under the Business Source License 1.1 (BSL 1.1).

TermDetail
PermittedCopy, modify, derivative works, non-production use
RestrictedOffering the licensed work as a commercial search service to third parties
Change date2036-01-01, converting to GPL v2.0 or later
CommercialOEM embedding and redistribution require a commercial agreement

For commercial licensing, OEM embedding or redistribution inside another product, write to pay@winnex.ai.

Resources

PyPI organizationall published packages
GitHubsource and CI
Technical specificationDOI, pre-patent disclosure
winnex.aicompany