All five detectors now ship in this codebase
The detector catalog has been carrying two "preview" rows (bias drift, hallucination) and one "external_api" row (coordination loop) since the marketplace launched. Today all five detectors ship inline -- the catalog is now an honest list of things that actually run.
What's new:
coordination_loop-- moved fromexternal_apitoinline. Re-implemented in TypeScript: builds the agent communication graph from the event'spayload.steps, runs Tarjan's SCC, fires when a cycle persists across 6+ steps. The historical Python version used persistent homology on a simplicial complex; for graphs of the size we see in real agent traces (<= 30 agents, <= 200 steps) Tarjan agrees with the math and is two orders of magnitude faster.bias_drift-- moved frompreviewtoinline. Statistical detector: pulls the 30-day baseline and current 24h window of decisions for a givensubject.group, fires when approval rates diverge by 20+ percentage points. Sampled at 10% of qualifying events to keep DB load bounded. Requires a group label and a binary outcome signal in the payload -- this is bias detection, not bias measurement, and it can't fire without labeled data.hallucination-- moved frompreviewtoinline. For RAG systems: whenpayload.retrieved_contextandpayload.completionare both present, the detector sends them to Claude Haiku as a strict JSON-mode entailment classifier. Fires on unsupported claims with classifier confidence >= 0.45. Sampled at 20% of qualifying events, ~$0.0001 per detection. RequiresANTHROPIC_API_KEY; without it the detector silently no-ops.
Architecture note: detector evaluators can now return Promise<DetectorMatch> in addition to the sync variant. The ingest evaluator wraps async detectors in a 1.5s timeout so a slow downstream (Anthropic API latency spike, slow Supabase query) cannot stall ingestion. A timed-out detector treats the event as "no match" -- the receipt still signs and persists.
What the docs used to say vs. what's true now: previous releases described an "external Python analyzer service" that hosted some of these detectors. There was never a deployed service. The references in the registry, the docs, and the CLAUDE.md were architectural intent. As of today the codebase is honest: every detector lives in lib/detectors/inline/* and runs in the Next.js process. The external_api mode is reserved for future heavy-ML detectors that genuinely need a separate runtime (a local entailment model, vector retrievers, etc.) but is unused today.
Cost of running this in production: the Anthropic-backed hallucination detector is the only one with a marginal cost. At 20% sampling and Haiku pricing, expect ~$0.10 per 1,000 receipts that have both retrieved context and a completion -- negligible at any reasonable scale. Disable the detector if your traffic pattern doesn't involve RAG.
No new migration.