For AI agents: the complete documentation index is available at https://flow.jig.md/llms.txt, the full documentation bundle is available at https://flow.jig.md/llms-full.txt, and this page is available as Markdown at https://flow.jig.md/spec/schema-files.md.
DocumentationSpecificationPrerelease

#FLOW Schema/0 files

View Markdown

Status: prerelease specification candidate. The machine meta-schema is published as schema-0.json.

Schema/0 describes bounded values in invocation contracts, channel contracts and the optional implementation settings schema. These declarations are inert; they are never runtime mailboxes, configuration stores, templates or code.

FileExact value validated
FLOW.contract.json operation inputThe actual invocation input
settings.schema.jsonflow/run.params.settings
FLOW.contract.json operation resultThe complete normal { "outcome", "output" } result

The result schema covers the complete envelope because a package may declare several outcomes whose legal output shapes differ. Validating the complete value lets a schema express that correlation; an output-only schema could not.

#1. Absence has exact semantics

  • Run settings is always a JSON object, whether or not a schema exists. Arrays, scalars, and null are never settings values.
  • Without an invocation input schema, any value admitted by the bounded FLOW JSON data model is valid input.
  • Without settings.schema.json, the only valid settings value is {}. A package must contain a settings schema to expose a configurable seam.
  • Without an invocation result schema, any result satisfying the Run/0 base envelope and declared-outcome rules is valid.

Absence never asks a host to infer a schema from TypeScript, Markdown, environment variables, defaults, examples, or an earlier invocation.

#2. Validation points

The host parses and validates every present schema while creating the inert package snapshot, before package code or instructions can run.

Settings are first required to be one complete JSON object and are then validated against settings.schema.json before runtime selection or execution. There is no inheritance, merge, per-Run overlay, environment fallback, or default insertion.

A value chosen once for a configured use, such as maxRetries, is a setting. A value expected to vary from one invocation to another is Run input. Durable working data belongs in an attachment or bound invocation. These three seams replace variable interpolation rather than hiding it elsewhere.

Input is validated against the actual call value before implementation dispatch.

A normal component result first passes the Run/0 envelope checks: it has one declared domain outcome and an output value, and it is not a protocol, execution, cancellation, provider-loss, or uncertainty failure disguised as a domain outcome. After all owner work has quiesced, the host validates the complete result against the selected invocation result schema; only then may owner success commit. Validation failure is INVALID_RESULT.

#3. Schema/0 dialect

A standalone settings schema is a JSON object whose root contains this exact declaration:

"$schema": "https://flow.jig.md/schemas/schema-0.json"

Schema/0 is a closed, resource-bounded dialect of JSON Schema 2020-12. Boolean schemas are allowed below a standalone root and at embedded schema roots. A keyword is valid only in the locations and with the value shapes assigned to it by JSON Schema 2020-12. Both schemas and instances first satisfy the FLOW JSON/0 value model.

The complete v1 keyword allowlist is:

$schema  $defs  $ref  $comment  title  description  examples
type  enum  const
allOf  anyOf  oneOf  not  if  then  else
properties  required  additionalProperties  minProperties  maxProperties
dependentRequired  dependentSchemas
prefixItems  items  contains  minContains  maxContains
minItems  maxItems
minLength  maxLength
minimum  exclusiveMinimum  maximum  exclusiveMaximum

Every other keyword is a schema error at every depth. In particular, v1 rejects:

$id  $anchor  $dynamicAnchor  $dynamicRef  $vocabulary
default  format
pattern  patternProperties
contentEncoding  contentMediaType  contentSchema
unevaluatedItems  unevaluatedProperties
multipleOf
uniqueItems
propertyNames

format is rejected rather than treated differently by different validator defaults. pattern is deferred to avoid regex-engine and resource-consumption differences. multipleOf is deferred to avoid cross-language numeric disagreement. uniqueItems is deferred because portable deep-uniqueness work is difficult to bound. propertyNames is deferred to avoid inventing a virtual instance-pointer identity for object keys. Values in const and enum are limited to JSON/0 scalars; structural alternatives use schema applicators. description and examples remain inert annotations. An Invocation Contract descriptor which embeds them still digests the complete descriptor; “inert for validation” does not mean “excluded from interface identity.”

$defs is allowed only on the root object. Definition names match [A-Za-z][A-Za-z0-9]{0,63}. $ref accepts only an acyclic same-document reference spelled exactly #/$defs/<name> with one such definition name; percent encoding and JSON Pointer ~ escapes are not supported. Remote, relative, anchor, recursive, and dynamic resolution are invalid. Referenced definitions use the same closed dialect.

For an Invocation Contract/0 graph, the descriptor's $defs is the sole root definition map. Input, result and definition schemas cannot declare their own $defs. All embedded roots, inline channel schemas and shared definitions, including unused definitions and unselected operations, share one graph's node, depth and reference limits. Inline channel schemas reject $ref and $defs in schema-keyword positions, including nested schemas; literal property names and inert annotation/example data remain data. Separately referenced Channel Contracts each own their independently bounded graph and definition namespace.

