# For agents

> A machine-oriented implementation guide — canonical endpoints, the minimum viable document, a pre-flight checklist, and what an agent-authored workflow must satisfy to be trusted.

This page is written for autonomous agents and scripted implementers. It is deliberately terse and checklist-shaped. Every claim here is stated more fully elsewhere and linked.

## Machine-readable endpoints

| Resource | Path |
|---|---|
| Documentation index for LLMs | `/llms.txt` |
| Full documentation, single file | `/llms-full.txt` |
| Any page as raw markdown | `/raw/<slug>.md` |
| Core schema (project document, current) | `/schemas/core/v0.92.json` |
| Core schema (project document, prior) | `/schemas/core/v0.91.json`, `/schemas/core/v0.9.json` |
| Core schema (legacy step document) | `/schemas/core/v0.8.json` |
| Domain/vendor profile schemas | `/schemas/profiles/<name>/v0.9.json` (botverse, generative-ai, physical-production, vfx) |
| `broadcast-newsroom` (SOM) profile schema | `/schemas/profiles/broadcast-newsroom/v0.1.json` |
| JSON-LD context | `/context/v0.9.jsonld` |
| Conformance corpus index | `/corpus/index.json` |
| Any corpus document | `/corpus/<file>` |

The corpus is 22 complete, validated documents — the closest thing to reference data. Fetch `index.json` first: it carries `kind`, `project_id`, and task/asset/participant counts for each, so you can pick one at the complexity you need rather than downloading all of them.

No authentication. Everything is public and fetchable directly.

```bash
curl https://openworkflowgraph.org/llms-full.txt
curl https://openworkflowgraph.org/schemas/core/v0.92.json
```

## Minimum viable document

The smallest thing that validates as a project document:

```json
{ "owg_version": "0.92", "id": "minimal" }
```

The smallest thing that is *useful* — one task with real provenance edges:

```json
{
  "owg_version": "0.92",
  "id": "minimal-useful",
  "participants": [
    { "id": "svc", "kind": "service" }
  ],
  "assets": [
    { "id": "in",  "role": "source" },
    { "id": "out", "role": "delivery", "produced_by": "work",
      "predecessor": "in", "version_relation": "representation" }
  ],
  "tasks": [
    { "id": "work", "type": "work", "ai_role": "none",
      "executor": { "type": "service" },
      "performed_by": "svc",
      "used": ["in"], "produced": ["out"],
      "failure_mode": "HALT" }
  ]
}
```

## Authoring rules

Ordered by how often they are got wrong.

