docs: define server CLI transport boundary
This commit is contained in:
@@ -81,12 +81,16 @@ auth admin are implemented. The next work is polish, not new broad surfaces.
|
|||||||
- New source families should follow the generic runtime source lifecycle rather
|
- New source families should follow the generic runtime source lifecycle rather
|
||||||
than being forced through MCP `ConnectionConfig`:
|
than being forced through MCP `ConnectionConfig`:
|
||||||
[`runtime source lifecycle`](superpowers/specs/2026-06-09-runtime-source-lifecycle.md).
|
[`runtime source lifecycle`](superpowers/specs/2026-06-09-runtime-source-lifecycle.md).
|
||||||
|
- Server startup policy should move out of the JSON-RPC transport package and
|
||||||
|
into `wf_server` before adding more hosted transports:
|
||||||
|
[`server CLI and transport boundary`](superpowers/specs/2026-06-10-server-cli-transport-boundary.md).
|
||||||
- Deferred auth work: OAuth/OIDC, production secret manager integration,
|
- Deferred auth work: OAuth/OIDC, production secret manager integration,
|
||||||
encrypted-at-rest file format, and provider-specific display models.
|
encrypted-at-rest file format, and provider-specific display models.
|
||||||
- Active specs:
|
- Active specs:
|
||||||
- [`workflow config targets and sources`](superpowers/specs/2026-06-03-workflow-config-targets-and-sources.md)
|
- [`workflow config targets and sources`](superpowers/specs/2026-06-03-workflow-config-targets-and-sources.md)
|
||||||
- [`store-backed source registry`](superpowers/specs/2026-06-03-store-backed-source-registry-design.md)
|
- [`store-backed source registry`](superpowers/specs/2026-06-03-store-backed-source-registry-design.md)
|
||||||
- [`runtime source lifecycle`](superpowers/specs/2026-06-09-runtime-source-lifecycle.md)
|
- [`runtime source lifecycle`](superpowers/specs/2026-06-09-runtime-source-lifecycle.md)
|
||||||
|
- [`server CLI and transport boundary`](superpowers/specs/2026-06-10-server-cli-transport-boundary.md)
|
||||||
- [`auth/source secrets boundary`](superpowers/specs/2026-06-06-auth-source-secrets-boundary.md)
|
- [`auth/source secrets boundary`](superpowers/specs/2026-06-06-auth-source-secrets-boundary.md)
|
||||||
|
|
||||||
## Priority 4: MCP Package Split Finish Line
|
## Priority 4: MCP Package Split Finish Line
|
||||||
|
|||||||
+7
-3
@@ -11,8 +11,8 @@ paths should go through `wf_server` plus transport/source packages.
|
|||||||
| `wf_core` | Deterministic workflow kernel: models, validation, runtime, run state, traces, interrupts, foreach, and path/state operations. | Runtime users, `wf_authoring`, workflow adapters. |
|
| `wf_core` | Deterministic workflow kernel: models, validation, runtime, run state, traces, interrupts, foreach, and path/state operations. | Runtime users, `wf_authoring`, workflow adapters. |
|
||||||
| `wf_authoring` | Ergonomic workflow construction: `@node`, `NodeSpec`, builder DSL, conditions, path helpers, reusable ops, subgraph nodes. | Humans, tests, future LLM workflow builders. |
|
| `wf_authoring` | Ergonomic workflow construction: `@node`, `NodeSpec`, builder DSL, conditions, path helpers, reusable ops, subgraph nodes. | Humans, tests, future LLM workflow builders. |
|
||||||
| `wf_api` | Workflow application surface over core/artifacts/platform: capabilities, drafts, artifacts, deployments, runs, and source/admin surfaces. | `wf_cli`, `wf_server`, JSON-RPC clients, future transports. |
|
| `wf_api` | Workflow application surface over core/artifacts/platform: capabilities, drafts, artifacts, deployments, runs, and source/admin surfaces. | `wf_cli`, `wf_server`, JSON-RPC clients, future transports. |
|
||||||
| `wf_server` | Durable server composition boundary around `WorkflowApi` plus optional admin/source-registry surfaces. | Transport packages and server startup code. |
|
| `wf_server` | Durable server composition boundary around `WorkflowApi` plus optional admin/source-registry surfaces. Target home for server startup CLI/policy. | Transport packages and server startup code. |
|
||||||
| `wf_transport_rpc_http` | JSON-RPC-over-HTTP app/client and `wf-rpc-server` CLI. | Remote `wf` clients and local server smoke tests. |
|
| `wf_transport_rpc_http` | JSON-RPC-over-HTTP app/client. The current `wf-rpc-server` CLI is slated to move to `wf_server` with a compatibility shim. | Remote `wf` clients and local server smoke tests. |
|
||||||
| `wf_sources_mcp` | MCP-as-upstream-source implementation: ids, registry DTOs, auth/catalog stores, discovery, SDK client/facade, runtime pool, wrappers. | `wf_server`, broker glue, MCP source tests. |
|
| `wf_sources_mcp` | MCP-as-upstream-source implementation: ids, registry DTOs, auth/catalog stores, discovery, SDK client/facade, runtime pool, wrappers. | `wf_server`, broker glue, MCP source tests. |
|
||||||
| `wf_mcp` | MCP frontend/compatibility package: legacy `wf-mcp` entrypoints, broker glue, proxy/admin tools, and shims while extraction continues. | Compatibility callers and MCP transport work. |
|
| `wf_mcp` | MCP frontend/compatibility package: legacy `wf-mcp` entrypoints, broker glue, proxy/admin tools, and shims while extraction continues. | Compatibility callers and MCP transport work. |
|
||||||
| `wf_cli` | Command-line frontend over local or remote workflow APIs. | Humans, scripts, agent skills. |
|
| `wf_cli` | Command-line frontend over local or remote workflow APIs. | Humans, scripts, agent skills. |
|
||||||
@@ -33,11 +33,15 @@ paths should go through `wf_server` plus transport/source packages.
|
|||||||
- `wf_server.WorkflowServer`: durable workflow server composition object.
|
- `wf_server.WorkflowServer`: durable workflow server composition object.
|
||||||
- `wf_transport_rpc_http.RpcWorkflowApiClient`: JSON-RPC client implementing
|
- `wf_transport_rpc_http.RpcWorkflowApiClient`: JSON-RPC client implementing
|
||||||
the workflow/admin surfaces over HTTP.
|
the workflow/admin surfaces over HTTP.
|
||||||
|
- `wf_transport_rpc_http.create_rpc_app`: JSON-RPC HTTP adapter over an existing
|
||||||
|
`WorkflowServer`.
|
||||||
- `wf_sources_mcp.McpRuntimePool`: persistent MCP source runtime for stateful
|
- `wf_sources_mcp.McpRuntimePool`: persistent MCP source runtime for stateful
|
||||||
upstream tools/resources/prompts.
|
upstream tools/resources/prompts.
|
||||||
- `wf_mcp`: MCP-specific frontend and compatibility package.
|
- `wf_mcp`: MCP-specific frontend and compatibility package.
|
||||||
- `wf-mcp`: legacy/special-purpose MCP script from `pyproject.toml`.
|
- `wf-mcp`: legacy/special-purpose MCP script from `pyproject.toml`.
|
||||||
- `wf-rpc-server`: preferred durable workflow server script for CLI/API clients.
|
- `wf-rpc-server`: preferred durable workflow server script for CLI/API clients;
|
||||||
|
currently implemented in `wf_transport_rpc_http.cli`, but the target owner is
|
||||||
|
`wf_server.cli`.
|
||||||
- `wf_mcp.broker.WfMcpService.get_catalog()`: backend MCP catalog snapshots.
|
- `wf_mcp.broker.WfMcpService.get_catalog()`: backend MCP catalog snapshots.
|
||||||
- `wf_mcp.broker.WfMcpService.get_planner_catalog()`: backend snapshots plus
|
- `wf_mcp.broker.WfMcpService.get_planner_catalog()`: backend snapshots plus
|
||||||
broker-local workflow sources such as `wf.std` and `wf.mcp`.
|
broker-local workflow sources such as `wf.std` and `wf.mcp`.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Related:
|
|||||||
- [wf_api architecture](../../wf_api_architecture.md)
|
- [wf_api architecture](../../wf_api_architecture.md)
|
||||||
- [wf_mcp architecture](../../wf_mcp_architecture.md)
|
- [wf_mcp architecture](../../wf_mcp_architecture.md)
|
||||||
- [Persisted run/resume contract](./2026-06-03-persisted-run-resume-contract.md)
|
- [Persisted run/resume contract](./2026-06-03-persisted-run-resume-contract.md)
|
||||||
|
- [Server CLI and transport boundary](./2026-06-10-server-cli-transport-boundary.md)
|
||||||
- [Current roadmap](../../current_roadmap.md)
|
- [Current roadmap](../../current_roadmap.md)
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
# Server CLI And Transport Boundary
|
||||||
|
|
||||||
|
Date: 2026-06-10
|
||||||
|
|
||||||
|
Status: design direction; implementation not started
|
||||||
|
|
||||||
|
Related:
|
||||||
|
|
||||||
|
- [Long-lived workflow API boundary](./2026-06-03-long-lived-workflow-api-boundary.md)
|
||||||
|
- [Runtime source lifecycle](./2026-06-09-runtime-source-lifecycle.md)
|
||||||
|
- [Workflow config targets and sources](./2026-06-03-workflow-config-targets-and-sources.md)
|
||||||
|
- [Project map](../../project_map.md)
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
`wf-rpc-server` currently lives in `wf_transport_rpc_http.cli`, but the module
|
||||||
|
does more than transport work. It parses server startup config, selects local
|
||||||
|
static vs MCP-backed composition, handles legacy `--mcp-config`, and starts the
|
||||||
|
JSON-RPC HTTP transport.
|
||||||
|
|
||||||
|
That made sense while JSON-RPC was the only long-lived server path. It is now
|
||||||
|
the wrong long-term ownership. Server composition belongs in `wf_server`; HTTP
|
||||||
|
JSON-RPC should stay a transport adapter around an already-built
|
||||||
|
`WorkflowServer`.
|
||||||
|
|
||||||
|
## Ownership Rule
|
||||||
|
|
||||||
|
```text
|
||||||
|
wf_server
|
||||||
|
owns process startup policy
|
||||||
|
owns WorkflowServer composition from wf_config / legacy inputs
|
||||||
|
decides which transports to host
|
||||||
|
|
||||||
|
wf_transport_rpc_http
|
||||||
|
owns JSON-RPC HTTP app/client/envelope code
|
||||||
|
owns create_rpc_app(server)
|
||||||
|
may provide a small serve helper for an already-built WorkflowServer
|
||||||
|
```
|
||||||
|
|
||||||
|
The script name can remain `wf-rpc-server` for compatibility, but its entrypoint
|
||||||
|
should eventually point at `wf_server.cli:main`.
|
||||||
|
|
||||||
|
## Current Shape
|
||||||
|
|
||||||
|
Current script registration:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
wf-rpc-server = "wf_transport_rpc_http.cli:main"
|
||||||
|
```
|
||||||
|
|
||||||
|
Current responsibilities inside `wf_transport_rpc_http.cli`:
|
||||||
|
|
||||||
|
- parse `--config`
|
||||||
|
- parse `--store-root`
|
||||||
|
- parse legacy `--mcp-config`
|
||||||
|
- load neutral `wf_config`
|
||||||
|
- detect MCP sources
|
||||||
|
- select local/static or MCP-backed `WorkflowServer`
|
||||||
|
- select RPC bind host/port/path
|
||||||
|
- call `create_rpc_app(server)`
|
||||||
|
- call `uvicorn.run(...)`
|
||||||
|
|
||||||
|
Only the last two bullets are transport-specific.
|
||||||
|
|
||||||
|
## Desired Shape
|
||||||
|
|
||||||
|
Recommended first refactor:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/wf_server/cli.py
|
||||||
|
Typer app for durable server startup
|
||||||
|
parses config and startup overrides
|
||||||
|
builds WorkflowServer through wf_server.config
|
||||||
|
starts configured transports
|
||||||
|
|
||||||
|
src/wf_transport_rpc_http/cli.py
|
||||||
|
compatibility shim:
|
||||||
|
from wf_server.cli import app, main
|
||||||
|
|
||||||
|
src/wf_transport_rpc_http/app.py
|
||||||
|
unchanged create_rpc_app(server, rpc_path="/rpc")
|
||||||
|
```
|
||||||
|
|
||||||
|
Updated script registration:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
wf-rpc-server = "wf_server.cli:main"
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep `wf_transport_rpc_http.cli` temporarily so tests and imports do not break
|
||||||
|
immediately.
|
||||||
|
|
||||||
|
## Why Not Move `create_rpc_app`
|
||||||
|
|
||||||
|
`create_rpc_app(server)` is transport code:
|
||||||
|
|
||||||
|
- JSON-RPC route and method registration
|
||||||
|
- JSON-RPC error mapping
|
||||||
|
- HTTP health endpoint
|
||||||
|
- FastAPI/fastapi-jsonrpc object construction
|
||||||
|
|
||||||
|
It should stay in `wf_transport_rpc_http`. Future transports should have their
|
||||||
|
own equivalent adapter over `WorkflowServer`.
|
||||||
|
|
||||||
|
## Why Move The Typer Entrypoint
|
||||||
|
|
||||||
|
The Typer entrypoint answers process-level questions:
|
||||||
|
|
||||||
|
- Which config file is used?
|
||||||
|
- Is this local/static or MCP-backed?
|
||||||
|
- Are source providers loaded from neutral config?
|
||||||
|
- Is legacy config accepted?
|
||||||
|
- Which transports are hosted?
|
||||||
|
- Which store roles are used?
|
||||||
|
|
||||||
|
Those questions are server composition policy. They should not live in an HTTP
|
||||||
|
transport package because the same process may later host JSON-RPC HTTP, MCP
|
||||||
|
HTTP, WebSocket, or other transports together.
|
||||||
|
|
||||||
|
## Compatibility Policy
|
||||||
|
|
||||||
|
- Keep the command name `wf-rpc-server` during the move.
|
||||||
|
- Keep `wf_transport_rpc_http.cli.app` and `.main` as re-export shims for one
|
||||||
|
compatibility window.
|
||||||
|
- Update tests to target `wf_server.cli` for behavior.
|
||||||
|
- Keep one compatibility test proving the old import path is identity-equal.
|
||||||
|
- Do not change runtime behavior in the move slice.
|
||||||
|
|
||||||
|
## First Implementation Slice
|
||||||
|
|
||||||
|
The first slice should be a pure move/refactor:
|
||||||
|
|
||||||
|
1. Create `src/wf_server/cli.py` by moving the current implementation from
|
||||||
|
`src/wf_transport_rpc_http/cli.py`.
|
||||||
|
2. Replace `src/wf_transport_rpc_http/cli.py` with:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from wf_server.cli import app, main
|
||||||
|
|
||||||
|
__all__ = ["app", "main"]
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Update `pyproject.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
wf-rpc-server = "wf_server.cli:main"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Move CLI behavior tests from `tests/wf_transport_rpc_http/test_cli.py` to a
|
||||||
|
server-focused test module, for example `tests/wf_server/test_cli.py`.
|
||||||
|
5. Update monkeypatch targets from `wf_transport_rpc_http.cli...` to
|
||||||
|
`wf_server.cli...`.
|
||||||
|
6. Add a compatibility import test for `wf_transport_rpc_http.cli`.
|
||||||
|
7. Update docs and project map.
|
||||||
|
|
||||||
|
## Non-Goals
|
||||||
|
|
||||||
|
- Do not add WebSocket, MCP HTTP, or multi-transport hosting in the move slice.
|
||||||
|
- Do not change `create_rpc_app`.
|
||||||
|
- Do not remove the `wf_transport_rpc_http.cli` shim immediately.
|
||||||
|
- Do not redesign `wf_config`.
|
||||||
|
- Do not change `wf` client targeting behavior.
|
||||||
|
|
||||||
|
## Future Follow-Up
|
||||||
|
|
||||||
|
After the move, `wf_server.cli` can grow toward multi-transport hosting:
|
||||||
|
|
||||||
|
```text
|
||||||
|
wf-server --config wf.config.json
|
||||||
|
hosts server.transports[] from config
|
||||||
|
```
|
||||||
|
|
||||||
|
`wf-rpc-server` can remain as an alias or convenience command for the RPC-only
|
||||||
|
case. The important boundary is that server startup composes transports; a
|
||||||
|
transport package does not compose the server.
|
||||||
Reference in New Issue
Block a user