T3-to-Vox Domain 2 Implementation Spec: RepetitionGuard, ToolRefusalDetector, Battery Ledger & Multi-Model Consensus (2026)
This document specifies the exact Rust and TypeScript implementation for Phases 218–220 (T3-GUARD-REFUSAL-01..04, T3-BATTERY-LEDGER-01..04, and T3-CONSENSUS-QA-01..04) of Milestone v4.1. It details the 1024-slot power-of-2 ring-buffer RepetitionGuard (NotT3Chat), ToolRefusalDetector auto-retry (pi-t3chat), MCP tool-search prompt-cache bloat mitigation (t3code ClaudeAdapterV2), the Battery Unit (1 BU = $0.001) pre-flight balance gate and 4-step transactional usage ledger (omnichat), <think>/<WebSearch> context sanitization, parallel Multi-Model Consensus SSE fan-out (lulkebit/t3-cloneathon), and the Flesch-Kincaid ResponseQualityAnalyzer.
1. Phase 218: RepetitionGuard, ToolRefusalDetector & Cache-Write Guard (T3-GUARD-REFUSAL-01..04)
Section titled “1. Phase 218: RepetitionGuard, ToolRefusalDetector & Cache-Write Guard (T3-GUARD-REFUSAL-01..04)”1.1 O(1) 1024-Slot Ring-Buffer RepetitionGuard (crates/vox-llm-egress/src/repetition_guard.rs)
Section titled “1.1 O(1) 1024-Slot Ring-Buffer RepetitionGuard (crates/vox-llm-egress/src/repetition_guard.rs)”- Source Inspiration:
shaltielshmid/NotT3Chatbackend/Program.cs:1080-1145(RepetitionGuard). - Legacy Code Replaced: Unbounded token accumulation in
crates/vox-orchestrator-mcp/src/chat_tools/chat/agent_loop/salvage_and_stream.rs:70-134that streams degenerate model loops untilmax_tokensis exhausted. - Implementation Design:
pub const REPETITION_BUFFER_SIZE: usize = 1024;pub const REPETITION_MODULO_MASK: usize = REPETITION_BUFFER_SIZE - 1;pub const MAX_SINGLE_TOKEN_REP: usize = 32;pub const MIN_NGRAM_PERIOD: usize = 3;pub const MAX_NGRAM_PERIOD: usize = 12;pub const MIN_NGRAM_REPETITIONS: usize = 5;pub struct RepetitionGuard {ring: [u64; REPETITION_BUFFER_SIZE],count: usize,consecutive_same: usize,last_hash: u64,}
- On each non-whitespace token/chunk (
push_token(token: &str) -> Result<(), RepetitionLoopError>):- Computes
hash = vox_crypto::fast_hash(token.as_bytes())(XXH3-64fromcrates/vox-crypto/src/facades.rs:25). - Increments
consecutive_sameifhash == self.last_hash; ifconsecutive_same >= MAX_SINGLE_TOKEN_REP(32), returnsErr(RepetitionLoopError::SingleTokenRun { count: 32 }). - Writes
self.ring[self.count & REPETITION_MODULO_MASK] = hash; self.count += 1;. - For each n-gram period
pinMIN_NGRAM_PERIOD..=MAX_NGRAM_PERIOD(3..=12), ifself.count >= p * MIN_NGRAM_REPETITIONS, checks whether the lastp * MIN_NGRAM_REPETITIONSslots repeat the finalphashes identically. If so, returnsErr(RepetitionLoopError::NGramCycle { period: p, repetitions: MIN_NGRAM_REPETITIONS }), aborting the stream immediately.
- Computes
- On each non-whitespace token/chunk (
1.2 ToolRefusalDetector & ```tool:<name> Salvage (crates/vox-orchestrator-mcp/src/chat_tools/chat/agent_loop/salvage_and_stream.rs)
Section titled “1.2 ToolRefusalDetector & ```tool:<name> Salvage (crates/vox-orchestrator-mcp/src/chat_tools/chat/agent_loop/salvage_and_stream.rs)”- Source Inspiration:
vibheksoni/pi-t3chattools.ts:45-305(ToolRefusalDetector&ToolCallTranslator). - Legacy Code Replaced:
- Delete stale
// ponytail: this ceiling (fallback-on-empty...)block atsalvage_and_stream.rs:1-34. - Update
looks_like_streamed_tool_call_envelope(salvage_and_stream.rs:219-248) to also recognize```tool:fenced blocks (trimmed.starts_with("```tool:")).
- Delete stale
- Refusal Detection & 1-Retry Recovery (
detect_false_tool_refusal):- When
available_tools_count > 0,assembled_tool_calls.is_empty(), andcontent.len() < 700, inspects the first350chars against both regexes:REFUSAL_RE:(?i)\b(can't|cannot|can not|don't have|do not have|unable to|not able to|no access|without access|can't actually|cannot actually)\bCAPABILITY_RE:(?i)\b(tool|terminal|shell|command|run|execute|file|filesystem|browse|browser|web search|search|calendar|schedule|environment)\b
- If both match and
!retried_refusal, discards the refusal turn and automatically re-invokes once with a corrective system reminder listing the active tool names.
- When
1.3 MCP Tool-Search Prompt-Cache Write Guard (crates/vox-orchestrator-mcp/src/external_mcp.rs)
Section titled “1.3 MCP Tool-Search Prompt-Cache Write Guard (crates/vox-orchestrator-mcp/src/external_mcp.rs)”- Source Inspiration:
t3codeapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts:66-105, 1295-1356(claudeToolSearchOverride, commit24c80f34). - Mechanics: When delegating to Claude Code or building MCP tool catalogs where
ENABLE_TOOL_SEARCHis unset orauto/auto:N(0 < N < 100), automatically enforcesENABLE_TOOL_SEARCH = "true"(and activatesLazyMcpGroupRegistry3-tool mode when MCP tool count> 12), preventing the 10x prompt-cache write cost explosion caused by inlining full MCP schemas into 1M-context sessions.
2. Phase 219: Battery Unit Pre-Flight Gate, 3-Tier Cost Ledger & Context Sanitization (T3-BATTERY-LEDGER-01..04)
Section titled “2. Phase 219: Battery Unit Pre-Flight Gate, 3-Tier Cost Ledger & Context Sanitization (T3-BATTERY-LEDGER-01..04)”2.1 BatteryAndCostLedger (crates/vox-orchestrator/src/budget/tracker.rs)
Section titled “2.1 BatteryAndCostLedger (crates/vox-orchestrator/src/budget/tracker.rs)”- Source Inspiration:
guitaripod/omnichatsrc/lib/battery-pricing.ts&src/lib/usage-tracking.ts:130-198,TGlide/thom-chat/api/v1/generation, andvibheksoni/t3routerpoll_credit_delta. - Legacy Code Replaced: Bare
UsageTracker(crates/vox-orchestrator/src/budget/tracker.rs:1-27) andcost_usd: Noneinsalvage_and_stream.rs:187. - Implementation Design:
- Unit Definition:
1 Battery Unit (BU) = $0.001 USD(1_000micro-USD). Local models (ProviderType::Ollama/VoxLocal/Mens) cost0 BUand bypass pre-flight balance checks (is_zero_cost_local). - Pre-Flight Balance Check (
check_preflight_balance): Before dispatching any paid provider turn, estimatesestimated_bufrom prompt token count + expected completion tokens; ifremaining_balance_bu < estimated_bu, returnsBudgetGateError::InsufficientBattery { required_bu, remaining_bu }(HTTP402/ RPC equivalent). - 4-Step Post-Stream Ledger Write (
record_turn_usage_and_reconcile):- Records
TurnCostDeltaReceipt(EstimatedTokenCount,ProviderGenerationLookup, orSubscriptionCreditDelta). - Decrements
remaining_balance_buatomically. - Appends a signed
BatteryTransaction(Purchase | Subscription | Bonus | Refund | Usage,amount_bu,balance_after_bu,model_id). - Updates
DailyUsageSummary(total_bu_used,total_messages,models_usedmap) and callsModelRegistry::reconcile_turn_cost_deltato updateobserved_cost_per_1k_usd.
- Records
- Unit Definition:
2.2 Subsequent-Turn Context Tag Sanitization (crates/vox-orchestrator-mcp/src/chat_tools/chat/context_sanitizer.rs)
Section titled “2.2 Subsequent-Turn Context Tag Sanitization (crates/vox-orchestrator-mcp/src/chat_tools/chat/context_sanitizer.rs)”- Source Inspiration:
shaltielshmid/NotT3Chatbackend/Program.cs:554-586, 629-670(CleanMessageFromSpecialEntities) &helioschatopenai-compatible.ts:452-498. - Mechanics:
- Parses all four reasoning tag pairs (
<think>...</think>,<thinking>...</thinking>,<reason>...</reason>,<reasoning>...</reasoning>) plus<WebSearch>...</WebSearch>during streaming. - When assembling prior assistant turns for subsequent LLM calls, strips closed
<think|thinking|reason|reasoning>blocks and replaces<WebSearch>[\s\S]*?</WebSearch>with"[web_search was called, results removed to save context.]", while escaping prompt-injection tokens (<|im_start|>,<|im_end|>,<tool_call>) in raw user inputs.
- Parses all four reasoning tag pairs (
2.3 External Multi-Benchmark Priors (SnitchBench, SkateBench, SweBench, LiveBench), /1e6 Cost Evaluator & LiteLLM 24h Rate Cache (crates/vox-orchestrator/src/models/bench_evidence.rs & discovery_pipeline.rs)
Section titled “2.3 External Multi-Benchmark Priors (SnitchBench, SkateBench, SweBench, LiveBench), /1e6 Cost Evaluator & LiteLLM 24h Rate Cache (crates/vox-orchestrator/src/models/bench_evidence.rs & discovery_pipeline.rs)”- Source Inspiration:
vibheksoni/t3routersrc/t3/models.rs:1-421(scrape_benchmarks,eval_js_number) &t3codeapps/server/src/usage/UsageService.ts(LiteLLM 24h rate cache). - Legacy Code Replaced: Single-index
intelligence_indexcheck incrates/vox-orchestrator/src/models/discovery_pipeline.rs:91and static pricing fallback incrates/vox-orchestrator/src/models/cost_tier.rs. - Mechanics:
ExternalBenchmarkPrior(crates/vox-orchestrator/src/models/bench_evidence.rs): ExtendsModelCapabilitiesandBenchEvidencewith normalized0.0..=1.0external benchmark scores:artificial_analysis_index: Option<f32>swe_bench_verified: Option<f32>live_bench_coding: Option<f32>skate_bench_score: Option<f32>snitch_bench_safety_penalty: Option<f32>
- Cold-Start Bayesian Prior Blending: When a model has
< 5local benchmark runs inBenchEvidence,blended_quality()seeds its Beta prior (alpha_0, beta_0) from the weighted mean of available external benchmarks (0.40 * swe_bench + 0.30 * live_bench + 0.20 * artificial_analysis + 0.10 * skate_bench), rather than flat0.5. eval_cost_expression& 24h LiteLLM Rate Table Cache: Supportst3router’s/1e6fractional cost expressions (eval_js_number("3.0/1e6") -> 0.000003) and caches upstream LiteLLM/OpenRouter per-token rate tables (input_cost_per_token,output_cost_per_token,cache_read_input_token_cost,cache_creation_input_token_cost) with a 24-hour TTL on disk soTurnCostDeltaReceiptalways computes exact cache-read and cache-write USD costs even for newly discovered models.
2.4 Partial History Compaction (up_to) & Gemini thoughtSignature Preservation (crates/vox-orchestrator/src/compaction.rs)
Section titled “2.4 Partial History Compaction (up_to) & Gemini thoughtSignature Preservation (crates/vox-orchestrator/src/compaction.rs)”- Source Inspiration:
t3codeapps/server/src/orchestration-v2/CompactionService.ts(up_to,compact_message_index) &helioschatsrc/lib/server/ai/openai-compatible.ts:127-205(thoughtSignaturepreservation). - Legacy Code Replaced: Whole-buffer-only compaction in
crates/vox-orchestrator/src/compaction.rs:210-340. - Mechanics:
- Adds
CompactionDirection { Full, UpToMessageId(String), FromMessageId(String) }and persistscompact_message_index: Option<usize>on the thread record so the UI renders an inline"Context compacted up to here"divider while keeping full raw messages inspectable in SQLite. - Preserves provider-specific
thought_signature: Option<String>on tool-call parts across compaction and turn replay so Gemini 2.5/3 thinking models never reject multi-step tool-calling turns.
- Adds
3. Phase 220: Multi-Model Consensus SSE Fan-Out & ResponseQualityAnalyzer (T3-CONSENSUS-QA-01..04)
Section titled “3. Phase 220: Multi-Model Consensus SSE Fan-Out & ResponseQualityAnalyzer (T3-CONSENSUS-QA-01..04)”3.1 ConsensusFanOutEngine (crates/vox-orchestrator/src/models/consensus.rs)
Section titled “3.1 ConsensusFanOutEngine (crates/vox-orchestrator/src/models/consensus.rs)”- Source Inspiration:
lulkebit/t3-cloneathonsrc/app/api/chat/consensus/route.ts&src/components/ConsensusMessage.tsx. - Mechanics:
- Accepts
models: Vec<String>(2..=4models) and dispatches them concurrently viafutures_util::future::join_all, multiplexing all streams over a single channel emitting:ConsensusEvent::Start { models }ConsensusEvent::Update { model_index, model, delta, is_streaming: true }ConsensusEvent::Complete { model_index, model, response_time_ms, quality_metrics: ResponseQualityMetrics }ConsensusEvent::Error { model_index, model, error }ConsensusEvent::Final { responses: Vec<ConsensusResponse>, average_response_time_ms }
- Accepts
3.2 Deterministic ResponseQualityAnalyzer (crates/vox-orchestrator/src/models/quality_analyzer.rs)
Section titled “3.2 Deterministic ResponseQualityAnalyzer (crates/vox-orchestrator/src/models/quality_analyzer.rs)”- Source Inspiration:
lulkebit/t3-cloneathonsrc/lib/response-quality-analyzer.ts. - Formula (
0.0..=100.0): [ \text{quality_score} = 0.30 \cdot \text{relevance} + 0.25 \cdot \text{clarity} + 0.20 \cdot \text{coherence} + 0.20 \cdot \text{completeness} + 0.05 \cdot \text{readability} - \text{penalties} ]readability: Flesch Reading Ease (206.835 - 1.015 * (words / sentences) - 84.6 * (syllables / words)clamped to0..=100).coherence: Density of 19 logical connectors (however,therefore,furthermore,consequently,specifically, etc.) + paragraph transition smoothness.clarity: Average sentence length (15..=25words optimal) + structural markdown formatting (headers, lists, code blocks) minus lexical repetition penalty.relevance: Non-stopword prompt keyword overlap ratio.- Bucketed into 5 tiers (
Excellent >= 85,Good >= 70,Fair >= 55,Poor >= 40,VeryPoor < 40) for router telemetry and/api/quality-analyticsreporting.
4. Verification Gates (Phases 218–220)
Section titled “4. Verification Gates (Phases 218–220)”timeout 900s cargo test -p vox-llm-egress --lib repetition_guard::tests(verifying 32-token single-token run halt and 3..12 n-gram period x5 cycle halt usingvox_crypto::fast_hash).timeout 900s cargo test -p vox-orchestrator-mcp --lib chat_tools::chat::agent_loop::salvage_and_stream::tests(verifyingdetect_false_tool_refusal1-retry recovery and```tool:<name>salvage).timeout 900s cargo test -p vox-orchestrator --lib budget::tracker::tests(verifying Battery Unit1 BU = $0.001pre-flight402balance gate,is_zero_cost_localbypass, and 4-step ledger reconciliation).timeout 900s cargo test -p vox-orchestrator --lib models::consensus::tests(verifying parallel 2..4 model fan-out and Flesch-KincaidResponseQualityAnalyzer).