1. **Set `failure_mode` explicitly.** `HALT` is the default, but declaring it states intent — especially on a task where a reader would expect something gentler.
2. **Declare `ai_role` on every task.** `generative`, `assistive`, or `none`. Never leave it unset on a task that could involve AI — that is validator rule R1. AI-ness is *never* inferred from `executor.type`.
3. **Give every agent participant an `operated_by`.** Required by the generative-AI profile, and the basis of the whole accountability chain. Ensure the chain terminates at a human or organization — nothing checks this for you.
4. **Use `used[]` and `produced[]` as the source of truth.** An asset's `produced_by` is a derived convenience; keep them consistent.
5. **Choose `version_relation` deliberately.** A proxy is a `representation`, not a `revision`. An approved retake is a `revision`, not a new asset. This is the single highest-leverage correctness decision in a document.
6. **Populate both `id` and `identity` on assets.** `id` is document-local; `identity` is the global content-derived identity that lets the asset be recognised elsewhere.
7. **Never inline a secret.** Use `executor.credentials_key`.
8. **Preserve every inbound identifier** in `identifiers[]` with its `scope`. Never strip one you do not recognise.
9. **Write `when` expressions against the grammar.** It is fully specified — comparisons, `&&`/`||`/`!`, parentheses, and `exists()`. Strings are single-quoted. Gate on `exists()` whenever an upstream output is conditional. See [Reference syntax](/reference-syntax#when-expressions).
10. **Use `metadata`, an `x-` prefix, or (on `context`/`asset`/`relationships[]`) a namespaced `profiles.<id>` key for anything the schema does not define.** Unknown bare keys are validation errors, by design.

## Pre-flight checklist

v0.92 specifies all of the following as validator checks. **Do not assume the validator you
are using performs them all** — establish which [passes](/validation) it implements, and verify
the rest yourself. A clean result from a structural-only validator does not mean a runnable
document.

**Referential integrity:**

- [ ] Every `depends_on` entry names a task that exists.
- [ ] Every `used` and `produced` entry names an asset that exists.
- [ ] Every `performed_by` names a participant; every `ran_on` names an infrastructure entry.
- [ ] Every `predecessor` names an asset.
- [ ] Every `on_pass`, `on_fail`, `on_failure_compensate`, and `reroute_feedback.to_task` names a task.
- [ ] Every `organization_id`, `works_for`, and `operated_by` resolves.
- [ ] Every `composes[].component` resolves.
- [ ] Every `relationships[].from.id` and `.to.id` resolves to an entity of the stated `kind`.
- [ ] Each asset's `produced_by` agrees with that task's `produced[]`, and no asset has two producers.

**Graph shape:**

- [ ] The `depends_on` graph is acyclic.
- [ ] Ids are unique within each registry.
- [ ] Every `operated_by` chain terminates at a `human` or `organization`.
- [ ] Every gate that routes backwards has `max_reroutes`, or the document has `governance.max_total_reroutes`.

**Expressions:**

- [ ] Every `when` expression parses against the grammar.
- [ ] Every `$.` reference resolves to a declared parameter, task, or field.
- [ ] Comparison operands are type-compatible; ordering operators are used only on numbers.
- [ ] No reference points at a task that is not upstream of the referring task.

**Field hygiene:**

- [ ] Every `failure_mode: "COMPENSATE"` task carries `on_failure_compensate`.
- [ ] Every `inferred` assurance carries `confidence` and `method`; no `attested` or `asserted` one does.
- [ ] Anything the schema does not define lives in `metadata`, under an `x-` prefix, or under a namespaced `profiles.<id>` key.

## Validating

```bash
owg-validate workflow.owg.json --json
```

Success:

```json
{ "valid": true, "id": "episodic-dailies", "owg_version": "0.9" }
```

Failure:

```json
{
  "valid": false,
  "errors": [
    {
      "code": "OWG_UNRESOLVED_REFERENCE",
      "path": "/tasks/2/when",
      "message": "Reference \"$.params.add_caption\" does not resolve.",
      "docs": "https://openworkflowgraph.org/reference-syntax"
    }
  ]
}
```

Treat any non-empty `errors` array as fatal. Errors carry `code`, `path` (a JSON Pointer),
`message`, and `docs`. Full code list in [Validation](/validation#error-codes).

## Being trusted to execute

An agent-authored workflow is only useful if it can be trusted enough to run. Three properties make that possible.

### 1. Schema validation is the floor

Every document, whoever wrote it, is checked before a single task runs. Malformed dependencies, unresolvable references, cycles, and hallucinated field names are caught at validation rather than discovered mid-shoot — that is what `additionalProperties: false` and the four validation passes are for.

That floor is only as high as your validator actually reaches, so confirm which passes it performs and cover the remainder with the checklist above.

### 2. Assurance tagging is how proposals are accepted selectively

A machine-proposed relationship or workflow is tagged, not silently trusted:

| Level | Meaning | Carries confidence |
|---|---|---|
| `attested` | Backed by a verified content credential | No |
| `asserted` | Declared by a system of record, or confirmed by a human | No |
| `inferred` | Proposed by a matcher | **Required** |

An implementation applies its own acceptance policy — what score warrants automatic acceptance
versus human review is not specified. What is specified: an accepted edge **stays `inferred`**
and gains `accepted_by`. It is never promoted to `asserted`, because that would erase the fact
that a machine proposed it and a named actor accepted it.

```json
{
  "id": "rel_0042",
  "relation": "same_as",
  "from": { "kind": "asset", "id": "plate_0140" },
  "to":   { "kind": "asset", "id": "ext_frameio_b2c8e9f1" },
  "assurance": "inferred",
  "confidence": 0.74,
  "method": "m-probabilistic-1",
  "proposed_by": "connector_frameio",
  "proposed_at": "2026-08-20T09:14:00Z"
}
```

**So an agent's job is to propose with an honest confidence score, not to assert.** Overstating
confidence is the one failure mode that corrupts the graph rather than merely wasting a review.
Populate `method` with a stable identifier too — it is the key by which a whole class of bad
matches gets re-reviewed later. Full payload rules in [Relationships](/relationships).

### 3. Provenance is not optional

Structural edges — `used`, `produced`, `performed_by`, `ran_on` — are the record. An agent that produces an asset without declaring what it consumed and on whose authority has produced an unaccountable asset, whatever else it got right.

## Hard constraints

Do not violate these; they are the boundaries that keep the model coherent.

- **Never absorb another standard's internals.** Reference them. `prim_path` and `timerange` are **opaque** — store, never parse.
- **Never descend below the published-asset boundary** when reading USD composition.
- **Never strip an identifier** you do not recognise.
- **Never infer AI involvement** from an executor type.
- **Never overwrite.** New versions are new assets with a typed relation to their predecessor. A rejected asset stays in the graph as `rejected`.
- **Never promote a referenced operation to a task** unless it is genuinely *work* — a generative transition or a colour transform, not a composition resolution the other standard already performs.

## Before you build

Read [Versioning and stability](/versioning-and-stability) for how much movement to expect in each area, and [Implementation considerations](/implementation-considerations) for the decisions the specification leaves to you — fan-out, turnover documents, compliance rule packs, confidence calibration, and enforcement.

The one habit that matters most: **establish what the tooling you depend on actually does** before treating a clean validation as a guarantee. A validator performing only the structural pass will accept documents that cannot execute.
