# `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(),
  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.
  * `:action` - what the caller must be allowed to do.
  * `:effect` - `"read"`, `"change"` or `"destructive"`.
  * `:subject` - what it acts on: `"agent"`, `"agents"`, `"deployment"`, `"owner"` (an org's or
    person's accounts and servers), `"hook"` (a request that proves itself with a secret, not a
    caller) or `"channel"` (a chat app's request, which its channel verifies).
  * `:parameters` - which input fields go in the HTTP path or query.
  * `:input` - one schema for its parameters and body together.
  * `:status` - the HTTP status it returns on success.
  * `:output` - its output schema, or `nil`.
  * `: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 `FunctionClauseError` 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 every `$ref` to another schema file 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` with every `$ref` inlined.

`name` is a file name in `dir/0` without `.json`, like `run.started`, `cloudevent` or `defs`.

# `types`

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

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

---

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