# Client core ownership and runtime contract `GridClient` construction is deliberately inert. `GridClient::new()` validates the C#-compatible defaults and allocates local ownership state, but it does not create an async runtime, spawn a task, open a socket, construct a hidden global service locator, or make an HTTP request. Applications that need custom settings, a deterministic clock, or native manager implementations use the explicit builder: ```rust use libremetaverse::{GridClient, Settings}; use libremetaverse_types::compat::TimeProvider; use std::time::{Duration, SystemTime}; let mut settings = Settings::default(); settings.timing().login_timeout = 30_000; let fixed = SystemTime::UNIX_EPOCH + Duration::from_secs(1_000); let client = GridClient::builder() .with_settings(settings) .with_time_provider(TimeProvider::from_fn(move || fixed)) .build()?; # Ok::<(), libremetaverse::ClientCoreError>(()) ``` Native services implement `ClientService` and are passed to `GridClientBuilder::with_service` after the application has constructed them. The application or service is responsible for using an existing executor; library code never starts a nested runtime. Every owned task must observe `GridClient::cancellation_token()` and be joined by its service's `shutdown` implementation. Shutdown is idempotent. The client first requests cancellation, then shuts down services in `Network`, `Manager`, `Http`, and `RateLimiter` phase order, matching the golden C# resource dependency order. Dropping a client performs the same shutdown path. Services must release their tasks and resources before returning. User callbacks must never run while a service holds an internal lock. `Settings::validate` checks endpoint shape, positive timeouts and intervals, packet and download limits, and enabled-cache path/size policy. Builder errors identify the public field without copying its value. `Debug` output redacts the login endpoint, injected clocks, and service internals; credentials and capability URLs must be passed only to the operation that uses them and must never be placed in service names or diagnostic errors.