Files
deepseek-harness/docs/rfc/proposed/simplification/2026-07-04-trim-acp-bridge-unreachable-surface.md
T
Tianyi Cui 9ebc38badf docs(rfc): revise the batch for the hooks-stack base; add three post-stack RFCs
The branch now bases on the hooks stack (PR #138's head), so every
'in-flight' reference to stack content became a current-state fact.
Audited all nine RFCs + three supplements claim-by-claim against the
merged tree (none invalidated; several strengthened):

- prune-dead-core-spine-surface: describe the landed tools/pre-execute →
  dispatch → tools/post-execute pipeline — listeners return Decisions,
  the registry builds every result and snapshots it to protect callId,
  and a second (mutation-guard) test pins the field; drop the resolved
  wait-for-interception hedge; scope the additionalContext ferry out.
- prune-producerless-vocabulary-variants: the ui-stdio fixture migrated
  off the continuation trigger (llm-replay is the sole writer now); the
  stack's own additions (rejected, prompt/blocked, hook/invoked+result)
  all arrived with producers — the admission policy demonstrated live.
- prune-unimplemented-subagent-vocabulary: enrichment landed as
  lastAssistantMessage only (agentType was dropped in the stack's own
  review — the same judgment this RFC extends); the seam RFC now names
  tools/pre-execute deny, which exists, sharpening the re-add path.
- drop-inert-request-knobs / drop-image-content-block /
  trim-acp-bridge-unreachable-surface: current-state rewordings (shipped
  bridges set no request fields; only compact-basic has explicit image
  arms; 13 hook goldens also pin agentInfo).
- generic-long-running-tool-runtime census: second production seam
  consumer (hook-protocol runHook: resolve+run, stdin/env, foreground
  only — background machinery stays single-consumer); scrub-duplication
  blast radius.
- discover-package-inventory: identical 54-entry tsconfig reference
  sets; the comparesLog scenario knob (fixture-derivable, like recorded).
- unify-agent-and-session-id: third divergence site (in-process subagent
  children mint two UUIDs), the hooks bridge id-lookups, and ui-stdio's
  labelBySession map as a consumer that deletes under unification.

New RFCs from the post-stack survey:
- remove-agent-steering-mirror: the last mirror-of-durable event; zero
  production listeners; both retention RFCs deferred its fate, and the
  'no durable twin' rationale is contradicted by the adjacent append.
- tighten-hook-protocol-contract: producer-less 'native' dialect,
  parsed-and-discarded suppressOutput, and hook/result semantics
  (truncation + decision-string) defined twice in the bridges instead
  of the lib that owns the event.
- single-source-acp-replay-config: cordis.yml/cordis.snapshot.yml differ
  by exactly one plugin entry, with no gate on the forced symmetry.
2026-07-04 11:24:44 +08:00

28 lines
3.4 KiB
Markdown

# RFC: Trim unreachable ACP bridge surface — the branding knobs and the kind-sniffing fallback
Status: proposed
## Problem
Two pieces of `dsh-acp` surface are unreachable from any shipped configuration:
1. **`AcpConfig.agentName` / `agentVersion`** (`packages/ui/acp/src/index.ts`). The shipped app package hands the bridge only `{ model, systemPrompt }` (`packages/ui/acp-agent/src/index.ts`), so no leaf `cordis.yml` — the only production config surface — can set the knobs at all; they are settable solely by direct-mounting the bridge, which only a unit test does. Every snapshot golden — the hook-matrix scenarios included — pins the schema defaults (`deepseek-harness-acp` / `0.0.1`). The pair also carries a live `TODO(double-default)`: the literals exist twice (schema `.default(...)` plus `??` fallbacks), with the TODO asking to pick one home.
2. **The `toolKindFor` name heuristic** (same file) special-cases `bash*`/`read*`/`write`/`edit*` tool names in the generic-fallback path. Since the [render-intent union](../../implemented/architecture/2026-07-02-tool-render-intent-union.md), every first-party tool those arms match ships its own `presentCall` carrying its kind, and the presenter-less production tools (`subagent`, `subagent_fork`) fall through to `other` anyway. The arms are production-reachable only when a tool's `presentCall` THROWS (the containment fallback) — and the bridge's own module doc states the design rule the heuristic violates: "the bridge never special-cases tool names".
## Proposal
Hardcode `agentInfo` at the `initialize` site (`{ name: 'deepseek-harness-acp', version: '0.0.1' }`), deleting the two config fields, their schema defaults, the `??` fallbacks, and the `TODO(double-default)` whose subject vanishes; drop the knob half of the direct-mount config test, the two rows in `packages/ui/acp/README.md`, and the `packages/ui/acp/acp-feature-support.md` cell that cites the knobs. Zero golden churn — the emitted wire value is unchanged. Replace `toolKindFor` with the constant `'other'` in both fallback sites (the presenter fallback and `nullToolPresenter`) and delete the heuristic with its test rows.
## Why not keep them?
`agentInfo` is client-visible branding a deployment will eventually want configurable — but a knob no shipped config can reach is not configurability, it is drift surface (the double-default TODO is its symptom), and the honest re-add must include the `dsh-acp-agent` plumb-through that does not exist today either; both arrive together with the deployment that needs them. For the heuristic: a hypothetical third-party presenter-less tool named `read_docs` would lose its inferred `read` icon — but inferring kinds from unknown plugins' names is exactly the special-casing the render-intent design rejected. The behavior delta on shipped paths is confined to the presenter-throw fallback, where rendering kind `other` makes the client show the raw input instead of a masquerading first-party card — strictly better diagnostics for a broken presenter.
## Acceptance criteria
- `agentName`/`agentVersion` and `toolKindFor` appear only in this RFC; snapshot goldens are byte-identical; bridge tests are green with the constant fallback.
- The `initialize` handshake continues to report `deepseek-harness-acp`/`0.0.1` (pinned by the handshake snapshot).
## Risks
None beyond the presenter-throw rendering delta described above — an error path whose new behavior is more diagnosable than the old.