Validation is pure. A conforming evaluator never coerces a value, inserts a default, removes a property, resolves a URI, executes code, or changes the instance. Number handling and equality use JSON/0 rather than host-language integer or decimal extensions.

The exact same Schema/0 keyword and evaluation dialect is used by embedded input and complete result schemas in Invocation Contract/0; embedded schemas do not repeat the file-root $schema declaration. FLOW does not maintain two subtly different schema languages.

#4. Required limits

A conforming host rejects before evaluation when any one schema exceeds:

encoded schema file       256 KiB
schema nesting depth      64
schema nodes              4,096

A schema node is the root or an object/boolean in a schema-valued position: each $defs or properties value; each allOf/anyOf/oneOf or prefixItems item; each not/if/then/else, additionalProperties, dependentSchemas, items, or contains schema. Data under const, enum, examples, and annotations is not a schema node. Schema depth is the longest schema-child path with the root at depth 1. A $ref does not duplicate its target for structural counting.

One validation has a deterministic budget of 1,000,000 work units. The meter is an abstract function of the parsed schema and instance, never a count of implementation actions. Each distinct (schema JSON Pointer, instance JSON Pointer) pair evaluated costs 1 and is memoized within its owning descriptor. Identical pointers in different documents never alias. This is a per-value validation budget, not a Run-lifetime quota. Each present, semantically applicable keyword adds exactly:

KeywordAdditional units and child evaluations
$ref1, then evaluate the target against the same instance.
type1 per allowed type name.
const1 scalar comparison.
enum1 scalar comparison per member, including members after a match.
allOf, anyOf, oneOf1 per listed branch and evaluate every branch.
not1 and evaluate its child.
if1 and evaluate the condition; if present, charge 1 and evaluate only the selected then or else.
properties1 per declared property; evaluate each declared property present in the instance.
required1 per listed name.
additionalProperties1 per instance member to classify; evaluate its schema for every member not declared by properties.
minProperties, maxProperties1 each.
dependentRequired1 per declared trigger plus 1 per required name for each trigger present in the instance.
dependentSchemas1 per declared trigger and evaluate each child whose trigger is present.
prefixItems1 per listed prefix schema and evaluate each position which exists.
items1 and evaluate every array item after the prefixItems range.
contains1 per array item and evaluate its child against every item.
minContains, maxContains, minItems, maxItems1 each.
minLength, maxLengthIf either is present, charge the instance's Unicode-scalar length once, plus 1 per present bound.
minimum, exclusiveMinimum, maximum, exclusiveMaximum1 numeric comparison each.
annotations and $defs0 during instance evaluation.

Object-key collections use RFC 8785 member order and arrays use index order. All applicable branches and comparisons named above are charged even if an implementation can logically short-circuit. An optimized validator may skip physical work only if it computes the same abstract charge. Crossing the limit is SCHEMA_LIMIT_EXCEEDED, never a false validation result.

Implementations may impose lower limits only in a separately named nonconforming local mode. They must compute the normative meter before treating an instance as merely invalid; exhaustion takes precedence. Once within the budget, they may report only the first validation error. They must not quietly skip an unsupported keyword or external reference.

#5. Errors and inspection

Schema compilation errors use stable codes:

SCHEMA_INVALID_JSON
SCHEMA_INVALID
SCHEMA_KEYWORD_UNSUPPORTED
SCHEMA_REFERENCE_INVALID
SCHEMA_LIMIT_EXCEEDED

SCHEMA_INVALID_JSON is reserved for invalid UTF-8, JSON syntax, duplicate members, and other JSON/0 failures. SCHEMA_INVALID means the parsed value violates Schema/0's root, keyword-location, or keyword-value-shape rules. Keeping those cases distinct lets a host report malformed data without misclassifying a well-formed but invalid schema as an unsupported extension.

Instance rejection uses INVALID_INPUT, INVALID_SETTINGS, or INVALID_RESULT. Each diagnostic contains:

code
instancePointer      RFC 6901; empty when no instance location applies
schemaPointer        RFC 6901
keyword              when applicable

Human wording and multi-error ordering are non-normative. Schema/0 defines no standalone public schema digest. A package schema is identified by its containing Package/0 digest and canonical logical path; an embedded schema by its containing Invocation Contract/0 or Channel Contract/0 identity and JSON Pointer. A host may use a private cache fingerprint, but that value is not a portable identity, compatibility token, lock input, or author-facing requirement. A host may report those containing identities and locations, plus schema compilation and example-fixture failures, without evaluating package code.

#6. Examples

The companion examples are:

They demonstrate shape validation and outcome/output correlation. They are examples, not implicit schemas for packages which omit the files.