28 KiB
Source Auth Diagnostics Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Add source-level auth and health diagnostics so users can tell whether a source is configured, authenticated, catalogued, and safe to call before running wf cap call.
Architecture: Keep wf_api neutral by adding an optional source diagnostics provider to WorkflowSourceAdminApi. Implement MCP-specific checks in wf_mcp.broker.service.source_diagnostics, wire that provider into MCP-backed WorkflowServer, and expose diagnostics over JSON-RPC and CLI via wf source diagnose. source inspect should include a compact diagnostics block when a provider exists, but local/static servers must keep working without MCP imports.
Tech Stack: Python 3.14, dataclasses/protocols, Pydantic JSON-RPC params, Typer CLI, pytest-asyncio, existing AuthRecord/StoredAuthRecord and MCP broker services.
File Structure
- Modify
src/wf_api/source_admin.py: addWorkflowSourceDiagnosticsProviderprotocol, optionaldiagnosticsprovider,diagnose_source(), and optional diagnostics ininspect_source(). - Modify
src/wf_api/surface.py: adddiagnose_source()toWorkflowSourceAdminSurface. - Create
src/wf_mcp/broker/service/source_diagnostics.py: MCP-specific diagnostics provider. - Modify
src/wf_mcp/broker/server.py: wire diagnostics provider when building MCP-backed server. - Modify
src/wf_transport_rpc_http/models.py: addDiagnoseSourceParams. - Modify
src/wf_transport_rpc_http/methods/sources.py: registerworkflow.sources.diagnose. - Modify
src/wf_transport_rpc_http/client/sources.py: adddiagnose_source(). - Modify
src/wf_cli/commands/sources.py: addwf source diagnose <source_id>. - Add/modify tests:
tests/wf_api/test_source_admin_api.pytests/wf_mcp/service/test_source_diagnostics.pytests/wf_mcp/test_mcp_workflow_server.pytests/wf_transport_rpc_http/test_app.pytests/wf_transport_rpc_http/test_client.pytests/wf_cli/test_remote_target.py
- Modify docs:
docs/wf_cli.mddocs/current_roadmap.md
Task 1: Neutral Source Diagnostics API
Files:
-
Modify:
src/wf_api/source_admin.py -
Modify:
src/wf_api/surface.py -
Test:
tests/wf_api/test_source_admin_api.py -
Step 1: Write neutral API tests
Create tests/wf_api/test_source_admin_api.py if it does not exist. Add:
from __future__ import annotations
import pytest
from wf_api.operation_context import WorkflowOperationContext
from wf_api.source_admin import WorkflowSourceAdminApi
from wf_api.stores import memory_workflow_stores
from wf_platform import CapabilityBuckets, CapabilitySource
class _Specs:
def __init__(self) -> None:
self.capability_sources = {
"demo.source": CapabilitySource(
id="demo.source",
kind="connection",
capabilities=CapabilityBuckets(),
description="Demo source",
)
}
def get_qualified_spec(self, qualified_name: str):
raise KeyError(qualified_name)
class _Diagnostics:
def __init__(self) -> None:
self.calls: list[str] = []
def diagnose_source(self, source_id: str) -> dict[str, object]:
self.calls.append(source_id)
return {
"source_id": source_id,
"status": "ok",
"auth": {"record_present": True},
"diagnostics": [],
}
def _api(*, diagnostics: object | None = None) -> WorkflowSourceAdminApi:
stores = memory_workflow_stores()
context = WorkflowOperationContext(
artifact_store=stores.artifact_store,
draft_workspace_store=stores.draft_workspace_store,
run_store=stores.run_store,
events=None,
specs=_Specs(),
runtime=None,
live_sources=None,
)
return WorkflowSourceAdminApi(context, diagnostics=diagnostics)
@pytest.mark.asyncio
async def test_inspect_source_includes_optional_diagnostics() -> None:
provider = _Diagnostics()
payload = await _api(diagnostics=provider).inspect_source(
source_id="demo.source"
)
assert payload["id"] == "demo.source"
assert payload["diagnostics"]["source_id"] == "demo.source"
assert provider.calls == ["demo.source"]
@pytest.mark.asyncio
async def test_inspect_source_omits_diagnostics_without_provider() -> None:
payload = await _api().inspect_source(source_id="demo.source")
assert payload["id"] == "demo.source"
assert "diagnostics" not in payload
@pytest.mark.asyncio
async def test_diagnose_source_uses_provider() -> None:
payload = await _api(diagnostics=_Diagnostics()).diagnose_source(
source_id="demo.source"
)
assert payload["status"] == "ok"
assert payload["auth"]["record_present"] is True
@pytest.mark.asyncio
async def test_diagnose_source_without_provider_returns_basic_status() -> None:
payload = await _api().diagnose_source(source_id="demo.source")
assert payload == {
"source_id": "demo.source",
"status": "unknown",
"diagnostics": [],
"message": "No source diagnostics provider is configured.",
}
- Step 2: Run tests and confirm failure
Run:
uv run pytest tests/wf_api/test_source_admin_api.py -q
Expected: fails because WorkflowSourceAdminApi.__init__() has no diagnostics argument and diagnose_source() does not exist.
- Step 3: Implement neutral protocol and API
In src/wf_api/source_admin.py, add:
from typing import Any, Protocol
Then add above WorkflowSourceAdminApi:
class WorkflowSourceDiagnosticsProvider(Protocol):
"""Optional source-specific diagnostics provider.
Implementations may know about transport/auth/catalog details. The neutral
API only forwards source ids and serializes returned dictionaries.
"""
def diagnose_source(self, source_id: str) -> dict[str, Any]: ...
Change the constructor:
def __init__(
self,
context: WorkflowOperationContext,
*,
diagnostics: WorkflowSourceDiagnosticsProvider | None = None,
) -> None:
self.context = context
self.diagnostics = diagnostics
Change inspect_source() to:
async def inspect_source(self, *, source_id: str) -> dict[str, Any]:
try:
source = self.context.specs.capability_sources[source_id]
except KeyError as exc:
raise KeyError(f"unknown source {source_id!r}") from exc
payload = source.as_inventory().model_dump(mode="json")
if self.diagnostics is not None:
payload["diagnostics"] = self.diagnostics.diagnose_source(source_id)
return payload
Add:
async def diagnose_source(self, *, source_id: str) -> dict[str, Any]:
try:
self.context.specs.capability_sources[source_id]
except KeyError as exc:
raise KeyError(f"unknown source {source_id!r}") from exc
if self.diagnostics is None:
return {
"source_id": source_id,
"status": "unknown",
"diagnostics": [],
"message": "No source diagnostics provider is configured.",
}
return self.diagnostics.diagnose_source(source_id)
In src/wf_api/surface.py, add to WorkflowSourceAdminSurface:
async def diagnose_source(self, *, source_id: str) -> dict[str, Any]: ...
- Step 4: Run tests and commit
Run:
uv run pytest tests/wf_api/test_source_admin_api.py -q
uv run basedpyright --level error src/wf_api/source_admin.py src/wf_api/surface.py tests/wf_api/test_source_admin_api.py
Expected: tests pass and typecheck has 0 errors.
Commit:
git add src/wf_api/source_admin.py src/wf_api/surface.py tests/wf_api/test_source_admin_api.py
git commit -m "feat: add neutral source diagnostics api"
Task 2: MCP Source Diagnostics Provider
Files:
-
Create:
src/wf_mcp/broker/service/source_diagnostics.py -
Modify:
src/wf_mcp/broker/server.py -
Test:
tests/wf_mcp/service/test_source_diagnostics.py -
Test:
tests/wf_mcp/test_mcp_workflow_server.py -
Step 1: Write provider tests
Create tests/wf_mcp/service/test_source_diagnostics.py:
from __future__ import annotations
from wf_api.auth import AuthRecord
from wf_mcp.broker.service.source_diagnostics import SourceDiagnosticsProvider
from wf_mcp.connections import ConnectionRegistry
from wf_mcp.models import ConnectionConfig
from wf_sources_mcp.catalog import CatalogSnapshot
from wf_sources_mcp.storage import FileAuthStore, FileCatalogStore
def _connection(**metadata: object) -> ConnectionConfig:
return ConnectionConfig(
id="demo.personal",
server="demo",
account="personal",
enabled=True,
metadata={"transport": "http", "url": "https://example.test/mcp", **metadata},
)
def _provider(tmp_path, connection: ConnectionConfig) -> SourceDiagnosticsProvider:
registry = ConnectionRegistry()
registry.register(connection)
return SourceDiagnosticsProvider(
connection_lookup=registry.get,
auth_store=FileAuthStore(tmp_path / "auth"),
catalog_store=FileCatalogStore(tmp_path / "catalog"),
)
def test_source_diagnostics_reports_present_auth(tmp_path) -> None:
connection = _connection(auth_ref="demo.creds")
provider = _provider(tmp_path, connection)
provider.auth_store.save_auth(
AuthRecord(
connection_id="demo.creds",
scheme="oauth_refresh_token",
payload={
"client_id": "client",
"client_secret": "secret",
"refresh_token": "refresh",
"token_url": "https://oauth2.example.test/token",
},
)
)
payload = provider.diagnose_source("demo.personal")
assert payload["source_id"] == "demo.personal"
assert payload["status"] == "ok"
assert payload["auth"]["auth_ref"] == "demo.creds"
assert payload["auth"]["record_present"] is True
assert payload["auth"]["scheme"] == "oauth_refresh_token"
assert payload["auth"]["transport_supported"] is True
assert payload["diagnostics"] == []
def test_source_diagnostics_reports_missing_auth(tmp_path) -> None:
payload = _provider(
tmp_path,
_connection(auth_ref="missing.creds"),
).diagnose_source("demo.personal")
assert payload["status"] == "error"
assert payload["auth"]["record_present"] is False
assert payload["diagnostics"][0]["code"] == "auth_not_found"
def test_source_diagnostics_reports_unsupported_transport_auth(tmp_path) -> None:
connection = ConnectionConfig(
id="demo.personal",
server="demo",
account="personal",
metadata={"transport": "stdio", "command": "demo", "auth_ref": "demo.creds"},
)
provider = _provider(tmp_path, connection)
provider.auth_store.save_auth(
AuthRecord(
connection_id="demo.creds",
scheme="oauth_refresh_token",
payload={
"client_id": "client",
"client_secret": "secret",
"refresh_token": "refresh",
"token_url": "https://oauth2.example.test/token",
},
)
)
payload = provider.diagnose_source("demo.personal")
assert payload["status"] == "error"
assert payload["auth"]["transport_supported"] is False
assert payload["diagnostics"][0]["code"] == "auth_scheme_not_supported"
def test_source_diagnostics_reports_catalog_snapshot(tmp_path) -> None:
provider = _provider(tmp_path, _connection())
provider.catalog_store.save_catalog(
CatalogSnapshot(
connection_id="demo.personal",
fetched_at_epoch_ms=123,
max_age_seconds=60,
)
)
payload = provider.diagnose_source("demo.personal")
assert payload["catalog"] == {
"has_snapshot": True,
"fetched_at_epoch_ms": 123,
"max_age_seconds": 60,
"node_count": 0,
"resource_count": 0,
"prompt_count": 0,
}
- Step 2: Run tests and confirm failure
Run:
uv run pytest tests/wf_mcp/service/test_source_diagnostics.py -q
Expected: fails because source_diagnostics.py does not exist.
- Step 3: Implement provider
Create src/wf_mcp/broker/service/source_diagnostics.py:
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any
from wf_api.auth import AuthRecord
from wf_core import DependencyDiagnostic, DiagnosticSeverity
from wf_sources_mcp.auth import connection_auth_diagnostic
from wf_sources_mcp.storage import AuthStore, CatalogStore
from ...models import ConnectionConfig
ConnectionLookup = Callable[[str], ConnectionConfig]
def _auth_ref(connection: ConnectionConfig) -> str | None:
value = connection.metadata.get("auth_ref")
return value if isinstance(value, str) and value else None
def _transport_kind(connection: ConnectionConfig) -> str | None:
value = connection.metadata.get("transport")
return value if isinstance(value, str) and value else None
def _auth_scheme_supported(
*,
transport_kind: str | None,
auth: AuthRecord | None,
) -> bool:
if auth is None:
return True
if transport_kind == "stdio":
return auth.scheme == "env"
if transport_kind == "http":
return auth.scheme in {"bearer", "headers", "oauth_refresh_token"}
return False
def _unsupported_auth_diagnostic(
*,
source_id: str,
auth_ref: str,
scheme: str,
transport_kind: str | None,
) -> dict[str, Any]:
return DependencyDiagnostic(
severity=DiagnosticSeverity.ERROR,
code="auth_scheme_not_supported",
logical_ref=auth_ref,
bound_source=source_id,
message=(
f"Source {source_id!r} uses {transport_kind or 'unknown'} transport, "
f"but auth record {auth_ref!r} has unsupported scheme {scheme!r}."
),
repair_hint=(
"Use env auth for stdio MCP sources, or bearer/headers/"
"oauth_refresh_token auth for HTTP MCP sources."
),
).model_dump(mode="json")
@dataclass(slots=True)
class SourceDiagnosticsProvider:
"""MCP broker diagnostics for source auth, transport, and catalog state."""
connection_lookup: ConnectionLookup
auth_store: AuthStore
catalog_store: CatalogStore
def diagnose_source(self, source_id: str) -> dict[str, Any]:
connection = self.connection_lookup(source_id)
auth_ref = _auth_ref(connection)
auth = self.auth_store.load_auth(auth_ref) if auth_ref else None
transport_kind = _transport_kind(connection)
snapshot = self.catalog_store.load_catalog(source_id)
diagnostics: list[dict[str, Any]] = []
missing_auth = connection_auth_diagnostic(
connection,
load_auth_ref=self.auth_store.load_auth,
)
if missing_auth is not None:
diagnostics.append(missing_auth.model_dump(mode="json"))
transport_supported = _auth_scheme_supported(
transport_kind=transport_kind,
auth=auth,
)
if auth_ref and auth is not None and not transport_supported:
diagnostics.append(
_unsupported_auth_diagnostic(
source_id=source_id,
auth_ref=auth_ref,
scheme=auth.scheme,
transport_kind=transport_kind,
)
)
return {
"source_id": source_id,
"status": "error" if diagnostics else "ok",
"enabled": connection.enabled,
"transport": {
"kind": transport_kind,
"configured": transport_kind is not None,
},
"auth": {
"auth_ref": auth_ref,
"record_present": auth is not None if auth_ref else None,
"scheme": None if auth is None else auth.scheme,
"transport_supported": transport_supported,
},
"catalog": {
"has_snapshot": snapshot is not None,
"fetched_at_epoch_ms": None
if snapshot is None
else snapshot.fetched_at_epoch_ms,
"max_age_seconds": None if snapshot is None else snapshot.max_age_seconds,
"node_count": 0 if snapshot is None else len(snapshot.nodes),
"resource_count": 0 if snapshot is None else len(snapshot.resources),
"prompt_count": 0 if snapshot is None else len(snapshot.prompts),
},
"diagnostics": diagnostics,
}
- Step 4: Wire provider into MCP-backed server
In src/wf_mcp/broker/server.py, import:
from .service.source_diagnostics import SourceDiagnosticsProvider
Inside workflow_server_from_service(), construct:
source_diagnostics = SourceDiagnosticsProvider(
connection_lookup=service.connections.get,
auth_store=service.auth_store,
catalog_store=service.catalog_store,
)
Change:
source_admin = WorkflowSourceAdminApi(context)
to:
source_admin = WorkflowSourceAdminApi(
context,
diagnostics=source_diagnostics,
)
If the function does not currently name source_admin, apply the same change where WorkflowSourceAdminApi is constructed.
- Step 5: Add server wiring test
In tests/wf_mcp/test_mcp_workflow_server.py, add:
async def test_workflow_server_source_admin_reports_mcp_diagnostics(tmp_path) -> None:
service = _service(tmp_path)
payload = await service.workflow_server.source_admin.diagnose_source(
source_id="demo.personal"
)
assert payload["source_id"] == "demo.personal"
assert "auth" in payload
assert "catalog" in payload
If the local helper is named differently, use the existing helper that builds a WfMcpService/WorkflowServer with demo.personal; keep the assertions above.
- Step 6: Run tests and commit
Run:
uv run pytest tests/wf_mcp/service/test_source_diagnostics.py tests/wf_mcp/test_mcp_workflow_server.py -q
uv run basedpyright --level error src/wf_mcp/broker/service/source_diagnostics.py src/wf_mcp/broker/server.py tests/wf_mcp/service/test_source_diagnostics.py tests/wf_mcp/test_mcp_workflow_server.py
Expected: tests pass and typecheck has 0 errors.
Commit:
git add src/wf_mcp/broker/service/source_diagnostics.py src/wf_mcp/broker/server.py tests/wf_mcp/service/test_source_diagnostics.py tests/wf_mcp/test_mcp_workflow_server.py
git commit -m "feat: add mcp source diagnostics provider"
Task 3: JSON-RPC Source Diagnose Method
Files:
-
Modify:
src/wf_transport_rpc_http/models.py -
Modify:
src/wf_transport_rpc_http/methods/sources.py -
Modify:
src/wf_transport_rpc_http/client/sources.py -
Test:
tests/wf_transport_rpc_http/test_app.py -
Test:
tests/wf_transport_rpc_http/test_client.py -
Step 1: Add RPC tests
In tests/wf_transport_rpc_http/test_app.py, add:
async def test_rpc_diagnoses_source(tmp_path) -> None:
server = build_local_static_workflow_server(tmp_path)
client = TestClient(create_app(server))
response = client.post(
"/rpc",
json={
"jsonrpc": "2.0",
"id": 1,
"method": "workflow.sources.diagnose",
"params": {"source_id": "wf.std"},
},
)
payload = response.json()
assert response.status_code == 200
assert payload["result"]["source_id"] == "wf.std"
assert payload["result"]["status"] == "unknown"
In tests/wf_transport_rpc_http/test_client.py, add:
async def test_rpc_client_diagnoses_source(tmp_path) -> None:
calls: list[tuple[str, dict[str, object]]] = []
class Client(RpcSourceAdminClientMixin):
async def _call(self, method: str, params: dict[str, object]):
calls.append((method, params))
return {"source_id": params["source_id"], "status": "ok"}
payload = await Client().diagnose_source(source_id="demo.personal")
assert payload == {"source_id": "demo.personal", "status": "ok"}
assert calls == [
("workflow.sources.diagnose", {"source_id": "demo.personal"})
]
- Step 2: Run tests and confirm failure
Run:
uv run pytest tests/wf_transport_rpc_http/test_app.py::test_rpc_diagnoses_source tests/wf_transport_rpc_http/test_client.py::test_rpc_client_diagnoses_source -q
Expected: fails because model/method/client are missing.
- Step 3: Implement RPC model/method/client
In src/wf_transport_rpc_http/models.py, add:
class DiagnoseSourceParams(RpcParamsModel):
source_id: str = Field(min_length=1)
In src/wf_transport_rpc_http/methods/sources.py, import DiagnoseSourceParams and add:
@entrypoint.method(name="workflow.sources.diagnose", errors=[WorkflowRpcError])
async def workflow_sources_diagnose(
params: DiagnoseSourceParams = RpcParams(),
) -> dict[str, Any]:
try:
return await server.source_admin.diagnose_source(
source_id=params.source_id
)
except (ValueError, KeyError, LookupError, FileNotFoundError) as exc:
raise_workflow_rpc_error(exc)
In src/wf_transport_rpc_http/client/sources.py, add:
async def diagnose_source(self: RpcCaller, *, source_id: str) -> dict[str, Any]:
return await self._call(
"workflow.sources.diagnose",
{"source_id": source_id},
)
- Step 4: Run tests and commit
Run:
uv run pytest tests/wf_transport_rpc_http/test_app.py::test_rpc_diagnoses_source tests/wf_transport_rpc_http/test_client.py::test_rpc_client_diagnoses_source -q
uv run basedpyright --level error src/wf_transport_rpc_http/models.py src/wf_transport_rpc_http/methods/sources.py src/wf_transport_rpc_http/client/sources.py tests/wf_transport_rpc_http/test_app.py tests/wf_transport_rpc_http/test_client.py
Expected: tests pass and typecheck has 0 errors.
Commit:
git add src/wf_transport_rpc_http/models.py src/wf_transport_rpc_http/methods/sources.py src/wf_transport_rpc_http/client/sources.py tests/wf_transport_rpc_http/test_app.py tests/wf_transport_rpc_http/test_client.py
git commit -m "feat: expose source diagnostics over rpc"
Task 4: CLI Source Diagnose Command
Files:
-
Modify:
src/wf_cli/commands/sources.py -
Test:
tests/wf_cli/test_remote_target.py -
Step 1: Write CLI tests
In tests/wf_cli/test_remote_target.py, add:
def test_wf_source_diagnose_uses_rpc_url_override(monkeypatch, tmp_path) -> None:
captured: dict[str, str] = {}
class FakeSourceAdmin:
async def diagnose_source(self, *, source_id: str) -> dict[str, object]:
captured["source_id"] = source_id
return {
"source_id": source_id,
"status": "ok",
"auth": {
"auth_ref": "demo.creds",
"record_present": True,
"scheme": "bearer",
"transport_supported": True,
},
"diagnostics": [],
}
class FakeContext:
source_admin = FakeSourceAdmin()
monkeypatch.setattr(
"wf_cli.commands.sources.load_cli_context_from_typer",
lambda ctx: FakeContext(),
)
result = runner.invoke(
app,
["--url", "http://127.0.0.1:8765/rpc", "source", "diagnose", "demo.personal"],
)
assert result.exit_code == 0, result.output
payload = json.loads(result.output)
assert captured == {"source_id": "demo.personal"}
assert payload["status"] == "ok"
assert payload["auth"]["scheme"] == "bearer"
If the file already has a runner or app helper, use the existing helper names.
- Step 2: Run test and confirm failure
Run:
uv run pytest tests/wf_cli/test_remote_target.py::test_wf_source_diagnose_uses_rpc_url_override -q
Expected: fails because wf source diagnose is not registered.
- Step 3: Implement CLI command
In src/wf_cli/commands/sources.py, add:
@app.command("diagnose")
def diagnose_source(
ctx: typer.Context,
source_id: Annotated[str, typer.Argument(help="Workflow source id.")],
) -> None:
"""Diagnose source transport, auth, and catalog state."""
context = load_cli_context_from_typer(ctx)
payload = run_cli_operation(
context,
context.source_admin.diagnose_source(source_id=source_id),
)
emit_json(payload)
- Step 4: Run tests and commit
Run:
uv run pytest tests/wf_cli/test_remote_target.py::test_wf_source_diagnose_uses_rpc_url_override -q
uv run basedpyright --level error src/wf_cli/commands/sources.py tests/wf_cli/test_remote_target.py
Expected: tests pass and typecheck has 0 errors.
Commit:
git add src/wf_cli/commands/sources.py tests/wf_cli/test_remote_target.py
git commit -m "feat: add source diagnose cli"
Task 5: Docs And Final Verification
Files:
-
Modify:
docs/wf_cli.md -
Modify:
docs/current_roadmap.md -
Step 1: Update CLI docs
In docs/wf_cli.md, add a source diagnostics subsection near the source commands:
### Diagnose A Source
Use `wf source diagnose <source_id>` to inspect source health before calling
capabilities:
```bash
wf --config wf.config.json source diagnose gdrive.personal
The output reports transport kind, auth reference, whether the auth record exists, whether the auth scheme is compatible with the transport, catalog snapshot counts, and non-secret diagnostics. Secret payload values are never printed.
- Step 2: Update roadmap
In docs/current_roadmap.md, add a completed item under the current source/auth roadmap section:
- Completed source auth diagnostics: `wf source diagnose <source_id>` now reports
transport/auth/catalog state without exposing secret payloads.
- Step 3: Run focused verification
Run:
uv run pytest tests/wf_api/test_source_admin_api.py tests/wf_mcp/service/test_source_diagnostics.py tests/wf_transport_rpc_http/test_app.py tests/wf_transport_rpc_http/test_client.py tests/wf_cli/test_remote_target.py -q
uv run ruff check src/wf_api/source_admin.py src/wf_api/surface.py src/wf_mcp/broker/service/source_diagnostics.py src/wf_mcp/broker/server.py src/wf_transport_rpc_http/models.py src/wf_transport_rpc_http/methods/sources.py src/wf_transport_rpc_http/client/sources.py src/wf_cli/commands/sources.py tests/wf_api/test_source_admin_api.py tests/wf_mcp/service/test_source_diagnostics.py tests/wf_transport_rpc_http/test_app.py tests/wf_transport_rpc_http/test_client.py tests/wf_cli/test_remote_target.py
uv run basedpyright --level error src/wf_api/source_admin.py src/wf_api/surface.py src/wf_mcp/broker/service/source_diagnostics.py src/wf_mcp/broker/server.py src/wf_transport_rpc_http/models.py src/wf_transport_rpc_http/methods/sources.py src/wf_transport_rpc_http/client/sources.py src/wf_cli/commands/sources.py tests/wf_api/test_source_admin_api.py tests/wf_mcp/service/test_source_diagnostics.py tests/wf_transport_rpc_http/test_app.py tests/wf_transport_rpc_http/test_client.py tests/wf_cli/test_remote_target.py
Expected:
-
Focused tests pass.
-
Ruff reports
All checks passed!. -
Basedpyright reports
0 errors. -
Step 4: Commit docs
git add docs/wf_cli.md docs/current_roadmap.md
git commit -m "docs: document source diagnostics"
Self-Review
- Spec coverage: plan adds neutral API, MCP diagnostics provider, RPC/client method, CLI command, docs, and tests. It explicitly avoids secret payload output.
- Placeholder scan: no
TBD,TODO, or "similar to" placeholders remain. - Type consistency: method name is
diagnose_sourceacross API, surface, RPC client, CLI, and tests. RPC method name isworkflow.sources.diagnose. Payload usesdiagnosticsfor the diagnostic list andauth/catalogfor structured summaries.