← Files KoraARCHIVED FILE
skills/kora-workflow-builder/references/yaml-resource-schemas.md
8.39 KB · Oct 5, 2026 · 18:29 UTC
# YAML Resource Schemas
This is a compact companion. The CLI schema is authoritative:
```bash
kora schema get <resource> --json
```
Schema resource names are lowercase registry names. They are not YAML `kind`
values. For example, use `kora schema get manifest --json` for `kora.yaml`;
`project` is not a schema name.
## Resource Locations
| Resource | Schema name | Kind | Path |
| --- | --- | --- | --- |
| Project manifest | `manifest` | `Project` | `kora.yaml` |
| Organization | `organization` | `Organization` | `org/org.yaml` |
| Role | `role` | `Role` | `org/roles/*.yaml` |
| Person | `person` | `Person` | `org/people/*.yaml` |
| Agent | `agent` | `Agent` | `org/agents/*.yaml` |
| Assignments | `assignments` | `Assignments` | `org/assignments.yaml` |
| Capability | `capability` | `Capability` | `capabilities/*.yaml` |
| Workflow | `process` | `Process` | `processes/*.yaml` |
| Operation | `operation` | `Operation` | `operations/*.yaml` |
| Decision | `decision` | `Decision` | `decisions/*.yaml` |
| Trigger | `trigger` | `Trigger` | `triggers/*.yaml` |
| Test | `test` | `Test` | `tests/*.yaml` |
Extension package manifest YAML belongs to the `kora-extension-builder` skill,
not this org project schema reference.
Most org resource documents use this outer shape:
```yaml
apiVersion: kora/v1
kind: ResourceKind
metadata:
name: resource-name
spec: {}
```
`Process` is different: it has top-level `start`, `flow`, and optional `types`
fields instead of a `spec` wrapper.
`Project` is also different: it lives in `kora.yaml` and uses the project
manifest schema.
```yaml
apiVersion: kora/v1
kind: Project
metadata:
name: acme-review
spec:
machineExecution:
defaults:
sandbox:
network:
defaultAction: deny
```
Use `spec.machineExecution.defaults` for shared execution defaults such as
sandbox policy. Agent task extension tools and skills are enabled on the
capability with `spec.agentConfig.extensions`, either by shorthand extension name
or by object-form `install` plus `tools`/`skills` selections.
## Operation
Operations are script-backed service calls.
```yaml
apiVersion: kora/v1
kind: Operation
metadata:
name: lookup-company
spec:
description: Look up company details
script:
command: node
args: ["scripts/lookup-company.ts"]
parseStdoutAsJson: true
bindings:
extensions:
crm:
name: crm-primary
functions: ["lookupCompany"]
paramBindings:
domain:
from: input
path: $.domain
resultMapping:
company:
from: $.stdout.company
timeoutMs: 30000
retry:
maxAttempts: 3
```
## Workflow Service Node
```yaml
- id: lookup
type: service
operation: lookup-company
input: CompanyLookupInput
output: CompanyLookupOutput
next: done
```
`input` and `output` refer to workflow `types:` entries. Operation
`resultMapping` must produce fields that satisfy the service node's `output`
type.
`task` and `task.each` nodes may declare whole-node retry:
```yaml
retry:
maxAttempts: 2
initialIntervalMs: 1000
backoffMultiplier: 2
maxIntervalMs: 30000
retryOn: ["agent_provider_error"]
nonRetryableErrors: ["agent_needs_human"]
```
Task nodes default to one attempt. Agent `maxRepairAttempts` is separate and
only repairs structured output inside a single agent task attempt.
Agent `task` and `task.each` nodes may declare prompt artifact attachments for
top-level file artifact input fields:
```yaml
promptAttachments:
imageArtifacts:
fields: [sourceImage]
textArtifacts:
fields: [extractedText]
maxCharsPerArtifact: 20000
```
Use image attachments for PNG/JPEG/GIF/WebP artifacts and text attachments for
extractor-produced text artifacts.
## Trigger
Triggers bind an installed extension event descriptor to a Core message. They do
not change workflow syntax: the target message must match exactly one workflow
message start. The installed extension advertises valid event names,
payload schema, optional selector schema, and redacted selector summary
metadata through its registration snapshot. Managed Composio built-ins use a
permissive object payload schema; inspect representative delivered payloads
when the workflow needs provider-specific fields.
How a trigger comes together:
- Discover advertised events before writing the trigger:
`kora extensions search <extension-name> --environment <environment> --kind event --json`,
then `kora extensions get <extension-name> --environment <environment> --event <name> --json`
for the payload and selector contract
(see `references/installed-extension-discovery.md`).
- Write the `Trigger` binding `spec.from` (install + event) to
`spec.target.message`, and define exactly one workflow message start with that
name.
- Release and deployment validation reject missing or ambiguous message-start
targets. Deployment validates the install, descriptor, and selector, then
provisions the provider subscription.
- At runtime the event starts the matching workflow directly. The provider
delivery id supplies idempotency; trigger YAML has no correlation or
message-id extractor.
```yaml
apiVersion: kora/v1
kind: Trigger
metadata:
name: github-issue-created
spec:
from:
extension: github-primary
event: issue.created
selector:
owner: raw-labs
repo: kora
target:
message: issue-created
```
Use `selector` only for provider fields needed to narrow the external event
stream, such as repository, channel, label, or query.
## Test
Workflow-node test suites are source-defined checks for workflow nodes. Put
`kind: Test` YAML under `tests/` and run it with `kora test suite --workspace . --environment
<environment> --json` or against a release with `--release <release>`.
```yaml
apiVersion: kora/v1
kind: Test
metadata:
name: final-approval-run8f3
spec:
target:
workflow: quality-deviation-review
node: final-approval
input:
file: cases/run8f3/final-approval.input.json
expected:
file: cases/run8f3/final-approval.output.json
checks:
- type: schema
gate: true
- path: $.decision
type: exact
gate: true
- path: $.riskScore
type: tolerance
tolerance: 0.1
gate: true
```
Checks support `schema`, `exact`, `tolerance`, `in_set`, `must_include`, and
`must_not_include`. A test gate-passes only when every `gate: true` check passes.
`input` and `expected` each accept exactly one of these value sources:
```yaml
input:
inline:
severity: high
input:
file: cases/run8f3/final-approval.input.json
input:
ref:
run: quality-deviation-review-run8f3
node: final-approval
attempt: 2
```
A `ref` must name a run previously pinned with `kora run save`. Its `node` is
the workflow node ID and `attempt` is the deterministic execution occurrence,
defaulting to `1`. `input.ref` reads the selected attempt's input evidence and
`expected.ref` reads its output evidence. See `references/testing.md` for the
complete test-data and execution flow. `kora run unpin` removes an unused pin;
release-referenced pins remain protected.
## Capability
```yaml
apiVersion: kora/v1
kind: Capability
metadata:
name: triage-pr
spec:
description: Triage pull request risk.
agentConfig:
mode: agentic
requiresOutputReview: true
model:
ref: openai/gpt-5.4-mini
thinkingLevel: off
output:
schemaRef: TriageResult
maxRepairAttempts: 2
humanConfig:
summary: Triage pull request
```
`agentConfig.model` is optional. Omit it to use the organization's workflow
default and then the deployment fallback; when set, `ref` must be one of the
refs in the bundled Core model catalog and the deployment must have matching
model access, normally added under Settings > Models. Exact field support can
change; use `kora schema get capability --json` before relying on a rarely used
field.
Human-assigned `task` nodes must declare an object `output` type; `task.each`
nodes must declare an object `itemOutput` type. Kora derives the reviewer
controls and completion validation from that declared type.
When `agentConfig.requiresOutputReview` is true, every ordinary task using the
capability must declare a structured object `output`, an ordinary `next`, and
an `agentOutputReview` target. The target must be an explicit human-assigned
task in the same execution scope whose object input admits the complete producer
output. The producer output type must set top-level
`additionalProperties: false`. `task.each` does not support this policy; use
`call.each` to a child workflow with producer and review tasks.
SHA-256: 5d9b28f325d37fb00de26ef8721bf4d1361618053f7ff042648f084ed7efd13b