Four-Tool Workflow Protocol
The workflow-engine MCP profile exposes exactly four tools. They are implemented by WorkflowEngineQueryModule in src/rimthan_workflow_mcp/workflow_engine.py, declared by workflow_engine_tool_contracts in tool_contracts.py, and dispatched by server._dispatch_tool. Their schemas are closed (additionalProperties: false) and embed the same JSON Schema contracts served as immutable resources.
This sequence shows the only Rimthan participant protocol. The validator participant is host-native; Rimthan returns instructions and verifies reports but does not run the subagent.
Tool contract surface
| Tool | Implementing method | Purpose | Mutability marker |
|---|---|---|---|
rimthan.start_workflow | WorkflowEngineQueryModule.start_workflow | Select a workflow by ID or alias, validate initial confirmed state and host capabilities, then return the mandatory setup-workspace step. | idempotent=False because it issues a fresh checkpoint token, but it is still read-only with respect to participant files and server state. |
rimthan.continue_workflow | continue_workflow and migrate_workflow | Verify a checkpoint, compare prior and next confirmed state, return one question or one active step, complete ungated steps, or perform explicit release migration. | Read-only server tool with a new checkpoint on advancement. |
rimthan.prepare_step_validation | prepare_step_validation | Validate exact declared JSON or Markdown artifact bytes, path/size/schema/attestation bindings, repository policy, capabilities, and validator requirements. | Does deterministic validation only; no semantic judgment. |
rimthan.submit_step_validation | submit_step_validation | Verify all required validator reports against the signed validation bundle, update artifact and validator receipts, return failure on same step or the next step. | Does not store reports; emits next checkpoint. |
server.create_mcp_application is also the MCP transport trace point. _build_runtime_state selects WorkflowEngineQueryModule and workflow_engine_tool_contracts for scope.profile == "workflow-engine"; the constructor checks every contract with Draft202012Validator.check_schema. The on_list_tools handler returns contract.definition() for the current verified state with private cache scope. The on_call_tool handler looks up the contract by name, validates arguments with _validate_instance, routes checkpoint-bearing calls to the checkpoint's pinned release when needed, calls _dispatch_tool, validates the result with the declared output schema, and emits both canonical JSON text and structuredContent. _dispatch_tool maps only rimthan.start_workflow, rimthan.continue_workflow, rimthan.prepare_step_validation, and rimthan.submit_step_validation to the four WorkflowEngineQueryModule methods; any other name raises METHOD_NOT_FOUND. Domain RegistryError exceptions become structured tool errors via domain_tool_error.
rimthan.start_workflow
start_workflow selects exactly one workflow from registry.workflow_definitions by workflow ID or entry_aliases. If workflow_version is omitted, candidates are sorted by semantic-version-like order and the newest version for the selected workflow owner is used. Alias collisions are rejected earlier by ReleaseLoader._validate_workflow_catalogue.
The call requires:
workflow: ID or alias.workflow_version: optional exact version.confirmed_state: aconfirmed-state-projectionwhosestatevalidates against the workflow'sconfirmed_state_schemaasset.host: harness, adapter ID/version, host capabilities, validator capabilities, and repository policy.
The engine computes a canonical confirmed-state digest and rejects unconfirmed initial fields with confirmation_required. It also calls _host_blockers to bind the host harness to a compatible pinned host adapter and required workflow capabilities. On success it issues sequence 1, current step setup-workspace, no parent checkpoint, no artifact or validator receipts, and a host binding containing only harness, adapter version, sorted capabilities, and sorted validator capabilities.
The response status is active, and the step payload includes the exact step definition, instruction asset, host assets, selected host adapter, validator payloads, and resource references needed by the harness. tests/test_workflow_engine.py::test_complete_stateless_validation_loop_fails_repairs_and_advances proves start returns setup-workspace, includes prompt/skill/subagent assets, and does not leak the objective in the continuation token.
rimthan.continue_workflow
continue_workflow verifies the supplied checkpoint token, reloads the pinned workflow from that checkpoint, validates the prior confirmed-state digest, then validates the proposed next confirmed state. If a state change is present, changed top-level fields must have contemporaneous confirmations; otherwise the tool returns blocked with confirmation_required and keeps the same checkpoint.
If the current step has outputs or validators, the engine does not advance merely because continue_workflow was called. It returns the current step again, optionally with a reissued checkpoint when confirmed state changed. That prevents skipping a gated or artifact-producing step.
If the current step has no outputs and no validators, _next_target evaluates either linear next or closed branch predicates from rimthan_workflow_registry.workflow_engine.resolve_branches:
- exactly one matching branch advances;
- missing predicate fields return
input_requiredwith one question; - no target at a terminal step returns
completed; - multiple matches are rejected during predicate evaluation or authoring validation.
The packaged research-decision@1.2.0 test exercises this behavior: interview and confirm-contract are ungated, route selection asks an input question until research_route is confirmed, then the engine advances to the selected route.
Explicit migration
The same tool schema includes optional migration, but continue_workflow itself refuses migration unless server.create_mcp_application has loaded a separate verified target release with provider.migration_target. _dispatch_migration calls WorkflowEngineQueryModule.migrate_workflow(source, target, arguments).
Migration is fail-closed:
- target release must match the verified target scope;
- target workflow version must be newer;
- target release must differ from the source release;
- every target confirmed-state field must be explicitly confirmed;
- target host capabilities and adapter must pass
_host_blockers; - the preview reports all prior artifacts and validators as invalidated;
- if compatible but not confirmed, status remains
blockedwithmigration_confirmation_required.
A confirmed migration restarts at setup-workspace in the target release with a new checkpoint whose parent is the old checkpoint digest. tests/test_workflow_engine.py::test_checkpoint_migration_previews_impact_then_restarts_on_new_release covers preview and restart semantics.
rimthan.prepare_step_validation
prepare_step_validation is deterministic and must run before any semantic validator. It verifies the checkpoint and confirmed-state digest, loads the current step, then accumulates closed failure objects instead of partially proceeding.
Deterministic checks include:
- repository policy conflict via
repository_policy.conflict; - submitted validator capabilities matching the checkpoint-bound host capabilities;
- required validator capabilities being available;
- artifact count, individual size, total size, declared artifact IDs, media type, schema validation for JSON, maximum bytes, and duplicate/undeclared artifact rejection;
- prior artifact digest bindings for step inputs;
setup-workspacehost attestation, including required prompt/skill/subagent/adapter assets, exact delivery, capabilities, and project-local path contracts;- non-setup output attestation, including symlink-free readback and output path/write-policy bindings.
On deterministic failure it returns deterministic_validation_failed, validation_bundle: null, no validators, and failure codes such as json_schema_failed, workspace_manifest_contract_mismatch, repository_policy_conflict, or output_attestation_required.
On success it builds a validation-bundle token. The bundle includes workflow/release identity, manifest digest, step ID, checkpoint digest, artifact receipts, validator summaries, issue time, signing key ID, and validation_token. The response also returns only validators whose prior pass receipts are absent or stale for the current artifact digest set. This allows validator pass reuse only when inputs are identical.
rimthan.submit_step_validation
submit_step_validation verifies the checkpoint, confirmed-state digest, validation-bundle schema, and HMAC-signed bundle payload. It then requires the submitted report set to match every report_required validator in the bundle exactly. Missing, extra, duplicate, stale, or host-mismatched reports raise WorkflowProtocolError.
For every validator:
- reused validators must have an existing pass receipt whose input digest matches the bundle;
- new reports must match instruction digest and input artifact digests;
validated_by.harnessand adapter version must match the checkpoint host binding;- failed reports collect their findings and keep the same step active;
- passed reports update
validators[validator_id@version]with outcome and input digest.
If any validator fails, the engine issues a new checkpoint on the same step and returns validation_failed with findings. If all pass, it updates artifact receipts, evaluates next transition or question, and returns advanced, input_required, or completed with the next checkpoint.
tests/test_workflow_engine.py::test_complete_stateless_validation_loop_fails_repairs_and_advances proves deterministic failure before semantic validation, report set rejection, wrong-host rejection, failure loop on the same step, failed-validator-only retry, and eventual advancement.
Status vocabulary
| Phase | Statuses |
|---|---|
| Start/continue progression | active, blocked, input_required, completed |
| Preparation | deterministic_validation_failed, ready_for_semantic_validation |
| Submission | validation_failed, input_required, advanced, completed |
Focused validation
- Four-tool MCP surface and exact workflow resources:
uv run pytest tests/test_workflow_engine.py -k four_tools - Full protocol loop:
uv run pytest tests/test_workflow_engine.py -k complete_stateless_validation_loop - Packaged MVP workflow:
uv run pytest tests/test_workflow_engine.py -k packaged_research_workflow_executes_every_mvp_gate - Pinned release resume and corrupt refresh behavior:
uv run pytest tests/test_workflow_engine.py -k "pinned_release or corrupt_active_refresh"