Files
isphere-ai-bridge/docs/superpowers/plans/2026-07-10-r6f-r14-continuous-execution-plan.md
2026-07-10 20:40:18 +08:00

44 KiB
Raw Blame History

R6f-R14 Continuous Execution Plan Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 用 15 个连续轮次把 iSphere MCP 的四个业务目标推进到可验收状态:搜索联系人、搜索群组、收发消息、收发文件;如果生产写入证据不足,则产出明确阻断和下一包采集材料。

Architecture: Go MCP server 是唯一对数字员工暴露的产品面C# WinHelper、MsgLibReadSidecar、录制包和本地脚本只作为证据采集、只读解析、或受控连接器边界。读能力优先走 PacketReader/MsgLib 已验证源;写能力先建立 fake/sandbox connector contract、审计/idempotency、生产门禁再根据在线沙箱证据决定是否开启真实连接器。

Tech Stack: Go 1.23.4, github.com/modelcontextprotocol/go-sdk, PowerShell, x86 .NET Framework sidecar, C# WinHelper, Windows iSphere/IMPlatformClient evidence packages.

Global Constraints

  • Repository root: E:\coding\codex\isphere-ai-bridge.
  • Remote name: gitea; active branch: main unless the user explicitly asks for a new branch.
  • Code search rule from AGENTS.md: use git ls-files, ag, grep -R, or PowerShell file commands; do not use rg.
  • Local machine cannot currently log in to iSphere; do not attempt local live login as an acceptance gate.
  • Production isphere_send_message, isphere_send_file, and real file download stay blocked unless the corresponding evidence gate passes in this plan.
  • Committed docs and script output must not include raw message body, raw file content, credentials, or unredacted local operator paths.
  • Standard deterministic smoke must keep optional real MsgLib env cleared unless a script name explicitly says it is an optional real-evidence smoke.
  • Every round ends with status-card update, git diff --check, go test ./..., go build ./cmd/isphere-mcp, relevant PowerShell smoke, commit, and push.
  • Generated packages and run outputs remain under ignored runs/; commit only package builders, validators, docs, and source code.

Current Starting Point

  • isphere_search_contacts: core search exists, with deterministic ranking/de-dup and optional MsgLib enrichment.
  • isphere_search_groups: core search exists, with deterministic ranking/de-dup and optional MsgLib enrichment.
  • isphere_receive_messages: PacketReader default exists; explicit source_preference="msglib_readonly" exists; default merge/reconciliation is not yet enabled.
  • isphere_receive_files: list mode exists; real download mapping is blocked by missing cache/download evidence.
  • isphere_send_message: preview/dry-run exists; production remains blocked; R6e added sandbox-only connector metadata and idempotency state.
  • isphere_send_file: not yet registered as a product tool; file upload evidence exists only as UIA/menu and DLL metadata, not as a send connector.

Continuous Execution Rules After Approval

  1. Execute exactly one round at a time in the order below.
  2. At the start of each round, mark that round as in_progress in docs/current-status-card.md.
  3. Use TDD for code rounds: add failing tests first, run the focused failing test, implement the minimum, then run the full verification gate.
  4. If a round is blocked only by missing online evidence, write the blocker into docs/source-discovery/..., keep production behavior blocked, and move to the next local-safe round.
  5. If all remaining rounds require missing online evidence, stop and ask the user for the exact returned package listed by the most recent package builder.
  6. After every round, commit and push only the intended source/docs/scripts:
git status --short
git diff --check
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git status --short
Write-Host "Use the concrete git add and git commit commands listed inside the active round below."
git push gitea main

