Files
isphere-ai-bridge/docs/go-mcp-runbook.md
2026-07-11 00:42:45 +08:00

559 lines
30 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Go MCP Operator Runbook
This runbook is for the first Go MCP phase of `isphere-ai-bridge`. It lets an operator build and verify the Windows helper and the Go MCP server without reading the source code.
Current scope: expose four WinHelper observation operations, four business read tools, and two preview-only send tools through Go MCP. Read tools are `isphere_receive_messages`, `isphere_search_contacts`, `isphere_search_groups`, and `isphere_receive_files` list mode plus download preview/blocked status. Send tools are `isphere_send_message` and `isphere_send_file` preview/dry-run only; production send/file upload is blocked. Read tools use an empty default message source unless `ISPHERE_PACKET_LOG_FILE` points to an operator-local encrypted PacketReader log-line file or `ISPHERE_PACKET_LOG_DIR` points to an operator-local directory of encrypted PacketReader `.log`/`.txt` files. Contact/group display names can also be optionally enriched from an operator-local copied `MsgLib.db` through the bounded read-only `MsgLibReadSidecar`; receive messages can use copied DB rows only when the caller explicitly passes `source_preference="msglib_readonly"`.
## 1. Prerequisites
Run all commands from the repository root:
```powershell
cd E:\coding\codex\isphere-ai-bridge
```
Required local tools:
- Windows PowerShell.
- .NET Framework C# compiler used by `scripts\build-win-helper.ps1`.
- Go toolchain compatible with this module.
- A normal user desktop session; administrator rights are not required for the first phase.
Python is not required. Python MCP is not part of this path.
## 2. Build C# helper
The C# helper is the Windows/UI Automation execution layer. Build it with:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\build-win-helper.ps1
```
Expected output includes `"ok":true` and writes:
```text
runs\win-helper\ISphereWinHelper.exe
```
## 3. Verify C# helper
Run the helper verification script:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-win-helper.ps1
```
Expected output includes `"ok":true`, helper version `0.4.0`, a window scan count, send preflight smoke fields, and a UIA availability value.
## 4. Build Go MCP
Run tests first:
```powershell
go test ./...
```
Build the Go MCP binary:
```powershell
go build ./cmd/isphere-mcp
```
This creates the platform default binary in the repository root, for example:
```text
isphere-mcp.exe
```
If you want a fixed operator path, use an explicit output path instead:
```powershell
go build -o runs\go-mcp\isphere-mcp.exe ./cmd/isphere-mcp
```
## 5. Verify Go MCP
Run the repeatable smoke verification:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
```
Expected final output includes:
```json
{"ok":true}
```
The verification confirms:
- C# helper can be built.
- Go MCP binary can be built.
- MCP initialize/list/call flow works through the SDK harness.
- Exactly ten tools are exposed: four WinHelper observation tools plus `isphere_receive_messages`, `isphere_search_contacts`, `isphere_search_groups`, `isphere_receive_files`, preview-only `isphere_send_message`, and preview-only `isphere_send_file`.
- `win_helper_version` returns `ISphereWinHelper`.
- `isphere_receive_messages` is callable and returns an empty `messages` array from the default empty source.
- `isphere_receive_messages` returns the contract-facing `ok`, `conversation`, `messages`, `next_cursor`, and `audit` envelope, while preserving legacy message aliases such as `id`, `text`, and `timestamp`.
- A synthetic configured-source smoke check proves `ISPHERE_PACKET_LOG_FILE` can drive `isphere_receive_messages` end-to-end with one redacted fixture message.
- A synthetic configured-directory smoke check proves `ISPHERE_PACKET_LOG_DIR` can drive `isphere_receive_messages`, contact search, group search, and file-list extraction from a temporary directory fixture.
- `isphere_search_contacts` is callable and returns JID-derived contact candidates from the same configured synthetic message fixture; exact ID/display/account matches rank before prefix/substring matches and case-insensitive duplicates are collapsed.
- `isphere_search_groups` is callable and returns JID-derived group candidates from the configured synthetic groupchat fixture; exact ID/display-name matches rank before prefix/substring matches and case-insensitive duplicates are collapsed.
- `isphere_receive_files` is callable in list mode and returns one file metadata candidate from the configured synthetic file-transfer fixture; download preview is callable and returns `download_status="blocked"` with `blocked_reason_code="file_cache_mapping_missing"` when no accepted mapping exists.
- `isphere_send_message` is callable in preview mode and returns `send_status="planned"` without raw content in the response; the default runtime still returns `execution_mode="production"` as `send_status="blocked"` and `production_send_enabled=false`.
- `isphere_send_file` is callable in preview mode when `ISPHERE_SEND_FILE_ALLOWED_DIR` points to the allowed local directory; it returns file SHA256/size metadata only, does not return file content, and keeps production upload blocked with `production_send_enabled=false`.
- `isphere_send_message` also exposes sandbox-only connector metadata and idempotency state: duplicate reuse of the same key for the same target/content is detectable, while conflicting reuse of the same key for different content/target is blocked.
- R6f adds a test-only fake/sandbox connector contract for accepted/failed connector outcomes. This is an injected unit-test boundary only; the production MCP server still registers no real connector and performs no real send.
- Verification uses synthetic/local helper checks and does not load raw N12-pre evidence.
- The deterministic verification path clears MsgLib env variables, so it proves the default no-MsgLib behavior remains stable.
- Real file download/copy, production message send, and production file upload remain later-stage work; file download preview now returns structured blocked/planned metadata with all copy/read side-effect flags false.
## 6. Configure optional message source
By default, `isphere_receive_messages` is registered but uses an empty source, so it returns:
```json
{"messages":[]}
```
To point the server at a local encrypted PacketReader log-line file, set:
```powershell
$env:ISPHERE_PACKET_LOG_FILE = "E:\coding\codex\isphere-ai-bridge\runs\offline-evidence-intake\<evidence-id>\packet-reader-lines.txt"
```
The file must contain one encrypted Base64 log line per line. Blank lines are ignored. Keep this file under ignored `runs/` paths or another operator-local location; do not commit raw logs or decrypted message content.
To point the server at a directory containing multiple local encrypted PacketReader files, set:
```powershell
$env:ISPHERE_PACKET_LOG_DIR = "E:\coding\codex\isphere-ai-bridge\runs\offline-evidence-intake\<evidence-id>\raw\temp\PacketReader"
```
The directory loader recursively reads `.log` and `.txt` files, sorts paths deterministically, and ignores blank lines. Set only one source variable at a time: if both `ISPHERE_PACKET_LOG_FILE` and `ISPHERE_PACKET_LOG_DIR` are set, server startup fails fast as an ambiguous configuration.
Then start the MCP server normally. The command entry point uses `ISPHERE_PACKET_LOG_FILE` when the file variable is set, otherwise `ISPHERE_PACKET_LOG_DIR` when the directory variable is set. The repeatable verification script checks three paths: default empty source, a temporary synthetic encrypted fixture file, and a temporary synthetic encrypted fixture directory.
## 7. Configure optional MsgLib display-name enrichment and explicit DB receive
This is optional. It enriches contact/group display metadata and can also serve `isphere_receive_messages` from copied `MsgLib.db` rows when the caller explicitly chooses `source_preference="msglib_readonly"`. It does not turn `MsgLib.db` into the default message source: empty or `auto` source preference still uses the PacketReader/log-backed source.
Build the bounded x86 sidecar first:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\build-msglib-sidecar.ps1
```
Then configure all three MsgLib variables before starting the MCP server:
```powershell
$env:ISPHERE_MSGLIB_SIDECAR_EXE = "E:\coding\codex\isphere-ai-bridge\runs\msglib-sidecar\MsgLibReadSidecar.exe"
$env:ISPHERE_MSGLIB_SQLITE_DLL = "<path-to-copied-System.Data.SQLite.dll>"
$env:ISPHERE_MSGLIB_DB = "<path-to-copied-MsgLib.db>"
```
Optional password override:
```powershell
$env:ISPHERE_MSGLIB_PASSWORD = "123"
```
Rules:
- Set all of `ISPHERE_MSGLIB_SIDECAR_EXE`, `ISPHERE_MSGLIB_SQLITE_DLL`, and `ISPHERE_MSGLIB_DB`, or set none of them. Partial MsgLib config fails server startup.
- Keep copied DB/provider files under ignored `runs/` paths or another operator-local location. Do not commit them.
- `MsgLibReadSidecar` is read-only and bounded to schema/display/message-list operations. It does not send messages, download files, mutate DB rows, log in, hook processes, or return raw rows.
- `source_preference="msglib_readonly"` is required to read messages from copied `MsgLib.db`; `auto` and empty source preference remain PacketReader/log-backed.
- Standard `scripts\verify-go-mcp.ps1` intentionally clears MsgLib variables to keep the default smoke deterministic.
Verify the optional provider path:
```powershell
$env:ISPHERE_MSGLIB_SQLITE_DLL = "<path-to-copied-System.Data.SQLite.dll>"
$env:ISPHERE_MSGLIB_DB = "<path-to-copied-MsgLib.db>"
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-msglib-sidecar.ps1
```
Expected provider evidence contains `provider_checked=true`, a `display_source_count`, and sanitized `display_entity_summaries` with counts/source table names only.
Verify MCP-level optional enrichment, including receive-message display fields and explicit DB receive:
```powershell
$env:ISPHERE_MSGLIB_SQLITE_DLL = "<path-to-copied-System.Data.SQLite.dll>"
$env:ISPHERE_MSGLIB_DB = "<path-to-copied-MsgLib.db>"
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-msglib-mcp-enrichment.ps1
```
Expected MCP evidence is sanitized and should include:
```json
{
"ok": true,
"db_receive_smoke": true,
"db_receive_message_count": 5,
"db_receive_sources": ["msglib:tblPersonMsg"],
"receive_display_smoke": true,
"receive_sender_name_populated": true,
"receive_conversation_display_populated": true,
"printed_entity_values": false,
"message_body_values_printed": false,
"message_bodies_returned": false,
"file_paths_returned": false,
"raw_rows_returned": false
}
```
The optional MCP smoke internally uses copied-DB display metadata to build a synthetic encrypted PacketReader fixture and explicitly calls `isphere_receive_messages` with `source_preference="msglib_readonly"`. The printed output must stay limited to counts, booleans, and `msglib:<source_table>` refs. It must not print entity values, JIDs, message body values, local DB paths, attachment paths, or raw rows.
## 8. Configure MCP client command
After building a stable binary, configure your MCP client to run the Go MCP executable as a stdio server.
Recommended command if using the fixed output path:
```text
E:\coding\codex\isphere-ai-bridge\runs\go-mcp\isphere-mcp.exe
```
Recommended working directory:
```text
E:\coding\codex\isphere-ai-bridge
```
Example client configuration shape:
```json
{
"mcpServers": {
"isphere-ai-bridge": {
"command": "E:\\coding\\codex\\isphere-ai-bridge\\runs\\go-mcp\\isphere-mcp.exe",
"cwd": "E:\\coding\\codex\\isphere-ai-bridge"
}
}
}
```
If you used `go build ./cmd/isphere-mcp` without `-o`, point the command to:
```text
E:\coding\codex\isphere-ai-bridge\isphere-mcp.exe
```
## 9. Allowed tools
These ten tools are currently allowed:
| Tool | Source/op | Purpose |
| --- | --- | --- |
| `win_helper_version` | helper `version` | Read helper version and protocol metadata. |
| `win_helper_self_check` | helper `self_check` | Read desktop/UIA availability status. |
| `win_helper_scan_windows` | helper `scan_windows` | Read visible window metadata or likely iSphere candidates. |
| `win_helper_dump_uia` | helper `dump_uia` | Read a UI Automation tree for a specified window handle. |
| `isphere_receive_messages` | log-backed `EncryptedPacketLogSource` | Read normalized messages from the configured PacketReader log source with a contract-shaped response envelope. The default server source is empty unless `ISPHERE_PACKET_LOG_FILE` or `ISPHERE_PACKET_LOG_DIR` is configured. |
| `isphere_search_contacts` | log-backed message JIDs plus optional MsgLib display enrichment | Search contact candidates extracted from sender/receiver bare JIDs in the configured message source, with deterministic exact-match-first ranking, case-insensitive de-duplication, and preserved `source`/`raw_ref`. |
| `isphere_search_groups` | log-backed groupchat JIDs plus optional MsgLib display enrichment | Search group candidates extracted from groupchat/conference/MUC bare JIDs in the configured message source, with deterministic exact-match-first ranking, case-insensitive de-duplication, and preserved `source`/`raw_ref`. |
| `isphere_receive_files` | log-backed file-transfer messages plus download preview resolver boundary | List file metadata candidates extracted from file-transfer message bodies. Download preview returns structured `blocked` or `planned` metadata; real file copy remains blocked. |
| `isphere_send_message` | B-route preview/dry-run contract | Plan a text-message send with target/content hash/idempotency/audit metadata. Production send is blocked. |
| `isphere_send_file` | file-send preview/dry-run contract | Plan a file send with target/file SHA256/size/idempotency metadata. Production upload is blocked. |
Allowed parameters:
- `win_helper_version`: zero business parameters.
- `win_helper_self_check`: zero business parameters.
- `win_helper_scan_windows`: `include_all_visible` only.
- `win_helper_dump_uia`: `hwnd`, `max_depth`, `include_text`, `max_children` only.
- `isphere_receive_messages`: `conversation_id`, `query`, `since`, `include_attachment_metadata`, `source_preference`, `preview`, `cursor`, `limit` only. `since` must be RFC3339/RFC3339Nano when supplied; `source_preference` currently supports empty/`auto`/`local_readonly`; `cursor` must be empty until pagination is implemented.
- `isphere_search_contacts`: `query`, `cursor`, `source_preference`, `include_inactive`, `limit` only. `source_preference` currently supports empty/`auto`/`local_readonly`; `cursor` must be empty until pagination is implemented.
- `isphere_search_groups`: `query`, `cursor`, `source_preference`, `include_archived`, `limit` only. `source_preference` currently supports empty/`auto`/`local_readonly`; `cursor` must be empty until pagination is implemented.
- `isphere_receive_files`: `conversation_id`, `message_id`, `file_id`, `file_ref`, `name_contains`, `mode`, `output_dir`, `cursor`, `source_preference`, `preview`, `limit` only. List mode supports empty/`list`; `source_preference` currently supports empty/`auto`/`local_readonly`; `cursor` must be empty. Download mode supports preview-only status with `mode="download"`, `preview=true`, `file_ref` or `file_id`, and optional `output_dir`; real copy remains blocked unless a future accepted resolver and copy gate are added.
- `isphere_send_message`: `target_type`, `target_id`, `content_text`, `content_sha256`, `idempotency_key`, `execution_mode` only. R6b supports `execution_mode` empty/`preview`/`dry_run` as planned preview. The default runtime returns `execution_mode="production"` as blocked until sandbox-send evidence passes. R6f adds a Go `SendMessageConnector` interface for fake/sandbox tests so accepted, failed, duplicate, and conflict paths can be validated without login. The response and audit store `content_sha256` and `idempotency_key_sha256`, not raw message body or raw idempotency key.
- `isphere_send_file`: `target_type`, `target_id`, `file_path`, `file_sha256`, `idempotency_key`, `execution_mode`, `preview` only. `file_path` must stay inside `ISPHERE_SEND_FILE_ALLOWED_DIR`; preview computes/validates `file_sha256` and `file_size_bytes`, returns `real_send_attempted=false`, and does not upload or return file content. The default runtime returns `execution_mode="production"` as blocked.
Optional send audit/idempotency paths:
```powershell
$env:ISPHERE_SEND_AUDIT_PATH = "E:\coding\codex\isphere-ai-bridge\runs\send-audit\send-message-preview.jsonl"
$env:ISPHERE_SEND_IDEMPOTENCY_PATH = "E:\coding\codex\isphere-ai-bridge\runs\send-audit\send-message-idempotency.jsonl"
```
If `ISPHERE_SEND_IDEMPOTENCY_PATH` is set, the send preview path records hashed idempotency state. Reusing the same idempotency key for the same target/content sets `duplicate_detected=true`; reusing it for different content or target returns blocked metadata with `conflict_detected=true`. Raw message body and raw idempotency key are not stored in the JSONL state.
Send-file preview requires an explicit allowed directory. Put only the files you want the digital employee to plan against inside that directory:
```powershell
$env:ISPHERE_SEND_FILE_ALLOWED_DIR = "E:\coding\codex\isphere-ai-bridge\runs\send-file-preview"
```
Optional send-file audit/idempotency paths:
```powershell
$env:ISPHERE_SEND_FILE_AUDIT_PATH = "E:\coding\codex\isphere-ai-bridge\runs\send-audit\send-file-preview.jsonl"
$env:ISPHERE_SEND_FILE_IDEMPOTENCY_PATH = "E:\coding\codex\isphere-ai-bridge\runs\send-audit\send-file-idempotency.jsonl"
```
`isphere_send_file` rejects `file_path` values outside that directory. It computes file SHA256 and size, but does not upload, click, type, or return file content. If `ISPHERE_SEND_FILE_IDEMPOTENCY_PATH` is set, duplicate same-key/same-target/same-file preview calls set `duplicate_detected=true`; reusing the same key for a different target or file hash returns blocked metadata with `conflict_detected=true`. The audit/idempotency JSONL stores file hash, size, target ref, and hashed idempotency key; it does not store raw file content, raw local file path, or raw idempotency key.
R6g adds a local diagnostic for replaying the redacted audit/idempotency files without opening iSphere:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-audit-idempotency.ps1 `
-AuditPath $env:ISPHERE_SEND_AUDIT_PATH `
-IdempotencyPath $env:ISPHERE_SEND_IDEMPOTENCY_PATH
```
The diagnostic prints sanitized counts and booleans: `audit_records`, `idempotency_records`, `duplicate_detected`, `conflict_detected`, `raw_body_present`, and `raw_idempotency_key_present`. It exits non-zero if a raw message body field or raw idempotency-key field is found.
R6h centralizes the production-send gate. Default `execution_mode="production"` responses include machine-readable `gate_reason_code` and `gate_reason_message`. The valid gate codes are:
- `send_disabled_by_default`
- `send_evidence_missing`
- `send_connector_missing`
- `send_gate_passed`
`ISPHERE_SEND_PRODUCTION_ENABLED=1` is recognized by the gate policy, but it is not sufficient by itself: the evidence gate and connector gate must also pass before production can be allowed. In the default MCP server path, `production_send_enabled` remains `false`.
R6l closes the current send-message production path after R6k: because `strict_v2_pass=false`, production send remains blocked even if `ISPHERE_SEND_PRODUCTION_ENABLED=1` is set. In that state, the MCP response uses `gate_reason_code="send_evidence_missing"` and still reports all real side-effect flags as false.
## 10. Current tool surface and next-stage route
The current runbook verifies ten tools:
- `win_helper_version`
- `win_helper_self_check`
- `win_helper_scan_windows`
- `win_helper_dump_uia`
- `isphere_receive_messages`
- `isphere_search_contacts`
- `isphere_search_groups`
- `isphere_receive_files`
- `isphere_send_message`
- `isphere_send_file`
The current log-backed business read tools have parser/source/tool registration and an empty default server source. Raw N12-pre evidence remains under ignored `runs/` paths and is not committed. The current command entry point can read an operator-local encrypted PacketReader log-line file via `ISPHERE_PACKET_LOG_FILE` or a directory of `.log`/`.txt` files via `ISPHERE_PACKET_LOG_DIR`; this is still not a production ingestion claim because raw evidence remains local and uncommitted. `isphere_receive_messages` now exposes contract-facing fields for digital-employee consumption while preserving older aliases for compatibility, supports `conversation_id`, keyword `query`, and RFC3339 `since` filtering, and validates the remaining safe contract args without pretending unsupported connectors/pagination exist. Contact and group search also accept the safe local-readonly contract args, rank exact matches before prefix/substring matches, collapse case-insensitive duplicates across log-derived candidates and optional `MsgLibReadSidecar` display metadata, and preserve `source`/`raw_ref`; receive-message `sender_name` and `conversation.display_name` can use that same optional metadata when MsgLib env is configured. `isphere_receive_files` supports list mode with safe contract arg validation and download preview with machine-readable blocked/planned status; real download/copy remains blocked until accepted cache mapping and a separate copy gate exist. `isphere_send_message` supports preview/dry-run metadata, sandbox-only connector-shell metadata, duplicate/conflict idempotency detection, redacted audit, and a test-only `SendMessageConnector` contract for fake accepted/failed outcomes; `isphere_send_file` now exposes preview/dry-run file SHA256/size planning behind `ISPHERE_SEND_FILE_ALLOWED_DIR` with all upload/send side-effect flags false. The default MCP server still has no real message/file connector and production send/file upload remains blocked until dynamic observation, full evidence gates, and controlled sandbox connector passes prove success/ack behavior.
Core business tools for contacts, groups, messages, and files are defined in `docs/mcp-core-tools-contract.md`. Send-message preview metadata and audit records are now in place; send-file preview metadata is in place with allowed-directory validation. Production message send, real file download/copy, and file upload still wait for later evidence gates.
## 11. Real-login UIA capture procedure
This is a later real-login capture gate used to collect live UI structure for connector work.
Procedure:
1. Build and verify first:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-win-helper.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
```
2. Manually open iSphere / IMPlatformClient.
3. Manually log in using the normal company login process.
4. Keep the main iSphere window visible.
5. Use `win_helper_scan_windows` to find the candidate window. Prefer read-only scan arguments such as:
```json
{ "include_all_visible": true }
```
6. Use `win_helper_dump_uia` on the selected `hwnd`, for example:
```json
{
"hwnd": "0x001A0B2C",
"max_depth": 8,
"include_text": true,
"max_children": 80
}
```
7. Save selected evidence under:
```text
runs\real-loggedin-lab\uia-dumps\
```
8. Review and redact any sensitive content before sharing reports.
## 12. If this outer-network environment cannot log in
iSphere is internal-network only. If the current repository environment is outside that network, use two separate routes:
1. **N12-pre offline evidence** for copied files and static analysis. Follow `docs/offline-evidence-intake-plan.md` and place packages under `runs\offline-evidence-intake\<evidence-id>\`.
2. **N12R internal-sandbox live capture** for real logged-in UIA evidence. Follow `docs/internal-sandbox-live-capture-plan.md` and `docs/internal-sandbox-operator-runbook.md`; place returned packages under `runs\internal-sandbox-live-capture\<capture-id>\`.
N12R is the active live-capture route when login is only possible in an internal-network test sandbox. The UIA capture procedure still uses only the four helper observation tools:
```text
win_helper_version
win_helper_self_check
win_helper_scan_windows
win_helper_dump_uia
```
The MCP server also registers the log-backed read tools (`isphere_receive_messages`, `isphere_search_contacts`, `isphere_search_groups`, and `isphere_receive_files`), but their default source is empty and they should not be used as N12R UIA evidence collection.
After receiving an N12R package, validate it with `docs/n12r-return-package-validation-checklist.md` before using it as evidence for selector-design review. Prefer the scripted read-only validator:
```powershell
$captureRoot = "runs\internal-sandbox-live-capture\<capture-id>"
$reportRoot = "runs\internal-sandbox-live-capture-reports"
New-Item -ItemType Directory -Force -Path $reportRoot | Out-Null
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\validate-n12r-return-package.ps1 `
-PackageRoot $captureRoot `
-ReportPath (Join-Path $reportRoot "<capture-id>-validation.md")
```
Keep the validation report outside `$captureRoot`; the returned package is evidence input and should remain unchanged.
## 13. R6c online sandbox send evidence package
The local development machine cannot log in to iSphere. Do not attempt to prove production send locally.
To prepare the online/internal sandbox evidence package:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\package-send-sandbox-gate.ps1
```
Verify the package locally:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-sandbox-gate-package.ps1
```
Expected output includes:
```json
{
"ok": true,
"local_login_required": false,
"online_sandbox_required": true,
"production_send_enabled": false
}
```
Generated package:
```text
runs\send-sandbox-gate-package.zip
```
Send that zip to the online/internal sandbox operator. The operator must follow `OPERATOR-STEPS.md` inside the package:
1. fill `SANDBOX-SEND-INPUTS.json`;
2. run `RUN-RECORDING-SUITE.bat` for the guided full flow, or run `01-run-before-recorder.bat`;
3. manually send exactly one sandbox message in the official client;
4. fill `success_ack_or_sent_record`;
5. continue the guided flow, or run `02-run-after-recorder.bat`;
6. continue the guided flow, or run `03-make-return-zip.bat`;
7. return the generated zip.
The package also contains `RECORDING-PACKAGE-MANIFEST.json`, `run-before-recorder.bat`, `run-after-recorder.bat`, `compute-content-hash.ps1`, `make-return-zip.ps1`, and the read-only recorder under `recorder\`.
Production `isphere_send_message` remains blocked until the returned package is analyzed.
## 14. Returned sandbox package validation
When a returned package comes back, validate it before treating it as evidence:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\validate-returned-send-sandbox-package.ps1 -PackagePath C:\Users\zhaoy\Downloads\1631.zip
```
For R6j strict-v2 packages, use:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\validate-returned-send-sandbox-package.ps1 -ZipPath C:\Users\zhaoy\Downloads\isphere-send-sandbox-return-20260710-180000.zip -StrictV2
```
The current partial returned package `C:\Users\zhaoy\Downloads\1631.zip` validates as:
```json
{
"partial_evidence_usable": true,
"r6d_gate_pass": false,
"strict_v2_pass": false,
"production_send_enabled": false,
"decision": "partial_use_only"
}
```
Use `partial_use_only` to continue local sandbox-only connector-shell and idempotency/audit work. Do not enable production send from a partial package. Full pass still requires after-recorder output, manual send timestamps, and the R6j strict-v2 fields: `operator_started_at_local`, `operator_clicked_send_at_local`, `operator_observed_success_at_local`, `before_recorder_present`, `after_recorder_present`, `success_ack_or_sent_record_present`, and `duplicate_second_send_attempted=false`.
The fixture test for the current partial package is:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\test-validate-returned-send-sandbox-package.ps1
```
## 15. Offline capability-test package
Use this second package when you want to test the current capability surface without logging in and without any real send.
Build and verify it locally:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\package-send-capability-test.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-capability-test-package.ps1
```
Generated package:
```text
runs\send-capability-test-package.zip
```
Inside the extracted package, run:
```text
run-capability-test.bat
```
Expected final JSON includes:
```json
{
"ok": true,
"tool_count": 10,
"helper_name": "ISphereWinHelper",
"send_preview_tool_present": true,
"production_send_enabled": false,
"send_file_preview_tool_present": true,
"send_file_production_enabled": false,
"local_login_required": false,
"no_real_send": true
}
```
This package includes `isphere-capability-smoke.exe` and `runs\win-helper\ISphereWinHelper.exe`. It verifies the ten-tool MCP surface, fixture-backed receive/search/file-list behavior, send preview, send-file preview, and the production-send/file-upload blocks. It does not log in, click, type, upload, hook, inject, or send.
## 16. Business goals smoke
Run the business-facing smoke when you need a single status line for the four goals:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts erify-business-goals-smoke.ps1
```
It reuses `scripts erify-go-mcp.ps1`, writes `docs/reports/2026-07-10-business-goals-smoke.md`, and prints these key fields:
- `search_contacts_ready`
- `search_groups_ready`
- `receive_messages_ready`
- `send_message_preview_ready`
- `send_message_production_ready`
- `receive_files_list_ready`
- `receive_files_download_ready`
- `send_file_preview_ready`
- `send_file_production_ready`
- `remaining_business_blockers`
Current expected production blockers are real send-message, real file download, and real file upload.
## 17. Troubleshooting
- If C# helper build fails, run `scripts\build-win-helper.ps1` directly and check for missing .NET Framework reference assemblies.
- If `win_helper_version` fails, rerun `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-win-helper.ps1` first.
- If Go MCP verification fails, rerun `go test ./...` and `powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1`.
- If a client cannot start the MCP server, confirm the configured command points to the built `.exe` and the working directory is the repository root.