FN-6473: document Route A ACP escalation blockage

Record the authenticated Route A ACP escalation rerun and keep U9 blocked.

- Update the ACP contract OQ1 status to FN-6473 with the observed unauthenticated bridge result.
- Capture the explicit request-permission instrumentation outcome: zero forwarded tool calls and zero permission callbacks.
- Extend the Claude ACP runtime plan with the escalation status and upstream bridge/ACP permission-forwarding requirement.

Files changed:
 docs/acp-contract.md                                      | 13 +++++++++++--
 docs/plans/2026-06-14-001-feat-claude-acp-runtime-plan.md |  3 +++
 2 files changed, 14 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-6473

Fusion-Task-Lineage: 2e6ec23b-a9cd-4fd0-b24e-72ee8bb145ac
This commit is contained in:
gsxdsm
2026-06-14 23:31:52 -07:00
parent d8fe994ca7
commit 1d474a1dff
2 changed files with 14 additions and 2 deletions

View File

@@ -112,11 +112,14 @@ FN-6466 reran U9 against pinned `claude-code-cli-acp` 0.1.1 with a real non-empt
FNXC:ACPRoute 2026-06-14-22:43:
FN-6467 reran U9 in this worktree with `claude` 2.1.177 present, the pinned bridge binary resolved under the ACP plugin, and the 62-tool `custom-tools` MCP payload shape from Route A. The bridge still reported `Not logged in · Please run /login`; keep the OQ1 decision in this committed contract so FN-6460's preflight is never re-blocked by lost task metadata or by mistaking binary presence for authenticated bridge readiness.
FNXC:ACPRoute 2026-06-15-00:12:
FN-6473 is the explicit authenticated-environment escalation for Route-A U9, so its OQ1 result must remain in committed docs even when task-local evidence ages out. This worktree had `claude` 2.1.177, the plugin-local pinned bridge 0.1.1, matching lockfile integrity, and the 62-tool `custom-tools` payload, but the bridge still reached an unauthenticated Claude session (`Not logged in · Please run /login`) before any forwarded tool call or permission callback.
-->
### OQ1 — Route A MCP-over-ACP forwarding and permission-gate traversal
**Status:** UNRESOLVED / BLOCKED as of FN-6467 (2026-06-14). **Gate traversal:** UNRESOLVED — no forwarded tool invocation reached the point where it could be classified as GATED or BYPASSED. **Combined Route A verdict: NOT GO** until this OQ records both required U9 answers as GO.
**Status:** UNRESOLVED / BLOCKED as of FN-6473 (2026-06-15). **Gate traversal:** UNRESOLVED — no forwarded tool invocation reached the point where it could be classified as GATED or BYPASSED. **Combined Route A verdict: NOT GO** until this OQ records both required U9 answers as GO.
**Recovery status:** NOT-RECOVERED. `fn_task_show FN-6459` retained only archived task metadata plus an archive log entry, `.fusion/tasks/FN-6459/` is absent in the FN-6465 worktree, and `fn_task_document_read(key="research")` returned not found from FN-6465's execution context. No surviving authoritative FN-6459 U9 verdict was available to transcribe.
@@ -135,6 +138,12 @@ FN-6467 reran U9 in this worktree with `claude` 2.1.177 present, the pinned brid
1. **Can Claude invoke a real forwarded Fusion tool through the bridge?** **UNPROVEN / BLOCKED.** The bridge accepts the non-empty `mcpServers` declaration, but the underlying `claude` session is still unauthenticated from the bridge's perspective and no forwarded MCP tool was invoked.
2. **Do forwarded tool calls traverse ACP `session/request_permission`?** **UNPROVEN / BLOCKED (neither GATED nor BYPASSED observed).** No forwarded tool call occurred, so the rerun observed no permission callback and cannot classify the security-critical gate path.
**Escalation path:** rerun U9 with an environment where the pinned bridge can reach an authenticated `claude`, the same non-empty `session/new.mcpServers` shape, and explicit `session/request_permission` instrumentation. If an authenticated rerun still ignores `mcpServers`, cannot invoke the forwarded tools, or bypasses the ACP permission gate without an MCP-layer permission hook or sensitive-tool exclusion, Route A remains blocked and the missing capability must be sponsored upstream in the bridge and/or ACP forwarding layer. A `claude -p` fallback is not an acceptable Route-A completion path.
**FN-6473 result (escalation rerun, still blocked):** The escalation re-verified the local prerequisites and an actual bridge turn: `claude` **2.1.177** resolved at `/Users/eclipxe/.local/bin/claude`; the plugin-local pinned bridge shim resolved at `plugins/fusion-plugin-acp-runtime/node_modules/.bin/claude-code-cli-acp` and reported **0.1.1**; the lockfile still records integrity `sha512-qpfRGOXkOs9mqI7oumsGistWisyXcCC0r7ng7wdLvGMIORdzHjmUUa+94Jftgr/NYAVnAUe6N7kimD8PaO3D5g==`. The instrumented harness opened ACP directly with one non-empty stdio MCP server named `custom-tools`, `command: "node"`, `args: [packages/pi-claude-cli/src/mcp-schema-server.cjs, <temp schema file>]`, `env: []`, containing **62** Fusion custom-tool names confirmed from `packages/cli/src/extension.ts` and matching `mcp-config.ts`'s `writeMcpConfig` shape. `initialize` returned `agentInfo.name="claude-code-cli-acp"`, `version="0.1.1"`, and `authMethods=["claude-code-login"]`; `session/new` accepted the non-empty `mcpServers` payload and returned a session. The prompt explicitly instructed Claude to invoke `fn_task_list`, but the turn ended with assistant text **`Not logged in · Please run /login`**, stopReason `end_turn`, **zero** tool-call updates, and **zero** ACP `session/request_permission` callbacks.
**Recorded OQ1 state after FN-6473:**
1. **Can Claude invoke a real forwarded Fusion tool through the bridge?** **UNPROVEN / BLOCKED.** The bridge still accepts the non-empty `mcpServers` declaration, but the underlying `claude` session remains unauthenticated from the bridge's perspective and no forwarded MCP tool was invoked.
2. **Do forwarded tool calls traverse ACP `session/request_permission`?** **UNPROVEN / BLOCKED (neither GATED nor BYPASSED observed).** The explicit request-permission instrumentation recorded zero callbacks because no forwarded tool call occurred.
**Escalation path:** rerun U9 with an environment where the pinned bridge can reach an authenticated `claude`, the same non-empty `session/new.mcpServers` shape, and explicit `session/request_permission` instrumentation. Sponsor the missing bridge/ACP MCP permission-forwarding capability upstream: the bridge/ACP layer must forward `session/new.mcpServers` to the underlying Claude session and surface forwarded tool calls through ACP `session/request_permission` or an MCP-layer permission hook. If an authenticated rerun still ignores `mcpServers`, cannot invoke the forwarded tools, or bypasses the ACP permission gate without an MCP-layer permission hook or sensitive-tool exclusion, Route A remains blocked. A `claude -p` fallback is not an acceptable Route-A completion path.
**U14 internal mechanisms:** GO for design, subject to U9. Route A should use a second `acp-claude` runtime posture rather than mutating the generic `acp` runtime; inject the ACP bridge client from the engine `registerExtensionProviders` seam into the vendored `@fusion/pi-claude-cli` provider options; and add `AgentRuntimeOptions.mcpServers` to both the engine runtime contract and the ACP plugin-local structural copy, with `newAcpSession` defaulting to `[]` for Route-B compatibility.

