6 September 2026 · Jarvis-owned code only
Jarvis layer implementation and performance review
The main problem is scattered ownership: catalogs, presentation projection, retries and speech lifetime are implemented in several places. Consolidate those responsibilities before adding more abstractions.
Scope
This is a normal review of the current workspace, not a PR comparison. Source links pin the inspected checkout (1668bd598) for reproducibility only. T3 implementations, the inherited sidebar, generic connection infrastructure and TTS model selection are excluded. Every proposed change belongs to Jarvis and uses existing public T3 seams.
Inspected Jarvis core grounding, confirmation, semantic/model selection, task state, identity, vocabulary and presentation; mesh and client adapters; server controller, task desk, aliases, follow-ups, presentation, push and voice compute; web/mobile interaction, settings, onboarding and speech; desktop worker/protocol and Jarvis packaging. This is source review with focused helper checks, not exhaustive runtime certification. No live database, app server, browser, simulator or microphone was used. Device behavior, production latency, heap and bundle impact remain unmeasured.
AGENTS.md now makes Jarvis ownership the default scope, forbids upstream refactoring under a broad “whole app” request, and requires explicit authorization for an upstream seam change.
What I would tackle first
- Fix consent, missing broker settlement and desktop decoding. These are small contracts with direct user consequences.
- Consolidate presentation projection and reconcile mobile listener lifetime. Their costs amplify each other.
- Remove global follow-up retry blocking and stop hydrating every recent task before deciding.
- Unify catalog and speech ownership, then share only the interaction transitions that both clients need.
- Apply alias indexing and streaming release hashes as smaller, local improvements.
No recommendation requires changing T3 provider, orchestration, persistence-query, terminal or coding-UI implementations.
High priority · Confirmed helper behavior
1. Approval parsing mistakes questions for consent
The positive-keyword regex accepts “should I approve it?”, “maybe allow it” and “allow it only if tests pass”. The pending-reply interpreter uses that decision to construct an approval answer. Negation handling alone does not make consent explicit.
Smaller implementation
Use a small closed grammar for explicit approval answers. Questions, conditions and mixed instructions must remain clarification. Keep the authority in Jarvis’s deterministic interpreter.
CurrentQuestion/conditional → positive keyword → accept
ProposedExplicit complete answer → deterministic decision
Focused proof
Add negative cases at interpretPendingJarvisReply, then check desktop/mobile/text/voice callers. Existing affirmative and refusal cases must survive.
packages/jarvis-core/src/confirmation.ts:42
High priority · Confirmed source path
2. Presentation projection runs once per subscriber
Every Jarvis presentation subscriber listens to all eligible domain events, loads thread detail and project data, and builds a presentation before filtering by origin. More devices and retained mobile turns multiply identical Jarvis work.
Smaller implementation
One Jarvis-owned live projection should build each presentation once and fan it out through a bounded ephemeral stream. Keep exact origin filtering, scoped shutdown and durable task inspection on reconnect. No replay ledger or T3 event-engine changes.
CurrentEach listener → load + build + origin filter
ProposedOne Jarvis projection → origin-filtered listeners
Focused proof
Assert one projection read per event with multiple origins and devices; verify overflow behavior, isolation and no replayed speech.
apps/server/src/jarvis/Layers/JarvisWsRpc.ts:419
High priority · Confirmed source path
3. Follow-up retries block unrelated tasks
One Jarvis worker handles all queued thread wakeups. Its dispatch and markDispatched chain retries twice with 30-second spacing. One failing item can occupy the worker through 60 seconds of retry delay, delaying unrelated tasks. It also hydrates details on ready events before checking whether Jarvis has pending work.
Smaller implementation
Keep per-thread serialization and cancellation ownership, but use a small bounded Jarvis worker pool and coalesced wakeups. Schedule retries without holding global progress. Separate accepted task execution from status cleanup. Check the Jarvis queue before expensive reads.
CurrentOne retrying thread → all follow-ups wait
ProposedBounded workers + per-thread owner → independent progress
Focused proof
Inject a failing A and ready B; B must dispatch without waiting for A’s retry clock. Check stop/claim/dispatch races and restart idempotency with typed drains.
apps/server/src/jarvis/Layers/JarvisFollowUpDispatcher.ts:78
High priority · Confirmed source path
4. Mobile retains listeners after missed completion
Refresh reloads catalog and selected desk, but does not reconcile activeTurns. Terminal live presentations remove retained turns; a completion missed offline does not. Each retained turn mounts another presentation subscription. Forgotten nodes are not pruned from activeTurns in the catalog effect.
Smaller implementation
Reconcile retained node-qualified tasks on reconnect/foreground using existing public task state reads. Retire settled or confirmed-missing tasks and removed nodes, preserve unreachable tasks, and deduplicate lookups. Do not build another completion store.
CurrentMissed completion → retained turn → permanent listener
ProposedReconnect inspection → settle or retain by durable state
Focused proof
Cover offline completion, removed node, 404, unreachable node and repeated foreground transitions. Subscription count should return to the number of genuinely active interactions.
apps/mobile/src/features/jarvis/JarvisMobileProvider.tsx:219
High priority · Source path and local TCP repro reported by review lane
5. Voice broker clean disconnect leaves a request pending
The socket handler settles on data, error, abort or inactivity timeout, but has no end/close handler. A broker that closes normally before returning a complete response can leave the promise pending after the socket is gone.
Smaller implementation
Use one Jarvis request-lifetime owner for complete response, EOF, close, timeout and abort. Reject incomplete EOF promptly; clean up every listener exactly once.
CurrentClean EOF → no settlement
ProposedEOF/error/response/abort → one settled request
Focused proof
Use a local broker that closes with no data and with a partial JSON line; both must reject promptly. Also test full response followed by close and abort races.
apps/server/src/jarvis/Services/JarvisVoiceCompute.ts:106
Medium priority · Confirmed Jarvis caller behavior
6. Controller loads every recent conversation before deciding
Before interpreting a request, the controller serially loads details for context, reference and all recent task IDs, up to 22 distinct threads. Most commands only need a task catalog and detail for the selected task. The Jarvis adapter chooses this broad read.
Smaller implementation
Build navigation candidates from existing shell data and bounded Jarvis metadata; defer full detail to the selected task or the exact history-dependent operation. Reuse existing public T3 interfaces. Do not modify upstream projection implementations or invent a second thread store.
CurrentEvery instruction → all recent details → choose task
ProposedShell catalog → choose task → necessary detail
Focused proof
Count detail calls for list/status/stop/start with 20 long recent tasks. Preserve title, objective, pending-input and origin correctness. If an existing seam cannot supply a field, report that constraint separately.
apps/server/src/jarvis/Layers/JarvisController.ts:356
Medium priority · Confirmed source path
7. Catalog ownership differs across Jarvis surfaces
Web creates a fresh mesh for every command while manager, control center and onboarding keep separate catalog state and stale-response bookkeeping. Mobile uses a runtime-owned mesh. Mesh refresh waits for all node reads before publishing its result, so one slow node delays visibility of fast nodes.
Smaller implementation
Give the Jarvis runtime one scoped catalog owner and per-node refresh sharing. Publish node progress independently, reject results from removed/replaced connections, and let UI adapters observe the same state. Keep connection lifecycle in the existing registry.
CurrentPrivate UI catalogs + new mesh per command
ProposedOne Jarvis catalog owner → thin UI adapters
Focused proof
Test overlapping refresh, one slow node, node removal during refresh and simultaneous settings/control surfaces. No repeated reads solely to reconstruct discarded Jarvis state.
apps/web/src/state/jarvisMesh.ts:17
Medium priority · Confirmed source path
8. Speech queue and cancellation have multiple incomplete owners
The renderer appends reports to an unbounded Promise chain. Browser utterances settle only through end/error callbacks. Disable, disconnect and unmount cancel through the desktop bridge only, leaving browser playback without equivalent ownership. Mobile background handling cancels current playback but enqueueSpeech itself has no foreground gate.
Smaller implementation
Use a bounded ephemeral Jarvis speech queue with platform adapters for playback and cancellation. Clear obsolete queued work on disconnect/disable; gate mobile admission by foreground state. Preserve durable visual approvals and task results. This concerns lifecycle, not TTS model choice.
CurrentPromise chain + partial platform cleanup
ProposedBounded queue → cancellable platform adapter
Focused proof
Test never-settling playback, disable during browser speech, reconnect, overflow and a live presentation arriving after mobile backgrounds. Do not infer cancellation from merely clearing a local ref.
apps/web/src/components/jarvis/JarvisVoiceReporter.tsx:104
Medium priority · Confirmed source path
9. Multi-project clarification has no cancel exit on mobile
The cancellation branch is gated by acceptsAffirmation. A multi-candidate project clarification normally does not accept affirmation, so “cancel” is treated as an unmatched project and the pending route remains.
Smaller implementation
Handle explicit discard before answering any clarification type. Centralize pending-interaction transitions shared by web and mobile, with platform capture/navigation kept outside. Avoid a generic workflow framework.
CurrentAmbiguous route + cancel → ask again
ProposedAny pending clarification + discard → idle
Focused proof
Cover cancel/no/new instruction across one-candidate confirmation and multi-candidate clarification. Preserve the original request identity only while the pending interaction remains active.
apps/mobile/src/features/jarvis/JarvisMobileProvider.tsx:386
Medium priority · Confirmed source ordering; overlap duration unmeasured
10. Desktop voice restart loses ownership before exit
On retry, the host clears the old child handle, sends SIGTERM and immediately spawns a replacement. Signal delivery does not establish that the old worker and its speech child have exited. A slow shutdown can overlap workers and hardware/model ownership.
Smaller implementation
Own restart as stop → observed exit → start, with a bounded shutdown deadline for the captured child PID and scoped child cleanup. Keep one authority for worker lifecycle.
CurrentSIGTERM → immediately spawn
ProposedStop owned child → await exit → spawn
Focused proof
Use a fake worker that delays exit. Assert replacement cannot acquire voice until cleanup completes and late messages cannot change current state.
apps/desktop/src/voice/DesktopJarvisVoice.ts:399
Medium priority · Confirmed source and byte-split reproduction
11. Desktop transcript decoding corrupts split UTF-8
The worker stdout handler calls chunk.toString("utf8") on each Buffer independently. A non-ASCII character split across pipe chunks becomes replacement characters before JSON parsing; a transcript can remain valid JSON while its project name is corrupted.
Smaller implementation
Use one stateful decoder per worker generation, or set the stream encoding once. Reset decoder and line buffer together on restart. The server voice-broker reader already demonstrates the required stateful behavior.
CurrentIndependent chunk decode → corrupted name
ProposedStateful stream decode → intact transcript
Focused proof
Split serialized transcripts at every byte boundary, including accented and non-Latin names. Verify emitted transcript and subsequent grounding input match the original.
apps/desktop/src/voice/DesktopJarvisVoice.ts:462
Low priority · Measured operation count with synthetic data
12. Vocabulary repeatedly scans the entire alias list
For each project the builder filters all aliases. At 100 projects with 20 aliases each the direct helper check counted 200,000 comparisons; at 1,000 projects it counted 20 million and took about 343 ms in this run. Semantic prompt preparation also repeatedly groups aliases through projectSemanticNames. Typical small catalogs may hide this.
Smaller implementation
Index aliases by project once per catalog construction and reuse the grouping in semantic preparation. Keep a simple Map inside the owning module; no cache invalidation framework is needed.
CurrentP projects × all aliases
ProposedGroup aliases once → per-project lookup
Focused proof
Assert identical ordering and content, then compare operation counts for representative catalog sizes. The reported elapsed time is a synthetic check, not production latency.
packages/jarvis-core/src/buildProjectVocabulary.ts:14
Low priority · Confirmed source path; peak memory unmeasured
13. Release verification repeatedly buffers whole installers
The Jarvis release verifier hashes files with readFileSync, buffering complete artifacts. Checksum, alias and provenance paths hash some artifacts repeatedly. Large bundled installers make this unnecessary memory and I/O work.
Smaller implementation
Stream hashes and reuse each digest within a verification invocation. Keep artifact correctness checks; avoid adding more provenance/checklist machinery. This is Jarvis packaging work, not an upstream build refactor.
CurrentRepeated full-file buffers
ProposedOne streaming digest per artifact
Focused proof
Check equal digests on fixtures and measure peak RSS/read volume on a large synthetic artifact. Do not regenerate release artifacts for a review.
scripts/verify-jarvis-release.mjs:5
Complexity worth keeping
Keep deterministic grounding, typed clarification and confirmation, execution-node identity, ordinary provider adapters, preset capability checks, cancellation ownership and durable task results with ephemeral speech. Those mechanisms protect real behavior. The presence animation already has finite bursts and visibility/reduced-motion controls; it is not a priority for speculative optimization.
What “simpler” means here
One Jarvis module should own each catalog, queue or lifecycle. Thin platform adapters should handle actual differences in audio, navigation and foreground state. Avoid another generic workflow engine, service locator, parallel task database or delivery ledger. A smaller interface should remove state from callers, not hide the same duplicated state behind more files.
Only AGENTS.md was changed in the application repository. Findings are recommendations, not implemented fixes.