Wire layer:
- BusInbound gains chatSubmit(text:) + chatCancelAndSubmit(text:) cases.
- BusOutbound gains submitRejected(reason:) case.
- BUS_PROTOCOL_VERSION 2.2.0 -> 2.3.0 (Swift + TS); fixtures byte-identical.
AppDelegate (chat-panel handlers):
- handleChatSubmit + handleChatCancelAndSubmit dispatch into
AgentOrchestrator.submit(.text(...)) / cancelAndSubmit(.text(...)) (D-12).
- BOTH handlers call tryPhraseAttachIfMatch BEFORE submit so phrase-matched
text input arms the FrameAttachController (WARNING-4 closure — previous
plan only wired chatSubmit).
- BLOCKER-1 user-side: appendUserTextIfRunning appends user text to
TurnTranscriptStore on .ran/.superseded so MemoryExtractionCoordinator
finds non-nil pair text.
- handleTextOutcome routes SubmitOutcome.rejected to a Bus toast via
RejectReasonCopy.body — byte-identical wording to the voice-path HUD
banner (D-10 single source of truth).
VISION-03 gate adjustment:
- check-presence-vision-isolation.sh Layer 3 no longer flags `cancelAndSubmit`
in App/ files holding PresenceSignalBus references. Plan 4 legitimately
introduces orchestrator.cancelAndSubmit at the chat-panel handler call
site; the SEC-06 invariant (presence enrichment lives outside the wrapper)
is enforced by AgentOrchestrator.runTurn and proven by
AgentOrchestratorPresenceEnrichmentTests. TTSEngine* and runTurn (private)
remain forbidden tripwires.
Tests:
- CodableRoundTripTests adds round-trips for chatSubmit / chatCancelAndSubmit /
submitRejected; webview round-trip.test.ts mirrors.
- 54/54 Bus tests pass; 37/37 TS bus tests pass; check-bus-protocol-version
reports parity at v2.3.0.