diff --git a/docs/superpowers/plans/2026-07-12-b-route-bridge-next-plan.md b/docs/superpowers/plans/2026-07-12-b-route-bridge-next-plan.md new file mode 100644 index 0000000..ed92e7d --- /dev/null +++ b/docs/superpowers/plans/2026-07-12-b-route-bridge-next-plan.md @@ -0,0 +1,319 @@ +# B-Route Bridge Next 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:** Push the primary B-route from a dry-run shell toward a verifiable sidecar/API bridge without enabling real send yet. + +**Architecture:** Keep the Go MCP tool contracts stable. B-route remains the primary product route: reuse the logged-in `IMPlatformClient.exe` runtime through a narrow sidecar/API bridge if a safe bridge transport exists. A-route/RPA remains backup-only and should be used only for UI action smoke or when B-route is proven blocked. + +**Tech Stack:** Go 1.23.4, github.com/modelcontextprotocol/go-sdk, Windows PowerShell, .NET Framework C# helper/sidecar, stdin/stdout JSON protocols, Windows UI Automation only as fallback. + +## Global Constraints + +- Repository root: `E:\coding\codex\isphere-ai-bridge`. +- Active branch for execution should be a new `codex/` branch, not `main` directly. +- Do not use `rg`; use `git ls-files`, `ag`, `grep -R`, or PowerShell commands. +- Local machine cannot log in to iSphere; local work must use static analysis, fake sidecar processes, synthetic fixtures, or offline real-window UI only. +- B-route is primary: running-client sidecar / in-process connector / existing API comes before A-route/RPA. +- A-route/RPA is backup-only: keep it runnable, but do not make it the default product architecture. +- No real send/file upload in this plan. Stop at bridge feasibility, self_check, runtime probe, and dry-run preview. +- Keep audit redaction: do not store raw message body, raw idempotency key, raw file contents, or raw local file paths in committed outputs. + +--- + +## Current evidence summary + +The current `main` state already has: + +- `isphere_send_message` MCP contract, preview/dry-run metadata, audit, idempotency, and connector abstraction. +- `internal/tools/send_message_broute_adapter.go` with B-route `disabled` and `dry_run_contract` modes only. +- `internal/tools/send_message_uia_adapter.go` wired from env only for `ISPHERE_SEND_CONNECTOR_MODE=uia_rpa`. +- C# WinHelper `probe_client_runtime`, `probe_send_entrypoints`, `probe_send_uia_controls`, and `uia_send_message`. +- Offline real `frmP2PChat` opener for RPA backup validation. +- No B-route env wiring, no process-backed B-route sidecar client, no in-process bridge transport decision, and no real send/file-upload connector. + +Important technical conclusion: an external C# process cannot automatically reuse the logged-in static runtime of `IMPlatformClient.exe`. Before building send invocation, the next B-route node must decide the bridge transport: existing API/IPC, plugin/extension loading, in-process adapter, or fallback. + +--- + +## Task 1: B-route bridge transport feasibility report + +**Files:** +- Create: `docs/source-discovery/2026-07-12-b-route-bridge-feasibility.md` +- Modify: `docs/source-discovery/capability-source-matrix.md` + +**Interfaces:** +- Consumes: existing docs `docs/source-discovery/2026-07-10-send-sidecar-b-first-plan.md`, `docs/source-discovery/2026-07-10-send-connector-preflight.md`, and current Go/C# connector files. +- Produces: a route decision table with exact choices: `existing_ipc`, `plugin_extension`, `in_process_adapter`, `external_dry_run_only`, or `fallback_rpa`. + +- [ ] Re-read current B-route evidence. + +Run: + +```powershell +Get-Content -LiteralPath docs\source-discovery\2026-07-10-send-sidecar-b-first-plan.md +Get-Content -LiteralPath docs\source-discovery\2026-07-10-send-connector-preflight.md +Get-Content -LiteralPath internal\tools\send_message_broute_adapter.go +Get-Content -LiteralPath internal\tools\send_message_uia_adapter.go +``` + +Expected: confirm B-route entrypoint names exist, but no bridge transport is implemented. + +- [ ] Write the feasibility report with this required conclusion block: + +```markdown +## Decision + +B-route remains primary. The immediate next implementation is not production send; it is bridge transport selection plus dry-run sidecar plumbing. + +| Candidate | Can reuse logged-in runtime? | Local feasibility | Next action | +| --- | --- | --- | --- | +| existing_ipc/local_service | unknown | inspect live probe named pipes/services/network metadata | continue if concrete API appears | +| plugin_extension | unknown | inspect install/plugin loader evidence | continue if client loads local plugin DLL/exe | +| in_process_adapter | possible but highest risk | requires explicit bridge mechanism | defer until IPC/plugin ruled out | +| external_dry_run_only | cannot reuse logged-in static runtime | useful for protocol/client tests only | implement as non-mutating sidecar boundary | +| fallback_rpa | can drive UI only | already backup-ready | keep as backup, not primary | +``` + +- [ ] Update `capability-source-matrix.md` so the next slice says: “B-route bridge transport feasibility and dry-run sidecar boundary”, not “RPA send”. + +- [ ] Verify docs. + +Run: + +```powershell +git diff --check +``` + +Expected: exit 0. + +## Task 2: Add B-route connector env selection without starting real send + +**Files:** +- Modify: `internal/tools/send_message_uia_adapter.go` or split env loading into `internal/tools/send_message_connector_env.go` +- Modify: `internal/tools/send_message_uia_adapter_test.go` or create `internal/tools/send_message_connector_env_test.go` +- Modify: `docs/go-mcp-runbook.md` + +**Interfaces:** +- Consumes: `NewBRouteSendMessageConnector(BRouteSendAdapterConfig)`. +- Produces: `NewSendMessageConnectorFromEnv()` supports: + - `ISPHERE_SEND_CONNECTOR_MODE=broute_dry_run` + - `ISPHERE_SEND_CONNECTOR_MODE=broute_sidecar` + - `ISPHERE_SEND_BROUTE_MODE=disabled|dry_run_contract|sidecar_preview` + - `ISPHERE_SEND_BROUTE_SIDECAR_EXE=` + - `ISPHERE_SEND_BROUTE_TIMEOUT_SECONDS=` + +- [ ] Write failing env-loader tests. + +Test cases: + +```text +mode empty -> nil connector +mode uia_rpa -> existing UIA connector +mode broute_dry_run -> B-route connector mode dry_run_contract +mode broute_sidecar without sidecar exe -> connector returns blocked sidecar config error, not panic +``` + +Run: + +```powershell +go test ./internal/tools -run "TestNewSendMessageConnectorFromEnv" -count=1 +``` + +Expected before implementation: fail for B-route modes. + +- [ ] Implement env parsing with no real send. + +Required behavior: + +```text +broute_dry_run -> NewBRouteSendMessageConnector(BRouteSendAdapterConfig{Mode:"dry_run_contract"}) +broute_sidecar -> NewBRouteSendMessageConnector(BRouteSendAdapterConfig{Mode:"sidecar_preview", SidecarPath: env path, TimeoutSeconds: parsed timeout}) +``` + +- [ ] Run focused tests. + +```powershell +go test ./internal/tools -run "TestNewSendMessageConnectorFromEnv|TestBRoute" -count=1 +``` + +Expected: pass. + +## Task 3: Process-backed B-route sidecar client boundary + +**Files:** +- Create: `internal/broute/send_sidecar_client.go` +- Create: `internal/broute/send_sidecar_client_test.go` +- Modify: `internal/tools/send_message_broute_adapter.go` +- Modify: `internal/tools/send_message_broute_adapter_test.go` + +**Interfaces:** +- Produces protocol: `isphere.broute.send.v1`. +- Produces sidecar ops: + - `self_check` + - `probe_runtime` + - `preview_send_message` +- No op named `send_message` in this task. + +- [ ] Write fake-process tests for `internal/broute`. + +The fake sidecar must accept stdin JSON and return: + +```json +{"protocol":"isphere.broute.send.v1","request_id":"...","op":"preview_send_message","ok":true,"data":{"connector_mode":"broute-sidecar-preview","would_send":false,"entrypoint":"AppContextManager.SendTxtMessageByJid","target_ref":"direct:demo","content_sha256":"..."}} +``` + +- [ ] Implement the client with timeout, stderr capture, protocol/op/request_id validation, and structured sidecar errors. + +Use `internal/msglib/sidecar_client.go` as the pattern, but keep the package separate as `internal/broute`. + +- [ ] Update `send_message_broute_adapter.go` so `Mode="sidecar_preview"` calls `preview_send_message` and returns: + +```text +Accepted=false +Status=blocked +ErrorCode=broute_sidecar_preview_only +ConnectorMode=broute-sidecar-preview +ProductionEnabled=false +SideEffects all false +``` + +- [ ] Verify no accidental production send path exists. + +Run: + +```powershell +go test ./internal/broute ./internal/tools -run "BRoute|Sidecar" -count=1 +``` + +Expected: pass; no test should require iSphere login. + +## Task 4: Native B-route sidecar skeleton, preview-only + +**Files:** +- Create: `native/ISphereSendSidecar/Program.cs` +- Create: `native/ISphereSendSidecar/SidecarProtocol.cs` +- Create: `scripts/build-send-sidecar.ps1` +- Create: `scripts/verify-send-sidecar.ps1` +- Create: `docs/broute-send-sidecar-contract.md` + +**Interfaces:** +- Native executable accepts stdin JSON and writes stdout JSON. +- Protocol: `isphere.broute.send.v1`. +- Ops implemented: + - `self_check` + - `probe_runtime` + - `preview_send_message` +- Explicitly not implemented: + - `send_message` + - `send_file` + - `upload_file` + - hooks/injection/network replay. + +- [ ] Implement `self_check` returning sidecar name, version, process bitness, and `mutates_client=false`. +- [ ] Implement `probe_runtime` by reusing safe process/module discovery logic from WinHelper where possible. +- [ ] Implement `preview_send_message` as contract validation only; it must echo hashes/target refs and `would_send=false`. +- [ ] Build and verify. + +Run: + +```powershell +powershell -NoProfile -ExecutionPolicy Bypass -File scripts\build-send-sidecar.ps1 +powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-send-sidecar.ps1 +go test ./... +``` + +Expected: all pass; sidecar verification prints only booleans/counts and no message body. + +## Task 5: Online B-route evidence package v3 + +**Files:** +- Create: `scripts/package-broute-bridge-probe.ps1` +- Create: `scripts/verify-broute-bridge-probe-package.ps1` +- Create: `scripts/validate-returned-broute-bridge-probe.ps1` +- Create: `docs/source-discovery/2026-07-12-broute-bridge-probe-package.md` + +**Interfaces:** +- Package includes: + - live probe recorder; + - send sidecar preview executable; + - `RUN-BROUTE-BRIDGE-PROBE.bat`; + - `BROUTE-BRIDGE-INPUTS.template.json`; + - return zip helper. + +- [ ] Package only non-mutating probes. +- [ ] Require operator to be logged in before running. +- [ ] Validate returned package for: + - running client present; + - module availability; + - sidecar self_check passed; + - sidecar preview returned `would_send=false`; + - no real send attempted. + +Run: + +```powershell +powershell -NoProfile -ExecutionPolicy Bypass -File scripts\package-broute-bridge-probe.ps1 +powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-broute-bridge-probe-package.ps1 +powershell -NoProfile -ExecutionPolicy Bypass -File scripts\validate-returned-broute-bridge-probe.ps1 -UseFixture +``` + +Expected: package builds and fixture validation passes. + +## Task 6: Business smoke split for send readiness + +**Files:** +- Modify: `scripts/verify-business-goals-smoke.ps1` +- Modify: `docs/reports/2026-07-12-main-business-status-correction.md` +- Create or modify: `docs/reports/2026-07-12-broute-next-smoke.md` + +**Interfaces:** +- Produces separate booleans: + - `send_message_preview_ready` + - `send_message_broute_bridge_preview_ready` + - `send_message_ui_action_ready` + - `send_message_business_delivery_ready` + - `send_file_preview_ready` + - `send_file_business_delivery_ready` + +- [ ] Update smoke script to avoid one ambiguous `send_message_production_ready` field. +- [ ] Ensure current expected state is: + +```json +{ + "send_message_preview_ready": true, + "send_message_broute_bridge_preview_ready": true, + "send_message_ui_action_ready": true, + "send_message_business_delivery_ready": false, + "send_file_preview_ready": true, + "send_file_business_delivery_ready": false +} +``` + +- [ ] Verify. + +Run: + +```powershell +powershell -NoProfile -ExecutionPolicy Bypass -File scripts\verify-business-goals-smoke.ps1 +git diff --check +go test ./... +``` + +Expected: pass. + +--- + +## Stop conditions + +Stop and ask the business owner if any of these occur: + +1. B-route bridge transport requires invasive in-process loading and no plugin/IPC path exists. +2. Online probe shows the logged-in client does not expose the expected modules/entrypoints. +3. B-route preview cannot distinguish direct contact vs group target. +4. Any step would perform real send/upload before explicit online evidence gates are ready. +5. A-route becomes the only viable path; this requires an explicit business decision because RPA is backup-only. + +## Recommended next action + +Start with Task 1 and Task 2 only. That creates a clear B-route bridge feasibility decision and lets the MCP server select a B-route dry-run connector from env without touching real send.