Development, Testing, and Deployment
This repository combines Python backend packages, a Next.js Workflow Studio, JSON Schemas, PostgreSQL migrations, deployment manifests, and tests. Use this page to route validation from a change intent to the narrowest meaningful check.
Backend setup
The backend requires Python 3.11 or newer and uses uv.
uv sync --all-groups --extra backend --extra mcp
uv run pytestProject scripts from pyproject.toml:
| Script | Entrypoint | Use |
|---|---|---|
rimthan-workflow | rimthan_workflow_registry.cli:main | Legacy local registry, schema, materialization, progress, pilot, and release verification CLI. |
rimthan-research-render | rimthan_research_runner.cli:main | Deterministic static HTML rendering for research artifacts. |
rimthan-sign-manifest | rimthan_workflow_registry.signing:main | Sign manifest files outside Admin API. |
rimthan-workflow-mcp | rimthan_workflow_mcp.server:main | Local stdio MCP adapter. |
rimthan-workflow-mcp-http | rimthan_workflow_mcp.http_server:main | Remote Streamable HTTP MCP service. |
rimthan-workflow-bootstrap-http | rimthan_workflow_mcp.bootstrap_server:main | Authenticated immutable wheel distribution for old bootstrap flows. |
rimthan-admin-api | rimthan_admin_api.server:main | Admin API and publication service. |
Frontend setup
Workflow Studio lives in apps/admin-web.
cd apps/admin-web
pnpm install --frozen-lockfile
pnpm typecheck
pnpm build
pnpm test:e2eThe Studio uses Next.js, React, Shadcn/Radix components, React Flow, Dagre, Tailwind, and Playwright.
Focused test routing
| Change intent | Primary source areas | Focused tests | Minimal validation |
|---|---|---|---|
| Four-tool protocol behavior | src/rimthan_workflow_mcp/workflow_engine.py, tool_contracts.py, server.py | tests/test_workflow_engine.py | uv run pytest tests/test_workflow_engine.py -k complete_stateless_validation_loop |
| Checkpoint signing, rotation, resume | workflow_engine.py, http_server.py, server.py | tests/test_workflow_engine.py | uv run pytest tests/test_workflow_engine.py -k "checkpoint or pinned_release" |
| Resources/prompts/host adapters | resources.py, prompts.py, workflow_engine.py, starter draft | tests/test_workflow_engine.py, tests/test_mcp.py | uv run pytest tests/test_workflow_engine.py -k "resources or adapter" |
| Engine draft schema/invariants | src/rimthan_workflow_registry/workflow_engine.py, schemas/ | tests/test_workflow_engine.py, tests/test_schema_validation.py | uv run pytest tests/test_schema_validation.py tests/test_workflow_engine.py -k engine_draft |
| Publication compiler | src/rimthan_publication/compiler.py, service.py, signer.py | tests/test_workflow_publication.py, tests/test_workflow_engine.py | uv run pytest tests/test_workflow_publication.py tests/test_workflow_engine.py -k compiles |
| PostgreSQL migrations/store | store.py, migrations/*.sql | tests/test_postgres_publication_e2e.py | RIMTHAN_TEST_POSTGRES_DSN=... uv run pytest tests/test_postgres_publication_e2e.py |
| Admin API | src/rimthan_admin_api/server.py | tests/test_admin_api.py | RIMTHAN_TEST_ADMIN_POSTGRES_DSN=... uv run pytest tests/test_admin_api.py |
| Workflow Studio UI | apps/admin-web/app, components, lib | apps/admin-web/tests/studio.spec.ts | cd apps/admin-web && pnpm typecheck && pnpm test:e2e |
| Release trust/loader | loader.py, trust.py, schemas.py | tests/test_loader.py, tests/test_trust.py | uv run pytest tests/test_loader.py tests/test_trust.py |
| Legacy local registry/pilot | resolver.py, materializer.py, progress.py, revision.py, participant.py, pilot.py, renderer.py | legacy-focused test files | uv run pytest tests/test_resolver.py tests/test_materializer.py tests/test_progress.py tests/test_revision.py tests/test_participant.py tests/test_pilot.py |
Optional PostgreSQL integration
PostgreSQL tests are skipped unless DSNs are configured:
RIMTHAN_TEST_POSTGRES_DSNfor store/publication E2E;RIMTHAN_TEST_ADMIN_POSTGRES_DSNfor Admin API plus MCP integration.
The tests apply migrations and exercise real tables, roles, channels, triggers, release loading, and MCP refresh. Use isolated disposable databases; migrations include immutable triggers and role grants.
Deployment topology
The maintained staging contract is docs/operations/workflow-studio-staging.md, with public non-secret environment names in deploy/workflow-studio/env.example. The topology has:
- PostgreSQL with no public port;
- Admin API and signer container;
- read-only workflow-engine MCP container;
- Next.js Studio container.
Application containers should be unprivileged, drop Linux capabilities, use only the proxy network, and have no host/project mounts. PostgreSQL alone needs its data volume.
Environment groups
Admin API:
RIMTHAN_ADMIN_PUBLIC_URLRIMTHAN_ADMIN_DATABASE_URLRIMTHAN_ADMIN_BEARER_TOKENRIMTHAN_ADMIN_ALLOWED_ORIGINSRIMTHAN_PUBLICATION_SIGNING_KEY_IDRIMTHAN_PUBLICATION_ED25519_PRIVATE_KEY_B64
Read-only MCP:
RIMTHAN_MCP_PUBLIC_URLRIMTHAN_MCP_DATABASE_URLRIMTHAN_MCP_BEARER_TOKENfor staging bearer mode, or OIDC variables instead;RIMTHAN_MCP_ALLOWED_ORIGINSRIMTHAN_MCP_PROFILE=workflow-engineRIMTHAN_MCP_SURFACERIMTHAN_MCP_REGISTRY_CHANNELRIMTHAN_MCP_TRUST_ROOT_JSONRIMTHAN_WORKFLOW_SIGNING_SECRETRIMTHAN_WORKFLOW_SIGNING_KEY_IDRIMTHAN_WORKFLOW_VERIFICATION_KEYS_JSON
Studio BFF:
STUDIO_PUBLIC_ORIGINSTUDIO_ACCESS_TOKENADMIN_API_URLADMIN_API_BEARER_TOKEN
Keep database URLs, bearer tokens, session tokens, checkpoint secrets, and Ed25519 private keys in deployment secret storage, not Git.
Auth modes
MCP HTTP supports either private bearer mode or OIDC/JWT mode. They are mutually exclusive: configuring OAuth issuer while also setting a bearer token fails. OIDC mode validates HTTPS issuer/JWKS URLs, audience, expiry, subject, organization claim/value, signature, and required scope before MCP dispatch. Staging still uses private bearer for synthetic acceptance; organization OIDC is a release gate.
Bootstrap distribution service
src/rimthan_workflow_mcp/bootstrap_server.py and the rimthan-workflow-bootstrap-http script serve an authenticated immutable wheel manifest and package for older agent-driven MCP bootstrap flows. BootstrapDistributionConfig requires an origin-only HTTPS public URL, a long bearer token, and an artifact directory. BootstrapDistribution.load accepts exactly one wheel matching the current package version, rejects symlinks and path escapes, bounds size, calculates SHA-256, validates bootstrap-install-manifest, and serves no-cache responses through Starlette. This service is operationally separate from the current participant workflow-engine contract, whose bootstrap paragraph explicitly says not to install or launch participant-local Rimthan software.
Focused validation: uv run pytest tests/test_bootstrap_distribution.py.
Release gates and current limits
Current docs identify open gates:
- organization OIDC configuration for participant MCP;
- fresh-host one-paste acceptance in Codex, Claude Code, Cowork, and Buzz;
- independently authenticated device/user handoff;
- real participant usefulness run;
- accountable approval of the participant data perimeter;
- PostgreSQL backup/PITR hardening;
- signer isolation beyond the Admin API process.
Do not claim production participant readiness from private synthetic staging alone.