# Workflow contract compatibility

`WorkflowDefinitionV1` is the portable workflow contract shared by isA Agent
SDK, isA Agent, isA App SDK, isA Console, and isA Maestro. Native consumers
must use the JSON Schemas in `schemas/` and the fixtures in `fixtures/`; they
must not copy a service runtime's persistence model.

## Version policy

- `schema_version` is an integer major version. Version 1 readers reject every
  other value.
- Compatible V1 additions are optional fields with safe defaults, new
  namespaced extension values, or new optional run-event data.
- Existing field meaning, requiredness, identifiers, enum members, or default
  execution behavior cannot change within V1.
- A change that an older V1 reader cannot preserve or safely ignore requires a
  new schema major and an explicit migration.
- Python wire models preserve unknown fields recursively. TypeScript and other
  consumers must provide equivalent passthrough behavior.

`canvas` is presentation-only and is excluded from the execution-content hash.
Consumers must preserve it, but runtimes must not derive control decisions from
it. Root, node, edge, and Canvas unknown fields must also survive round trips.

## Canonical artifacts

- `workflow-definition-v1.schema.json`
- `node-capability-descriptor-v1.schema.json`
- `workflow-release-v1.schema.json`
- `workflow-run-v1.schema.json`
- `workflow-run-event-v1.schema.json`
- `workflow-sla-breach-v1.schema.json`

The Python tests compare every packaged schema with the corresponding Pydantic
model so a hand-edited artifact cannot drift. Valid fixtures must parse,
serialize, parse, and validate in every supported language. Invalid fixtures
must produce the listed stable diagnostic codes even when JSON Schema alone
cannot express the graph or side-effect safety rule.

## SLA and escalation semantics

`WorkflowPolicies.sla` is optional. When present, `deadline_seconds` is measured
from `WorkflowRunV1.created_at`, including queue and durable-wait time. A breach
does not fail, cancel, pause, or otherwise change workflow control flow.

The portable executor records one `sla.breached` event and the matching
`WorkflowSlaBreachV1` payload in the same fenced checkpoint transition.
`breach_key` is stable across recovery, so a replay cannot create a second
logical breach. Durable waits are scheduled to wake at the earlier of their own
deadline and the SLA deadline. Long-running activity calls can only observe a
breach at the next durable execution boundary.

An optional `SlaEscalationPolicy.route_ref` identifies a deployment-owned route
registry entry. It is not a URL, recipient, credential, or vendor configuration.
Managed runtimes consume the canonical breach event and use its event identity
or `breach_key` for idempotent delivery. Delivery and acknowledgement guarantees
remain deployment responsibilities.

## Legacy DAG migration

`import_legacy_dag` is deterministic for a canonicalized legacy payload. It
preserves safe task IDs, emits stable replacements where IDs are absent or
invalid, records the original payload digest, and reports every approximation
or unsupported field. Legacy substring conditions and skip-branch behavior are
never silently reinterpreted.

Legacy readers may remain during a documented compatibility window. New writes
and releases use `WorkflowDefinitionV1`; an in-flight legacy external-engine
instance is not automatically migrated.