View File

@@ -139,6 +139,7 @@ sequenceDiagram
- **FN-6465 recovery outcome (2026-06-14): UNRESOLVED / BLOCKED; combined Route A verdict: NOT GO.** Recovery status: **NOT-RECOVERED** — `fn_task_show FN-6459` retained only archived task metadata plus an archive log entry, this worktree has no `.fusion/tasks/FN-6459/`, and `fn_task_document_read(key="research")` returned not found in FN-6465's context. No authoritative U9 verdict survived to transcribe. The U9 spike was **not re-run to a verdict** in this recovery task: local binaries are present (`claude` 2.1.177 and pinned `claude-code-cli-acp` 0.1.1), but no authenticated, instrumented run against the real Fusion MCP config and ACP `session/request_permission` telemetry was completed. Therefore both security-critical U9 answers remain unknown: (1) forwarded real Fusion MCP tool invocation through the bridge is **unproven**; (2) permission-gate traversal versus bridge-local autonomous invocation is **unproven**. FN-6460 must not start U10-U13 until a follow-up spike records both answers here and in `docs/acp-contract.md`; the no-go path is upstream bridge/ACP MCP passthrough or permission-hook work, not a `claude -p` fallback.
- **FN-6466 authenticated-bridge spike outcome (2026-06-14): still UNRESOLVED / BLOCKED; combined Route A verdict remains NOT GO.** The spike bypassed the ACP runtime's current `mcpServers: []` helper by opening `session/new` directly against pinned `claude-code-cli-acp` **0.1.1** with a **non-empty** ACP payload built from the real Fusion Route-A config shape: one stdio MCP server named `custom-tools`, `command: "node"`, `args: [packages/pi-claude-cli/src/mcp-schema-server.cjs, <temp schema file>]`, `env: []`, and a schema file containing **62** captured Fusion custom tools from `packages/cli/src/extension.ts`. The bridge accepted `initialize` and `session/new` with that payload, but the first prompt turn ended before any MCP tool invocation with assistant text **`Not logged in · Please run /login`**. Therefore answer **(1)** remains **unproven** — no forwarded Fusion tool was actually invoked through the bridge — and answer **(2)** remains **unproven** because no `session/request_permission` call or tool-call update occurred. The required escalation is unchanged: rerun U9 in an environment where the underlying `claude` is authenticated for the bridge, and if a later authenticated run still ignores `mcpServers` or bypasses the permission gate, sponsor the missing bridge/ACP capability upstream instead of falling back to `claude -p`.
- **FN-6467 rerun outcome (2026-06-14): UNRESOLVED / BLOCKED; combined Route A verdict remains NOT GO.** This rerun verified the same local bridge prerequisites (`claude` **2.1.177** on PATH, pinned `claude-code-cli-acp` **0.1.1** binary present under `plugins/fusion-plugin-acp-runtime/node_modules/.bin`, lockfile integrity `sha512-qpfRGOXkOs9mqI7oumsGistWisyXcCC0r7ng7wdLvGMIORdzHjmUUa+94Jftgr/NYAVnAUe6N7kimD8PaO3D5g==`) and opened the pinned bridge directly with one non-empty ACP stdio MCP server named `custom-tools`, `command: "node"`, `args: [packages/pi-claude-cli/src/mcp-schema-server.cjs, <temp schema file>]`, `env: []`, containing **62** Fusion custom-tool names confirmed from `packages/cli/src/extension.ts` and matching the FN-6466 payload shape. `initialize` returned `agentInfo.name="claude-code-cli-acp"`, `version="0.1.1"`, and `authMethods=["claude-code-login"]`; `session/new` accepted the non-empty `mcpServers` entry and returned a session. The prompt explicitly asked Claude to call `fn_task_list`, but the only assistant content was **`Not logged in · Please run /login`** with stopReason `end_turn`, **zero** tool-call updates, and **zero** ACP `session/request_permission` callbacks. Therefore answer **(1)** remains **UNPROVEN / BLOCKED** (no forwarded Fusion tool was invoked) and answer **(2)** remains **UNPROVEN / BLOCKED** (gate traversal cannot be classified as GATED or BYPASSED). The escalation path remains an authenticated rerun or upstream bridge/ACP MCP permission work; a `claude -p` fallback is explicitly not acceptable.
- **FN-6473 escalation outcome (2026-06-15): UNRESOLVED / BLOCKED; combined Route A verdict remains NOT GO.** This explicit escalation again verified real bridge prerequisites (`claude` **2.1.177** at `/Users/eclipxe/.local/bin/claude`, plugin-local pinned `claude-code-cli-acp` **0.1.1**, unchanged lockfile integrity `sha512-qpfRGOXkOs9mqI7oumsGistWisyXcCC0r7ng7wdLvGMIORdzHjmUUa+94Jftgr/NYAVnAUe6N7kimD8PaO3D5g==`) and drove the pinned bridge with explicit `session/request_permission` instrumentation. The non-empty ACP payload was the Route-A `custom-tools` stdio server (`command: "node"`, `args: [packages/pi-claude-cli/src/mcp-schema-server.cjs, <temp schema file>]`, `env: []`) carrying **62** Fusion custom-tool names confirmed from `packages/cli/src/extension.ts` and matching `mcp-config.ts`'s `writeMcpConfig` shape. `initialize` returned `agentInfo.name="claude-code-cli-acp"`, `version="0.1.1"`, and `authMethods=["claude-code-login"]`; `session/new` accepted the non-empty `mcpServers` entry. The prompt instructed Claude to call `fn_task_list`, but the turn ended with **`Not logged in · Please run /login`**, stopReason `end_turn`, **zero** tool-call updates, and **zero** ACP `session/request_permission` callbacks. Therefore answer **(1)** remains **UNPROVEN / BLOCKED** and answer **(2)** remains **UNPROVEN / BLOCKED** (neither GATED nor BYPASSED observed). Sponsor bridge/ACP MCP permission-forwarding and rerun in a genuinely authenticated bridge environment; never resolve this by falling back to `claude -p`.
- **OQ2 (blocking sub-gate of U11) — Resume loss is amnesia, not a slowdown.** On resume the provider sends **only the latest user turn** (`buildResumePrompt`, `packages/pi-claude-cli/src/provider.ts:114-125`) and relies on `--resume` to load prior conversation from disk. The ACP path opens a **fresh session per turn** with no `sessionId` passthrough (`loadAcpSession` deferred). Dropping resume **without** switching to full-history prompts makes Claude answer multi-turn chat/executor conversations with zero prior context — silently. **Decision required in U11:** either thread `sessionId` → `loadAcpSession`, or send full flattened history (`buildPrompt`) every turn. No path may send latest-turn-only without resume.
- **OQ3 (blocking sub-gate of U11) — Tool-call & partial-message fidelity through the round-trip.** The provider consumes native `stream-json` with `--include-partial-messages` (exact tool-call argument boundaries); the ACP path re-derives chunks from transcript-JSONL → ACP `session/update` → the event bridge, which sanitizes/space-repairs/bounds the stream. Confirm tool-call arguments survive with intact start/end correlation and no space-repair corruption of JSON args, and that executor/reviewer lanes tolerate the transformed deltas. Capture exact tool-call argument bytes in U11's characterization tests, not just token ordering.
@@ -310,6 +311,8 @@ plugins/fusion-plugin-acp-runtime/src/
**FN-6467 status (2026-06-14):** **UNRESOLVED / BLOCKED after a second direct bridge attempt.** This rerun again bypassed the runtime helper and sent `session/new` with the non-empty `custom-tools` stdio MCP server (`command: "node"`, `args: [packages/pi-claude-cli/src/mcp-schema-server.cjs, <temp schema file>]`, `env: []`) carrying **62** Fusion custom-tool names. The pinned bridge **0.1.1** accepted `initialize` and `session/new`; however, `initialize` advertised `authMethods=["claude-code-login"]`, and the first prompt to invoke `fn_task_list` ended with **`Not logged in · Please run /login`**. No forwarded tool invocation and no `session/request_permission` callback were observed, so U9 remains **NOT GO** and FN-6460 must still not start U10-U13 until an authenticated run proves both forwarded-tool invocation and gate traversal (or records a definitive no-go/escalation).
**FN-6473 status (2026-06-15):** **UNRESOLVED / BLOCKED after the explicit escalation rerun.** The harness again used the plugin-local pinned bridge **0.1.1** and the real non-empty Route-A `custom-tools` stdio MCP payload carrying **62** Fusion custom-tool names, with explicit client-side `session/request_permission` instrumentation. Local prerequisites were present (`claude` **2.1.177**, bridge binary resolved, lockfile integrity unchanged), and `session/new` accepted the non-empty `mcpServers` payload. The first prompt to invoke `fn_task_list` still returned **`Not logged in · Please run /login`** with stopReason `end_turn`, zero tool-call updates, and zero permission callbacks. U9 therefore remains **NOT GO**: forwarded-tool invocation is still unproven, gate traversal is neither GATED nor BYPASSED, and the next step is sponsored bridge/ACP MCP permission-forwarding plus an authenticated-environment rerun — not a `claude -p` fallback.
### U14. Design-confirmation: resolve Route A's internal blockers (Route A gate 2 of 2)
**Goal:** Resolve the internal blockers that no spike screens — knowable today — before committing U10–U13. **KTD9, KTD10, KTD11.**