> Canonical guide: https://developers.foxlight.ai/build/guides/choose-a-contract/
> Contract snapshots: Skulk 2.0.0 (b0af39c79b6b7102b2478062904f1d7cc8619975); SDK 0.4.0 (31bb090b8f64689f87514e48385e22b6ad94a6c2). Check the installed runtime when versions differ.

# Choose a capability contract

Start with the shape of the work. A descriptor’s `io_mode` is part of the negotiated contract, not a flag the caller can change later.

| Work                                   | Contract                                 | Example                                     |
| -------------------------------------- | ---------------------------------------- | ------------------------------------------- |
| Small request with an immediate answer | Unary                                    | Validate text or read application readiness |
| One request, incremental output        | Server streaming                         | Emit generated text or audio chunks         |
| Incremental input, one final result    | Client streaming                         | Process a bounded recording                 |
| Incremental input and output together  | Bidirectional                            | Transform live media                        |
| Work outlives the invocation budget    | Durable operation carried by unary calls | Render a video and observe it later         |

Unary calls have a maximum local budget of 30 seconds; managed streams have a ceiling of 300 seconds. Neither becomes a durable job merely because it emits progress. Use [operations](https://developers.foxlight.ai/build/guides/durable-jobs/) for work that must remain observable after the initiating call ends.

## Describe inputs precisely

Define an object schema with required fields, value limits and an explicit additional-properties policy. Use a semantic version for the operation. Discovery gives callers a descriptor revision; they submit that exact revision with the version, so changed schemas cannot silently reinterpret an old request.

The managed host validates the negotiated contract and admission. Validate inputs again in application code where direct tests or internal calls can bypass that boundary. Return typed failures rather than a successful response containing an error string.

## Separate two authoring paths

The capability SDK serves operations from an isolated child process. `skulk.extensions` is the in-process extension and Fabric caller interface. They share discoverable capability concepts but have different startup and lifecycle contracts. Choose the managed SDK for a separately packaged application; use the [extension example](https://developers.foxlight.ai/build/first-capability/) when your provider deliberately runs inside Skulk.

A managed child’s local socket is not a network endpoint for clients. Fabric clients call through Skulk. The [caller guide](https://developers.foxlight.ai/build/calling-and-streaming/) explains negotiation; [managed streaming](https://developers.foxlight.ai/build/sdk/streams/) explains implementation in the child.
