T3 Wave 4 Gap Closure & Live Pipeline Audit (2026)
Forensic code-to-specification audit comparing the T3 Wave 1–3 architecture blueprints against the live vox_chat_message, agent_loop, t3_wave3_tools, agy_worktree, webhook_intake, and Tauri IPC execution paths. Identifies ten concrete integration gaps where domain primitives were unit-tested in isolation but bypassed, stubbed, or broken on the live request path, and defines the six-phase Wave 4 (v4.8, Phases 265–270) remediation specification.
1. Executive Summary
Section titled “1. Executive Summary”Across Milestones v4.5 (Phases 247–252), v4.6 (Phases 253–258), and v4.7 (Phases 259–264), Vox implemented the core domain primitives from the T3 research corpus (t3code, t3router, pi-t3chat, thom-chat, helioschat):
- Typed IDs, Outbox & Compaction:
VoxIdAllocatorV2,OutboxQueue,context_sanitizer,CompactionConfig. - Router, Consensus, Battery & Stream Guards:
ConsensusOrchestrator,BatteryCostLedger,ResponseQualityAnalyzer,StreamIdleWatchdog,ToolRefusalDetector,AtomicResumableStreamBuffer. - Worktrees, Checkpoints, MCP & Local Sync:
GitPlumbingCheckpointStore,WorkspaceLeaseMap,provision_untracked_env_files,McpOAuthPKCEFlow,CommandOutputHub,ChatTranscriptCache. - Agentic UX, Rules, Webhooks & Session Interop:
UserRuleRegistry,resolve_user_rule_mentions,interpolate_system_prompt_variables,WebhookDedupeAndRateGate,GuestShareService,ExternalSessionImporter. - TOESTUB /
vox-code-auditStatic Detectors: 9 detectors (wire_unbounded_collection,sql_unbounded_query,v8_Map_Set_hot_path_clone,css_unscoped_transition_all,child_process_shell_true,worktree_git_index_race,git_log_unbounded_all,react_provider_inline_value,llm_stream_missing_idle_watchdog).
However, a line-by-line call-graph audit of crates/vox-orchestrator-mcp/src/chat_tools/chat/ and crates/vox-gui/ui/src/transport/t3Wave3Rpc.ts revealed 10 high-impact integration gaps (GAP-01 through GAP-10) where these modules are either broken on edge cases or bypassed on the live production execution path.
2. Forensic Gap Catalog (GAP-01 – GAP-10)
Section titled “2. Forensic Gap Catalog (GAP-01 – GAP-10)”GAP-01: tool:<name> Fence Stream Suppression Drops Tool Calls Without Salvaging (salvage_and_stream.rs)
Section titled “GAP-01: tool:<name> Fence Stream Suppression Drops Tool Calls Without Salvaging (salvage_and_stream.rs)”- Location:
crates/vox-orchestrator-mcp/src/chat_tools/chat/agent_loop/salvage_and_stream.rs(L211vsL377–390). - Root Cause:
looks_like_streamed_tool_call_envelope(L211) checkstrimmed.starts_with("```tool:")and returnstrue, suppressingTokenStreamedevents so raw tool fences are not leaked to the user transcript.- When the stream finishes and native
tool_callsis empty,salvage_tool_calls_from_text(L377) runsr"(?s)```(?:json|tool_call|xml)?\s*(.*?)\s*```". - For a
pi-t3chat-styletool:vox_read_filecode fence containing{"path": "Cargo.toml"},innercaptures"tool:vox_read_file\n{\"path\": \"Cargo.toml\"}", which failsserde_json::from_str. Tier 4 (extract_balanced_json_objects) extracts{"path": "Cargo.toml"}, which lacks a"name"field (normalize_salvaged_tool_call_itemreturnsNone). - Impact: Both the streamed text AND the salvaged tool call are silently dropped.
- Remediation (
T3-SALVAGE-RULES-01):- Add Tier 1.5 in
salvage_tool_calls_from_textmatchingr"(?s)```tool:([A-Za-z0-9_.:-]+)\s*\n(.*?)\s*```". Extractcap[1]asnameand parsecap[2](or balanced JSON object withincap[2]) asarguments, then normalize vianormalize_salvaged_tool_call_item.
- Add Tier 1.5 in
GAP-02: @rule:<name> Mentions & $variable System Prompt Interpolation Bypassed on Live Chat Turn (mentions.rs, preamble_and_retrieval.rs)
Section titled “GAP-02: @rule:<name> Mentions & $variable System Prompt Interpolation Bypassed on Live Chat Turn (mentions.rs, preamble_and_retrieval.rs)”- Location:
- Root Cause:
resolve_user_rule_mentions(mentions.rs:36) is never called byresolve_mentions(mentions.rs:308) orprepare_turn_context_and_retrieval. Worse,MENTION_RE(@([A-Za-z0-9_.:/\\-]+)) matches@rule:rust-strictand attempts to resolverule:rust-strictas a workspace file path, emitting[ Mention @rule:rust-strict not found in workspace ]!interpolate_system_prompt_variables(system_prompt_vars.rs:36) is never called when constructing the system prompt inbuild_system_prompt_with_skillorprepare_turn_context_and_retrieval.
- Remediation (
T3-SALVAGE-RULES-02..04):- In
resolve_mentions_with_rules/resolve_mentions, strip and resolve@rule:<name>tags (plusAlways-mode rules) viaresolve_user_rule_mentionsbefore runningMENTION_REfile resolution, loading persisted user rules fromstate.db(get_user_preference("local_user", "gui.user_rules")) with default fallback. - In
prepare_turn_context_and_retrieval(preamble_and_retrieval.rs), constructSystemPromptVarContextfromstate.repository(workspace_root, git branch from.git/HEAD),params.session_id,params.active_file,model_used_pre, andparams.cognitive_profile, and passsystem_promptthroughinterpolate_system_prompt_variables.
- In
GAP-03: context_sanitizer & UpToMessageId Compaction Not Wired into conversation.rs
Section titled “GAP-03: context_sanitizer & UpToMessageId Compaction Not Wired into conversation.rs”- Location:
crates/vox-orchestrator-mcp/src/chat_tools/chat/conversation.rs(L428–454). - Root Cause:
transcript_entry_to_llm_message(L428) pushes rawentry.contentdirectly intoChatMessagewithout callingvox_orchestrator::context_sanitizer::sanitize_assistant_for_historyon"assistant"turns orescape_prompt_injection_tokenson"user"/"tool"turns.- Closed
<think>...</think>blocks and<WebSearch>...</WebSearch>blocks from earlier turns remain in context on every subsequent turn. - Additionally,
vox_chat_compact_up_to(CompactionDirection::UpToMessageId) is not exposed inchat_tools/chat/history.rs.
- Remediation (
T3-HIST-BATTERY-01..02):- Wire
sanitize_assistant_for_history(&entry.content)for"assistant"messages andescape_prompt_injection_tokens(&entry.content)for"user"messages insidetranscript_entry_to_llm_message. - Add
chat_compact_up_to(vox_chat_compact_up_to) tocrates/vox-orchestrator-mcp/src/chat_tools/chat/history.rsanddispatch.rsso the GUI and agents can compact transcript history up to or from a specific anchormessage_id.
- Wire
GAP-04: BatteryCostLedger, VoxIdAllocatorV2 & Real ResponseQualityAnalyzer Scores Bypassed in message.rs & persist_and_envelope.rs
Section titled “GAP-04: BatteryCostLedger, VoxIdAllocatorV2 & Real ResponseQualityAnalyzer Scores Bypassed in message.rs & persist_and_envelope.rs”- Location:
- Root Cause:
BatteryCostLedger(crates/vox-orchestrator/src/budget/tracker.rs) is never instantiated onServerStateor checked/debited duringchat_message.persist_and_envelope.rs:44,53mints message IDs viaformat!("usr-{}", now_ts())andformat!("ast-{}", now_ts())(which collide whenever two turns complete within the same second) instead ofVoxIdAllocatorV2::derive.persist_and_envelope.rs:348hardcodesquality_score: Some(1.0)inLlmSurfaceTelemetryinstead of computing the actualResponseQualityAnalyzer::analyze_response_quality(¶ms.prompt, &response_text)score.
- Remediation (
T3-HIST-BATTERY-03..04):- Add
battery_ledger: Arc<BatteryCostLedger>andid_allocator: VoxIdAllocatorV2toServerState. - Run
state.battery_ledger.check_preflight_balance("local_user", 1.0)before turn execution andstate.battery_ledger.record_turn_usage("local_user", &session_id, &model_used, prompt_tokens, completion_tokens)inpersist_and_build_chat_envelope. - Mint deterministic collision-free
usr-*andast-*IDs viastate.id_allocator.derive(...). - Compute
analyze_response_quality(¶ms.prompt, &response_text)inpersist_and_build_chat_envelope, feed(quality.quality_score / 100.0)intoLlmSurfaceTelemetry::quality_score, and includequality_scoreandbattery_spent_buin the response envelope’sposture_audit.
- Add
GAP-05: CommandOutputHub \r Folding, bound_snapshot_metadata DOM Shedding, Pre-Write Sparse Checkpoints, Resumable Stream Buffer & Mid-Turn Steer Draining Not Wired in agent_loop.rs
Section titled “GAP-05: CommandOutputHub \r Folding, bound_snapshot_metadata DOM Shedding, Pre-Write Sparse Checkpoints, Resumable Stream Buffer & Mid-Turn Steer Draining Not Wired in agent_loop.rs”- Location:
- Root Cause:
- Tool outputs in
agent_loop.rs:542bypassvox_orchestrator::command_output_hub::normalize_terminal_output(\rprogress bar folding) andvox_orchestrator::snapshot::bound_snapshot_metadata(20 KiBDOM snapshot shedding). - Write/mutation tools (
should_sparse_checkpoint(&call.name)) execute atL524without capturing a pre-mutation sparse Git checkpoint (GitPlumbingCheckpointStore::capture_checkpoint). stream_llm_with_pref_and_events(salvage_and_stream.rs:69) emitsAgentEventKind::TokenStreamedtoEventBuswithout appending chunks to aResumableTurnStreamRegistry(AtomicResumableStreamBuffer) onServerState.- Between tool iterations (
agent_loop.rs:279), promoted steering prompts fromThreadRunQueue(ServerState::thread_run_queue) are never drained intomessages.
- Tool outputs in
- Remediation (
T3-LOOP-CHECKPOINT-01..04):- Normalize tool output strings with
normalize_terminal_outputandbound_snapshot_metadatabeforecap_and_summarize_tool_output. - When
should_sparse_checkpoint(&call.name)is true, automatically record a pre-tool sparse checkpoint onstate.checkpoint_store. - Hold
resumable_streams: Arc<ResumableTurnStreamRegistry>andthread_run_queue: Arc<RwLock<ThreadRunQueue>>onServerState; append streamed chunks instream_llm_with_pref_and_eventsand exposevox_chat_stream_resume; drain promoted steering items (QueueDisposition::Steer) intomessagesat the start of eachagent_loopiteration.
- Normalize tool output strings with
GAP-06: Synthetic/Stateless Handlers in t3_wave3_tools.rs
Section titled “GAP-06: Synthetic/Stateless Handlers in t3_wave3_tools.rs”- Location:
crates/vox-orchestrator-mcp/src/t3_wave3_tools.rs(L141–231,L406–564). - Root Cause:
handle_consensus_run(L141) generates synthetic string templates whenlegsis omitted instead of fanning out concurrentcall_llm_with_prefcalls across the requestedmodelsviafutures_util::future::join_all(with graceful fallback when no upstream API key is configured).handle_context_handoff(L194) ignoresstate(_state) whenturnsis omitted instead of hydratingsource_thread_id’s live conversation history viacontext_history_or_hydrate(state, &format!("chat_history:{source_thread_id}"))and writing the handoff brief intochat_history:{new_thread_id}.handle_guest_share_mint&handle_guest_share_moderate(L406–474) instantiate a fresh localGuestShareService::new_from_clavis()on every call instead of sharing a persistentArc<RwLock<GuestShareService>>onServerStateand appending approved guest prompts intochat_history:{thread_id}.handle_session_import_external,handle_session_export_bundle, andhandle_session_import_bundle(L477–564) ignorestate:import_externaldoes not read realfile_path/~/.claude/projects,~/.codex/sessions, or~/.cursor/chatsfiles whenraw_payloadis omitted, nor does it persist imported turns intochat_history:{session_id}.export_bundledoes not hydratechat_history:{session_id}fromstatewhenmessagesis omitted.import_bundledoes not write the verified bundle’s messages intochat_history:{session_id}andstate.db.
- Remediation (
T3-STATEFUL-TOOLS-01..04):- Wire all six handlers in
t3_wave3_tools.rsto liveServerState(context_history_or_hydrate,persist_context_Async,state.guest_share_service, and concurrentjoin_allLLM fan-out inhandle_consensus_run).
- Wire all six handlers in
GAP-07: Missing vox_chat_regenerate & vox_chat_edit_message_in_place Backend MCP Tools (history.rs, dispatch.rs)
Section titled “GAP-07: Missing vox_chat_regenerate & vox_chat_edit_message_in_place Backend MCP Tools (history.rs, dispatch.rs)”- Location:
crates/vox-orchestrator-mcp/src/chat_tools/chat/history.rs. - Root Cause:
t3-vox-agentic-ux-rules-webhooks-and-session-interop-spec-2026.md§1.3 specified two distinct message mutation operations:vox_chat_edit_message_in_place: mutates an assistant (or user) message’s content in-place inchat_history:{session_id}without truncating subsequent messages ([Edited]badge).vox_chat_regenerate: truncates history from the target message onward and re-triggerschat_messagewith the storedGenerationPostureSnapshotor an explicitmodel_override/reasoning_effort.
- Currently only
vox_chat_slash/retryandvox_chat_forkexist.
- Remediation (
T3-REGEN-WORKTREE-01):- Implement
chat_edit_message_in_placeandchat_regenerateincrates/vox-orchestrator-mcp/src/chat_tools/chat/history.rsand registervox_chat_edit_message_in_place,vox_chat_regenerate,vox_chat_compact_up_to,vox_chat_stream_resume, andvox_chat_queue_steerintool_registry.rs,input_schemas.rs, anddispatch.rs.
- Implement
GAP-08: DelegationWorktree::create & submit_webhook_events Internal Bypass (agy_worktree.rs, webhook_intake.rs)
Section titled “GAP-08: DelegationWorktree::create & submit_webhook_events Internal Bypass (agy_worktree.rs, webhook_intake.rs)”- Location:
crates/vox-orchestrator-mcp/src/agy_worktree.rs(L94,L157–170)crates/vox-orchestrator-mcp/src/server_state/webhook_intake.rs(L94,L188–209)
- Root Cause:
DelegationWorktree::createspawnsgit worktree addwithout acquiringWorkspaceLeaseMap::global().lease_for(repo_root)and without callingprovision_untracked_env_files(repo_root, &wt_path)(L94) after worktree creation.submit_webhook_events(webhook_intake.rs:188) validates the HMAC signature and immediately pushes events intowebhook_inboxwithout callingWebhookDedupeAndRateGate::admit_delivery(L94) to reject replayeddelivery_ids or> 60/minbursts.
- Remediation (
T3-REGEN-WORKTREE-02..03):- Acquire the
WorkspaceLeaseMapmutex guard acrossgit worktree addand callprovision_untracked_env_files(repo_root, &wt_path)inDelegationWorktree::create. - Hold a
WebhookDedupeAndRateGateonServerState(or global singleton) and gate everyWebhookEventIteminsubmit_webhook_eventsviaadmit_delivery.
- Acquire the
GAP-09: vox_orchestrator_status Ignores compact Argument & transfer_budget.rs Uses Synthetic Fixtures
Section titled “GAP-09: vox_orchestrator_status Ignores compact Argument & transfer_budget.rs Uses Synthetic Fixtures”- Location:
- Root Cause:
dispatch.rs:806callsdei_tools::orchestrator_status(state).awaitunconditionally, ignoringargs["compact"]andargs["omit_idle_subagents"]instead of routing todei_tools::orchestrator_status_compact(state, omit_idle_subagents).transfer_budget.rstests a hardcoded 5-fieldserde_json::json!literal instead of building a 900-row / 1.1 MiB payload and asserting thatorchestrator_status_compact+cap_and_summarize_tool_outputkeep the wire payload under256 KiBand4DB round-trips.
- Remediation (
T3-REGEN-WORKTREE-04):- Route
vox_orchestrator_statusindispatch.rstoorchestrator_status_compactwhencompact == true(defaultingomit_idle_subagentstotrue), and upgradecrates/vox-orchestrator-mcp/tests/transfer_budget.rsto exercise the real compact projection and 1.1 MiB tool-output capping functions.
- Route
GAP-10: t3Wave3Rpc.ts unwrapMcpData Fails on Tauri invoke_mcp_tool { is_error, result } Wrapper (t3Wave3Rpc.ts)
Section titled “GAP-10: t3Wave3Rpc.ts unwrapMcpData Fails on Tauri invoke_mcp_tool { is_error, result } Wrapper (t3Wave3Rpc.ts)”- Location:
crates/vox-gui/ui/src/transport/t3Wave3Rpc.ts(L88–104). - Root Cause:
- In Tauri desktop mode,
voxTransport.invokeMcpToolinvokes Tauri commandinvoke_mcp_tool(crates/vox-gui/src/commands/mod.rs:146), which returns{ is_error: false, result: { success: true, data: ... } }(or a JSON string insideresult). unwrapMcpDataint3Wave3Rpc.ts:96only checksif ('data' in obj && obj.data !== undefined) return obj.data as T;at the outer object level. Becausedatais nested insideobj.result.data,unwrapMcpDatareturns the outer{ is_error: false, result: ... }wrapper, which fails every caller’s field check ('winning_response' in res,'bundle_json' in res,'share_token' in res, etc.) and causes the GUI to fall through to hardcoded mock objects even when connected to the live Rust backend!
- In Tauri desktop mode,
- Remediation (
T3-GUI-ENVELOPE-01..04):- Fix
unwrapMcpDataint3Wave3Rpc.tsto recursively unwrap{ is_error, result }, stringified JSON payloads, MCP{ content: [{ type: 'text', text: '...' }] }blocks, and{ success, data }envelopes (throwing whenis_error === trueorsuccess === false). - Add typed client wrappers
regenerateChatTurn,editChatMessageInPlace,compactChatUpTo,resumeChatStream, andsteerChatQueueint3Wave3Rpc.ts, wire in-place assistant message editing and posture-aware regeneration intoChatTranscript.tsx, and add Vitest coverage verifying real Tauri{ is_error: false, result: { success: true, data: ... } }envelope unwrapping.
- Fix
3. Milestone v4.8 Phase Mapping (Phases 265–270, 24 Requirements)
Section titled “3. Milestone v4.8 Phase Mapping (Phases 265–270, 24 Requirements)”| Phase | Requirement IDs | Scope |
|---|---|---|
| Phase 265 | T3-SALVAGE-RULES-01..04 | Fix tool:<name> fence salvage in salvage_and_stream.rs, wire @rule:<name> + Always rules into resolve_mentions (mentions.rs), and wire interpolate_system_prompt_variables into preamble_and_retrieval.rs. |
| Phase 266 | T3-HIST-BATTERY-01..04 | Wire sanitize_assistant_for_history & escape_prompt_injection_tokens into conversation.rs, expose vox_chat_compact_up_to, and wire live BatteryCostLedger, VoxIdAllocatorV2, and ResponseQualityAnalyzer into message.rs & persist_and_envelope.rs. |
| Phase 267 | T3-LOOP-CHECKPOINT-01..04 | Wire normalize_terminal_output (\r), bound_snapshot_metadata (20 KiB DOM cap), automatic pre-write sparse Git checkpoints (should_sparse_checkpoint), ResumableTurnStreamRegistry (vox_chat_stream_resume), and mid-turn ThreadRunQueue steer draining into agent_loop.rs. |
| Phase 268 | T3-STATEFUL-TOOLS-01..04 | Upgrade t3_wave3_tools.rs to dispatch concurrent join_all LLM calls in vox_consensus_run, hydrate/persist real chat_history:{session_id} transcripts in vox_context_handoff & vox_session_*, and persist GuestShareService on ServerState. |
| Phase 269 | T3-REGEN-WORKTREE-01..04 | Implement vox_chat_regenerate & vox_chat_edit_message_in_place in history.rs, wire WorkspaceLeaseMap + provision_untracked_env_files in DelegationWorktree::create, wire WebhookDedupeAndRateGate in submit_webhook_events, and wire compact in vox_orchestrator_status + transfer_budget.rs. |
| Phase 270 | T3-GUI-ENVELOPE-01..04 | Fix unwrapMcpData in t3Wave3Rpc.ts for nested Tauri { is_error, result: { success, data } } & MCP content blocks, wire regenerateChatTurn & editChatMessageInPlace in ChatTranscript.tsx, and verify all Rust, Vitest, TypeScript, and audit gates. |