# `WardrikProtocol`

Wardrik's wire format: events as CloudEvents, and operations as OpenAPI.

    schema = JSV.build!(WardrikProtocol.schema("run.started"))
    {:ok, _data} = JSV.validate(event["data"], schema)

    %{method: "post", path: "/v1/agents/{agent}/messages"} = WardrikProtocol.operation("agent.ask")

# `operation`

```elixir
@type operation() :: %{
  id: String.t(),
  summary: String.t(),
  description: String.t() | nil,
  method: String.t(),
  path: String.t(),
  conversation: String.t() | nil,
  action: String.t(),
  effect: String.t(),
  subject: String.t(),
  parameters: [%{name: String.t(), in: String.t()}],
  input: map(),
  status: pos_integer(),
  output: map() | nil,
  stream: boolean()
}
```

An operation from `openapi.json`.

  * `:id` - its `operationId`, as `"agent.ask"`.
  * `:summary` and `:description` - what it does.
  * `:method` and `:path` - its HTTP route.
  * `:conversation` - its route for one of the agent's conversations, or `nil`.
  * `:action` - what the caller must be allowed to do.
  * `:effect` - `"read"`, `"change"` or `"destructive"`.
  * `:subject` - what it acts on: `"agent"`, `"agents"`, `"deployment"`, `"hook"` or
    `"channel"`.
  * `:parameters` - which input fields go in the HTTP path or query.
  * `:input` - one schema for its parameters and body together. A hook's or channel's body is
    the request as it came, so its input is its `x-wardrik-input`.
  * `:status` - the HTTP status it returns on success.
  * `:output` - its output schema, or `nil`. A channel's is its `x-wardrik-output`.
  * `:stream` - `true` if it can stream events.

# `dataschema`

```elixir
@spec dataschema(String.t()) :: String.t()
```

Returns the `dataschema` for an event type.

    WardrikProtocol.dataschema("wardrik.run.started")
    #=> "urn:wardrik:schema:v1:run.started"

Raises for an unknown type.

# `dir`

```elixir
@spec dir() :: Path.t()
```

Returns the directory of the schema files.

# `live?`

```elixir
@spec live?(String.t()) :: boolean()
```

Returns `true` if events of the type are sent as they happen and never stored.

# `openapi`

```elixir
@spec openapi() :: map()
```

Returns the OpenAPI document, with `$ref`s to other files inlined.

# `operation`

```elixir
@spec operation(String.t()) :: operation() | nil
```

Returns the operation with ID `id`, like `agent.ask`, or `nil`.

# `operations`

```elixir
@spec operations() :: [operation()]
```

Lists every operation, ordered by path.

# `schema`

```elixir
@spec schema(String.t()) :: map()
```

Returns the schema `name`, like `"run.started"` or `"cloudevent"`, with every `$ref` inlined.

# `types`

```elixir
@spec types() :: [String.t()]
```

Lists every event type, like `wardrik.run.started`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
