Full captured speech
The screenshot is from Full Desktop's compact voice flow, not the standalone Companion process analyzed in the supplied review.
Jarvis architecture review · voice routing
The screenshot is explained by two defects working together in Jarvis 0.0.47: Full's client-side grounding can be bypassed before its catalog is ready, and the installed server skipped authoritative grounding whenever an ambient context thread existed. The current source fixes the second defect. The architecture is still incomplete because Full, Companion, and Host use separate match-and-rewrite paths.
28 Aug 2026 Reviewed installed Jarvis 0.0.47, source commits db20e55f3 and 0784a00a2, focused tests, the attached screenshot, and the supplied third-party review. Claims below separate observed behavior from inference.
Diagnosis
The provider started in rivvl and received I need you to check out Zivil. The screenshot proves those two facts. It does not prove that Companion's recent-project fallback chose Rivvl.
The screenshot is from Full Desktop's compact voice flow, not the standalone Companion process analyzed in the supplied review.
Capture may start with an empty catalog. The transcript is then queued, and grounding is not rerun after the catalog arrives.
The installed code disabled inferred project grounding whenever context or reference thread IDs were present.
Ambient context supplied Rivvl as the execution project while the ungrounded ASR objective remained unchanged.
| Input | Context | Result | Meaning |
|---|---|---|---|
| I need you to check out Zivil | Fresh voice turn | needs input Did you mean Rivvl? | Current Host code catches the exact case. |
| I need you to check out Zivil | continueContext: true | ready project Rivvl, objective still Zivil | Safe only when continuation was explicitly requested and Zivil is literal task content. It is unsafe as an ambient default. |
| Same utterance, real eight-project catalog | Full client matcher | phonetic candidate Rivvl | The claimed matcher-margin failure does not reproduce with the installed catalog. |
Release mismatch
The running AppImage is Jarvis-0.0.47-x86_64.AppImage, built on 27 Aug at 22:20. It contains the older context suppression. Commit 0784a00a2, pushed on 28 Aug, changes that rule so only deliberate continueContext suppresses project inference. A server-level test now proves that context and reference threads do not stop a spoken project from winning.
Pushback and salvage
Routing and provider text must come from one result. A project span consumed for routing cannot remain as conflicting free text.
Confirmation must retain the original request, candidate IDs, expected slot, expiry, and request identity. It is not a prompt fragment.
Parakeet context and better pronunciation matching reduce errors. They cannot authorize a project or replace clarification.
Technical names need phoneme-aware candidates or learned pronunciations. That improves recall but does not change authority.
| Claim | Verdict | Correction |
|---|---|---|
| Companion recent-project fallback caused this screenshot. | Wrong path | The screenshot came from Full Desktop. Full uses JarvisManagerDialog → JarvisMesh → JarvisManager, not apps/companion/src/main.ts. |
| No unresolved entity-bearing ASR text may reach a provider. | Too broad | Branch names, files, symbols, tickets, and literal user terms often belong in the objective. The rule applies to spans Jarvis consumed as control or routing evidence. |
| Only execute-as-Rivvl or ask “Rivvl?” are legitimate. | False dichotomy | Zivil may be a branch or other literal target inside Rivvl. That third meaning is valid when Jarvis has not also treated the same span as the project selector. |
| A small LLM should be the Turn Interpreter. | Wrong authority | An optional model may propose a parse over bounded candidates. The deterministic Director still resolves IDs, confidence, ambiguity, authorization, and dispatch. |
| The 0.68 matcher threshold explains the failure. | Unproven | That threshold belongs to the client lexicon matcher. The Host uses different rules, and the actual catalog returns Rivvl as a phonetic client candidate. |
| Compile a generic inspect-project objective. | Needs product semantics | Compilation must preserve the user's task. If “check out <project>” is defined as an inspection command, encode that deliberately and test it. Do not silently invent a richer objective. |
End architecture
Do not add a second authoritative “Turn Interpreter” beside prepareJarvisTurn. Turn that existing seam into one deep module that owns extraction, candidate generation, grounding, clarification, and objective compilation. Full and Companion may run it early for feedback. The Host must run or validate it before any provider command.
RecognitionEnvelope
rawText, captureId, inputMode, ASR metadata
│
▼
GroundedTurnDirector
real ProjectRef / TaskRef catalogs
provider + model catalogs
explicit continuation state
ambient focus and attention as defaults only
confirmed pronunciation aliases
│
├── Clarify(frame with candidates + original request)
├── Reject(reason)
└── Execute(closed control plan)
│
▼
deterministic plan validator
│
▼
provider prompt compiler
│
▼
ordinary T3 orchestration command
Small external interface
One recognition envelope plus one bounded context snapshot.
Closed output union
Callers never combine a project resolver result with an independently edited transcript.
Action, exact node-qualified project, optional exact task, provider/model selection, and whether continuation was explicitly requested.
Natural task text with consumed control spans removed or replaced. Literal branch, file, symbol, and ticket terms remain.
Each consumed span records heard text, role, canonical entity, match kind, and confirmation source. This is diagnostic data, not provider text.
Raw ASR text, capture and request IDs, and recognition metadata stay available for replay, metrics, and corrections.
Hard invariant
If a span selected or changed a project, task, provider, model, approval, or control action, the provider objective cannot retain that span with a conflicting meaning. Ambient focus may fill a missing route. It may never resolve an explicit but uncertain route silently.
Not on the critical path by default. Add it later as an internal candidate-proposal adapter when deterministic parsing cannot label a long paraphrase. Give it bounded candidate handles, not raw authority. Reject invented handles. Re-score deterministically. Clarify on ties, timeout, malformed output, or model unavailability. The system must remain correct with that adapter disabled.
Acceptance
| Utterance and state | Required result | Forbidden result |
|---|---|---|
| Voice: “check out Zivil”; Rivvl is a unique phonetic project candidate | Clarify before thread creation | Project Rivvl plus provider text Zivil |
| User confirms Rivvl | Resume the same request ID once, store scoped pronunciation, compile canonical objective | Start a second request or ask the provider to infer Zivil |
| “In Rivvl, check out branch Zivil” | Route to Rivvl and preserve branch Zivil as literal objective text | Rewrite both spans to Rivvl |
| Explicit continuation of the current task with “check out Zivil” | Keep current TaskRef; preserve literal Zivil unless another bounded entity catalog resolves it | Treat ambient focus as proof that Zivil means Rivvl |
| Capture completes before project catalog loads | Queue the envelope, then ground against the fresh catalog | Queue a pre-grounded raw transcript and skip reevaluation |
| Two Rivvl projects on two nodes | Clarify with node labels | Use recency to choose a node silently |
| Typed: git checkout zivil | Preserve literal command intent under normal approval policy | Run ASR phonetic project correction |
| Model parser disabled or timed out | Deterministic result or clarification | Loss of basic voice routing |
Implementation sequence
Add Zivil tests at the Director and JarvisManager seams, with ambient context present. Repair the orphaned groundVoiceTurn suite.
Make provider prompt compilation accept only a closed plan. Assert route and consumed-span consistency before dispatch.
Move Full and Companion extraction, matching, confirmation, and canonicalization behind the shared Director module.
Queue recognition envelopes and ground at dequeue time against the current catalog. Client preview may be discarded and recomputed.
Add pronunciation-aware matching and telemetry after the correctness seam is fixed. Keep thresholds conservative.
Only then test a bounded model proposal adapter against real captured utterances and compare it with deterministic clarification rates.
The pushed commit fixes the specific Host rule that made ambient thread context suppress project grounding. It should not be called complete yet. The broken missing-module test, client catalog race, and duplicated grounding implementations leave the same class of split decision possible elsewhere.
Evidence
apps/web/src/components/jarvis/JarvisManagerDialog.tsx, apps/web/src/components/jarvis/JarvisNativeCapture.ts, packages/jarvis-client-runtime/src/jarvis/voiceLexicon.ts, packages/jarvis-core/src/prepareJarvisTurn.ts, packages/jarvis-core/src/resolveProjectTarget.ts, apps/server/src/jarvis/Layers/JarvisManager.ts, apps/companion/src/voice-routing.ts, contracts and task-desk architecture docs.
Verification: five focused test files, 72 tests passed in 1.52 seconds. The separate groundVoiceTurn.test.ts suite failed before collecting tests because groundVoiceTurn.ts is absent.