Chio/Docs

Workflow

The skill and workflow authority system extends the Chio capability model with multi-step tool compositions, I/O contracts between steps, budget envelopes, and signed workflow receipts. Implementations MUST follow the grant, manifest, receipt, and authority lifecycle described here.

Source

This page normatively reflects spec/WORKFLOW.md in the chio repository. Status: Normative. Version 1.0.


Purpose

A skill is an ordered sequence of tool invocations that composes multiple tools into a single authorized unit of work. The workflow system provides four primitives:

  • SkillGrant. Extends the capability model for ordered tool sequences with budget envelopes and execution limits.
  • SkillManifest. Declares tool dependencies, I/O contracts between steps, and budget requirements.
  • WorkflowReceipt. Captures the complete execution trace as a single signed artifact.
  • WorkflowAuthority. Validates each step against declared scope, ordering, budget, and time constraints.

SkillGrant

A SkillGrant authorizes an agent to execute a named skill. Unlike individual tool grants, a skill grant binds an entire tool sequence under a single authorization with a shared budget envelope.

Schema

FieldTypeRequiredDefaultDescription
schemastringyes--MUST be "chio.skill-grant.v1"
skill_idstringyes--Unique skill identifier
skill_versionstringyes--Version of the skill manifest this grant authorizes
authorized_stepsstring[]yes--Tool steps in declared order; format "server_id:tool_name"
max_executionsu32nonull (unlimited)Maximum number of complete skill executions
budget_envelopeMonetaryAmountnonullBudget for the entire execution
max_duration_secsu64nonullMaximum wall-clock seconds per execution
strict_orderingboolnotrueWhether steps MUST execute in declared order

Step Authorization

A step is authorized if "server_id:tool_name" appears in the authorized_steps list. Invocations of tools not in the list MUST be rejected.

Ordering Modes

When strict_ordering is true (the default), each step MUST execute at index equal to the number of previously completed steps. A step submitted out of order MUST be rejected with StepOutOfOrder.

When strict_ordering is false (relaxed mode), steps may execute in any order. All steps MUST still be in the authorized_steps list.


SkillManifest

A SkillManifest is authored by the skill developer and declares the full execution plan for a skill.

Schema

FieldTypeRequiredDescription
schemastringyesMUST be "chio.skill-manifest.v1"
skill_idstringyesUnique skill identifier
versionstringyesSemantic version
namestringyesHuman-readable name
descriptionstringnoHuman-readable description
stepsSkillStep[]yesOrdered steps in the skill
budget_envelopeMonetaryAmountnoBudget for a single execution
max_duration_secsu64noMaximum wall-clock seconds
authorstringnoAuthor identifier

SkillStep

FieldTypeRequiredDefaultDescription
indexusizeyes--Step index (0-based)
server_idstringyes--Tool server hosting this step's tool
tool_namestringyes--Tool to invoke
labelstringnonullHuman-readable step label
input_contractIoContractnonullInput data contract
output_contractIoContractnonullOutput data contract
budget_limitMonetaryAmountnonullPer-step budget limit
retryableboolnofalseWhether this step can be retried
max_retriesu32nonullMaximum retries (only relevant when retryable is true)

IoContract

The IoContract type describes data flow between steps.

FieldTypeDescription
required_fieldsstring[]Field names required by the step (inputs) or guaranteed (outputs)
produced_fieldsstring[]Field names this step produces
optional_fieldsstring[]Optional field names
json_schemaJSONOptional JSON Schema for the data structure

I/O Contract Validation

Implementations MUST validate that I/O contracts form a consistent data flow:

  • For each step after the first, every field in input_contract.required_fields MUST appear in the output_contract.produced_fields of some preceding step.
  • The first step's input requirements come from the caller, not from preceding steps, and are therefore not validated against the manifest.
  • Violations MUST be reported with the step index, tool name, and missing field name.

Tool Dependencies

The manifest's tool dependencies are the list of "server_id:tool_name" strings derived from each step. The workflow authority uses this list to verify the grant covers all required tools.


WorkflowReceipt

A WorkflowReceipt captures the complete execution of a skill as a single signed artifact.

WorkflowReceiptBody

FieldTypeDescription
idstringUnique receipt ID
schemastringMUST be "chio.workflow-receipt.v1"
started_atu64Unix timestamp when execution started
completed_atu64Unix timestamp when execution completed
skill_idstringSkill ID from the manifest
skill_versionstringSkill version from the manifest
agent_idstringAgent that executed the workflow
session_idstringSession binding (nullable)
capability_idstringCapability that authorized the workflow
outcomeWorkflowOutcomeOverall outcome
stepsStepRecord[]Per-step execution records
total_costMonetaryAmountTotal cost (nullable)
duration_msu64Wall-clock duration in milliseconds
kernel_keyPublicKeyKernel public key

WorkflowReceipt (Signed)

The signed WorkflowReceipt inlines all fields from WorkflowReceiptBody and adds a signature field (Ed25519 signature over canonical JSON of the body). The signature MUST be computed over canonical_json_bytes(body) using RFC 8785 canonical JSON.

WorkflowOutcome

VariantFieldsDescription
Completed--All steps completed successfully
DeniedreasonWorkflow denied before execution started
StepFailedstep_index, reasonA step failed, halting the workflow
BudgetExceededlimit_units, spent_units, currencyBudget envelope exceeded
TimedOutlimit_secs, elapsed_secsTime limit exceeded
CancelledreasonCancelled by agent or operator

StepRecord

