cli_subprocess_core normalizes provider, runtime, transport, and protocol
failures into a shared recovery envelope before those failures move upward into
ASM or higher runtimes.
This guide describes the contract owned here.
Why It Exists
Provider CLIs are inconsistent about failure labels:
- capacity errors may arrive as runtime failures
- auth/config/runtime claims are often flaky or mislabeled
- transport failures can masquerade as provider exits
cli_subprocess_core does not decide packet/job policy, but it does decide the
normalized facts that upper layers need in order to make good policy
decisions.
Envelope Shape
The recovery envelope is attached under metadata["recovery"] on structured
payload errors and under runtime_failure.recovery on runtime-failure
metadata.
Current keys:
originclassretryable?repairable?resumeable?local_deterministic?remote_claim?severityphaseprovider_codesuggested_delay_mssuggested_max_attempts
Current Class Vocabulary
cli_missingcwd_missingtransport_invalid_optionstransport_unsupportedbuffer_overflowtransport_disconnecttransport_timeoutprotocol_errorprovider_auth_claimprovider_config_claimprovider_rate_limitprovider_runtime_claimapproval_deniedguardrail_blockeduser_cancelled
cli_subprocess_core may expand this set over time, but it should not emit
ambiguous, provider-specific class names when a shared class already exists.
Ownership Boundary
cli_subprocess_core owns:
- provider-profile parsing and normalization
- transport/protocol failure normalization
- honest lower-layer recoverability facts
cli_subprocess_core does not own:
- packet/job retry budgets
- repair prompting
- verifier-driven completion
- workflow-level terminal/fail-open policy
Those belong in higher runtimes such as agent_session_manager and
prompt_runner_sdk.
Design Intent
The key design rule is:
- normalize facts here
- decide policy above
That keeps provider and transport semantics close to the runtime that actually observed them, while letting upper layers remain provider-agnostic.