Files
isphere-ai-bridge/docs/source-discovery/2026-07-10-send-sidecar-b-first-plan.md
2026-07-10 14:04:33 +08:00

12 KiB

Send Connector B-First Plan

Date: 2026-07-10 Node: C29 / write-side connector route correction Decision owner: user/business manager

Decision

The selected send route is now:

  1. Primary route B: in-process / sidecar connector that reuses the already logged-in IMPlatformClient.exe runtime and its existing message/file send classes.
  2. Fallback route A: constrained UI/RPA wrapper only if B cannot attach, load, or invoke safely.
  3. Network replay/protocol reimplementation remains deferred because it would require independently reproducing login/session/ack behavior.

This document supersedes the previous C15/R5 conclusion for future send work. The old conclusion was correct for the evidence available at that time: no write connector had been selected. This node records the newly approved route and the evidence that makes B worth trying first.

Business goal

Expose controlled MCP actions for digital employees:

  • isphere_send_message
  • isphere_send_file

The implementation must preserve these business controls:

  • target must be resolved from existing contact/group search results;
  • text/file content must be previewed before execution;
  • execution must use an idempotency_key and content hash;
  • every outbound attempt must produce an audit record;
  • early versions should support sandbox/test-target verification before normal production use.

Static evidence summary

Offline package evidence under:

runs/offline-evidence-intake/zyl-qqfile-20260709/

Relevant extracted binaries:

zyl/Impp/IMPlatformClient.exe
zyl/Impp/smack.dll
zyl/Impp/IMPP.Interface.dll
zyl/Impp/IMPP.ServiceBase.dll
zyl/Impp/IMPP.Service.dll
zyl/Impp/TcpFileTransfer.dll
zyl/Impp/HYHC.IMPP.DAL.dll

Relevant IL snapshots:

runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il/IMPlatformClient.exe.il
runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il/smack.dll.il
runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il/IMPP.Interface.dll.il
runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il/IMPP.Service.dll.il
runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il/IMPP.ServiceBase.dll.il

Text-send call chain

Preferred sidecar candidate

IMPlatformClient.exe contains a high-level helper:

IMPP.Client.Core.Plugins.Manager.AppContextManager.SendTxtMessageByJid(jid, chatType, content)

Observed behavior from IL:

  • for direct/P2P chat, it gets a P2PChatManager from IMPPManager.Instance;
  • it resolves a Chat by JID;
  • it finds or opens a chat form;
  • it calls frmP2PChat.SendTxtMessage(content);
  • for temporary/reserved group chat, it calls the corresponding room form send method.

This is the best B-route first target because it reuses the logged-in client's own state and UI/business rules.

Central message construction candidate

IMPlatformClient.exe also contains:

IMPP.Client.Core.MessageEngine.MessageScheduling.SendChatMessage(chat, msgText, toJid, messageType, isSaveMessage, msgGuid, IsReceipt)

Observed behavior from IL:

  • reads local font/style settings;
  • builds message body via UtilsText.GetMessageStyleBodyText;
  • decides chat vs groupchat;
  • creates smack.packet.XmppMessage;
  • sets body, subject, offline flag, receipt flag, time, and message type;
  • calls chat.SendMessage(xmppMessage);
  • optionally persists/parses message through MessageManager.MessageParsing.

This is the cleanest lower-level B candidate if the sidecar can obtain a valid Chat object from the running client context.

Protocol bottom

smack.dll provides the real wire-send chain:

com.vision.smack.Chat.SendMessage(XmppMessage)
  -> com.vision.smack.XMPPConnection.send(string)
  -> Sharp.Xmpp.Core.XmppCore.Send(string)
  -> stream.Write(...)

This proves that the send capability exists in the installed client binaries. It also shows why an external reimplementation is less attractive: it would need the same active connection, stanza format, message id, receipt, and session state.

Important trap: plugin interface text send is not enough

IMPP.Interface.dll declares:

IAppContextManager.SendP2PMessage(string pJid, string pMessage)
IAppContextManager.SendP2PFiles(UserInfo[] pUserInfo, string[] pFiles)
IAppContextManager.SendChatRoomMessage(string pRoomJid, string pMessage, string pluginID)
IAppContextManager.SendPluginMessage(string pluginID, int command, string para)

But the implementation of:

IMPP.Client.Core.Plugins.Manager.AppContextManager.SendP2PMessage(...)

records the plugin call and then throws NotImplementedException.

Therefore the B route must not choose SendP2PMessage as the text-send entry. The sidecar should prefer SendTxtMessageByJid or, if necessary, MessageScheduling.SendChatMessage with an existing Chat object.

File-send call chain

File sending appears split into upload plus file-message notification.

Upload engine

IMPP.ServiceBase.dll defines IFileTransfer.

IMPP.Service.dll implements:

IMPP.Service.BLL.FileTransfer.FileUpload(...)
IMPP.Service.BLL.FileTransfer.AsynFileUpload(...)
IMPP.Service.BLL.FileTransfer.FileDownload(...)
IMPP.Service.BLL.FileTransfer.SyncFileTransfer(...)

Offline file send

IMPlatformClient.exe contains:

IMPP.Client.OffLineFileSend.sendFile()
IMPP.Client.OffLineFileSend.trans_UploadCompleted(fileId)

Observed behavior:

  • builds a generated file GUID;
  • builds remote name as filename____guid.ext;
  • uses Config.ServerInfo.HTTPFileServer and FileTransferManager.GetDomain;
  • creates FileUploadPara;
  • calls IMPPManager.Instance.Service.FileTransfer.FileUpload(uploadPara);
  • after upload completion, creates an OFFLINE_FILE_TRANSFER;... message body;
  • calls Chat.sendFileMessage(...);
  • sets packet id to fileId and records metadata.

