AbbyplanSecond pass · 5 September 2026 · no AbbyView
Fix control correctness before adding more machinery.
Nine findings about behavior that hurts the app today. The first two should block further voice-approval polish: ambiguous words can authorize an action, and pending questions can swallow stop commands.
Read-only review of 50db1ffea. App files and ongoing changes were left untouched. Pure functions were exercised directly and three existing focused test files were run. No live provider, microphone, browser or user database was used. Reproduced means local code execution; source-traced means the consequence follows from the inspected call path but was not exercised end to end.
Evidence
Existing tests: 50 passed across 3 files.
Independent negative regression checks: 6 failed, 1 passed. The failures cover three defects across several inputs; they are not six separate product bugs.
Why should I approve this? → accept
If the tests pass, go ahead. → accept
I said allow on the previous task. → accept
stop + pending question → question answer
stop + pending approval → say allow or deny
long spoken question → final choices omitted
The control check for explicit allow/deny passed. The regression script imports the real production helpers and adds assertions only; it does not launch external actions.
- Approval detection treats a mentioned word as consent
- Pending questions take over the command channel
- One utterance is copied into every answer field
- Mobile stops listening after accepting queued or steered work
- Stop feedback claims completion before the provider acts
- Everyday controls depend on a model round trip
- Independent node speech queues compete for one speaker
- Desktop truncates the question the user must answer
- Tests bypass the entry point whose ordering matters
Reproduced1. Approval detection treats a mentioned word as consent
The parser returns accept for “Why should I approve this?”, “If the tests pass, go ahead”, and “I said allow on the previous task.” It searches for approval words anywhere in a sentence. Negation handling does not make this a consent parser.
What should change
Accept only a bounded set of explicit, unconditional approval replies tied to the current request. Questions, conditional instructions and references to earlier approvals must clarify. Keep model output outside authorization.
Reproduced at the production helper; controller ordering traced2. Pending questions take over the command channel
With a pending worker question, “stop that task” becomes the question answer. With an approval pending, it becomes “Say allow or deny.” The controller runs this shortcut before semantic interpretation, so later stop handling cannot rescue it.
What should change
Define explicit control precedence before reply handling. Exact stop/status controls must remain available against a validated task. An arbitrary utterance is not automatically an answer merely because a question exists.
Source-traced3. One utterance is copied into every answer field
When a provider asks several questions, the controller maps each question ID to the same grounded utterance. “Use staging, and keep backups” becomes the complete answer to both environment and backup questions. Distinct typed questions are flattened into prose and then fanned out without mapping.
What should change
Keep each question and its choices in pending state. Ask one at a time, or require a validated structured mapping. Submit only the answers actually provided; do not invent a value for every field.
Source-traced4. Mobile stops listening after accepting queued or steered work
Server queue and steer paths return status acknowledged even when a new turn starts or will start later. Mobile retains listeners only for status started, removing every other active turn. The new origin can therefore have no listener when its eventual result arrives.
What should change
Make response state describe the work lifecycle: accepted work with a task/origin reference, immediate answer, or pending input. Retain result subscriptions for every work-producing response and reconcile them through durable task state.
Source-traced5. Stop feedback claims completion before the provider acts
Jarvis returns “I’ve stopped that task” after dispatching thread.turn.interrupt. T3 records an interrupt-requested event and the provider reactor performs the actual interrupt later, with failure paths. Accepted dispatch does not establish that the process stopped.
What should change
Say “I’ve requested a stop” at acceptance. Derive stopped or failed feedback from the ordinary provider/task outcome. Do not add a new completion ledger or modify provider internals for Jarvis.
Source-traced design cost; no latency benchmark6. Everyday controls depend on a model round trip
Outside pending-reply handling, stop, status and project listing enter the semantic supervisor. That path creates a temporary working directory and calls structured generation. Several ordinary provider text-generation adapters allow 180 seconds. Supervisor failure becomes generic needs-input even when the target and requested control could be exact.
What should change
Keep the semantic proposal path for open language, but provide a small deterministic route for exact controls and explicit UI actions. Reuse ordinary typed commands and validated task references. Do not build another broad regex language parser. Give interpretation a Jarvis-appropriate deadline and distinct unavailable/timeout feedback.
Source-traced interleaving7. Independent node speech queues compete for one speaker
Each environment reporter has its own promise queue. The desktop voice owner rejects another speak call while local speech is active, returning deferred/busy. The reporter only reports failed outcomes; a busy report has already been marked seen and is neither retried nor visibly reported as missed. Two healthy nodes can produce simultaneous updates and one is silently dropped.
What should change
Have one bounded, in-memory scheduling owner for the local speaker across nodes and interaction/report lanes. Define cancellation and supersession explicitly. Preserve important pending questions and terminal updates, and expose delivery failure when they cannot be delivered. No durable speech ledger is needed.
Reproduced8. Desktop truncates the question the user must answer
Desktop applies completion-style truncation before switching on presentation kind, so it also truncates questions and approval prompts. A 666-character question lost its final “Choose retain or delete.” Mobile preserves this same question. The user hears that a decision is needed but may never hear the actual decision.
What should change
Use one shared policy that distinguishes summaries from actionable questions. Bound completions; preserve the current question and options. For long requests, split speech deliberately or direct the user to the visible full request. Do not silently cut the required answer off.
Verified against existing tests9. Tests bypass the entry point whose ordering matters
All 50 focused tests passed while six negative checks failed. The test named “keeps stop ahead of pending-reply answers” supplies an already-classified stop intent to the later interpreter. The production controller first calls the pending-reply shortcut, which prevents reaching that tested branch. This is a concrete source of false confidence.
What should change
Keep pure-function tests, but prove control precedence through the controller’s actual interface using real classification policy and fake external effects. Add the negative cases above and a few cross-path cases. More source-string assertions or tests of isolated downstream branches will not cover the interaction.
Recommended order
Fix approval consent and control precedence first. Then repair question mapping and the accepted-work/result contract across mobile and desktop. Consolidate local speech scheduling and preserve actionable speech. Remove exact controls from the supervisor dependency after the command authority rules are explicit.
The common error is compressing distinct states into a shortcut: a word means consent, pending means answer, acknowledged means done, accepted means stopped, and any text can be shortened the same way. Quality improves when these distinctions are typed and owned in one place.
Keep T3 provider execution intact. These changes belong in Jarvis policy, Jarvis client workflow and their public contracts. This pass does not call for replacing the foundation or adding a general workflow framework.
Companion to the first architecture review. No fixes were applied in this inspection pass.