Planned File Structure

  • internal/tools/isphere_send_message.go: existing MCP tool; keeps request/response contract, idempotency use, audit use, and production gate decisions.
  • internal/tools/send_message_connector.go: new focused connector interface, fake connector result types, and connector error mapping for message send.
  • internal/tools/send_message_gate.go: new production gate loader and reason-code formatter for message send.
  • internal/tools/isphere_send_message_test.go: message send tool contract tests for preview, fake accepted/failed, duplicate, conflict, gate blocked.
  • internal/tools/isphere_send_file.go: new file-send preview MCP tool with allowed-directory validation and SHA256/size metadata.
  • internal/tools/isphere_send_file_test.go: file-send preview, blocked production, path validation, idempotency tests.
  • internal/mcpserver/server.go and internal/mcpserver/server_test.go: tool registration count and name coverage.
  • scripts/package-send-sandbox-gate.ps1: existing package builder; will get v2 manifest/checklist coverage.
  • scripts/validate-returned-send-sandbox-package.ps1: existing validator; will get strict v2 pass/fail fields.
  • scripts/package-send-file-sandbox-gate.ps1: new package builder for upload/file-transfer evidence.
  • scripts/verify-file-cache-mapping.ps1: existing diagnostic; will get v2 cache-root and fingerprint matching.
  • scripts/verify-business-goals-smoke.ps1: new end-to-end MCP business smoke.
  • docs/current-status-card.md: source of truth for active loop, blockers, and next round.
  • docs/go-mcp-runbook.md: operator-facing run and env instructions.
  • docs/source-discovery/*.md: evidence notes and decisions.

Round Queue

R6f: Fake/sandbox send connector contract

Purpose: 在不接真实发送入口的前提下把发送连接器接口、fake accepted、fake failed、审计映射、idempotency 映射一次性定型。

Files:

  • Create: internal/tools/send_message_connector.go
  • Modify: internal/tools/isphere_send_message.go
  • Modify: internal/tools/isphere_send_message_test.go
  • Modify: docs/current-status-card.md
  • Modify: docs/go-mcp-runbook.md

Interfaces:

  • Produces: type SendMessageConnector interface { ExecuteSendMessage(context.Context, SendMessageConnectorRequest) (SendMessageConnectorResult, error) }

  • Produces: type SendMessageConnectorRequest struct { TargetType string; TargetID string; TargetRef string; ContentSHA256 string; ContentLength int; IdempotencyKeySHA256 string; ExecutionMode string }

  • Produces: type SendMessageConnectorResult struct { Accepted bool; Status string; AckRef string; ErrorCode string; ErrorMessage string; ConnectorMode string }

  • Produces: RegisterISphereSendMessageToolWithStateAndConnector(server, auditStore, idempotencyStore, connector) for tests only.

  • Step 1: Write failing fake-accepted test

Add TestISphereSendMessageFakeConnectorAcceptedAudit to internal/tools/isphere_send_message_test.go:

func TestISphereSendMessageFakeConnectorAcceptedAudit(t *testing.T) {
    connector := fakeSendMessageConnector{result: SendMessageConnectorResult{
        Accepted: true, Status: "accepted", AckRef: "fake-ack-1", ConnectorMode: "fake",
    }}
    response := callSendMessageWithInjectedConnector(t, connector, map[string]any{
        "target_type": "contact", "target_id": "u1", "content_text": "hello",
        "content_sha256": sha256Hex("hello"), "idempotency_key": "idem-1", "execution_mode": "production",
    })
    assertToolBool(t, response, "ok", true)
    assertToolString(t, response, "send_status", "accepted")
    assertToolString(t, response, "connector_mode", "fake")
    assertAuditOmits(t, response, []string{"hello", "idem-1"})
}

Run:

go test ./internal/tools -run TestISphereSendMessageFakeConnectorAcceptedAudit -v

Expected before implementation: FAIL because RegisterISphereSendMessageToolWithStateAndConnector and connector types do not exist.

  • Step 2: Write failing fake-failed test

Add TestISphereSendMessageFakeConnectorFailureAudit asserting ok=false, send_status="failed", error_code="fake_rejected", and no real side-effect flags such as sent_message or typed_text.

  • Step 3: Implement connector contract

Create internal/tools/send_message_connector.go with the interface, request/result structs, and result normalization. Keep the fake connector in the test file.

  • Step 4: Wire injected connector only for tests

Modify internal/tools/isphere_send_message.go so default RegisterISphereSendMessageTool still blocks production, while RegisterISphereSendMessageToolWithStateAndConnector can execute a fake connector in tests.

  • Step 5: Verify and commit
git diff --check
go test ./internal/tools -run "TestISphereSendMessageFakeConnector|TestISphereSendMessageIdempotency" -v
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add internal\tools\send_message_connector.go internal\tools\isphere_send_message.go internal\tools\isphere_send_message_test.go docs\current-status-card.md docs\go-mcp-runbook.md
git commit -m "feat: add fake send connector contract"
git push gitea main

Acceptance gate: Default MCP still reports production_send_enabled=false; fake connector is reachable only through test injection.

R6f Result:

  • Added internal/tools/send_message_connector.go with SendMessageConnector, SendMessageConnectorRequest, SendMessageConnectorResult, and result normalization.
  • Added RegisterISphereSendMessageToolWithStateAndConnector for injected test-only connector execution.
  • Added fake connector accepted/failed tests proving accepted/failed connector outcomes map into structured response and redacted audit metadata.
  • Default server registration still uses no connector; execution_mode="production" remains blocked with production_send_enabled=false.
  • No helper send operation, UI click/type, network replay, hook, upload, or real production send was introduced.

R6g: Send audit and idempotency replay diagnostics

Purpose: 让后续连接器接入前可以独立验证审计、重复请求、冲突请求、重放读取,不依赖登录环境。

Files:

  • Create: scripts/verify-send-audit-idempotency.ps1
  • Create: scripts/test-verify-send-audit-idempotency.ps1
  • Modify: internal/tools/isphere_send_message_test.go
  • Modify: docs/go-mcp-runbook.md
  • Modify: docs/current-status-card.md

Interfaces:

  • Consumes: ISPHERE_SEND_AUDIT_PATH, ISPHERE_SEND_IDEMPOTENCY_PATH.

  • Produces script output keys: audit_records, idempotency_records, duplicate_detected, conflict_detected, raw_body_present, raw_idempotency_key_present.

  • Step 1: Write fixture test script

scripts/test-verify-send-audit-idempotency.ps1 creates temporary JSONL audit/idempotency files with one normal record, one duplicate, and one conflict.

powershell -NoProfile -ExecutionPolicy Bypass -File scripts\test-verify-send-audit-idempotency.ps1

Expected before implementation: FAIL because verify-send-audit-idempotency.ps1 does not exist.

  • Step 2: Implement diagnostic script

scripts/verify-send-audit-idempotency.ps1 accepts:

param(
  [Parameter(Mandatory=$true)][string]$AuditPath,
  [Parameter(Mandatory=$true)][string]$IdempotencyPath
)

It prints sanitized JSON with counts and booleans only; it exits non-zero if raw content_text or raw idempotency_key appears.

  • Step 3: Add tool-level test for audit redaction regression

Add TestISphereSendMessageAuditRedactionIsStable asserting JSONL audit files do not contain the submitted message body or raw idempotency key.

  • Step 4: Verify and commit
git diff --check
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\test-verify-send-audit-idempotency.ps1
go test ./internal/tools -run TestISphereSendMessageAuditRedactionIsStable -v
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add scripts\verify-send-audit-idempotency.ps1 scripts\test-verify-send-audit-idempotency.ps1 internal\tools\isphere_send_message_test.go docs\go-mcp-runbook.md docs\current-status-card.md
git commit -m "test: add send audit idempotency diagnostics"
git push gitea main

Acceptance gate: Diagnostics can prove audit/idempotency shape without opening iSphere.

R6g Result:

  • Added scripts/test-verify-send-audit-idempotency.ps1 and confirmed the red test failed before the verifier existed.
  • Added scripts/verify-send-audit-idempotency.ps1 to summarize redacted audit/idempotency JSONL files with sanitized counts and booleans.
  • Diagnostic detects duplicate same-key/same-target/content replay, conflict same-key/different-content replay, and raw field leaks.
  • Added TestISphereSendMessageAuditRedactionIsStable to prove file-backed audit JSONL does not store raw message body or raw idempotency key.
  • No iSphere login, real send, helper action, hook, upload, or network replay was introduced.

R6h: Central production gate policy for send message

Purpose: 把“为什么不能生产发送”变成单独 gate 对象,避免后续连接器代码散落硬编码。

Files:

  • Create: internal/tools/send_message_gate.go
  • Create: internal/tools/send_message_gate_test.go
  • Modify: internal/tools/isphere_send_message.go
  • Modify: docs/current-status-card.md
  • Modify: docs/go-mcp-runbook.md

Interfaces:

  • Produces: type SendMessageGatePolicy struct { ProductionAllowed bool; ReasonCode string; ReasonMessage string; EvidenceGatePass bool; ConnectorConfigured bool }

  • Produces: LoadSendMessageGatePolicy(env map[string]string, evidenceGatePass bool, connectorConfigured bool) SendMessageGatePolicy.

  • Valid reason codes: send_evidence_missing, send_connector_missing, send_disabled_by_default, send_gate_passed.

  • Step 1: Write table tests

Create TestLoadSendMessageGatePolicy with cases for default disabled, env set but evidence missing, evidence pass but connector missing, and all pass.

go test ./internal/tools -run TestLoadSendMessageGatePolicy -v

Expected before implementation: FAIL because the gate type does not exist.

  • Step 2: Implement gate policy

Create send_message_gate.go with the exact type/function and reason-code order from the test.

  • Step 3: Route blocked production through the gate

Modify isphere_send_message.go so blocked production responses include gate_reason_code and gate_reason_message from SendMessageGatePolicy.

  • Step 4: Verify and commit
git diff --check
go test ./internal/tools -run TestLoadSendMessageGatePolicy -v
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add internal\tools\send_message_gate.go internal\tools\send_message_gate_test.go internal\tools\isphere_send_message.go docs\current-status-card.md docs\go-mcp-runbook.md
git commit -m "feat: centralize send message production gate"
git push gitea main

Acceptance gate: The default runtime stays blocked, but the response explains the exact reason in machine-readable fields.

R6h Result:

  • Added internal/tools/send_message_gate.go with SendMessageGatePolicy and LoadSendMessageGatePolicy.
  • Added table tests for send_disabled_by_default, send_evidence_missing, send_connector_missing, and send_gate_passed.
  • Default isphere_send_message production-blocked responses and audit events now include gate_reason_code and gate_reason_message.
  • ISPHERE_SEND_PRODUCTION_ENABLED=1 is recognized by policy tests, but the default MCP runtime still has no real connector and reports production_send_enabled=false.

R6i: B-route connector adapter shell

Purpose: 为后续 IMPlatformClient/B-route sidecar 接入定义请求/响应 JSON 边界,但本轮不执行真实发送。

Files:

  • Create: internal/tools/send_message_broute_adapter.go
  • Create: internal/tools/send_message_broute_adapter_test.go
  • Modify: docs/source-discovery/2026-07-10-send-connector-preflight.md
  • Modify: docs/current-status-card.md

Interfaces:

  • Produces: type BRouteSendAdapterConfig struct { SidecarPath string; TimeoutSeconds int; Mode string }.

  • Produces: func NewBRouteSendMessageConnector(config BRouteSendAdapterConfig) SendMessageConnector.

  • In this round, accepted modes are disabled and dry_run_contract; any other mode returns broute_mode_blocked.

  • Step 1: Write disabled-mode test

func TestBRouteSendMessageConnectorDisabledMode(t *testing.T) {
    connector := NewBRouteSendMessageConnector(BRouteSendAdapterConfig{Mode:"disabled"})
    result, err := connector.ExecuteSendMessage(context.Background(), SendMessageConnectorRequest{
        TargetType:"contact", TargetID:"u1", ContentSHA256:"abc", IdempotencyKeySHA256:"idem",
    })
    if err == nil { t.Fatalf("expected disabled error") }
    if result.ErrorCode != "broute_mode_blocked" { t.Fatalf("unexpected error code: %s", result.ErrorCode) }
}
  • Step 2: Write dry-run contract test

Add TestBRouteSendMessageConnectorDryRunContract asserting no external process starts and result contains ConnectorMode="broute-dry-run-contract" and Accepted=false.

  • Step 3: Implement adapter shell

Implement a connector that validates request fields and returns contract-shaped blocked/dry-run results only. Do not call Start-Process, do not load DLLs, do not click/type.

  • Step 4: Verify and commit
git diff --check
go test ./internal/tools -run TestBRouteSendMessageConnector -v
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add internal\tools\send_message_broute_adapter.go internal\tools\send_message_broute_adapter_test.go docs\source-discovery\2026-07-10-send-connector-preflight.md docs\current-status-card.md
git commit -m "feat: add b-route send adapter shell"
git push gitea main

Acceptance gate: B-route contract exists; no real send entrypoint is invoked.

R6i Result:

  • Added internal/tools/send_message_broute_adapter.go with BRouteSendAdapterConfig and NewBRouteSendMessageConnector.
  • Added disabled-mode and dry-run-contract tests.
  • disabled returns broute_mode_blocked; dry_run_contract validates request shape and returns broute_dry_run_only.
  • The adapter shell does not start a sidecar, load DLLs, click/type UI, replay network traffic, or upload files.
  • Production isphere_send_message remains blocked in the default MCP runtime.

R6j: Online sandbox-send recording package v2

Purpose: 修正 R6d 缺失项,一次性要求 before/after recorder、人工时间戳、ack/sent-record、重复发送确认减少用户反复跑包。

Files:

  • Modify: scripts/package-send-sandbox-gate.ps1
  • Modify: scripts/verify-send-sandbox-gate-package.ps1
  • Modify: scripts/validate-returned-send-sandbox-package.ps1
  • Modify: docs/source-discovery/2026-07-10-send-sandbox-gate.md
  • Modify: docs/current-status-card.md

Required returned fields:

  • operator_started_at_local

  • operator_clicked_send_at_local

  • operator_observed_success_at_local

  • before_recorder_present=true

  • after_recorder_present=true

  • success_ack_or_sent_record_present=true

  • duplicate_second_send_attempted=false

  • Step 1: Add v2 manifest assertions to package verifier

powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-sandbox-gate-package.ps1

Expected before implementation: FAIL because v2 required returned fields are not enforced.

  • Step 2: Add v2 checklist to package builder

Update package contents to include RETURN-CHECKLIST-V2.md, SANDBOX-SEND-INPUTS.schema.json, and a stricter CREATE-RETURN-ZIP.ps1 that refuses to package if after-recorder output is missing.

  • Step 3: Add validator strict mode

Add parameter:

param([string]$ZipPath, [switch]$StrictV2)

-StrictV2 exits non-zero if any required returned field is absent.

  • Step 4: Verify and commit
git diff --check
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-sandbox-gate-package.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\test-validate-returned-send-sandbox-package.ps1
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add scripts\package-send-sandbox-gate.ps1 scripts\verify-send-sandbox-gate-package.ps1 scripts\validate-returned-send-sandbox-package.ps1 scripts\test-validate-returned-send-sandbox-package.ps1 docs\source-discovery\2026-07-10-send-sandbox-gate.md docs\current-status-card.md
git commit -m "chore: harden send sandbox evidence package v2"
git push gitea main

Acceptance gate: A generated package can no longer omit the R6d missing after-recorder/timestamp fields.


R6k: Returned sandbox evidence intake v2

Purpose: 自动检查 Downloads 是否已有新返回包;有则按 strict v2 intake没则写清楚生产发送仍阻断并继续本地可推进工作。

Files:

  • Create or modify: docs/source-discovery/2026-07-10-returned-send-sandbox-analysis-v2.md

  • Modify: docs/current-status-card.md

  • Modify: docs/source-discovery/capability-source-matrix.md

  • Step 1: Look for a new returned package

Get-ChildItem C:\Users\zhaoy\Downloads -Filter *.zip | Sort-Object LastWriteTime -Descending | Select-Object -First 10 FullName,LastWriteTime,Length

Prefer a zip whose contents include SANDBOX-SEND-INPUTS.json, after-recorder output, and return manifest.

  • Step 2A: If a new candidate exists, validate strict v2
$candidate = Get-ChildItem C:\Users\zhaoy\Downloads -Filter *.zip | Sort-Object LastWriteTime -Descending | Select-Object -First 1
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\validate-returned-send-sandbox-package.ps1 -ZipPath $candidate.FullName -StrictV2

Expected pass output must include r6d_gate_pass=true and strict_v2_pass=true before production send can move beyond blocked state.

  • Step 2B: If no candidate exists, document no-intake state

Create docs/source-discovery/2026-07-10-returned-send-sandbox-analysis-v2.md stating no strict-v2 returned package was found, r6d_gate_pass=false, and production isphere_send_message remains blocked.

  • Step 3: Verify and commit
git diff --check
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add docs\source-discovery\2026-07-10-returned-send-sandbox-analysis-v2.md docs\source-discovery\capability-source-matrix.md docs\current-status-card.md
git commit -m "docs: record send sandbox evidence v2 intake"
git push gitea main

Acceptance gate: The status card explicitly says whether production send is still blocked or evidence-gated for the next round.


R6l: Send-message production path gate closure

Purpose: 根据 R6k 决策收口:如果 strict v2 通过,只打开 gated fake/sandbox connector path如果没通过保持生产阻断并让响应/文档完全一致。

Files:

  • Modify: internal/tools/isphere_send_message.go
  • Modify: internal/tools/isphere_send_message_test.go
  • Modify: scripts/verify-go-mcp.ps1
  • Modify: docs/go-mcp-runbook.md
  • Modify: docs/current-status-card.md

Branching rule:

  • If r6d_gate_pass=false: add regression tests proving production remains blocked with gate_reason_code="send_evidence_missing".

  • If r6d_gate_pass=true: add tests that production can only run through an injected connector with ISPHERE_SEND_PRODUCTION_ENABLED=1, evidence gate pass, and idempotency key present.

  • Step 1: Write default-blocked regression test

Add TestISphereSendMessageProductionGateBlockedWithoutStrictEvidence, asserting ok=false, send_status="blocked", gate_reason_code is not empty, production_send_enabled=false, and real_send_attempted=false.

  • Step 2: Write gated fake-production test if strict v2 passed

Add TestISphereSendMessageProductionRequiresEvidenceAndConnector. If strict v2 did not pass, keep this test skipped with explicit skip reason: strict v2 send evidence not present in this repository state.

  • Step 3: Update verification smoke

verify-go-mcp.ps1 must continue printing production_send_enabled=false on the default path unless strict evidence and env gate are configured.

  • Step 4: Verify and commit
git diff --check
go test ./internal/tools -run "TestISphereSendMessageProduction" -v
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add internal\tools\isphere_send_message.go internal\tools\isphere_send_message_test.go scripts\verify-go-mcp.ps1 docs\go-mcp-runbook.md docs\current-status-card.md
git commit -m "feat: close send message production gate behavior"
git push gitea main

Acceptance gate: No ambiguous state remains: send-message is either gated by validated evidence or explicitly blocked with a machine-readable reason.


R7: isphere_send_file preview tool

Purpose: 补齐“发文件”的 MCP 产品面,先支持 preview/dry-run校验目标、文件存在性、允许目录、大小、SHA256不上传不点击。

Files:

  • Create: internal/tools/isphere_send_file.go
  • Create: internal/tools/isphere_send_file_test.go
  • Modify: internal/mcpserver/server.go
  • Modify: internal/mcpserver/server_test.go
  • Modify: scripts/verify-go-mcp.ps1
  • Modify: cmd/isphere-capability-smoke/main.go
  • Modify: docs/go-mcp-runbook.md
  • Modify: docs/current-status-card.md

Interfaces:

  • Tool name: isphere_send_file.

  • Args: target_type, target_id, file_path, file_sha256, idempotency_key, execution_mode, preview.

  • Env: ISPHERE_SEND_FILE_ALLOWED_DIR required for previewing real local file paths.

  • Response fields: ok, send_status, file_sha256, file_size_bytes, target_ref, production_send_enabled, side_effect_flags.

  • Step 1: Write file-preview test

Add TestISphereSendFilePreviewComputesHashAndSize, creating a temp allowed directory and hello.txt, then asserting preview returns ok=true, send_status="planned", file_size_bytes=5, and real_send_attempted=false.

  • Step 2: Write path rejection test

Add TestISphereSendFileRejectsPathOutsideAllowedDir asserting paths outside ISPHERE_SEND_FILE_ALLOWED_DIR return ok=false and send_status="blocked".

  • Step 3: Implement tool and registration

Register the tenth MCP tool. Production execution returns blocked with production_send_enabled=false.

  • Step 4: Update smoke scripts

verify-go-mcp.ps1 and isphere-capability-smoke must assert tool count includes isphere_send_file, preview works with a temp fixture file, and production remains blocked.

  • Step 5: Verify and commit
git diff --check
go test ./internal/tools -run TestISphereSendFile -v
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add internal\tools\isphere_send_file.go internal\tools\isphere_send_file_test.go internal\mcpserver\server.go internal\mcpserver\server_test.go scripts\verify-go-mcp.ps1 cmd\isphere-capability-smoke\main.go docs\go-mcp-runbook.md docs\current-status-card.md
git commit -m "feat: add send file preview tool"
git push gitea main

Acceptance gate: 数字员工能看到“发文件”工具,但默认路径只做 preview不上传。


R8: Send-file idempotency and audit hardening

Purpose: 把发文件的审计/idempotency 与发消息保持一致,后续接上传连接器时不再重做控制面。

Files:

  • Modify: internal/tools/isphere_send_file.go
  • Modify: internal/tools/isphere_send_file_test.go
  • Modify: scripts/verify-go-mcp.ps1
  • Modify: docs/go-mcp-runbook.md
  • Modify: docs/current-status-card.md

Interfaces:

  • Env: ISPHERE_SEND_FILE_AUDIT_PATH.

  • Env: ISPHERE_SEND_FILE_IDEMPOTENCY_PATH.

  • Duplicate same target/file/idempotency returns duplicate_detected=true with no second send.

  • Reusing the same idempotency key for a different target or file hash returns conflict_detected=true.

  • Step 1: Write duplicate test

Add TestISphereSendFileDuplicateIdempotencyDetected: same target, same file hash, same idempotency key called twice; second response has duplicate_detected=true and real_send_attempted=false.

  • Step 2: Write conflict test

Add TestISphereSendFileIdempotencyConflictBlocked: same idempotency key with a different file hash returns send_status="blocked" and conflict_detected=true.

  • Step 3: Implement audit and idempotency state

Reuse the message idempotency pattern or extract a shared small helper only if it reduces duplication without changing message behavior.

  • Step 4: Verify and commit
git diff --check
go test ./internal/tools -run TestISphereSendFile -v
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add internal\tools\isphere_send_file.go internal\tools\isphere_send_file_test.go scripts\verify-go-mcp.ps1 docs\go-mcp-runbook.md docs\current-status-card.md
git commit -m "feat: harden send file idempotency audit"
git push gitea main

Acceptance gate: File upload remains blocked, but duplicate/conflict behavior is deterministic.


R9: Send-file upload evidence package

Purpose: 为“真实发文件”采集一次性材料:文件菜单、上传路径、大小限制、发送确认、上传/文件传输 DLL 状态。

Files:

  • Create: scripts/package-send-file-sandbox-gate.ps1
  • Create: scripts/verify-send-file-sandbox-gate-package.ps1
  • Create: scripts/validate-returned-send-file-sandbox-package.ps1
  • Create: docs/source-discovery/2026-07-10-send-file-sandbox-gate.md
  • Modify: docs/current-status-card.md

Required package contents:

  • RUN-FILE-RECORDING-SUITE.bat

  • FILE-SEND-INPUTS.json

  • RETURN-FILE-CHECKLIST.md

  • CREATE-FILE-RETURN-ZIP.ps1

  • WinHelper recorder executable and dependencies

  • Capability smoke executable if already built

  • Step 1: Build verifier first

powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-file-sandbox-gate-package.ps1

Expected before implementation: FAIL because package builder does not exist.

  • Step 2: Implement package builder

The builder outputs runs/send-file-sandbox-gate-package.zip and includes only executables/scripts/docs needed by an online operator.

  • Step 3: Implement returned-package validator

Validator requires file send attempt timestamps, before/after recorder output, file SHA256, observed upload/sent status, and duplicate-send confirmation.

  • Step 4: Verify and commit
git diff --check
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-file-sandbox-gate-package.ps1
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add scripts\package-send-file-sandbox-gate.ps1 scripts\verify-send-file-sandbox-gate-package.ps1 scripts\validate-returned-send-file-sandbox-package.ps1 docs\source-discovery\2026-07-10-send-file-sandbox-gate.md docs\current-status-card.md
git commit -m "chore: add send file sandbox evidence package"
git push gitea main

Acceptance gate: 用户可以把一个包带到可登录环境采集发文件证据。


R10: Receive-file download resolver v2 diagnostic

Purpose: 继续推进“收文件”的下载/落地问题,验证 MsgLib 记录、cache/archive 文件、文件名/source-id/大小/时间窗口是否能形成可信映射。

Files:

  • Modify: scripts/verify-file-cache-mapping.ps1
  • Create: scripts/test-verify-file-cache-mapping.ps1
  • Create: docs/source-discovery/2026-07-10-file-download-mapping-v2.md
  • Modify: docs/current-status-card.md

Diagnostic inputs:

  • -CacheRoot accepts an absolute operator-local cache root selected at runtime; fixture tests create the cache root under $env:TEMP.

  • -MsgLibDb and -SQLiteDll accept copied DB/runtime paths when real copied DB is available; fixture tests do not require real DB files.

  • -SanitizedOutputPath writes committed-safe JSON summary to a caller-selected output file.

  • Step 1: Add fixture test for resolver scoring

Fixture contains three DB-like file records and four cache-like file entries. Expected scoring:

exact filename + exact size + close timestamp => score 100
exact size + source id in name/ref => score 80
filename only => score 40 and not accepted
  • Step 2: Implement scoring and sanitized output

Output fields: records_checked, cache_candidates_checked, accepted_matches, ambiguous_matches, raw_paths_printed=false, file_contents_read=false.

  • Step 3: Write decision note

docs/source-discovery/2026-07-10-file-download-mapping-v2.md records whether accepted matches exist. If not, download remains blocked and UI/client download connector becomes the next route.

  • Step 4: Verify and commit
git diff --check
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\test-verify-file-cache-mapping.ps1
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add scripts\verify-file-cache-mapping.ps1 scripts\test-verify-file-cache-mapping.ps1 docs\source-discovery\2026-07-10-file-download-mapping-v2.md docs\current-status-card.md
git commit -m "test: add file download resolver v2 diagnostic"
git push gitea main

Acceptance gate: 文件下载要么得到可实现映射,要么得到明确阻断证据。


R11: Receive-file download preview contract

Purpose: 即使真实下载还不能做,也让 isphere_receive_files 对 download 请求返回可机器解析的 preview/blocked 结果,而不是只有泛化拒绝。

Files:

  • Modify: internal/tools/isphere_receive_files.go
  • Modify: internal/tools/isphere_receive_files_test.go
  • Modify: scripts/verify-go-mcp.ps1
  • Modify: docs/go-mcp-runbook.md
  • Modify: docs/current-status-card.md

Interfaces:

  • Args accepted: mode="download", preview=true, file_ref, output_dir.

  • If resolver lacks accepted mapping, response: ok=false, download_status="blocked", blocked_reason_code="file_cache_mapping_missing".

  • If resolver has accepted mapping in fixture tests, response: ok=true, download_status="planned", no file copy during preview.

  • Step 1: Write blocked-preview test

Add TestISphereReceiveFilesDownloadPreviewBlockedWithoutMapping, asserting blocked_reason_code="file_cache_mapping_missing" and file_contents_read=false.

  • Step 2: Write planned-preview fixture test

Add TestISphereReceiveFilesDownloadPreviewPlannedWithFixtureMapping, using an injected fixture resolver and asserting download_status="planned", file_contents_read=false, and file_copied=false.

  • Step 3: Implement preview contract

Keep non-preview real download blocked unless R10 accepted mapping exists and a separate production-copy gate is added.

  • Step 4: Verify and commit
git diff --check
go test ./internal/tools -run TestISphereReceiveFilesDownloadPreview -v
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add internal\tools\isphere_receive_files.go internal\tools\isphere_receive_files_test.go scripts\verify-go-mcp.ps1 docs\go-mcp-runbook.md docs\current-status-card.md
git commit -m "feat: add receive file download preview contract"
git push gitea main

Acceptance gate: 数字员工可以理解“为什么现在不能下载”,并在有映射时得到 planned preview。


R12: Receive-message reconciliation helper

Purpose: 给收消息建立 PacketReader/MsgLib 对账能力,用于后续提升默认 auto 的可信度,但本轮不改变默认路由。

Files:

  • Create: internal/isphere/message_reconciliation.go
  • Create: internal/isphere/message_reconciliation_test.go
  • Create: scripts/verify-receive-source-reconciliation.ps1
  • Modify: docs/source-discovery/2026-07-10-receive-message-reconciliation-precheck.md
  • Modify: docs/current-status-card.md

Interfaces:

  • Produces: type MessageReconciliationCandidate struct { Source string; MessageID string; ConversationID string; SenderID string; TimestampUnixMilli int64; BodyPresent bool; AttachmentPresent bool }.

  • Produces: func ReconcileMessageSources(left, right []MessageReconciliationCandidate) MessageReconciliationSummary.

  • Summary fields: strong_matches, medium_matches, unmatched_left, unmatched_right, auto_merge_recommended.

  • Step 1: Write reconciliation tests

Add TestReconcileMessageSourcesStrongAndMediumMatches: same message id is strong; same conversation/sender and timestamp within 3000ms is medium; auto merge remains false until a strong-ratio threshold is met.

  • Step 2: Implement pure Go helper

No DB/log IO in the helper. It only compares sanitized candidates.

  • Step 3: Add script wrapper

Script runs against fixture JSON first; optional real evidence mode prints counts and booleans only.

  • Step 4: Verify and commit
git diff --check
go test ./internal/isphere -run TestReconcileMessageSources -v
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-receive-source-reconciliation.ps1 -UseFixture
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add internal\isphere\message_reconciliation.go internal\isphere\message_reconciliation_test.go scripts\verify-receive-source-reconciliation.ps1 docs\source-discovery\2026-07-10-receive-message-reconciliation-precheck.md docs\current-status-card.md
git commit -m "feat: add receive message reconciliation helper"
git push gitea main

Acceptance gate: 对账能力存在,但默认 receive routing 不改变。


R13: End-to-end business goals smoke

Purpose: 用一个脚本从数字员工视角验证四个业务目标的当前状态:能搜联系人、搜群、收消息、列文件、预览发消息、预览发文件,并列出阻断项。

Files:

  • Create: scripts/verify-business-goals-smoke.ps1
  • Create: docs/reports/2026-07-10-business-goals-smoke.md
  • Modify: docs/current-status-card.md
  • Modify: docs/go-mcp-runbook.md

Output keys:

  • 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

  • Step 1: Implement fixture-backed smoke

The script starts cmd/isphere-mcp with temp fixture env and calls MCP requests using the same pattern as verify-go-mcp.ps1.

  • Step 2: Assert business booleans

Default expected state after R12:

search_contacts_ready=true
search_groups_ready=true
receive_messages_ready=true
send_message_preview_ready=true
receive_files_list_ready=true
send_file_preview_ready=true
send_message_production_ready=false unless strict send evidence passed
receive_files_download_ready=false unless R10 accepted mapping exists
send_file_production_ready=false unless file sandbox evidence passed
  • Step 3: Create report

docs/reports/2026-07-10-business-goals-smoke.md summarizes the current business state in plain Chinese.

  • Step 4: Verify and commit
git diff --check
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-business-goals-smoke.ps1
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
git add scripts\verify-business-goals-smoke.ps1 docs\reports\2026-07-10-business-goals-smoke.md docs\current-status-card.md docs\go-mcp-runbook.md
git commit -m "test: add end-to-end business goals smoke"
git push gitea main

Acceptance gate: 业务目标完成度可以用脚本输出,而不是口头判断。


R14: Operator packaging, runbook, and release-candidate report

Purpose: 把当前可交付能力、包、用法、阻断项整理成用户能执行、业务能审核、下一轮能继续的最终材料。

Files:

  • Modify: docs/go-mcp-runbook.md
  • Create: docs/reports/2026-07-10-r6f-r14-release-candidate.md
  • Modify: docs/source-discovery/capability-source-matrix.md
  • Modify: docs/current-status-card.md
  • Modify: package scripts touched in earlier rounds only if packaging verification finds missing required files.

Required report sections:

  • ## Business capability status

  • ## MCP tools available to digital employees

  • ## Packages generated under runs

  • ## Production blockers

  • ## Exact next evidence request if blocked

  • ## Verification commands and latest results

  • Step 1: Rebuild local packages

powershell -NoProfile -ExecutionPolicy Bypass -File scripts\package-send-sandbox-gate.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-sandbox-gate-package.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\package-send-file-sandbox-gate.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-file-sandbox-gate-package.ps1
  • Step 2: Run full verification
git diff --check
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-business-goals-smoke.ps1
go test ./...
go build ./cmd/isphere-mcp
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-go-mcp.ps1
  • Step 3: Write release-candidate report

The report must state the business status using these exact categories:

已完成:可直接给数字员工用
可预览:数字员工可规划但不会真实发出/下载
阻断:需要在线可登录环境返回证据
  • Step 4: Commit and push
git status --short
git add docs\go-mcp-runbook.md docs\reports\2026-07-10-r6f-r14-release-candidate.md docs\source-discovery\capability-source-matrix.md docs\current-status-card.md scripts\package-send-sandbox-gate.ps1 scripts\verify-send-sandbox-gate-package.ps1 scripts\package-send-file-sandbox-gate.ps1 scripts\verify-send-file-sandbox-gate-package.ps1
git commit -m "docs: publish r6f r14 release candidate status"
git push gitea main

Acceptance gate: 用户可以审核一个清晰结论:哪些目标已经能给数字员工用,哪些只到 preview哪些必须回到在线环境采证。


Expected Business State After R14

Goal Expected state after local-only rounds If strict online evidence arrives during R6k/R9
搜索联系人 已完成,可给数字员工用 unchanged
搜索群组 已完成,可给数字员工用 unchanged
收消息 已完成基础能力;增加对账辅助 可进一步判断是否切换 default auto merge
发消息 preview/idempotency/audit/gate 完整;生产默认阻断 可进入 gated connector production path
收文件 list 完整download preview 能解释阻断 若 R10 映射成立,可进入真实 download gate
发文件 preview/idempotency/audit/tool surface 完整;生产默认阻断 若 R9 返回包通过,可进入 upload connector path

Stop Conditions That Require User Input

  • R6k strict-v2 returned send package missing, and remaining desired work is real production send.
  • R9 returned send-file package missing, and remaining desired work is real upload/send file.
  • R10 cannot map received-file metadata to cache/download and user wants real download rather than preview/blocked explanation.
  • A future online package contains raw sensitive material that cannot be summarized into committed docs without user choosing a redaction policy.

Self-Review

  • Spec coverage: the plan covers search contacts, search groups, receive messages, send messages, receive files, and send files.
  • Loop coverage: there are 15 ordered rounds from R6f through R14, each with files, commands, acceptance gates, commit messages, and push commands.
  • Placeholder scan: the plan does not use placeholder markers; evidence-dependent branches have exact pass/fail behavior and concrete next actions.
  • Type consistency: send-message connector types introduced in R6f are consumed by R6h, R6i, and R6l; file-send tool fields introduced in R7 are consumed by R8, R9, and R13.