Native TCP file transfer

TcpFileTransfer.dll is native and exposes strings/exports indicating:

Send
SendFile
GetTcpFileMsgGuid
_StartWaitForSendFileThread@8
_StartRecvFileThread@24

This is a candidate for online/TCP file transfer, but the first B route should use the managed offline-file path because it is closer to the normal client business flow and already integrates upload metadata with XMPP file messages.

Proposed sidecar architecture

Go MCP Server
  -> controlled action contract and audit
  -> C# WinHelper / Sidecar command
  -> B-route sidecar adapter
  -> running IMPlatformClient context
  -> existing AppContextManager / MessageScheduling / OffLineFileSend / smack.dll

The sidecar should be a narrow adapter, not a general-purpose remote code executor.

Candidate sidecar operations

version
self_check
probe_client_runtime
probe_send_entrypoints
resolve_runtime_jid
preview_send_message
send_message_after_approval
preview_send_file
send_file_after_approval
read_send_audit

The first implementation slice should stop before real production send:

version
self_check
probe_client_runtime
probe_send_entrypoints

Then run a live sandbox observation before enabling send_message_after_approval.

B-route validation gates

Gate B1: runtime discovery

Pass condition:

  • find a running IMPlatformClient.exe process;
  • record PID, bitness, install path, module list summary;
  • confirm the discovered path matches the extracted evidence family;
  • confirm whether the sidecar must be x86 or x64.

Stop condition:

  • no logged-in process;
  • process bitness incompatible with available sidecar build;
  • module names differ too much from the extracted package.

Gate B2: entrypoint availability

Pass condition:

  • confirm IMPlatformClient.exe exposes AppContextManager and MessageScheduling in the runtime module set;
  • confirm smack.dll is loaded or loadable from the same install directory;
  • confirm IMPP.Interface.dll and IMPP.Service*.dll are present.

Stop condition:

  • app is not .NET Framework / cannot inspect CLR runtime safely;
  • required assemblies are missing;
  • only SendP2PMessage is available but SendTxtMessageByJid/MessageScheduling cannot be reached.

Gate B3: non-mutating dynamic observation

Pass condition:

  • during one operator-approved manual test send, observe the expected chain:
    • SendTxtMessageByJid or UI send method;
    • MessageScheduling.SendChatMessage;
    • Chat.SendMessage;
    • XMPPConnection.send;
  • capture only redacted method names, argument shape, message id/hash, and success/ack indicator.

Stop condition:

  • method chain differs from static evidence;
  • no success/ack indicator can be mapped;
  • message id/idempotency cannot be correlated.

Gate B4: sidecar dry run

Pass condition:

  • sidecar can resolve the target JID/chat type;
  • sidecar can build a preview object without sending;
  • preview contains target, content hash, connector, and proposed entrypoint;
  • audit event is appended.

Stop condition:

  • no deterministic target resolution;
  • preview cannot distinguish direct vs group chat;
  • no auditable dry-run object.

Gate B5: one sandbox send

Pass condition:

  • one explicit test target only;
  • one idempotency key only;
  • one message content hash only;
  • success/ack or local sent-record evidence captured;
  • duplicate retry with same idempotency key is rejected locally.

Stop condition:

  • duplicate send risk;
  • wrong target risk;
  • no post-send verification.

A-route fallback

A remains the backup route if B cannot be made reliable.

A should not be arbitrary desktop control. It should expose only:

search_contact(query)
open_conversation(target)
write_draft(text)
verify_draft(target, text_hash)
send_after_approval(approval_id)
upload_file(path)
verify_send_result()

A-route fallback is activated when any of these happen:

  • B cannot attach/probe safely;
  • required runtime classes are unavailable in the logged-in process;
  • B can observe but cannot invoke without unstable side effects;
  • B cannot provide idempotency/audit guarantees;
  • sidecar bitness/runtime mismatch is too costly to resolve in the current cycle.

MCP contract impact

The MCP business tools should not expose B/A internals directly. They should keep the stable user-facing shape:

isphere_send_message(target_type, target_id, content_text, mode, idempotency_key, content_sha256)
isphere_send_file(target_type, target_id, file_path, mode, idempotency_key, file_sha256)

Connector metadata should show the route:

connector = "implatform-sidecar" | "uia-rpa"
connector_stage = "preview" | "sandbox_send" | "production"

Next implementation loop

R6b B-route preview/dry-run contract is now complete. isphere_send_message is registered as preview/dry-run only, validates target/content-hash/idempotency input, appends redacted audit JSONL, and blocks production with all side-effect flags false.

Next node should be R6c online sandbox-send evidence gate:

  1. Prepare or collect one operator-approved sandbox send evidence package.
  2. Use one explicit sandbox target, one content hash, and one idempotency key.
  3. Observe success/ack or local sent-record evidence.
  4. Prove duplicate retry with the same idempotency key is locally rejected before any second send.
  5. Capture method names, argument shape, IDs/hashes, status booleans, and refs only.
  6. Do not enable production send_message_after_approval until the evidence gate passes.

Current status

B is selected as the primary send/file-send route. Runtime discovery, entrypoint metadata preflight, and preview/dry-run audit are in place. A remains the fallback and now has concrete UIA selector/offline-blocker classifier support. Production send remains blocked until dynamic observation and one approved sandbox send prove success/ack behavior.