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
|
||||
than being forced through MCP `ConnectionConfig`:
|
||||
[`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,
|
||||
encrypted-at-rest file format, and provider-specific display models.
|
||||
- Active specs:
|
||||
- [`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)
|
||||
- [`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)
|
||||
|
||||
## 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_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_server` | Durable server composition boundary around `WorkflowApi` plus optional admin/source-registry surfaces. | 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_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. 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_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. |
|
||||
@@ -33,11 +33,15 @@ paths should go through `wf_server` plus transport/source packages.
|
||||
- `wf_server.WorkflowServer`: durable workflow server composition object.
|
||||
- `wf_transport_rpc_http.RpcWorkflowApiClient`: JSON-RPC client implementing
|
||||
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
|
||||
upstream tools/resources/prompts.
|
||||
- `wf_mcp`: MCP-specific frontend and compatibility package.
|
||||
- `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_planner_catalog()`: backend snapshots plus
|
||||
broker-local workflow sources such as `wf.std` and `wf.mcp`.
|
||||
|
||||
@@ -15,6 +15,7 @@ Related:
|
||||
- [wf_api architecture](../../wf_api_architecture.md)
|
||||
- [wf_mcp architecture](../../wf_mcp_architecture.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)
|
||||
|
||||
## 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