ARCPRuntime.runDispatchLoop treats any exception thrown while handling an envelope as a session-ending transport failure. The loop at lib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:153 collects envelopes and calls handleEnvelope, while the catch block at lib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:160 logs "session ended" and exits. Several normal client input errors can throw from handlers, including malformed cost.budget values through parseCostBudget at lib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:495, malformed expires_at through parseExpiresAt at lib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:508, and non-numeric cost metrics through asBigDecimal at lib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:534. Those cases should produce a correlated Nack, not kill the session.
Fix prompt: Isolate message handling failures per envelope. Wrap handleEnvelope(env, transport) in a handler that catches ARCPException and returns nack(env, error), catches IllegalArgumentException and NumberFormatException as ARCPException.InvalidArgument, rethrows CancellationException, and keeps collecting subsequent envelopes after sending the error reply. Add integration tests that submit invalid lease_request.cost.budget, invalid lease_constraints.expires_at, and invalid cost metric values and assert that the runtime replies with a correlated Nack while the session remains usable.
ARCPRuntime.runDispatchLooptreats any exception thrown while handling an envelope as a session-ending transport failure. The loop atlib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:153collects envelopes and callshandleEnvelope, while the catch block atlib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:160logs "session ended" and exits. Several normal client input errors can throw from handlers, including malformedcost.budgetvalues throughparseCostBudgetatlib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:495, malformedexpires_atthroughparseExpiresAtatlib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:508, and non-numeric cost metrics throughasBigDecimalatlib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:534. Those cases should produce a correlatedNack, not kill the session.Fix prompt: Isolate message handling failures per envelope. Wrap
handleEnvelope(env, transport)in a handler that catchesARCPExceptionand returnsnack(env, error), catchesIllegalArgumentExceptionandNumberFormatExceptionasARCPException.InvalidArgument, rethrowsCancellationException, and keeps collecting subsequent envelopes after sending the error reply. Add integration tests that submit invalidlease_request.cost.budget, invalidlease_constraints.expires_at, and invalid cost metric values and assert that the runtime replies with a correlatedNackwhile the session remains usable.