fix(voice-call): survive gateway in-process restart and stop CLI dead-ends (#125458)

* fix(voice-call): survive gateway in-process restart and stop CLI dead-ends

The gateway's in-process restart (SIGUSR1 config reload) reuses the cached
plugin registry, so service stop/start run on the same retained voice-call
registration. Generation fencing from #120289 treated that restart as a stale
actor: stop retired the generation forever, the next start silently bailed,
and every voicecall.* RPC answered UNAVAILABLE "runtime generation is
retired" while the webhook never rebound.

- Registrations now hold a replaceable generation: service start after stop
  mints a fresh generation, takes over a running slot owned by a retired
  predecessor, and reports start failures to service health instead of
  silently returning.
- The voicecall CLI classifies gateway failures with typed guards instead of
  message substrings: standalone/store fallback only when the gateway is
  genuinely absent; reachable-but-failed (request errors, auth, timeout)
  exits with actionable text; a standalone webhook port collision explains
  that a running Gateway probably owns the port instead of raw EADDRINUSE.
- Plugin SDK gateway-runtime exports structural isGatewayTransportError /
  isGatewayClientRequestError guards (+2 documented surface budget).
- Regression coverage: same-registration stop/start restart, retired-owner
  takeover, typed CLI fallback classification, and a real token-auth gateway
  server routing voicecall.status through callGatewayFromCli.

* refactor(voice-call): split CLI modules and dedupe gateway fallbacks

Collapse the four duplicated gateway-or-runtime command blocks (speak, dtmf,
end, continue fallback) into one generic runGatewayManagerCommand helper —
the continue command owns its legacy-method fallback and operation polling
via a gatewayCall closure, so the helper carries no per-command policy.
Smoke reuses the shared initiateVoiceCall path instead of a bespoke
fallback.

Split the 988-line cli.ts into concept modules (cli-gateway-call,
cli-call-log, cli-command-io) and drop its grandfathered max-lines
suppression plus the now-stale max-lines and assertion-safety baseline
entries (shrink-only ratchet maintenance).

Behavior-frozen: stdout/exit semantics unchanged; net -2 production LOC.

* fix(voice-call): redact gateway URLs in CLI operational errors

ClawSweeper P1: the operational-error formatter interpolated the raw
connectionDetails.url, so a configured gateway URL with userinfo or query
tokens would print credentials into terminal output. Redact the composed
message once with the canonical net-policy redactor (also covers
remote-controlled close-reason text), exported through the plugin SDK
gateway-runtime subpath (+1 documented surface budget). Regression test
covers a credential-bearing URL in both the URL and message fields.
This commit is contained in:
Peter Steinberger
2026-08-17 18:59:19 -07:00
committed by GitHub
parent b82d07f466
commit 75fcaba919
15 changed files with 1030 additions and 716 deletions
+6 -2
View File
@@ -295,7 +295,9 @@ export function readPluginSdkSurfaceBudgets(env: NodeJS.ProcessEnv = process.env
// -2: remove obsolete transcript display helper exports.
// +2: lightweight agent config resolution and nonthrowing default-agent lookup.
// +1: focused media-store URL/path ingestion (saveMediaSource) off the deprecated barrel.
4328,
// +2: structural Gateway transport and request-error guards for plugin CLI routing.
// +1: canonical sensitive-URL redactor so plugin CLI errors never print URL userinfo.
4331,
env,
),
publicFunctionExports: readPluginSdkSurfaceBudgetEnv(
@@ -376,7 +378,9 @@ export function readPluginSdkSurfaceBudgets(env: NodeJS.ProcessEnv = process.env
// -1: remove the obsolete transcript tool-call predicate.
// +2: lightweight agent config resolution and nonthrowing default-agent lookup.
// +1: focused media-store URL/path ingestion (saveMediaSource) off the deprecated barrel.
2572,
// +2: structural Gateway transport and request-error guards for plugin CLI routing.
// +1: canonical sensitive-URL redactor so plugin CLI errors never print URL userinfo.
2575,
env,
),
publicDeprecatedExports: readPluginSdkSurfaceBudgetEnv(