Files
fusion/plugins/fusion-plugin-acp-runtime
gsxdsm 590383bd3a fix(acp): address code-review findings (security, correctness, reliability)
Tier-2 code review fixes:
- P1 correctness: EventBridge per-turn state never reset — once the per-turn
  output cap tripped, all later turns were silently suppressed and tool/accum
  state bled across turns. Surface resetTurn() and call it per prompt turn.
- P1: plan_update read a non-existent .entries field (wrong SDK shape) and
  wiped the displayed plan — now a documented no-op (full 'plan' is source of
  truth).
- P1 security: write-path TOCTOU — open without O_TRUNC, re-validate realpath,
  then truncate, so an intermediate-symlink-swapped escaped target is never
  truncated before rejection.
- DoS: fs read stat-gates and bounded-reads oversized files instead of loading
  them fully before the ceiling.
- Security: stderr redaction now spans chunk boundaries; secret deny-list adds
  .git-credentials/*.p12/*.pfx/*.keystore/.pgpass/.htpasswd/etc.
- Reliability: cancelAcpSession bounded by a timeout so a blocked stdin can't
  delay the registry SIGKILL.
- Maintainability: drop dead ACP_NOT_IMPLEMENTED export; type agentCapabilities
  via the SDK AgentCapabilities; strengthen the S1 write-denial assertion.

+4 tests (181 total); typecheck + eslint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 09:44:36 -07:00
..

@fusion-plugin-examples/acp-runtime

A Fusion runtime plugin that drives any external Agent Client Protocol (ACP) agent over JSON-RPC/stdio. One integration unlocks every ACP-compatible agent (Gemini CLI, the Claude Code ACP adapter, and any future agent that speaks the protocol) through the standard protocol instead of a bespoke per-CLI integration.

Selected via runtimeId: "acp". Installed on demand (experimental) — see the Fusion plugin catalog (fn plugin install fusion-plugin-acp-runtime).

Security posture

The ACP agent is an untrusted subprocess that calls back into Fusion for permissions and filesystem access. This plugin enforces a defense-in-depth floor:

  • Per-category permission gating. Each session/request_permission is classified by tool kind into a Fusion action category and checked against the live permission policy — never a preset shortcut. allow_once only (never a persisted blanket grant). Unmappable kinds and missing policy default-deny.
  • Unrestricted-risk acknowledgement (acpAllowUnrestricted). Because the shipped default policy is unrestricted (allow-all), a blanket allow on a sensitive category is escalated to approval unless the user explicitly sets acpAllowUnrestricted: true. Prefer running the ACP runtime under an approval-required policy.
  • Filesystem jail. fs/read_text_file / fs/write_text_file are opt-in (acpFsRead / acpFsWrite, writes default OFF), confined to the session cwd by a real symlink-resolving jail (realpath + O_NOFOLLOW), with a deny-list for secrets (.env, *.pem, …) and git internals (.git/**). Writes are gated through the file_write_delete permission category.
  • Untrusted-input bounds. Streamed output is sanitized (ANSI/control strip) and bounded (per-turn + per-chunk caps; bounded tool-call correlation map).
  • Subprocess isolation. The agent env is built from an allow-list (acpEnvAllowList) — inherited process.env is not forwarded.

Not sandboxed in v1: the agent's own process/network syscalls run with Fusion's user privileges (OS-level sandboxing is recommended future work).

Settings

Key Default Meaning
acpBinaryPath acp-agent Agent binary to spawn
acpArgs [] Args that launch the agent in ACP/stdio mode (e.g. ["--acp"])
acpModel — Optional model identifier reported via describeModel
acpFsRead false Advertise/register fs/read_text_file
acpFsWrite false Advertise/register fs/write_text_file (gated)
acpEnvAllowList [] Env var names forwarded to the agent subprocess
acpAllowUnrestricted false Acknowledge the untrusted-agent risk under an allow-all policy

Upstream / third-party integration evidence

Per AGENTS.md (External-integration evidence):

See docs/acp-contract.md for the launch/readiness contract and failure taxonomy.