Metadata-Version: 2.5
Name: arkitekt-spec
Version: 3.0.0
Summary: the wire format of an Arkitekt app: manifest, requirements, inspection, hardware selectors and deployments.yaml
Author-email: jhnnsrs <jhnnsrs@gmail.com>
License-Expression: MIT
Requires-Python: >=3.11
Requires-Dist: docstring-parser>=0.11
Requires-Dist: fieldz>=0.0.2
Requires-Dist: inflection>=0.5.1
Requires-Dist: pydantic>=2.11
Requires-Dist: pyyaml>=6
Description-Content-Type: text/markdown

# arkitekt-spec

The wire format of an Arkitekt app: one definition of *what an app is*, shared by everything
that produces or consumes it.

| Model | What it is | Produced by | Consumed by |
| --- | --- | --- | --- |
| `AppManifest`, `Requirement` | who the app is, which services it needs | arkitekt (from the `App`) | kabinet |
| `Inspection` | what the app declares (rekuest's action language, carried as JSON) | `arkitekt inspect all`, inside the image | arkitekt's plugin CLI, kabinet |
| `Selector` (`cpu`, `ram`, `cuda`, `rocm`, `oneapi`, `label`) | where a flavour may run | a flavour's `config.yaml` | kabinet, deployers |
| `DeploymentsFile` | `.arkitekt/deployments.yaml`, the images a repo publishes | `arkitekt plugin publish` | kabinet's repo scan |

It also owns the **action language** (`arkitekt_spec.actions`: definitions, ports,
implementations) and the **declaration layer** (`arkitekt_spec.declare`): `AppRegistry`, the
`@app.action` / `@app.workflow` / `@app.declare` machinery, structures, and the `Task` protocol a
runtime implements. SDKs build on it; apps import the same names from
[arkitekt](https://github.com/arkitektio/arkitekt). It depends on pydantic, pyyaml and three small
pure-python helpers, and on no runtime, transport or client.

## Workflows and recovery

An implementation carries two claims the server keeps:

| Field | Values | Meaning |
| --- | --- | --- |
| `execution` | `PLAIN`, `WORKFLOW` | Only a `WORKFLOW` may call other actions; it is resumed when its agent dies, a `PLAIN` task ends LOST. |
| `effects` | `NONE`, `REPEATABLE`, `UNKNOWN`, `IRREVERSIBLE` | What running it again would do. Information for whoever decides about a lost task, never a rule. |

`code_hash` pins a resume to the code that started the run. The errors a caller sees
(`AgentLost`, `NonDeterministicWorkflow`, `NotAWorkflowError`, `StateChanged`) live in
`arkitekt_spec.declare.errors`, and the workflow helpers (`record`, `retry`, `hold`, `guard`) are
on the `Task` protocol.

## Compatibility

Every envelope model **ignores** unknown keys. An inspection is written by the arkitekt inside
an image and read by the host CLI, and `deployments.yaml` is written by the CLI and read by a
kabinet server that upgrades on its own schedule. Adding a field is therefore a minor change
an older reader survives. A change an older reader must refuse bumps `spec_version`.

Selectors are the exception: they refuse unknown keys, because they are written by hand and a
typo must not silently widen a placement constraint.

```python
from arkitekt_spec import load_deployments, dump_deployments

file = load_deployments(open(".arkitekt/deployments.yaml").read())
```

`python -m arkitekt_spec` prints the JSON Schema. The committed snapshot in
`tests/fixtures/deployments.schema.json` makes every format change show up in review.
