design fast session pipeline - sinrimin/harness-nexus GitHub Wiki

Fast session pipeline — pinned adapter provisioning, dist patches, live-channel listings (Issue #2)

Issue-driven era. Anchor: issue #2 (investigation + measurements in its comments: root-cause chain, wrapper set-model decomposition, reference-implementation comparison). Daily-work orientation lives in the repo's AGENTS.md feature index.

Context

After Phase 9 W16, every ACP-related interaction was slow because of costs that are paid per spawn, not per feature:

  • Every spawn paid npx -y re-resolution — ~1–2.5s per listing and per channel open; ~13s during the 2026-09-18 npx-cache incident.
  • Every claude resume paid a redundant set_model re-assert — the wrapper re-asserts the pinned model on every resume via a set_model IPC that the CLI does not service until its resume bootstrap completes (upstream issues #886/#880), ~2.2s of pure queueing per session/load.
  • Every sessions-rail refresh spawned a short-lived adapter even while a live channel's adapter for the same target was already running.

Design

Pinned adapter provisioning (cli/src/daemon/acp/adapter-provision.ts)

  • The daemon provisions pinned adapters once into ~/.hnx/acp-adapters, fire-and-forget at boot: npm i --prefix into a staging dir + atomic rename. Complete stores only re-check patches. ANY failure degrades to the npx fallback. Kill switch: HN_ACP_NO_AUTO_PROVISION=1.
  • Specs are version-pinned in acp/adapters.ts (pkg: [spec, bin]) for BOTH the pinned install and the npx -y fallback — upgrading an adapter = bump the constant + re-check patch anchors. Resolution order: HN_ACP_COMMAND_* env override → pinned bin → npx.

Idempotent dist patch set

  • Anchored string replaces (ADAPTER_PATCHES), marker-detected; anchor-missing ⇒ skip with a warning (correct-but-slow, never broken).
  • Patch #1: skip-redundant-setmodel-on-resume on the claude wrapper — skips the re-assert when the resumed model already matches the resolved pin. Rig: claude session/load 3.37s → 0.98s.

Live-channel listings (liveConnectionFor)

  • attachChatHandlers exposes liveConnectionFor(target) — the newest live channel's adapter connection for a target. The sessions:list handler rides it: session/list is a plain concurrent JSON-RPC request, the same trick the reference portal uses on its resident adapter. Any failure (dead connection, mid-turn stall, no such method) falls back to the short-lived spawn.
  • Applies to the adapter-backed targets (claude-code | codex | opencode).

Rig numbers

path before after
claude listing (cold) 2.7s 0.13s
claude listing (live channel) 2.7s 0.09s
claude resume-open 6.1s ~1.2s

Known follow-ups (not built)

  • Event-driven listing-cache invalidation (the listing cache is TTL-only).
  • dsh listing bounded reads (today whole-file reads).
  • W3's settings model key is what triggers the wrapper's re-assert path — keep it (default-model feature); the patch, not config, is the fix.