Skip to content

Legacy HTTP factory migration (11.4)

From 11.4, importing symfonic.agent.fastapi.router.create_agent_router still succeeds, and its signature stays (agent, prefix="/api/v1", app=None, *, audit_sink=None). Calling it raises EntryPointRemovedError with entry_point="create_agent_router", removed_in="11.4" and last_legacy_line="9.12". This happens before inspecting any injected object, checking production authentication, constructing an APIRouter or claiming an HTTP chat owner. No handlers are mounted and no turn or SSE event is emitted. The default and explicit selection="legacy" in mount_selected_chat_root consequently refuse as well.

Compose Agent behind AgentHost and use symfonic.platform.transport.create_kernel_agent_router for host HTTP transport. Applications that need the shared authenticated conversation root must explicitly select selection="agent" with their host and conversation authority. Native composition still validates authentication, scope, owner conflicts and supported capabilities before serving. The old wire contract does not silently become the native one; review the native route and event contracts for the application being migrated. Existing FrameworkConfig callers can use symfonic.migration.agent_from_config, whose named refusals identify settings it cannot honour. Unchanged legacy deployments must pin symfonic-core==9.12.*, the newest published legacy release line.

flowchart TD
    Old[create_agent_router or legacy root selection] --> Refuse[EntryPointRemovedError: 11.4 / pin 9.12]
    Refuse --> Stop[No router, owner claim, agent access or events]
    Native[AgentHost with native HTTP composition] --> Auth[Authentication and scope validation]
    Auth --> Owner[Owner and capability admission]
    Owner --> Agent[Agent serves the turn]
    Agent --> Wire[Native JSON response or typed SSE events]

Sub-router factories (CORE-25)

create_agent_router used to mount four sub-routers whose public factories took the same legacy agent. From 11.4 each keeps its import path and its (agent) signature, imports without FastAPI, and raises EntryPointRemovedError under its own name (removed_in="11.4", last_legacy_line="9.12") before reading the agent. The error's native_ports names the create_kernel_agent_router ports that mount the same routes:

Refused factory Native ports (services) Not served natively
create_graph_router graph= (GraphAdminService), edge_delete= (EdgeDeleteService) POST /edges
create_graph_maintenance_router edge_delete= (EdgeDeleteService), graph_audit= (GraphAuditService) POST /memories/bulk-delete, POST /memory/prune
create_memory_create_router semantic_create=, episodic_create=, procedural_create=, prospective_create=, working_create= none
create_tenant_privacy_router privacy= (symfonic.platform.PrivacyService) none

For the v11 generated AgentHost, POST /api/v1/memories/procedural is withdrawn. The generated native memory identity is kind-aware v1 and composes no procedural-create port; injecting the ordinary service would still address positional v0 and refuse. Procedure behavior requires separately composed, deployment-owned native Agent tools and capabilities. LocalProceduralHost offers a separate, explicitly selected single-worker ephemeral HTTP path with its own host-issued audited binding; it is not durable PostgreSQL procedural-create parity. Do not mount the v0 service or treat a 501 refusal as a successful migration.

On that host /memories, point read, delete and /memories/status are native (status counts the Agent's published v1 semantic records); the remaining positional-v0 routes answer the typed 501 before touching a store. Binding is all-or-nothing per startup: a failed or finished lifespan withdraws every mounted route, so the same app can start again.

The memory services are in symfonic.capabilities.memory; working_create= takes symfonic.platform.working_create.WorkingCreateService and needs its owning WorkingReference as the host. Route identity is not behavioural parity: review each native route's request, response and authentication contract before switching clients. The legacy erase route also swept symfonic.services.shadow.PRIVACY_DELETION_PARTICIPANTS; the native PrivacyService sweeps only its own SubjectDataStoreRegistry, so those participants are erased natively only once registered there, for example with symfonic.services.privacy.adapt_legacy_registry.

The four factory bodies are gone, so no private patch restores them, and the retained test-only create_agent_router body no longer mounts them.

Other legacy bodies remain in source pending the separate fourteen-condition retirement gate. Their characterization tests use an unsupported private monkeypatch scoped to the legacy oracle. The package exposes no admission flag, environment switch or compatibility router that restores this factory.