Participant Architecture
Rimthan's current product is a stateless MCP workflow engine. Administrators author workflow content centrally, publish immutable releases, and expose only read-only progression and validation tools to participant agent harnesses. The participant's existing harness writes files, runs tools, and invokes native subagents; Rimthan never installs a runtime into the participant repository and never executes participant work.
This page is the canonical architecture boundary. The older local registry, materializer, operator MCP, and pilot tools still exist, but they are covered separately in Legacy Local Registry and Pilot and must not be treated as the current participant architecture.
This diagram shows the write plane ending at publication and the participant action plane staying outside Rimthan.
Authoring and publication plane
Workflow authoring starts in apps/admin-web/app/page.tsx, which loads drafts, modules, assets, validators, releases, and channels through lib/api.ts. Browser calls go to /api/backend/*; that server-side BFF proxies to the Admin API using ADMIN_API_URL and ADMIN_API_BEARER_TOKEN, so backend credentials are not exposed to browser JavaScript. Studio session state is separate and handled by apps/admin-web/app/api/session/route.ts with an HttpOnly rimthan_studio_session cookie and STUDIO_ACCESS_TOKEN.
The Admin API entrypoint is rimthan_admin_api.server:create_admin_app, exposed by the rimthan-admin-api script. AdminApiConfig.from_environment fails closed unless it has an exact HTTPS public origin, PostgreSQL URL, long bearer token, signing key ID, and Ed25519 private key. AdminAuthAndLimitMiddleware applies bearer auth, request-size limiting, Cache-Control: private, no-store, X-Content-Type-Options: nosniff, and X-Frame-Options: DENY to protected routes.
The write path uses PostgresRegistryStore for mutable draft heads and append-only history, PublicationService for idempotent publication jobs, WorkflowEngineDraftCompiler for aggregate step-gate releases, and Ed25519ManifestSigner for signed manifests. See Admin API, Publication Pipeline, and PostgreSQL Store.
Read-only MCP delivery plane
The current participant profile is selected by McpScope.profile == "workflow-engine". In rimthan_workflow_mcp.server._build_runtime_state, that profile requires a WorkflowTokenSigner, constructs WorkflowEngineQueryModule, and exposes exactly the four workflow tools declared by workflow_engine_tool_contracts:
rimthan.start_workflowrimthan.continue_workflowrimthan.prepare_step_validationrimthan.submit_step_validation
All tool definitions set readOnlyHint=True, destructiveHint=False, and openWorldHint=False; this describes the MCP server's authority, not the participant harness's local actions. The server also serves immutable Resources from ImmutableResourceCatalogue, including workflow definitions, steps, assets, validators, schemas, manifest, summary, and rimthan://bootstrap/agent-entrypoint. The workflow-engine profile intentionally does not expose legacy module or pilot resources.
HTTP deployment uses rimthan_workflow_mcp.http_server:RemoteHttpConfig and create_http_app. It supports private bearer mode or mutually exclusive OIDC/JWT mode. Database-backed MCP requires RIMTHAN_MCP_TRUST_ROOT_JSON; the service verifies a complete active release before replacing its in-memory scope and retains the last-good scope when refresh fails.
Participant action plane
The participant harness controls all local side effects. The canonical bootstrap paragraph in docs/operations/workflow-engine-bootstrap.md instructs hosts to register the remote MCP endpoint, discover exactly the four tools, start a workflow, create only declared project-relative outputs, run semantic validators as separate native subagents, submit structured reports, and atomically persist checkpoints to .rimthan/workflow-session.json.
Rimthan's outputs are instructions and contracts. Markdown assets, prompts, skills, and subagent definitions do not authorize filesystem, network, credential, deployment, or tool access. System, user, repository, and host policies outrank served content; repository-policy conflicts are represented as closed failure/blocker codes.
Core invariants
| Invariant | Owner | Evidence |
|---|---|---|
| Participant MCP writes no project files and stores no participant session rows. | WorkflowEngineQueryModule, HTTP app, docs | workflow_engine.py; docs/operations/participant-data-perimeter.md; tests/test_workflow_engine.py::test_participant_artifacts_and_findings_are_transient_and_not_checkpointed |
| One workflow step or one confirmed-state question is active at a time. | continue_workflow, submit_step_validation | workflow_engine.py; rimthan_workflow_registry.workflow_engine.resolve_branches; complete packaged workflow test |
| Published content is immutable and digest-pinned. | Compiler, store, migrations, loader | WorkflowEngineDraftCompiler._merge_immutable_identity; migrations 0004 and 0005; ReleaseLoader |
| Admin writes are not MCP tools. | Admin API and MCP adapters | server.py switches by profile; tests/test_mcp.py; tests/test_workflow_engine.py::test_mcp_workflow_engine_profile_exposes_four_tools_and_exact_resources |
| Active releases verify against a configured trust root before MCP delivery. | Store, loader, trust module | McpScope.load, PostgresRegistryStore.load_active_release, verify_manifest_signatures |
Focused validation
- Backend full suite:
uv run pytest - Workflow-engine protocol:
uv run pytest tests/test_workflow_engine.py - Admin/publication database integration when DSNs are configured:
uv run pytest tests/test_admin_api.py tests/test_postgres_publication_e2e.py - Studio type/build/e2e:
cd apps/admin-web && pnpm typecheck && pnpm build && pnpm test:e2e