The findings
- Reports can steal command focus
- Replies are not bound to the exact clarification
- The follow-up queue lacks one execution owner
- Work starts before result ownership is recorded
- Speech waits for unrelated node catalogs
- Client workflow is duplicated, and clarification edits English
- Voice admission disagrees with voice interruption
- Each listener rebuilds every relevant task presentation
- Mobile cannot retire a turn when its live ending was missed
- A generic T3 extension exists for one Jarvis startup caller
- Voice packaging policy is spread through the shared builder
- A successful publication cannot resume verification
- Development and release use different Pipecat source
StrongCommand authority1. Reports can steal command focus
A presentation is persisted as attention, navigates the workspace, and takes precedence over the selected task, project and route. A completion from task A can become the ambient target for a follow-up intended for B. That incidental attention also survives a renderer reload.
Current ownershipReport → persisted attention → navigation → next command target
Proposed ownershipReport → display; explicit focus → command target
Better design
Give deliberate task focus and origin-bound follow-up state sole ownership of command context. Reports may offer an explicit focus action. Remove the localStorage attention-to-authority path.
Proof the replacement should provide
Exercise the client controller: focus B, deliver a completion from A, then submit an ambient continuation. B remains authoritative. Also cover reload and an explicit project mention.
Source-traced behavior. Explicit voice project mentions can override attention; the finding concerns ambient context. This conflicts with the documented rule that visible attention is not authority.
StrongCommand authority2. Replies are not bound to the exact clarification
The controller chooses a candidate from a previously read pending frame, then consumes the current frame using only the session ID. It checks the frame kind, not its identity. A replaced task question can supply a new original command while the old candidate supplies its target.
Current ownershipRead A → resolve A → consume current B → combine A target + B command
Proposed ownershipAnswer + expected frame → one atomic task-desk transition
Better design
Give each pending interaction a stable identity and let one task-desk module atomically validate the answer, resolve its candidate, consume that exact frame and transition focus. Reject stale answers without consuming the replacement.
Proof the replacement should provide
Pause between selection and consumption, replace the pending question, and resume. The old answer must fail without changing the new question. Cover task, project, expiry and cancellation.
Source-traced interleaving, not a reproduced concurrent run. Existing transactional consumption correctly prevents two replies from consuming the same unchanged frame.
StrongQueued work3. The follow-up queue lacks one execution owner
The controller reads readiness and enqueues; a separate dispatcher wakes only on later readiness events. A ready event before insertion can strand accepted work. Cancellation can also land after the dispatcher status check but before turn start. A shared sequential worker spends up to two 30-second retry delays on one task, delaying other task queues. Startup recovery uses an invalid SQLite aggregate query and suppresses its failure.
Current ownershipSnapshot check → SQL insert; separate event wakeup; separate stop
Proposed ownershipPer-thread queue coordinator → ordinary T3 dispatch
Better design
Use one Jarvis queue coordinator for enqueue, wakeup, stop and ready-state reconciliation. Serialize dispatch decisions per thread with bounded concurrency across threads. Define cancellation relative to the actual accepted dispatch. Repair recovery and keep deterministic T3 command IDs.
Proof the replacement should provide
Run coordinator startup against SQLite; inject ready-before-insert and cancel-before-dispatch interleavings; hold one failing thread while another progresses. Current dispatcher tests manually reconcile and do not cover startup.
The exact query shape was reproduced in an in-memory SQLite database: misuse of aggregate: MIN(). Scheduling and cancellation risks are source-traced. More status checks alone would only move the race.
StrongTask launch4. Work starts before result ownership is recorded
New-task dispatch starts the turn before appending its Jarvis origin marker. A fast terminal event can reach the live projector before the task is recognized as managed. Later metadata and task-desk focus writes still gate returning started, so an accepted task can be reported as a failed dispatch.
Current ownershipStart turn → append origin → focus desk → report started
Proposed ownershipRecord origin → start turn → return accepted task; maintain focus
Better design
Persist the required origin before launching. Treat accepted turn dispatch as the execution outcome. Report later focus maintenance failures separately while preserving the accepted task reference. Apply the same ordering to new tasks, reviews and reroutes.
Proof the replacement should provide
Deliver a terminal event immediately after turn acceptance and inject failures in later desk maintenance. Preserve both origin-directed output and the accepted-task response.
Ordering and failure propagation are verified in source; fast-result loss is a race risk. Continuations already record origin before turn dispatch, so this requires consistent Jarvis composition, not a new T3 execution path.
StrongClient latency5. Speech waits for unrelated node catalogs
The mesh publishes a catalog only after every node read finishes. Desktop then waits for every task desk, and a fresh voice submission refreshes the whole mesh again. A slow connected node can delay a request with an already-qualified target on a healthy node.
Current ownershipAll node configs + vocabularies → all desks → refresh all again → submit
Proposed ownershipNode-level catalog updates → validate required target → submit
Better design
Keep one observable catalog with independent node updates and explicit freshness. Validate the selected execution node for an explicit target. Require broader freshness only for cross-node name resolution; do not guess when unavailable catalogs could contain an ambiguous match.
Proof the replacement should provide
Hold an unrelated node response indefinitely and submit to a known healthy task reference. Then test unqualified duplicate names: unresolved freshness must cause clarification or a clear availability result.
Structural latency finding, not a timing benchmark. Reads already have bounded concurrency and per-node error handling; preserve those protections.
StrongClient ownership6. Client workflow is duplicated, and clarification edits English
Web creates a new mesh module for each command while mobile keeps one. Each UI owns catalogs, selection and submission state. Web repairs provider/model/effort clarification by regex-editing the original utterance and parsing it again; mobile displays needs-input and drops the active turn. Mobile also owns a separate question classifier and conversation route.
Current ownershipWeb workflow + regex repair | mobile workflow + separate routing
Proposed ownershipShared Jarvis interaction module → web/mobile adapters
Better design
Deepen the Jarvis client runtime into the shared owner of catalog state, grounding, submission identity and pending answers. Carry typed pending intent and stable choices rather than mutable English. Web and mobile should render that state and supply platform capture/playback adapters.
Proof the replacement should provide
Run the same interaction cases through both adapters: provider/model clarification, multiword choices, conversation without a project, cancellation and node disconnection. Tests should cross the shared interface.
This is a policy consolidation, not a request to share React UI. Durable server control-target clarification already exists and is the better direction to extend.
StrongDesktop voice7. Voice admission disagrees with voice interruption
The main-process voice module marks local speech busy through playback and rejects capture while busy. The hotkey calls that capture method directly. The worker explicitly implements capture as an interruption of speech, but the outer check prevents it from reaching that transition.
Current ownershipHotkey → main busy rejection ✕ worker speech interruption
Proposed ownershipHotkey → one admission/preemption owner → capture worker
Better design
Make one typed voice operation owner decide admission, preemption and completion. Beginning capture should perform the intended preemption transition there. Keep process isolation, resource guards and protocol validation inside the worker and Python host.
Proof the replacement should provide
At the public voice interface, start a long report then request capture. Verify the chosen interruption policy and exactly one terminal result. Cover release during startup and cancellation; real-device hotkey acceptance remains separate.
Source-traced contradiction, not a microphone test. Remote compute busy rejection and one-model-at-a-time memory limits are legitimate constraints.
StrongServer fan-out8. Each listener rebuilds every relevant task presentation
Every presentation subscriber reads full thread history and project data, builds a presentation, and only then checks its origin. More devices multiply identical reads, including work for unrelated tasks. Mobile retained subscriptions make this cost worse.
Current ownershipEvent → N listeners × full history → N builds → origin filter
Proposed ownershipEvent → one Jarvis projection → origin-filtered listeners
Better design
Compose one ephemeral presentation stream per node and project each source event once, then route by origin. Where history remains costly, use a narrow public T3 read for the relevant output and correlation. Keep delivery live-only with no second durable report ledger.
Proof the replacement should provide
Count projection reads for one event with one and several subscribers. Reads should stay constant as subscribers grow. Verify origin isolation, late subscribe and reconnect without speech replay.
Source-proven repeated work, no measured throughput or memory claim. This preserves the documented ephemeral-presentation decision.
StrongReconnect lifecycle9. Mobile cannot retire a turn when its live ending was missed
Mobile keeps one presentation listener per active turn. Successful starts remain until a completed/failed live event arrives. Reconnect and foreground refresh catalogs and task desks, but do not reconcile active turns against durable task state. Completion while disconnected can retain the turn and listener until the provider unmounts.
Current ownershipStart → live listener → missed terminal event → retained listener
Proposed ownershipReconnect → inspect durable task → retire finished listener
Better design
Reconcile retained task references against ordinary durable state on reconnect and foreground. Retire completed, removed or abandoned interactions without speaking old results. Bound local subscription ownership and clean it up when a node is removed.
Proof the replacement should provide
Start, disconnect, complete remotely, reconnect. Assert that the listener is retired and no old completion is spoken. Include node removal and several such cycles.
Source-traced lifecycle gap. Presentation history is already bounded to eight entries; the active-turn collection is the separate concern.
StrongUpstream rebase cost10. A generic T3 extension exists for one Jarvis startup caller
OrchestrationReactor now depends on an extension whose only real implementation is Jarvis Expo push. A no-op adapter and generic reactor test wiring support it. This avoids naming Jarvis inside the reactor while still making upstream orchestration own a product startup hook.
Current ownershipT3 reactor → generic extension → Jarvis Expo push
Proposed ownershipServer composition → T3 reactor + Jarvis push
Better design
Start the Jarvis push module at server composition alongside the existing Jarvis follow-up dispatcher. Delete the extension contract, no-op implementation and generic reactor dependency. A real future generic requirement can justify a public seam then.
Proof the replacement should provide
Test push startup and shutdown through product composition and keep upstream reactor tests independent. This improves locality without changing notification behavior.
Directly conflicts with the documented preference for explicit Jarvis composition over a generic callback framework for one caller. The push sender abstraction itself has a useful test adapter and need not be removed.
StrongUpstream rebase cost11. Voice packaging policy is spread through the shared builder
The shared desktop builder contains individual voice model filenames, native dependency resolution, Windows payload validation and Pipecat/worker staging. Jarvis voice changes and upstream desktop packaging changes therefore touch the same large implementation.
Current ownershipShared desktop builder: platform build + voice models + native rules + staging
Proposed ownershipShared builder → explicit Jarvis packaging module
Better design
Move Jarvis payload staging and validation into a product-owned packaging module. Leave a small explicit composition call in the shared builder. Keep actual platform and artifact-integrity checks; do not introduce a general plugin framework.
Proof the replacement should provide
Run existing focused packaging tests against the new interface and compare payload contents for applicable targets and presets. The deletion test should remove product knowledge from the shared builder.
Maintenance finding. Shallow build and branding hooks are allowed and worth keeping. No estimate of future merge-conflict frequency is claimed.
StrongRelease process12. A successful publication cannot resume verification
The release transaction publishes, then makes fallible network reads to verify the release and latest pointer. If one read fails after publication, the run fails. Retrying refuses every already-published release, including the exact release it just created.
Current ownershipPublish succeeds → verification fails → retry rejects published state
Proposed ownershipPublish once → retry verifies immutable published result
Better design
Separate draft construction from published-release verification. On retry, inspect a published release without mutating it; matching source identity and assets can resume verification and return success. Reject mismatches explicitly.
Proof the replacement should provide
Use the transport adapter to fail the first read after publication, then rerun. Verify one publication, no asset mutation and eventual verified success. Keep mismatch rejection.
Source-traced failure path, no release was created. Existing draft recovery, identity and artifact checks protect correctness and should remain.
Worth exploringDependency maintenance13. Development and release use different Pipecat source
The frozen build copies Pipecat and rewrites exact Python source fragments to defer imports. Development uses the ordinary installed dependency. Updates require maintaining textual patches, and local development does not exercise the same import behavior as the released runtime.
Current ownershipStock dependency in dev | source-rewritten dependency in release
Proposed ownershipSame reviewed dependency in dev and release → package smoke
Better design
Prefer upstream lazy imports or one explicit pinned patched dependency used in both development and packaging. Keep frozen-runtime smoke verification and the offline package-size constraints that motivated the patch.
Proof the replacement should provide
Exercise the same startup and speech paths against the common dependency, then inspect the frozen artifact. Verify imports and offline startup, not just matching source fragments.
The overlay is pinned, fails closed and avoids mutating installed packages. This is a maintenance opportunity, not evidence of a broken shipped runtime.
Start with command authority and the queue.
First separate report attention from deliberate focus and bind replies to exact pending interactions. Those are task-selection correctness issues. Then give queued work one owner and fix launch ordering so accepted work cannot disappear behind metadata failures.
Next, deepen the client runtime and unify voice admission. That gives later UI work leverage through a smaller shared interface. Remove global catalog barriers and duplicate presentation reads as separate performance changes. Reconcile mobile subscriptions through durable task state.
For rebases, remove the one-caller reactor extension and extract Jarvis packaging policy. These are small, specific ways to reduce upstream conflict surface. Do not start by moving every T3 file or designing a plugin framework.
Keep these decisions
Keep the pure deterministic Jarvis core, qualified node/task references, ordinary provider adapters, explicit Full/Controller/Headless permissions, one desktop identity, isolated native voice processes and ephemeral origin-directed presentations. Platform shortcut adapters and one-model-at-a-time memory policy solve real constraints.
Make tests follow ownership
Use negative behavioral tests at the owning interface for each failure, then the smallest broader set covering other entry points and reverse states. Source-string tests can guard forbidden imports, but they cannot prove wakeup ordering, focus authority or real playback interruption. Avoid adding more scattered guards around the current split ownership.