From cfc7787cddf898f592076b1ae5fb11a53286d43e Mon Sep 17 00:00:00 2001 From: zhaoyilun Date: Thu, 9 Jul 2026 21:30:34 +0800 Subject: [PATCH] docs: realign iSphere bridge around core MCP capabilities --- README.md | 15 +- docs/current-status-card.md | 57 +++++ docs/go-mcp-minimal-plan.md | 8 +- docs/mcp-core-business-plan.md | 145 +++++++++++++ docs/mcp-core-tools-contract.md | 369 ++++++++++++++++++++++++++++++++ 5 files changed, 583 insertions(+), 11 deletions(-) create mode 100644 docs/current-status-card.md create mode 100644 docs/mcp-core-business-plan.md create mode 100644 docs/mcp-core-tools-contract.md diff --git a/README.md b/README.md index 98c381c..73d4a79 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,18 @@ # iSphere AI Bridge -This project is for building a safe message-handoff gateway between iSphere/IMPlatformClient and AI digital employees. +This project is for building MCP core communication tools for iSphere / IMPlatformClient so AI digital employees can safely use authorized contacts, groups, messages, and files. -The first goal is not full automation. The first goal is to let AI reliably see authorized messages, normalize them, generate reply drafts, and keep evidence. Sending messages is a later step and must stay behind human approval until explicitly changed. +The business goal is not a selector/report project. The business goal is an MCP tool surface for searching contacts, searching groups, receiving/reading messages, sending messages after approval, receiving/downloading files, and sending files after approval. ## Scope - Authorized company communication software only. -- Read messages first; do not modify the original client state in the first POC. +- Implement read-only MCP tools first: search contacts, search groups, receive/read messages, and receive/download files. +- Keep real sending and file upload behind explicit human approval, audit, and `dry_run` preview. - Prefer stable entry points in this order: - 1. Local data/log/cache discovery. - 2. Plugin or existing bridge API. - 3. UI automation/RPA wrapper. + 1. Existing bridge / API / local service. + 2. Local data/log/cache discovery in read-only mode. + 3. UI automation/RPA wrapper as fallback. 4. Network/API discovery. 5. Binary reverse engineering only when needed to explain or validate the above. @@ -28,7 +29,7 @@ The first goal is not full automation. The first goal is to let AI reliably see - `prompts/` - ready-to-use Codex prompts for each investigation phase. - `evidence/` - local evidence output; ignored by Git except `.gitkeep`. - `runs/` - run logs and temporary investigation outputs; ignored by Git except `.gitkeep`. -- `src/` - future implementation code. +- `cmd/`, `internal/`, `native/` - current Go MCP server, helper client, tool registration, and C# WinHelper code. ## Safety Baseline diff --git a/docs/current-status-card.md b/docs/current-status-card.md new file mode 100644 index 0000000..4878215 --- /dev/null +++ b/docs/current-status-card.md @@ -0,0 +1,57 @@ +# Current Status Card + +Date: 2026-07-09 +Branch: `main` +HEAD: `b2d839e (HEAD -> main, gitea/main, gitea/HEAD) Merge branch 'codex/n15-report-hardening'` + +## Business direction + +项目核心不是继续做 UIA selector/report,而是通过 MCP 暴露 iSphere 的联系人、群组、消息、文件能力。 + +后续研发主线切换为 MCP 核心通信能力:搜索联系人、搜索群组、收发消息、收发文件。现有 UIA/selector/report 只作为底层辅助和证据,不再作为主线继续扩展。 + +## Current completed state + +- Go MCP foundation exists: `cmd/isphere-mcp`, `internal/mcpserver`, `internal/helperclient`, and `internal/tools` build a stdio MCP server. +- The current MCP surface exposes only four read-only helper tools: + - `win_helper_version` + - `win_helper_self_check` + - `win_helper_scan_windows` + - `win_helper_dump_uia` +- C# `ISphereWinHelper` exists under `native/ISphereWinHelper` and uses the `isphere.helper.v1` stdin/stdout JSON contract. +- `scripts/verify-win-helper.ps1` and `scripts/verify-go-mcp.ps1` provide repeatable local checks for the helper and first-phase Go MCP server. +- N12-pre and N12R documents define safe offline evidence intake and internal-sandbox live UIA capture procedures. +- N13/N14/N15 produced selector catalog/report validation infrastructure, but those are supporting validation assets only. + +## What cannot be claimed externally + +- The project has not yet implemented business MCP tools for contact search, group search, message receiving, message sending, file receiving, or file sending. +- The project has not completed production iSphere integration. +- The project has not proven a stable real message source for the full business workflow. +- The project has not implemented approval-backed real sending or real file upload. +- N12-pre offline evidence is not N12 pass. +- N13/N14/N15 selector/report work is not business completion and must not be described as finished contact/message/file capability. + +## What can be claimed externally + +- The repository has a Go MCP + C# WinHelper foundation for controlled Windows-side read-only observation. +- The helper protocol boundary is explicit and avoids automatic login, process injection, hooks, memory reading, and endpoint-security bypass. +- The current code can support future MCP business tools by routing low-level Windows/UIA fallback work through a bounded helper layer. +- The project has repeatable verification scripts for the first-phase helper/MCP foundation. +- The project now has a corrected business contract and plan for core MCP communication tools. + +## N13/N14/N15 positioning + +N13/N14/N15 are pre-business validation results. They can help identify UI elements and validate reports if UI automation becomes necessary, but they are not the product route. Do not start N16/N17 selector/report hardening by default. New work should first validate real business capability sources and core MCP tool contracts. + +## Next business mainline + +1. Freeze the MCP core tools contract in `docs/mcp-core-tools-contract.md`. +2. Discover the best real capability source for: + - `isphere_search_contacts` + - `isphere_search_groups` + - `isphere_receive_messages` + - `isphere_receive_files` +3. Build the read-only loop first. +4. Add `isphere_send_message` and `isphere_send_file` only after approval and audit are implemented. +5. Keep UIA selector/report work as fallback support, not as the primary roadmap. diff --git a/docs/go-mcp-minimal-plan.md b/docs/go-mcp-minimal-plan.md index b23a6da..2c3713b 100644 --- a/docs/go-mcp-minimal-plan.md +++ b/docs/go-mcp-minimal-plan.md @@ -965,16 +965,16 @@ Every node must satisfy these rules: ## 4. Current Next Node -Current guidance after N0-N11 completion is: +Current guidance after N0-N15 remote updates is: ```text -N12-pre has been used for offline evidence. Because the current environment is outside the internal network, the active live-capture route is N12R internal-sandbox live capture. N12-current remains blocked unless network placement changes. +当前下一步:MCP 核心工具合同冻结 + 只读消息源 discovery + N12-pre 证据包整理。 ``` Immediate next action: ```text -If live UI evidence is needed, use `docs/internal-sandbox-live-capture-plan.md` and `docs/internal-sandbox-operator-runbook.md` to collect an N12R package from an internal-network test sandbox. Continue to use `docs/offline-evidence-intake-plan.md` only for offline file evidence. +Use `docs/mcp-core-tools-contract.md` and `docs/mcp-core-business-plan.md` as the active business route. Prioritize `isphere_search_contacts`, `isphere_search_groups`, `isphere_receive_messages`, and `isphere_receive_files` before any write-capable tool. Keep `isphere_send_message` and `isphere_send_file` behind `dry_run=true`, `approval_id`, and audit requirements. ``` -Do not treat offline evidence as N12 pass. Do not start selector/action design until N12R live evidence is accepted, or until N12-current becomes possible and passes in the current environment. +Do not treat N12-pre offline evidence as N12 pass. Do not start N16/N17 selector/report hardening as the mainline. Existing UIA selector/report work is auxiliary evidence and fallback support only; the project core is MCP communication capability for contacts, groups, messages, and files. diff --git a/docs/mcp-core-business-plan.md b/docs/mcp-core-business-plan.md new file mode 100644 index 0000000..dd35b8c --- /dev/null +++ b/docs/mcp-core-business-plan.md @@ -0,0 +1,145 @@ +# MCP Core Business Plan + +Date: 2026-07-09 + +## Business correction + +项目核心不是继续做 UIA selector/report,而是通过 MCP 暴露 iSphere 的联系人、群组、消息、文件能力。 + +后续研发主线切换为 MCP 核心通信能力:搜索联系人、搜索群组、收发消息、收发文件。现有 UIA/selector/report 只作为底层辅助和证据,不再作为主线继续扩展。 + +## Core business capabilities + +The product roadmap is limited to six business capabilities: + +1. Search contacts. +2. Search groups. +3. Receive/read messages. +4. Send messages. +5. Receive/download files. +6. Send files. + +Everything else is infrastructure or fallback support. Selector catalog/report validation may support UI automation if needed, but it is not the main product deliverable. + +## Capability source priority + +Use this priority order when searching for real implementations: + +1. Existing bridge / API / local service. +2. Local database / log / cache read-only access. +3. UI automation. +4. Network/API analysis. +5. Reverse engineering, only for explanation and validation, not as the default route. + +Implications: + +- Prefer an existing bridge/API/local service before reading local storage or using UIA. +- Prefer read-only database/log/cache access before UI automation when it can answer the business question. +- UIA selector work is a fallback access mechanic, not the primary roadmap. +- Do not continue investing in selector report hardening unless a concrete business tool is blocked by selector quality. +- Reverse engineering is last resort and should explain formats or validate assumptions; it should not become the default delivery path. + +## Stage A: Freeze MCP core tools contract + +Goal: lock the business-facing MCP tool surface before adding more helper or selector work. + +Deliverables: + +- `docs/mcp-core-tools-contract.md` exists and defines: + - `isphere_search_contacts` + - `isphere_search_groups` + - `isphere_receive_messages` + - `isphere_send_message` + - `isphere_receive_files` + - `isphere_send_file` +- Write-capable tools require `approval_id` for real execution. +- Write-capable tools support `dry_run=true` and default to dry-run until approved. +- Read-only tools do not mutate the iSphere client state. + +Acceptance: + +- Contract names, input parameters, output JSON, error codes, audit fields, read-only/write status, approval behavior, and implementation priority are explicit. +- No new selector/report node is introduced as the next primary step. + +## Stage B: Find real capability sources + +Goal: identify the best source for each read-only capability. + +Tasks: + +1. Inventory existing bridge/API/local service artifacts and current Go/C# boundaries. +2. Re-check whether existing bridge endpoints or local services can provide contacts, groups, messages, or files. +3. Re-check local database/log/cache artifacts only in read-only mode. +4. Use UIA only if higher-priority sources cannot satisfy the read-only tool. +5. Document source decisions per tool before implementation. + +Acceptance: + +- Each read-only tool has a selected primary source and a fallback source. +- The decision is evidence-backed and does not rely on stale prior notes without current verification. +- No automatic login, hook, injection, memory read, or endpoint-security bypass is introduced. + +## Stage C: Read-only loop + +Goal: deliver useful MCP read capability before any real write capability. + +Implementation order: + +1. `isphere_search_contacts` +2. `isphere_search_groups` +3. `isphere_receive_messages` +4. `isphere_receive_files` + +Acceptance: + +- Each tool can return normalized JSON through MCP. +- Each tool records audit metadata. +- File receiving/download writes only to an approved local output directory and never mutates source client state. +- Tests and verification do not send messages, upload files, click destructive controls, or alter production data. + +## Stage D: Approval-after-read-only write capability + +Goal: add write behavior only after the read-only loop is proven. + +Implementation order: + +1. `isphere_send_message` with `dry_run=true` preview first. +2. Approval store and audit validation. +3. `isphere_send_message` real send only with valid `approval_id`. +4. `isphere_send_file` with `dry_run=true` preview first. +5. `isphere_send_file` real send only with valid `approval_id`. + +Acceptance: + +- No valid `approval_id`, no real send. +- Every real send records target, content/file hash, approver, time, connector, and result. +- Idempotency prevents accidental duplicate sends. +- Operator can review dry-run output before approval. + +## Stage E: Pre-production safety, audit, and deployment acceptance + +Goal: make the MCP service safe and operable before broader use. + +Checks: + +- Tool allowlist and source allowlist are explicit. +- Audit records are durable and redacted where needed. +- Approval records are traceable. +- Deployment docs include exact commands, rollback, logs, and known limits. +- Security boundaries are still enforced: no automatic login, no bypass, no injection, no hook, no target-process memory read. + +Acceptance: + +- Full test suite passes. +- Operator runbook covers normal operation and failure modes. +- A business user can understand which of the six capabilities are supported and which remain staged. + +## Immediate next action + +Current next step is: + +```text +MCP core tools contract freeze + read-only message source discovery + N12-pre evidence package organization. +``` + +Do not start N16/N17 selector/report hardening as the mainline. If UIA is needed later, use the existing N13/N14/N15 results as auxiliary evidence only. diff --git a/docs/mcp-core-tools-contract.md b/docs/mcp-core-tools-contract.md new file mode 100644 index 0000000..86e36de --- /dev/null +++ b/docs/mcp-core-tools-contract.md @@ -0,0 +1,369 @@ +# MCP Core Tools Contract + +Date: 2026-07-09 + +## Route statement + +项目核心不是继续做 UIA selector/report,而是通过 MCP 暴露 iSphere 的联系人、群组、消息、文件能力。 + +This contract defines the business-facing MCP tool surface. The existing `win_helper_*` tools remain low-level auxiliary tools for controlled read-only observation and fallback implementation work. They are not the product API. + +## Hard boundaries + +- No automatic login. +- No permission bypass. +- No process injection, hook, target-process memory read, credential extraction, or endpoint-security bypass. +- Search contacts, search groups, receive messages, and receive files should be implemented read-only first. +- Real message sending and file sending require `approval_id`. +- Without `approval_id`, write-capable tools must stay in `dry_run=true` behavior and must not send. +- Every real write must produce an audit record with target, content/file hash, approver, timestamp, source connector, and result. +- UIA selectors are allowed only as fallback access mechanics after higher-priority sources are exhausted or unavailable. + +## Common error codes + +| Code | Meaning | +| --- | --- | +| `INVALID_ARGUMENT` | Required parameter missing or invalid. | +| `SOURCE_UNAVAILABLE` | Selected bridge/API/database/UIA source is unavailable. | +| `NOT_LOGGED_IN` | A required manually logged-in client session is not present. | +| `PERMISSION_DENIED` | Current operator/account is not authorized for the requested object. | +| `APPROVAL_REQUIRED` | A real write was requested without valid approval. | +| `DRY_RUN_ONLY` | Tool is currently limited to dry-run behavior. | +| `TARGET_NOT_FOUND` | Contact, group, conversation, message, or file was not found. | +| `AMBIGUOUS_TARGET` | Multiple possible targets match and the request must be narrowed. | +| `TIMEOUT` | The connector did not complete before timeout. | +| `CONNECTOR_FAILED` | Underlying source or helper returned a structured failure. | +| `INTERNAL_ERROR` | Unexpected implementation error. | + +## Common audit fields + +Every tool response should include an `audit` object: + +```json +{ + "tool": "isphere_search_contacts", + "request_id": "uuid", + "source": "bridge|local_readonly|uia|network|mock", + "operator_id": "optional operator identity", + "approval_id": null, + "dry_run": false, + "target_ref": "optional stable target reference", + "content_sha256": null, + "file_sha256": null, + "started_at": "ISO-8601", + "finished_at": "ISO-8601", + "result": "ok|error" +} +``` + +## Tool: `isphere_search_contacts` + +| Field | Value | +| --- | --- | +| Business purpose | Search authorized iSphere contacts so a digital employee can resolve a person before reading or drafting work. | +| Read-only | Yes. | +| Requires `approval_id` | No. | +| Supports `dry_run` | Not required; optional `dry_run` may return the planned query only. | +| Current priority | Stage C read-only loop, first priority. | + +Input parameters: + +```json +{ + "query": "string, required", + "limit": "integer, optional, default 20, max 100", + "cursor": "string, optional", + "source_preference": "bridge|local_readonly|uia|network|auto, optional, default auto", + "include_inactive": "boolean, optional, default false" +} +``` + +Output JSON: + +```json +{ + "ok": true, + "contacts": [ + { + "contact_id": "string", + "display_name": "string", + "account": "string|null", + "department": "string|null", + "title": "string|null", + "source": "bridge|local_readonly|uia|network|mock", + "confidence": 0.98, + "raw_ref": "redacted source reference" + } + ], + "next_cursor": null, + "audit": {} +} +``` + +Errors: `INVALID_ARGUMENT`, `SOURCE_UNAVAILABLE`, `NOT_LOGGED_IN`, `PERMISSION_DENIED`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`. + +## Tool: `isphere_search_groups` + +| Field | Value | +| --- | --- | +| Business purpose | Search authorized iSphere groups so a digital employee can resolve a group conversation before reading or drafting work. | +| Read-only | Yes. | +| Requires `approval_id` | No. | +| Supports `dry_run` | Not required; optional `dry_run` may return the planned query only. | +| Current priority | Stage C read-only loop, first priority. | + +Input parameters: + +```json +{ + "query": "string, required", + "limit": "integer, optional, default 20, max 100", + "cursor": "string, optional", + "source_preference": "bridge|local_readonly|uia|network|auto, optional, default auto", + "include_archived": "boolean, optional, default false" +} +``` + +Output JSON: + +```json +{ + "ok": true, + "groups": [ + { + "group_id": "string", + "display_name": "string", + "member_count": "integer|null", + "owner_ref": "string|null", + "source": "bridge|local_readonly|uia|network|mock", + "confidence": 0.96, + "raw_ref": "redacted source reference" + } + ], + "next_cursor": null, + "audit": {} +} +``` + +Errors: `INVALID_ARGUMENT`, `SOURCE_UNAVAILABLE`, `NOT_LOGGED_IN`, `PERMISSION_DENIED`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`. + +## Tool: `isphere_receive_messages` + +| Field | Value | +| --- | --- | +| Business purpose | Read authorized recent messages and normalize them for digital employee reasoning and drafting. | +| Read-only | Yes. | +| Requires `approval_id` | No. | +| Supports `dry_run` | Optional; if true, returns source/query plan without message bodies. | +| Current priority | Stage C read-only loop, first priority after contact/group source discovery. | + +Input parameters: + +```json +{ + "conversation_id": "string, optional when query is supplied", + "conversation_type": "direct|group|system|unknown, optional", + "query": "string, optional target name or keyword", + "since": "ISO-8601 timestamp, optional", + "limit": "integer, optional, default 50, max 200", + "cursor": "string, optional", + "include_attachment_metadata": "boolean, optional, default true", + "source_preference": "bridge|local_readonly|uia|network|auto, optional, default auto", + "dry_run": "boolean, optional, default false" +} +``` + +Output JSON: + +```json +{ + "ok": true, + "conversation": { + "conversation_id": "string", + "conversation_type": "direct|group|system", + "display_name": "string" + }, + "messages": [ + { + "message_id": "string", + "sender_id": "string|null", + "sender_name": "string|null", + "content_type": "text|image|file|rich|notify|unknown", + "content_text": "authorized text or redacted summary", + "attachments": [ + { + "file_id": "string", + "file_name": "string", + "size_bytes": "integer|null", + "download_ref": "string|null" + } + ], + "created_at": "ISO-8601|null", + "received_at": "ISO-8601|null", + "source": "bridge|local_readonly|uia|network|mock", + "raw_ref": "redacted source reference" + } + ], + "next_cursor": null, + "audit": {} +} +``` + +Errors: `INVALID_ARGUMENT`, `SOURCE_UNAVAILABLE`, `NOT_LOGGED_IN`, `PERMISSION_DENIED`, `TARGET_NOT_FOUND`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`. + +## Tool: `isphere_receive_files` + +| Field | Value | +| --- | --- | +| Business purpose | List and receive/download authorized files from messages without mutating the iSphere client state. | +| Read-only | Yes for source/client state. It may write downloaded files only to an operator-approved local output directory. | +| Requires `approval_id` | No for read-only listing or authorized download. Approval can be added later for sensitive destinations. | +| Supports `dry_run` | Yes. `dry_run=true` lists planned files and destination paths without downloading. | +| Current priority | Stage C read-only loop after messages expose file metadata. | + +Implementation note: if the implementation becomes clearer with two internal operations, split into `list_files` and `download_file` behind this business contract. Do not expand the roadmap beyond receive/download. + +Input parameters: + +```json +{ + "conversation_id": "string, optional", + "message_id": "string, optional", + "file_id": "string, optional for download, omitted for list", + "mode": "list|download, optional, default list", + "output_dir": "string, optional, required for download", + "limit": "integer, optional, default 50, max 200", + "cursor": "string, optional", + "source_preference": "bridge|local_readonly|uia|network|auto, optional, default auto", + "dry_run": "boolean, optional, default true for download" +} +``` + +Output JSON: + +```json +{ + "ok": true, + "mode": "list|download", + "files": [ + { + "file_id": "string", + "message_id": "string|null", + "conversation_id": "string|null", + "file_name": "string", + "size_bytes": "integer|null", + "mime_type": "string|null", + "created_at": "ISO-8601|null", + "download_ref": "string|null", + "saved_path": "string|null", + "sha256": "string|null", + "source": "bridge|local_readonly|uia|network|mock" + } + ], + "next_cursor": null, + "audit": {} +} +``` + +Errors: `INVALID_ARGUMENT`, `SOURCE_UNAVAILABLE`, `NOT_LOGGED_IN`, `PERMISSION_DENIED`, `TARGET_NOT_FOUND`, `DRY_RUN_ONLY`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`. + +## Tool: `isphere_send_message` + +| Field | Value | +| --- | --- | +| Business purpose | Send an approved text message to a resolved contact or group. | +| Read-only | No. | +| Requires `approval_id` | Yes for any real send. | +| Supports `dry_run` | Yes, required. Default must be `true` until production approval flow is accepted. | +| Current priority | Stage D approval-after-read-only loop. | + +Input parameters: + +```json +{ + "target_type": "contact|group|conversation, required", + "target_id": "string, required", + "content_text": "string, required", + "approval_id": "string, required when dry_run=false", + "dry_run": "boolean, optional, default true", + "idempotency_key": "string, optional but recommended", + "source_preference": "bridge|uia|network|auto, optional, default auto" +} +``` + +Output JSON: + +```json +{ + "ok": true, + "dry_run": true, + "send_status": "planned|sent|rejected", + "target": { + "target_type": "contact|group|conversation", + "target_id": "string", + "display_name": "string|null" + }, + "message_ref": null, + "content_sha256": "sha256 hex", + "audit": {} +} +``` + +Errors: `INVALID_ARGUMENT`, `APPROVAL_REQUIRED`, `PERMISSION_DENIED`, `NOT_LOGGED_IN`, `TARGET_NOT_FOUND`, `AMBIGUOUS_TARGET`, `DRY_RUN_ONLY`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`. + +## Tool: `isphere_send_file` + +| Field | Value | +| --- | --- | +| Business purpose | Send an approved local file to a resolved contact or group. | +| Read-only | No. | +| Requires `approval_id` | Yes for any real send. | +| Supports `dry_run` | Yes, required. Default must be `true` until production approval flow is accepted. | +| Current priority | Stage D after `isphere_send_message`. | + +Input parameters: + +```json +{ + "target_type": "contact|group|conversation, required", + "target_id": "string, required", + "file_path": "string, required; must be under an approved outbound directory", + "caption": "string, optional", + "approval_id": "string, required when dry_run=false", + "dry_run": "boolean, optional, default true", + "idempotency_key": "string, optional but recommended", + "source_preference": "bridge|uia|network|auto, optional, default auto" +} +``` + +Output JSON: + +```json +{ + "ok": true, + "dry_run": true, + "send_status": "planned|sent|rejected", + "target": { + "target_type": "contact|group|conversation", + "target_id": "string", + "display_name": "string|null" + }, + "file_ref": null, + "file_sha256": "sha256 hex", + "file_size_bytes": 12345, + "audit": {} +} +``` + +Errors: `INVALID_ARGUMENT`, `APPROVAL_REQUIRED`, `PERMISSION_DENIED`, `NOT_LOGGED_IN`, `TARGET_NOT_FOUND`, `AMBIGUOUS_TARGET`, `DRY_RUN_ONLY`, `TIMEOUT`, `CONNECTOR_FAILED`, `INTERNAL_ERROR`. + +## Stage priority summary + +| Priority | Tool | Stage | +| --- | --- | --- | +| 1 | `isphere_search_contacts` | C read-only loop | +| 2 | `isphere_search_groups` | C read-only loop | +| 3 | `isphere_receive_messages` | C read-only loop | +| 4 | `isphere_receive_files` | C read-only loop | +| 5 | `isphere_send_message` | D approval-backed write | +| 6 | `isphere_send_file` | D approval-backed write |