FieldTypeDescription
step_indexusizeStep index in the manifest
server_idstringTool server
tool_namestringTool name
allowedboolWhether the step was authorized to execute
tool_receipt_idstringReceipt ID for the underlying tool call (nullable)
outcomeStepOutcomeStep-level outcome
duration_msu64Step duration in milliseconds
costMonetaryAmountCost attributed to this step (nullable)
output_hashstringSHA-256 hash of step output (nullable)

StepOutcome

ValueDescription
successStep completed successfully
deniedStep denied by policy
failedStep failed during execution
skippedStep skipped (workflow aborted before reaching it)

Signature Verification

Verification reconstructs the WorkflowReceiptBody from the receipt fields and verifies the Ed25519 signature over its canonical JSON serialization using the embedded kernel_key. A tampered receipt (any field modified after signing) MUST fail verification.


WorkflowAuthority Lifecycle

The WorkflowAuthority manages the lifecycle of skill executions. It holds the kernel signing key and tracks execution counts for limit enforcement.

begin

text
begin(manifest, grant, agent_id, capability_id, session_id)
  -> Result<WorkflowExecution, WorkflowError>

Preconditions, all of which MUST be checked:

  • grant.skill_id == manifest.skill_id and grant.skill_version == manifest.version. Fail: UnauthorizedSkill.
  • If grant.max_executions is set, execution_count < limit. Fail: ExecutionLimitReached.
  • Every step in the manifest MUST be authorized by the grant. For each step, grant.authorized_steps MUST contain "step.server_id:step.tool_name". Fail: UnauthorizedStep.

On success, returns a WorkflowExecution with:

  • Budget limit from grant.budget_envelope or manifest.budget_envelope (grant takes precedence).
  • Time limit from grant.max_duration_secs or manifest.max_duration_secs (grant takes precedence).
  • active set to true.
  • Empty step_records and zero budget_spent.

validate_step

text
validate_step(execution, step, grant) -> Result<(), WorkflowError>

Preconditions, checked in order:

  • execution.active MUST be true. Fail: InvalidState.
  • The step MUST be authorized by the grant. Fail: UnauthorizedStep.
  • If strict ordering is enabled, step.index == execution.completed_steps(). Fail: StepOutOfOrder.
  • If a time limit is set, elapsed time MUST be less than the limit. Fail: TimeLimitExceeded.

record_step

text
record_step(execution, step, outcome, duration_ms, cost, tool_receipt_id, output_hash)
  -> Result<(), WorkflowError>

Behavior:

  • If execution.active is false, return InvalidState.
  • Add cost.units (if present) to execution.budget_spent using saturating addition.
  • Append a StepRecord to execution.step_records. The record is always appended, even if the budget is about to be exceeded, so the audit trail includes the offending step.
  • After recording, check the budget envelope. If budget_spent > budget_limit.units, set active to false and return BudgetExceeded.
  • If outcome is Failed or Denied, set active to false.

Audit ordering

The step record is written before the budget check so that the finalized receipt contains evidence of the step that triggered the budget breach.

finalize

text
finalize(execution) -> Result<WorkflowReceipt, WorkflowError>

Behavior:

  • Set execution.active to false.
  • Determine the WorkflowOutcome by inspecting step records and budget. If any step has outcome == Failed or outcome == Denied, the outcome is StepFailed. If budget_spent > budget_limit.units, the outcome is BudgetExceeded. Otherwise the outcome is Completed.
  • Construct WorkflowReceiptBody with all execution data.
  • Sign the body: keypair.sign_canonical(body).
  • Increment the authority's execution_count.
  • Return the signed WorkflowReceipt.

WorkflowError

ErrorFieldsDescription
UnauthorizedSkillskill_id, versionGrant does not authorize the requested skill
UnauthorizedStepstep_index, server, toolStep not in the grant's authorized list
StepOutOfOrderstep_index, expectedStep submitted out of sequence
BudgetExceededlimit_units, spent_units, currencyBudget envelope exceeded
TimeLimitExceededelapsed_secs, limit_secsTime limit exceeded
ExecutionLimitReachedlimitMaximum executions reached
InvalidStatemessageWorkflow is not in the correct state
SigningFailedmessageReceipt signing error

Example

A two-step search-and-summarize skill:

skill-manifest.yaml
schema: chio.skill-manifest.v1
skill_id: search-and-summarize
version: "1.0.0"
name: Search and Summarize
steps:
  - index: 0
    server_id: search-srv
    tool_name: search
    label: Search
    output_contract:
      produced_fields: [results]
  - index: 1
    server_id: llm-srv
    tool_name: summarize
    label: Summarize
    input_contract:
      required_fields: [results]
    output_contract:
      produced_fields: [summary]
budget_envelope:
  units: 1000
  currency: USD
skill-grant.yaml
schema: chio.skill-grant.v1
skill_id: search-and-summarize
skill_version: "1.0.0"
authorized_steps:
  - search-srv:search
  - llm-srv:summarize
budget_envelope:
  units: 1000
  currency: USD
max_executions: 10
strict_ordering: true

Execution flow:

  • authority.begin(manifest, grant, agent, capability, session). Validates grant matches manifest, creates execution.
  • authority.validate_step(execution, step_0, grant). Checks authorization, ordering, time.
  • Invoke search-srv:search, collect result.
  • authority.record_step(execution, step_0, Success, 100ms, $0.50). Records cost, checks budget.
  • authority.validate_step(execution, step_1, grant).
  • Invoke llm-srv:summarize, collect result.
  • authority.record_step(execution, step_1, Success, 200ms, $1.00).
  • authority.finalize(execution). Signs receipt, increments count.