{"openapi":"3.1.0","info":{"title":"genroc","description":"Minimalist business process orchestrator. HTTP endpoints are generated from the action registry.","version":"1.0.0"},"servers":[{"url":"/api"}],"paths":{"/channels":{"get":{"tags":["Channels"],"summary":"List all channels for a process","operationId":"list_channels","parameters":[{"name":"name","in":"query","description":"Process name","schema":{"description":"Process name","type":"string"}},{"name":"sort","in":"query","description":"Sort key (per-endpoint whitelist; omit for the default)","schema":{"description":"Sort key (per-endpoint whitelist; omit for the default)","type":"string"}},{"name":"order","in":"query","description":"Sort direction (omit for the endpoint default)","schema":{"description":"Sort direction (omit for the endpoint default)","enum":["asc","desc"],"type":"string"}},{"name":"limit","in":"query","description":"Page size (default 20, cap 100)","schema":{"description":"Page size (default 20, cap 100)","type":"integer"}},{"name":"after","in":"query","description":"Cursor from a previous page's page.next_cursor — fetch the next page","schema":{"description":"Cursor from a previous page's page.next_cursor — fetch the next page","type":"string"}},{"name":"before","in":"query","description":"Cursor from a previous page's page.previous_cursor — fetch the previous page","schema":{"description":"Cursor from a previous page's page.previous_cursor — fetch the previous page","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiPageRespGenrocInternalApiChannelEntry"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Channels"],"summary":"Set a channel pointer to a specific process version","operationId":"put_channel","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiPutChannelReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"delete":{"tags":["Channels"],"summary":"Remove a channel pointer from a process","operationId":"delete_channel","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/channels/promote":{"post":{"tags":["Channels"],"summary":"Copy all channel pointers from one channel to another (optionally scoped to a process subtree)","operationId":"promote_channel","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiPromoteChannelReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/channels/status":{"post":{"tags":["Channels"],"summary":"Report stale child references within a channel","operationId":"channel_status","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiChannelStatusReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/definitions":{"get":{"tags":["Definitions"],"summary":"List all registered process definitions (newest registered first)","operationId":"list_definitions","parameters":[{"name":"created_after","in":"query","description":"Only versions registered at/after this unix-millis timestamp","schema":{"description":"Only versions registered at/after this unix-millis timestamp","type":"integer"}},{"name":"created_before","in":"query","description":"Only versions registered strictly before this unix-millis timestamp","schema":{"description":"Only versions registered strictly before this unix-millis timestamp","type":"integer"}},{"name":"sort","in":"query","description":"Sort key (per-endpoint whitelist; omit for the default)","schema":{"description":"Sort key (per-endpoint whitelist; omit for the default)","type":"string"}},{"name":"order","in":"query","description":"Sort direction (omit for the endpoint default)","schema":{"description":"Sort direction (omit for the endpoint default)","enum":["asc","desc"],"type":"string"}},{"name":"limit","in":"query","description":"Page size (default 20, cap 100)","schema":{"description":"Page size (default 20, cap 100)","type":"integer"}},{"name":"after","in":"query","description":"Cursor from a previous page's page.next_cursor — fetch the next page","schema":{"description":"Cursor from a previous page's page.next_cursor — fetch the next page","type":"string"}},{"name":"before","in":"query","description":"Cursor from a previous page's page.previous_cursor — fetch the previous page","schema":{"description":"Cursor from a previous page's page.previous_cursor — fetch the previous page","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiPageRespGenrocInternalApiDefinitionSummary"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Definitions"],"summary":"Register or update a process definition","operationId":"put_definition","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelProcessDefinition"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/definitions/batch":{"put":{"tags":["Definitions"],"summary":"Apply process definitions to a channel, atomically","operationId":"put_definitions_batch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiPutDefinitionsBatchReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApiBatchApplyResult"},"type":"array"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/definitions/compat":{"post":{"tags":["Definitions"],"summary":"Compare two sets of process versions: could an instance running one continue under the other, and does the newer one still honour the output contract consumers were written against. It is a shape check — it cannot see a change of meaning such as dollars becoming cents","operationId":"compare_definitions","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiCompatReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiCompatResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/definitions/validate":{"post":{"tags":["Definitions"],"summary":"Validate process definitions and return inferred JSON schemas (no save)","operationId":"validate_definitions","requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ModelProcessDefinition"},"type":"array"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"items":{"additionalProperties":{},"type":"object"},"type":"array"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/external-tasks/claim":{"post":{"tags":["External Tasks"],"summary":"Lease parked external tasks to a worker (FIFO by park time); the returned token is the only handle accepted while the claim is live","operationId":"claim_external_tasks","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiClaimExternalTasksReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/external-tasks/release":{"post":{"tags":["External Tasks"],"summary":"Hand a claim back to the queue immediately instead of waiting out its lease","operationId":"release_external_task","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiReleaseExternalTaskReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/external-tasks/renew":{"post":{"tags":["External Tasks"],"summary":"Extend this worker's claims. Answers per token: `renewed` is still yours, `lost` is already someone else's (stop, do not release), `cancelled` is yours but no longer wanted (stop and release). Renewal is mandatory, not an optimisation — it is the only channel that reaches a running worker","operationId":"renew_external_claims","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiRenewExternalClaimsReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/external-tasks/resolve":{"post":{"tags":["External Tasks"],"summary":"Submit an outcome for a waiting external task — a result, or an `error` routed through the task's on_error rules; validated against what the task declares, then the process resumes","operationId":"resolve_external_task","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResolveExternalTaskReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/external-tasks/signal":{"post":{"tags":["External Tasks"],"summary":"Deliver an outcome (result or error) to an external task by instance id + task id: resolves it if armed now, else buffers FIFO until the task next arms","operationId":"signal_instance","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiSignalInstanceReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/healthz":{"servers":[{"url":"/"}],"get":{"tags":["Debug"],"summary":"Readiness probe: 200 when this worker can reach its database, 503 when it cannot","operationId":"health","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiHealthResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"503":{"description":"Service Unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/instances":{"get":{"tags":["Instances"],"summary":"List process instances - roots only unless children=true, so one row per tree","operationId":"list_instances","parameters":[{"name":"status","in":"query","description":"Filter by status, or several comma-separated (running,paused) -- the grammar genctl upgrade --status takes. The enum is the vocabulary; a comma-separated list of those values is accepted","schema":{"$ref":"#/components/schemas/ModelStatus","description":"Filter by status, or several comma-separated (running,paused) -- the grammar genctl upgrade --status takes. The enum is the vocabulary; a comma-separated list of those values is accepted"}},{"name":"phase","in":"query","description":"Filter by why a running instance is not executing a task. The three are not one kind of thing: children (blocked until its children settle), collecting (children terminal, their outputs still to merge — runnable now), external (parked until someone answers, or until its timeout). Orthogonal to status — all three are still running, and survive a pause","schema":{"description":"Filter by why a running instance is not executing a task. The three are not one kind of thing: children (blocked until its children settle), collecting (children terminal, their outputs still to merge — runnable now), external (parked until someone answers, or until its timeout). Orthogonal to status — all three are still running, and survive a pause","type":"string"}},{"name":"task","in":"query","description":"Filter by the exact task id the instance sits on — where it is running, parked, or where it stopped. A task id is unique only within its definition, so pair it with process to mean one task","schema":{"description":"Filter by the exact task id the instance sits on — where it is running, parked, or where it stopped. A task id is unique only within its definition, so pair it with process to mean one task","type":"string"}},{"name":"error_code","in":"query","description":"Filter by exact error code. Authored codes (from a raise or panic clause) are lower_snake_case; engine-produced codes contain a dot, e.g. http.500, pre.timeout, engine.spawn.","schema":{"description":"Filter by exact error code. Authored codes (from a raise or panic clause) are lower_snake_case; engine-produced codes contain a dot, e.g. http.500, pre.timeout, engine.spawn.","type":"string"}},{"name":"process","in":"query","description":"Filter by exact process name, across every version","schema":{"description":"Filter by exact process name, across every version","type":"string"}},{"name":"version","in":"query","description":"Filter by exact process version (0 = any)","schema":{"description":"Filter by exact process version (0 = any)","type":"integer"}},{"name":"children","in":"query","description":"Include child instances. Omitted, the listing is ROOTS ONLY - one row per tree, which is the unit an upgrade or a pause acts on; a child_list fan-out would otherwise bury the roots it belongs to. Every row carries parent_id, so the two are still told apart when children are included","schema":{"description":"Include child instances. Omitted, the listing is ROOTS ONLY - one row per tree, which is the unit an upgrade or a pause acts on; a child_list fan-out would otherwise bury the roots it belongs to. Every row carries parent_id, so the two are still told apart when children are included","type":"boolean"}},{"name":"created_after","in":"query","description":"Only instances created at/after this unix-millis timestamp","schema":{"description":"Only instances created at/after this unix-millis timestamp","type":"integer"}},{"name":"created_before","in":"query","description":"Only instances created strictly before this unix-millis timestamp","schema":{"description":"Only instances created strictly before this unix-millis timestamp","type":"integer"}},{"name":"updated_after","in":"query","description":"Only instances updated at/after this unix-millis timestamp","schema":{"description":"Only instances updated at/after this unix-millis timestamp","type":"integer"}},{"name":"updated_before","in":"query","description":"Only instances updated strictly before this unix-millis timestamp","schema":{"description":"Only instances updated strictly before this unix-millis timestamp","type":"integer"}},{"name":"sort","in":"query","description":"Sort key (per-endpoint whitelist; omit for the default)","schema":{"description":"Sort key (per-endpoint whitelist; omit for the default)","type":"string"}},{"name":"order","in":"query","description":"Sort direction (omit for the endpoint default)","schema":{"description":"Sort direction (omit for the endpoint default)","enum":["asc","desc"],"type":"string"}},{"name":"limit","in":"query","description":"Page size (default 20, cap 100)","schema":{"description":"Page size (default 20, cap 100)","type":"integer"}},{"name":"after","in":"query","description":"Cursor from a previous page's page.next_cursor — fetch the next page","schema":{"description":"Cursor from a previous page's page.next_cursor — fetch the next page","type":"string"}},{"name":"before","in":"query","description":"Cursor from a previous page's page.previous_cursor — fetch the previous page","schema":{"description":"Cursor from a previous page's page.previous_cursor — fetch the previous page","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiPageRespGenrocInternalApiInstanceSummaryResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"post":{"tags":["Instances"],"summary":"Start a new process instance (omit version to use latest)","operationId":"start_instance","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiStartInstanceReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiStartInstanceResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/instances/{id}":{"get":{"tags":["Instances"],"summary":"Get status of a process instance","operationId":"get_instance","parameters":[{"name":"id","in":"path","description":"The instance id","required":true,"schema":{"description":"The instance id","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiInstanceStatusResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/instances/{id}/cancel":{"post":{"tags":["Instances"],"summary":"Stop a root process instance and its entire descendant tree for good. Terminal and irreversible — unlike pause there is no way back, and a cancelled instance is not retryable. Takes effect at the next task boundary, so a task already executing runs to completion; a claimed external task is told to stop on its next renewal. An assertion: 200 if the tree stopped, 202 if a task already in flight is still draining, 204 if there was nothing live to stop","operationId":"cancel_instance","parameters":[{"name":"id","in":"path","description":"The root instance's id; the call acts on its whole tree and refuses a child","required":true,"schema":{"description":"The root instance's id; the call acts on its whole tree and refuses a child","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLifecycleResp"}}}},"202":{"description":"Accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLifecycleResp"}}}},"204":{"description":"No Content"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/instances/{id}/detail":{"get":{"tags":["Instances"],"summary":"Get everything stored on a process instance: its state verbatim, plus the columns around it","operationId":"get_instance_detail","parameters":[{"name":"resolve","in":"query","description":"Splice externalized values into the state where they fit; anything over the per-object limit stays listed under objects for the caller to fetch","schema":{"description":"Splice externalized values into the state where they fit; anything over the per-object limit stays listed under objects for the caller to fetch","type":"boolean"}},{"name":"id","in":"path","description":"The instance id","required":true,"schema":{"description":"The instance id","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiInstanceDetailResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/instances/{id}/logs":{"get":{"tags":["Instances"],"summary":"Get the execution audit trail for a process instance (newest first) - the whole tree when the id names a root, unless flat=true","operationId":"list_instance_logs","parameters":[{"name":"level","in":"query","description":"Lowest level to return: this level and everything above it (warn keeps errors)","schema":{"description":"Lowest level to return: this level and everything above it (warn keeps errors)","enum":["debug","info","warn","error"],"type":"string"}},{"name":"created_after","in":"query","description":"Only logs at/after this unix-millis timestamp","schema":{"description":"Only logs at/after this unix-millis timestamp","type":"integer"}},{"name":"created_before","in":"query","description":"Only logs strictly before this unix-millis timestamp","schema":{"description":"Only logs strictly before this unix-millis timestamp","type":"integer"}},{"name":"flat","in":"query","description":"This instance's own rows only. Without it a ROOT id answers with every row in its tree, which is one indexed read rather than a walk; a child id answers with its own rows either way, since a tree is addressed by its root","schema":{"description":"This instance's own rows only. Without it a ROOT id answers with every row in its tree, which is one indexed read rather than a walk; a child id answers with its own rows either way, since a tree is addressed by its root","type":"boolean"}},{"name":"sort","in":"query","description":"Sort key (per-endpoint whitelist; omit for the default)","schema":{"description":"Sort key (per-endpoint whitelist; omit for the default)","type":"string"}},{"name":"order","in":"query","description":"Sort direction (omit for the endpoint default)","schema":{"description":"Sort direction (omit for the endpoint default)","enum":["asc","desc"],"type":"string"}},{"name":"limit","in":"query","description":"Page size (default 20, cap 100)","schema":{"description":"Page size (default 20, cap 100)","type":"integer"}},{"name":"after","in":"query","description":"Cursor from a previous page's page.next_cursor — fetch the next page","schema":{"description":"Cursor from a previous page's page.next_cursor — fetch the next page","type":"string"}},{"name":"before","in":"query","description":"Cursor from a previous page's page.previous_cursor — fetch the previous page","schema":{"description":"Cursor from a previous page's page.previous_cursor — fetch the previous page","type":"string"}},{"name":"id","in":"path","description":"The instance id","required":true,"schema":{"description":"The instance id","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiPageRespGenrocInternalApiLogEntryResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/instances/{id}/pause":{"post":{"tags":["Instances"],"summary":"Pause a running root process instance and its entire descendant tree; takes effect at the next task boundary, so a task already executing runs to completion. An assertion: 200 if the tree stopped, 202 if a task already in flight is still draining, 204 if it was not running anyway","operationId":"pause_instance","parameters":[{"name":"id","in":"path","description":"The root instance's id; the call acts on its whole tree and refuses a child","required":true,"schema":{"description":"The root instance's id; the call acts on its whole tree and refuses a child","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLifecycleResp"}}}},"202":{"description":"Accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLifecycleResp"}}}},"204":{"description":"No Content"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/instances/{id}/resume":{"post":{"tags":["Instances"],"summary":"Resume a paused root process instance and its tree, continuing exactly where it stopped (timers kept running while paused). An assertion: 200 if it was resumed, 204 if the tree was already advancing; 409 only if it has settled and cannot advance again","operationId":"resume_instance","parameters":[{"name":"id","in":"path","description":"The root instance's id; the call acts on its whole tree and refuses a child","required":true,"schema":{"description":"The root instance's id; the call acts on its whole tree and refuses a child","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLifecycleResp"}}}},"204":{"description":"No Content"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/instances/{id}/retry":{"post":{"tags":["Instances"],"summary":"Retry a failed root process instance, reviving its tree where it died and granting the failing task another attempt beyond its on_error budget","operationId":"retry_instance","parameters":[{"name":"force","in":"query","description":"Override only_once retry protection","schema":{"description":"Override only_once retry protection","type":"boolean"}},{"name":"id","in":"path","description":"The root instance's id; the call acts on its whole tree and refuses a child","required":true,"schema":{"description":"The root instance's id; the call acts on its whole tree and refuses a child","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLifecycleResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/instances/{id}/upgrade":{"post":{"tags":["Instances"],"summary":"Move a process instance and every live descendant to another version of their definitions","operationId":"upgrade_instance","parameters":[{"name":"id","in":"path","description":"The root instance's id; the call acts on its whole tree and refuses a child","required":true,"schema":{"description":"The root instance's id; the call acts on its whole tree and refuses a child","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiUpgradeInstanceReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiUpgradeResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/objects/{ref}":{"get":{"tags":["Objects"],"summary":"Fetch an externalized value by its content hash, as listed in a response's objects section","operationId":"get_object","parameters":[{"name":"ref","in":"path","description":"The value's content hash, as a response's objects section lists it","required":true,"schema":{"description":"The value's content hash, as a response's objects section lists it","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/tick":{"post":{"tags":["Debug"],"summary":"Manually trigger one engine poll cycle (useful when started with -poll 0); optionally shift the server clock forward first to expire leases and retry timers without real waits (testing only)","operationId":"tick","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiTickReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not Implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/tokens":{"get":{"tags":["Tokens"],"summary":"List API tokens. Secrets are never included — the row cannot produce one","operationId":"list_tokens","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"post":{"tags":["Tokens"],"summary":"Mint an API token. The secret is returned once and never again — only its hash is stored","operationId":"create_token","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiCreateTokenReq"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiCreateTokenResp"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/tokens/{id}":{"delete":{"tags":["Tokens"],"summary":"Revoke an API token. Takes effect on the next request that presents it","operationId":"revoke_token","parameters":[{"name":"id","in":"path","description":"The token id, as GET /tokens lists it","required":true,"schema":{"description":"The token id, as GET /tokens lists it","type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"additionalProperties":{},"type":"object"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}}},"components":{"schemas":{"ApiBatchApplyResult":{"properties":{"name":{"type":"string"},"previous":{"type":"integer"},"saved":{"type":"boolean"},"version":{"type":"integer"}},"required":["name","version","saved","previous"],"type":"object"},"ApiChannelEntry":{"properties":{"actor":{"type":"string"},"channel":{"type":"string"},"updated_at":{"type":"string"},"version":{"type":"integer"}},"required":["channel","version"],"type":"object"},"ApiChannelStatusReq":{"properties":{"channel":{"type":"string"}},"required":["channel"],"type":"object"},"ApiClaimExternalTasksReq":{"properties":{"lease_ms":{"type":"integer"},"limit":{"type":"integer"},"process":{"type":"string"},"task":{"type":"string"},"version":{"type":"integer"},"worker_id":{"type":"string"}},"required":["worker_id"],"type":"object"},"ApiCode":{"enum":["invalid","unauthenticated","forbidden","not_found","conflict","internal","unsupported","unavailable"],"type":"string"},"ApiCompatReq":{"properties":{"from":{"$ref":"#/components/schemas/ApiCompatSelector"},"ignore":{"description":"Members excused from the exit code. Only \"contract\" is accepted: the upgrade check answers for rows this deployment already owns","items":{"type":"string"},"type":"array"},"process":{"type":"string"},"to":{"$ref":"#/components/schemas/ApiCompatSelector"}},"required":["from","to"],"type":"object"},"ApiCompatResp":{"properties":{"compatible":{"type":"boolean"},"passes":{"description":"False only where a gating check broke. Equals compatible when ignore is empty","type":"boolean"},"processes":{"items":{"$ref":"#/components/schemas/ValidationReport"},"type":["array","null"]}},"required":["compatible","passes","processes"],"type":"object"},"ApiCompatSelector":{"properties":{"channel":{"description":"Every process on this channel, at the version the channel points at.","type":"string"},"definitions":{"description":"Documents that are not stored yet — the ones an apply would take. They have no version, so they report version null.","items":{"$ref":"#/components/schemas/ModelProcessDefinition"},"type":"array"},"versions":{"additionalProperties":{"$ref":"#/components/schemas/ApiVersionRef"},"description":"Process name → version number, or a channel name to resolve it through.","type":"object"}},"type":"object"},"ApiCreateTokenReq":{"properties":{"label":{"type":"string"},"perms":{"items":{"type":"string"},"type":["array","null"]}},"required":["label","perms"],"type":"object"},"ApiCreateTokenResp":{"properties":{"id":{"type":"string"},"label":{"type":"string"},"perms":{"items":{"type":"string"},"type":["array","null"]},"token":{"type":"string"}},"required":["id","token","perms"],"type":"object"},"ApiDefinitionSummary":{"properties":{"actor":{"type":"string"},"created_at":{"type":"string"},"name":{"type":"string"},"raises":{"items":{"type":"string"},"type":"array"},"version":{"type":"integer"}},"required":["name","version","created_at"],"type":"object"},"ApiErrorBody":{"properties":{"code":{"$ref":"#/components/schemas/ApiCode"},"error":{"type":"string"},"fields":{"items":{"$ref":"#/components/schemas/ModelFieldError"},"type":"array"}},"required":["error","code"],"type":"object"},"ApiFailureReq":{"properties":{"code":{"type":"string"},"data":{},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"ApiHealthResp":{"properties":{"database":{"description":"Storage engine backing this worker: sqlite or postgres","type":"string"},"lease_age_ms":{"description":"Milliseconds since this worker last renewed its leases. Past --lease-duration means its claimed instances are being taken over by peers.","type":"integer"},"manual_tick":{"description":"True when started with -poll 0: the engine only advances via POST /tick","type":"boolean"},"status":{"description":"ok — this worker reached its database; any other outcome is a 503","type":"string"},"worker_id":{"description":"Worker id stamped on the leases this worker holds","type":"string"}},"required":["status","worker_id","database","lease_age_ms","manual_tick"],"type":"object"},"ApiInstanceDetailResp":{"properties":{"call_stack":{"items":{"type":"string"},"type":"array"},"children":{"additionalProperties":{},"type":"object"},"created_at":{"type":"string"},"error_code":{"type":"string"},"error_data":{},"error_message":{"type":"string"},"external_claim_epoch":{"type":"integer"},"external_input":{},"external_lease_expires_at":{"type":"string"},"external_worker_id":{"type":"string"},"id":{"type":"string"},"lease_epoch":{"type":"integer"},"lease_expires_at":{"type":"string"},"next_replayable":{"type":"boolean"},"objects":{"items":{"$ref":"#/components/schemas/ApiObjectEntry"},"type":"array"},"output":{},"parent_id":{"type":"string"},"parent_task_epoch":{"type":"integer"},"phase":{"type":"string"},"process":{"type":"string"},"retry_count":{"type":"integer"},"spawn_task_id":{"type":"string"},"state":{"additionalProperties":{},"type":["object","null"]},"status":{"$ref":"#/components/schemas/ModelStatus"},"task":{"type":"string"},"task_epoch":{"type":"integer"},"updated_at":{"type":"string"},"version":{"type":"integer"},"wake_at":{"type":"string"},"worker_id":{"type":"string"}},"required":["id","process","version","status","retry_count","created_at","updated_at","state","lease_epoch","task_epoch","parent_task_epoch","next_replayable","external_claim_epoch"],"type":"object"},"ApiInstanceStatusResp":{"properties":{"created_at":{"type":"string"},"error_code":{"type":"string"},"error_data":{},"error_message":{"type":"string"},"external_input":{},"id":{"type":"string"},"objects":{"items":{"$ref":"#/components/schemas/ApiObjectEntry"},"type":"array"},"output":{},"phase":{"type":"string"},"process":{"type":"string"},"retry_count":{"type":"integer"},"status":{"$ref":"#/components/schemas/ModelStatus"},"task":{"type":"string"},"updated_at":{"type":"string"},"version":{"type":"integer"}},"required":["id","process","version","status","retry_count","created_at","updated_at"],"type":"object"},"ApiInstanceSummaryResp":{"properties":{"created_at":{"type":"string"},"error_code":{"type":"string"},"error_message":{"type":"string"},"id":{"type":"string"},"parent_id":{"type":"string"},"phase":{"type":"string"},"process":{"type":"string"},"retry_count":{"type":"integer"},"status":{"$ref":"#/components/schemas/ModelStatus"},"task":{"type":"string"},"updated_at":{"type":"string"},"version":{"type":"integer"}},"required":["id","process","version","status","retry_count","created_at","updated_at"],"type":"object"},"ApiLifecycleResp":{"properties":{"instances":{"description":"How many instances in the tree this call wrote","type":"integer"},"outcome":{"description":"What this call did: applied (the assertion holds and this call made it hold), or accepted (recorded, not yet in effect — a pause left rows draining a task already in flight). A 204 with no body means unchanged: the assertion already held.","type":"string"},"status":{"$ref":"#/components/schemas/ModelStatus","description":"The root instance's status once the write committed"}},"required":["outcome","status","instances"],"type":"object"},"ApiLogEntryResp":{"properties":{"actor":{"type":"string"},"code":{"type":"string"},"created_at":{"type":"string"},"data":{},"event":{"type":"string"},"instance_id":{"type":"string"},"level":{"type":"string"},"message":{"type":"string"},"meta":{"additionalProperties":{},"type":"object"},"objects":{"items":{"$ref":"#/components/schemas/ApiObjectEntry"},"type":"array"},"task":{"type":"string"}},"required":["created_at","instance_id","level","event"],"type":"object"},"ApiObjectEntry":{"properties":{"path":{"items":{},"type":["array","null"]},"ref":{"type":"string"},"size":{"type":"integer"}},"required":["path","ref","size"],"type":"object"},"ApiPageRespGenrocInternalApiChannelEntry":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ApiChannelEntry"},"type":["array","null"]},"page":{"$ref":"#/components/schemas/DbPageInfo"}},"required":["items","page"],"type":"object"},"ApiPageRespGenrocInternalApiDefinitionSummary":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ApiDefinitionSummary"},"type":["array","null"]},"page":{"$ref":"#/components/schemas/DbPageInfo"}},"required":["items","page"],"type":"object"},"ApiPageRespGenrocInternalApiInstanceSummaryResp":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ApiInstanceSummaryResp"},"type":["array","null"]},"page":{"$ref":"#/components/schemas/DbPageInfo"}},"required":["items","page"],"type":"object"},"ApiPageRespGenrocInternalApiLogEntryResp":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ApiLogEntryResp"},"type":["array","null"]},"page":{"$ref":"#/components/schemas/DbPageInfo"}},"required":["items","page"],"type":"object"},"ApiPromoteChannelReq":{"properties":{"from":{"type":"string"},"process":{"type":["null","string"]},"to":{"type":"string"}},"required":["from","to"],"type":"object"},"ApiPutChannelReq":{"properties":{"channel":{"type":"string"},"name":{"type":"string"},"version":{"type":"integer"}},"required":["name","channel","version"],"type":"object"},"ApiPutDefinitionsBatchReq":{"properties":{"channel":{"type":"string"},"definitions":{"items":{"$ref":"#/components/schemas/ModelProcessDefinition"},"type":["array","null"]}},"required":["definitions","channel"],"type":"object"},"ApiReleaseExternalTaskReq":{"properties":{"token":{"type":"string"}},"required":["token"],"type":"object"},"ApiRenewExternalClaimsReq":{"properties":{"lease_ms":{"type":"integer"},"tokens":{"items":{"type":"string"},"type":["array","null"]},"worker_id":{"type":"string"}},"required":["worker_id","tokens"],"type":"object"},"ApiResolveExternalTaskReq":{"properties":{"error":{"$ref":"#/components/schemas/ApiFailureReq"},"result":{},"token":{"type":"string"}},"required":["token"],"type":"object"},"ApiSignalInstanceReq":{"properties":{"error":{"$ref":"#/components/schemas/ApiFailureReq"},"instance_id":{"type":"string"},"result":{},"task":{"type":"string"}},"required":["instance_id","task"],"type":"object"},"ApiStartInstanceReq":{"properties":{"channel":{"type":["null","string"]},"input":{},"process":{"type":"string"},"version":{"type":["null","integer"]}},"required":["process"],"type":"object"},"ApiStartInstanceResp":{"properties":{"id":{"type":"string"},"process":{"type":"string"},"status":{"$ref":"#/components/schemas/ModelStatus"},"version":{"type":"integer"}},"required":["id","process","version","status"],"type":"object"},"ApiTickReq":{"properties":{"advance_ms":{"type":"integer"}},"required":["advance_ms"],"type":"object"},"ApiUpgradeInstanceReq":{"properties":{"from_version":{"type":"integer"},"to_version":{"type":"integer"}},"required":["from_version","to_version"],"type":"object"},"ApiUpgradeMove":{"properties":{"from_version":{"type":"integer"},"id":{"type":"string"},"process":{"type":"string"},"reason":{"type":"string"},"skipped":{"type":"boolean"},"status":{"type":"string"},"task":{"type":"string"},"to_version":{"type":"integer"}},"required":["id","process","task","from_version","to_version","status"],"type":"object"},"ApiUpgradeResp":{"properties":{"moves":{"items":{"$ref":"#/components/schemas/ApiUpgradeMove"},"type":["array","null"]},"upgraded":{"type":"boolean"}},"required":["upgraded","moves"],"type":"object"},"ApiVersionRef":{"type":"object"},"DbPageInfo":{"properties":{"after":{"type":"string"},"before":{"type":"string"},"items_after":{"type":"integer"},"items_before":{"type":"integer"},"order":{"type":"string"},"size":{"type":"integer"},"sort":{"type":"string"}},"required":["size","items_before","items_after","sort","order"],"type":"object"},"ModelAction":{"discriminator":{"propertyName":"type"},"oneOf":[{"additionalProperties":false,"description":"HTTP call. URL, method, headers and body are all expressions.","properties":{"accepted_status":{"anyOf":[{"items":{"description":"A literal string, or a $: expression / ${ } template evaluated against the context.","type":"string"},"type":"array"},{"description":"A literal string, or a $: expression / ${ } template evaluated against the context.","type":"string"}],"description":"HTTP status patterns accepted as non-errors, e.g. \"2xx\" or \"404\" (defaults to any 2xx). Author it as a literal array (each element a ${ } template or $: expression yielding a string), or as a single $: expression yielding the whole array."},"body":{"$ref":"#/components/schemas/ModelShape","description":"Templated value building the request body; an object is sent as JSON."},"body_schema":{"additionalProperties":true,"description":"JSON Schema the body is checked against and conformed to before the request is built. An undeclared key is refused.","type":"object"},"headers":{"anyOf":[{"additionalProperties":{"description":"A literal string, or a $: expression / ${ } template evaluated against the context.","type":"string"},"type":"object"},{"description":"A literal string, or a $: expression / ${ } template evaluated against the context.","type":"string"}],"description":"Request headers, evaluating to an object of string values. Author it as a literal map (each value a ${ } template or a $: expression yielding a string), or as a single $: expression yielding the whole map."},"method":{"description":"HTTP method, lowercase (e.g. get, post) or a template such as ${ input.method }. Required — the verb is never guessed.","type":"string"},"query":{"anyOf":[{"additionalProperties":{"anyOf":[{"anyOf":[{"description":"A literal string, or a $: expression / ${ } template evaluated against the context.","type":["string","number","boolean","null"]},{"anyOf":[{"items":{"description":"A literal string, or a $: expression / ${ } template evaluated against the context.","type":["string","number","boolean","null"]},"type":"array"},{"description":"A literal string, or a $: expression / ${ } template evaluated against the context.","type":"string"}]}]},{"description":"A literal string, or a $: expression / ${ } template evaluated against the context.","type":"string"}]},"type":"object"},{"description":"A literal string, or a $: expression / ${ } template evaluated against the context.","type":"string"}],"description":"Query parameters appended to the url, evaluating to an object of scalar values. A null value omits its parameter. Author it as a literal map (each value a ${ } template or a $: expression) or as a single $: expression yielding the whole map."},"query_schema":{"additionalProperties":true,"description":"JSON Schema the query map is checked against and conformed to. An optional non-nullable parameter fed null is omitted.","type":"object"},"responses":{"additionalProperties":{"additionalProperties":true,"type":["object","null"]},"description":"Status pattern -\u003e JSON Schema for that body. A 2xx key types self.result and accepts the status.","propertyNames":{"pattern":"^\\s*[1-5](\\d\\d|xx)(\\s*,\\s*[1-5](\\d\\d|xx))*\\s*$"},"type":"object"},"timeout":{"description":"Budget for one attempt, e.g. \"30s\" (defaults to 30s). A retry gets a fresh budget. Only 'for' applies here — 'until' is external-only.","oneOf":[{"description":"Shorthand for 'for', resolved in UTC: \"2h30m\", a number of milliseconds, or a $: expression.","type":["string","number"]},{"additionalProperties":false,"description":"The long form, naming exactly one of 'for' or 'until' plus an optional 'tz'.","oneOf":[{"required":["for"]},{"required":["until"]}],"properties":{"for":{"description":"A duration from when the task is reached: \"2h30m\", a number of milliseconds, or a $: expression.","type":["string","number"]},"tz":{"description":"IANA name (\"Europe/Prague\") or fixed offset (\"+02:00\"); defaults to UTC. Abbreviations are rejected.","type":"string"},"until":{"description":"An absolute deadline, external tasks only. The same instants as a delay's 'until'.","type":["string","number"]}},"type":"object"}]},"type":{"const":"fetch","type":"string"},"url":{"description":"Request URL. May contain ${ } interpolations, e.g. ${ config.server_url }/path.","type":"string"}},"required":["type","url","method"],"type":"object"},{"additionalProperties":false,"description":"Single child call: runs one named process and waits. The result is its output, unwrapped.","properties":{"input":{"$ref":"#/components/schemas/ModelShape","description":"Templated value building the child's input payload."},"input_schema":{"additionalProperties":true,"description":"JSON Schema the input is checked against and conformed to before it is sent. Checkable with no server.","type":"object"},"name":{"description":"Name of the child process to invoke.","type":"string"},"raises":{"additionalProperties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}]},"description":"Raise code -\u003e JSON Schema for that code's payload, read as error.data by a rule that catches it.","propertyNames":{"pattern":"^[a-z][a-z0-9_]*$"},"type":"object"},"result_schema":{"additionalProperties":true,"description":"JSON Schema validating and exposing the child's output.","type":"object"},"type":{"const":"child","type":"string"},"version":{"description":"Version to run; 0 means latest published version.","type":"integer"}},"required":["type","name"],"type":"object"},{"additionalProperties":false,"description":"Keyed child call: named processes run concurrently. The result is keyed by child name.","properties":{"children":{"additionalProperties":{"additionalProperties":false,"properties":{"input":{"$ref":"#/components/schemas/ModelShape","description":"Templated value building the child's input payload."},"input_schema":{"additionalProperties":true,"description":"JSON Schema this entry's input is checked against and conformed to before it is sent.","type":"object"},"name":{"description":"Name of the child process to invoke.","type":"string"},"raises":{"additionalProperties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}]},"description":"Raise code -\u003e JSON Schema for that code's payload, declared per entry.","propertyNames":{"pattern":"^[a-z][a-z0-9_]*$"},"type":"object"},"result_schema":{"additionalProperties":true,"description":"JSON Schema validating and exposing this child's output.","type":"object"},"version":{"description":"Version to run; 0 means latest published version.","type":"integer"}},"required":["name"],"type":"object"},"description":"Keyed map of child processes to run concurrently. Keys become the access names in outputs.taskID.","minProperties":1,"type":"object"},"type":{"const":"child_map","type":"string"}},"required":["type","children"],"type":"object"},{"additionalProperties":false,"description":"List fan-out: one child per element of 'over'. The result is an array in 'over' order.","properties":{"input_schema":{"additionalProperties":true,"description":"JSON Schema EACH element is checked against and conformed to before it is sent as one child's input.","type":"object"},"name":{"description":"Name of the child process to invoke for every element.","type":"string"},"over":{"description":"A $: expression evaluating to an array; one child is spawned per element, with it as input.","type":"string"},"raises":{"additionalProperties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}]},"description":"Raise code -\u003e JSON Schema for that code's payload, read as error.data by a rule that catches it.","propertyNames":{"pattern":"^[a-z][a-z0-9_]*$"},"type":"object"},"result_schema":{"additionalProperties":true,"description":"JSON Schema validating and exposing EACH child's output; the result is an array.","type":"object"},"type":{"const":"child_list","type":"string"},"version":{"description":"Version to run; 0 means latest published version.","type":"integer"}},"required":["type","name","over"],"type":"object"},{"additionalProperties":false,"description":"Delay action: parks the instance until a duration elapses (for) or an instant arrives (until).","oneOf":[{"required":["for"]},{"required":["until"]}],"properties":{"for":{"description":"A duration from when the task is reached: \"2h30m\", a number of milliseconds, or a $: expression.","type":["string","number"]},"type":{"const":"delay","type":"string"},"tz":{"description":"IANA name (\"Europe/Prague\") or fixed offset (\"+02:00\"); defaults to UTC. Abbreviations are rejected.","type":"string"},"until":{"description":"An instant: RFC 3339, \"+2d 08:00\", a calendar pattern, unix milliseconds, or a $: expression.","type":["string","number"]}},"required":["type"],"type":"object"},{"additionalProperties":false,"description":"External task: parks the instance until an outside caller submits a result. No worker is held.","properties":{"input":{"$ref":"#/components/schemas/ModelShape","description":"Templated value snapshotted for the resolver — the only context the queue exposes."},"input_schema":{"additionalProperties":true,"description":"JSON Schema the input snapshot is checked against and conformed to. It is the contract a worker reads.","type":"object"},"raises":{"additionalProperties":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}]},"description":"Code -\u003e JSON Schema for a payload submitted to /external-tasks/fail, read as error.data.","propertyNames":{"pattern":"^[a-z][a-z0-9_]*$"},"type":"object"},"result_schema":{"additionalProperties":true,"description":"JSON Schema the submitted result is validated against. Without it any JSON is accepted.","type":"object"},"timeout":{"description":"How long to park before raising external.timeout. Omitted, the task waits indefinitely. Takes 'for' or an absolute 'until'.","oneOf":[{"description":"Shorthand for 'for', resolved in UTC: \"2h30m\", a number of milliseconds, or a $: expression.","type":["string","number"]},{"additionalProperties":false,"description":"The long form, naming exactly one of 'for' or 'until' plus an optional 'tz'.","oneOf":[{"required":["for"]},{"required":["until"]}],"properties":{"for":{"description":"A duration from when the task is reached: \"2h30m\", a number of milliseconds, or a $: expression.","type":["string","number"]},"tz":{"description":"IANA name (\"Europe/Prague\") or fixed offset (\"+02:00\"); defaults to UTC. Abbreviations are rejected.","type":"string"},"until":{"description":"An absolute deadline, external tasks only. The same instants as a delay's 'until'.","type":["string","number"]}},"type":"object"}]},"type":{"const":"external","type":"string"}},"required":["type"],"type":"object"}]},"ModelErrorCase":{"properties":{"case":{"description":"Extra condition on the matched error, checked alongside code. A false case falls to the next rule.","type":"string"},"code":{"description":"Error code patterns. '%' is the only wildcard; every other character is literal. Empty = catch-all.","items":{"type":"string"},"type":"array"},"goto":{"description":"Task to route to when retries are exhausted. '$task-id' or 'end'. Omit to fail the instance.","type":"string"},"not_reached":{"description":"Assert this code means the remote was never reached, so an only_once task may retry it.","type":["null","boolean"]},"panic":{"$ref":"#/components/schemas/ModelFault","description":"Terminate as 'failed' with this code and message — a defect. Nothing can catch a panic."},"raise":{"$ref":"#/components/schemas/ModelFault","description":"Terminate as 'raised' with this code and message — a condition a parent can catch."},"retry":{"$ref":"#/components/schemas/ModelRetry","description":"Retry policy applied before the rule routes. Omit for no retries."}},"type":"object"},"ModelFault":{"properties":{"code":{"description":"Error code, lower_snake_case with no dots. A literal — never an expression.","type":"string"},"data":{"$ref":"#/components/schemas/ModelShape","description":"Structured payload this fault carries, evaluated when the clause fires. Lands on error.data."},"message":{"description":"Human-readable message. A template: ${ } renders when the clause fires.","type":"string"}},"required":["code","message"],"type":"object"},"ModelFieldError":{"properties":{"field":{"type":"string"},"message":{"type":"string"},"param":{"type":"string"},"rule":{"type":"string"}},"required":["field","rule","message"],"type":"object"},"ModelProcessDefinition":{"properties":{"$defs":{"$ref":"#/components/schemas/SchemaDefs","description":"Shared schema definitions, referenced as \"#/$defs/\u003cname\u003e\"."},"config_schema":{"$ref":"#/components/schemas/SchemaSchema","description":"Flat object of primitive config variables, resolved from the server environment and read as config.\u003cNAME\u003e."},"input_schema":{"$ref":"#/components/schemas/SchemaSchema","description":"JSON Schema used to validate the input payload when starting a new instance."},"name":{"description":"Unique process identifier.","type":"string"},"output":{"$ref":"#/components/schemas/ModelShape","description":"Templated value evaluated at completion to produce the process output."},"output_schema":{"$ref":"#/components/schemas/SchemaSchema","description":"JSON Schema the process output is checked against and conformed to. Declared, it is what this process publishes."},"tasks":{"description":"Ordered list of execution tasks. Control advances linearly unless a switch case redirects.","items":{"$ref":"#/components/schemas/ModelTask"},"type":["array","null"]}},"required":["name","tasks"],"type":"object"},"ModelRetry":{"oneOf":[{"description":"Shorthand for 'retries', on the default backoff curve (1s, doubling, capped at 5m).","minimum":0,"type":"integer"},{"additionalProperties":false,"description":"The long form: retry count plus any part of the backoff curve. Every slot takes a $: expression.","properties":{"delay":{"description":"Wait before the first retry: \"30s\", a number of milliseconds, or a $: expression. Defaults to 1s.","type":["string","number"]},"factor":{"description":"Multiplier applied to the wait after each attempt. 1 keeps it constant. Defaults to 2.","minimum":1,"type":["number","string"]},"max_delay":{"description":"Ceiling the growing wait is clamped to. Defaults to 5m, or to 'delay' when that is longer.","type":["string","number"]},"retries":{"description":"Number of retries before following goto or failing. 0 = no retries.","minimum":0,"type":["integer","string"]}},"type":"object"}]},"ModelShape":{"anyOf":[{"description":"A $: typed expression, a ${ } interpolation template, or a literal string.","type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"description":"Literal array; each element is recursively a Shape.","items":{},"type":"array"},{"additionalProperties":{"$ref":"#/components/schemas/ModelShape"},"description":"Literal object; each value is recursively a Shape.","type":"object"}]},"ModelStatus":{"enum":["running","pausing","paused","failing","cancelling","completed","failed","raised","cancelled"],"type":"string"},"ModelSwitchMap":{"oneOf":[{"description":"A single unconditional route: \"next\", \"end\", or \"$task-id\".","type":"string"},{"description":"Ordered routing rules; first match wins and the last must be a catch-all (omit 'case').","items":{"additionalProperties":false,"properties":{"case":{"description":"Boolean expression. Omit for a catch-all; must be last.","type":"string"},"goto":{"description":"\"end\" to terminate, \"next\" to advance, or \"$task-id\" to jump to a task.","type":"string"},"panic":{"$ref":"#/components/schemas/ModelFault","description":"Terminate as 'failed' with this code and message — a defect. Nothing can catch a panic."},"raise":{"$ref":"#/components/schemas/ModelFault","description":"Terminate as 'raised' with this code and message — a condition a parent can catch."}},"type":"object"},"minItems":1,"type":"array"}]},"ModelTask":{"properties":{"action":{"$ref":"#/components/schemas/ModelAction","description":"Describes the action to perform. Omit for switch-only (routing) tasks."},"id":{"description":"Task identifier, unique within the definition.","type":"string"},"on_error":{"description":"Ordered error-routing rules evaluated when the call fails. First match wins.","items":{"$ref":"#/components/schemas/ModelErrorCase"},"type":"array"},"only_once":{"description":"At-most-once execution: only errors that never reached the remote may retry. Defaults to false.","type":["null","boolean"]},"output":{"$ref":"#/components/schemas/ModelShape","description":"Templated value remapping this task's output; it becomes outputs.taskID and self.output."},"output_schema":{"$ref":"#/components/schemas/SchemaSchema","description":"JSON Schema this task's output is checked against and conformed to. It becomes the published type of outputs.taskID."},"switch":{"$ref":"#/components/schemas/ModelSwitchMap","description":"Required. Routing: a shorthand (\"next\", \"end\", \"$task-id\") or an ordered list of cases."}},"required":["id","switch"],"type":"object"},"SchemaDefs":{"additionalProperties":{"additionalProperties":false,"description":"A JSON Schema, in the subset genroc supports.","properties":{"$anchor":{"description":"A name this schema can be referenced by."},"$defs":{"description":"Named schemas this document's $refs resolve against."},"$id":{"description":"An identifier for this schema."},"$ref":{"description":"A reference to another schema, as `#/$defs/\u003cname\u003e`."},"additionalProperties":{"description":"The schema undeclared keys conform to, making the object an open map. Omit to close the object: undeclared keys are stripped."},"anyOf":{"description":"The value conforms to at least one of these schemas."},"default":{"description":"The value used when this one is absent. Annotation only — it does not make a required property optional."},"description":{"description":"Free text. Shown in the editor, and never a constraint."},"enum":{"description":"The complete set of values allowed here."},"items":{"description":"The schema every element of an array conforms to."},"maxItems":{"description":"Most allowed array elements."},"maxLength":{"description":"Longest allowed string."},"maximum":{"description":"Largest allowed number, inclusive."},"minItems":{"description":"Fewest allowed array elements."},"minLength":{"description":"Shortest allowed string."},"minimum":{"description":"Smallest allowed number, inclusive."},"oneOf":{"description":"The value conforms to exactly one of these schemas."},"properties":{"description":"The named members of an object, each a schema."},"required":{"description":"Which properties must be present. A property not listed here may be absent, and reading it yields null."},"secret":{"description":"Redacts the value from logs. Only meaningful in a process config_schema."},"type":{"description":"The value's JSON type, or a list of types it may take."}},"type":"object"},"type":"object"},"SchemaSchema":{"additionalProperties":false,"description":"A JSON Schema, in the subset genroc supports.","properties":{"$anchor":{"description":"A name this schema can be referenced by."},"$defs":{"description":"Named schemas this document's $refs resolve against."},"$id":{"description":"An identifier for this schema."},"$ref":{"description":"A reference to another schema, as `#/$defs/\u003cname\u003e`."},"additionalProperties":{"description":"The schema undeclared keys conform to, making the object an open map. Omit to close the object: undeclared keys are stripped."},"anyOf":{"description":"The value conforms to at least one of these schemas."},"default":{"description":"The value used when this one is absent. Annotation only — it does not make a required property optional."},"description":{"description":"Free text. Shown in the editor, and never a constraint."},"enum":{"description":"The complete set of values allowed here."},"items":{"description":"The schema every element of an array conforms to."},"maxItems":{"description":"Most allowed array elements."},"maxLength":{"description":"Longest allowed string."},"maximum":{"description":"Largest allowed number, inclusive."},"minItems":{"description":"Fewest allowed array elements."},"minLength":{"description":"Shortest allowed string."},"minimum":{"description":"Smallest allowed number, inclusive."},"oneOf":{"description":"The value conforms to exactly one of these schemas."},"properties":{"description":"The named members of an object, each a schema."},"required":{"description":"Which properties must be present. A property not listed here may be absent, and reading it yields null."},"secret":{"description":"Redacts the value from logs. Only meaningful in a process config_schema."},"type":{"description":"The value's JSON type, or a list of types it may take."}},"type":"object"},"ValidationIssue":{"properties":{"address":{"type":"string"},"gating":{"type":"boolean"},"member":{"type":"string"},"message":{"type":"string"},"path":{"type":"string"},"task":{"type":"string"}},"required":["member","address","message","gating"],"type":"object"},"ValidationReport":{"properties":{"added":{"items":{"type":"string"},"type":"array"},"changed":{"items":{"$ref":"#/components/schemas/ValidationSlotChange"},"type":"array"},"contract":{"$ref":"#/components/schemas/ValidationVerdict"},"from":{"type":"integer"},"issues":{"items":{"$ref":"#/components/schemas/ValidationIssue"},"type":"array"},"name":{"type":"string"},"reason":{"type":"string"},"side":{"type":"string"},"status":{"type":"string"},"to":{"type":"integer"},"upgrade":{"$ref":"#/components/schemas/ValidationVerdict"}},"required":["name","upgrade","contract"],"type":"object"},"ValidationSlotChange":{"properties":{"address":{"type":"string"},"affects":{"items":{"type":"string"},"type":"array"},"task":{"type":"string"}},"required":["address"],"type":"object"},"ValidationVerdict":{"properties":{"compatible":{"type":"boolean"}},"required":["compatible"],"type":"object"}}}}