Feature Preservation Reference
Every feature symfonic-core shipped before the capability refactor, and
where its behaviour lives now. The refactor's ground rule is that
nothing is dropped implicitly: a capability can only leave through an
explicit recorded decision, and this program made none. Every row below is
therefore preserved, and every entry point you import today still
imports.
Read the columns like this:
- Entry point today — what your code imports right now. It keeps
working: tier-1 and tier-2 import paths do not break within a major
line, and no path was vacated by this refactor.
- Layer — which of the six layers owns the behaviour after the
refactor. This is what decides where the topic is documented.
- Where the behaviour lives now — the module holding the narrow
contract, for when you want it instead of the facade. Where this equals
the entry point, the code did not move at all.
For the narrative version — legacy pattern beside its replacement, domain
by domain — read
Guide 22 — Capability-Architecture Migration.
Generated, not hand-maintained
This page is rendered from the refactor's preservation catalogue and
feature-to-layer matrix by
.agent/team/framework-refactor/evidence/T4.3.2/render_preservation_reference.py.
Editing it by hand will be overwritten; change the catalogue instead.
A module named here that does not exist fails the task's validator.
D1 — Model providers, OAuth development providers, tuning, role models, routing
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D1.1 |
ModelProvider protocol |
symfonic.core.ModelProvider (core/providers.py) |
Low-level core |
symfonic.core.providers |
| D1.2 |
Anthropic provider |
symfonic.core.providers.AnthropicProvider |
Integration |
symfonic.core.providers |
| D1.3 |
OpenAI / DeepSeek / Kimi / OpenRouter providers |
OpenAIProvider, DeepSeekProvider, KimiProvider, OpenRouterProvider (core/providers.py) |
Integration |
symfonic.core.providers |
| D1.4 |
Google / Ollama / AWS Bedrock providers |
GoogleProvider, OllamaProvider, AWSBedrockProvider |
Integration |
symfonic.core.providers |
| D1.5 |
OAuth development providers (Codex, Kimi OAuth) |
codex_oauth / kimi_oauth examples + provider seams |
Integration |
symfonic.core.providers |
| D1.6 |
Per-dispatch routing / multi-provider |
symfonic.core.providers.MultiProviderRouter |
Integration |
symfonic.services.models |
| D1.7 |
Model tuning & role models |
ModelConfig, AgentConfig (symfonic.core), SymfonicAgent.resolve_model_config |
Agent API |
symfonic.services.models |
| D1.8 |
HttpClientUnsupportedWarning seam |
core/providers.py |
Integration |
symfonic.core.providers |
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D2.1 |
@symfonic_tool decorator + metadata |
symfonic.core.symfonic_tool, SymfonicToolMetadata, get_symfonic_metadata, is_symfonic_tool |
Capability |
symfonic.core.tools |
| D2.2 |
Tool registry & registration |
symfonic.core.ToolRegistry, ToolRegistration, ToolCategory, Visibility, ScopeLiteral |
Capability |
symfonic.capabilities.tools.catalog |
| D2.3 |
Routing modes & tool policies |
RoutingMode (symfonic.core.tools), ToolCallPolicy (symfonic.core.contracts) |
Capability |
symfonic.capabilities.tools.stages |
| D2.4 |
Steering & forced tool choice |
FrameworkConfig.resolve_force_tool_choice |
Agent API |
symfonic.capabilities.tools.stages |
| D2.5 |
Compaction |
CompactionConfig (symfonic.core) |
Capability |
symfonic.capabilities.prompting |
| D2.6 |
Tool offload & progress events |
ToolProgressEvent (symfonic.core.contracts), offload seams in engine |
Capability |
symfonic.capabilities.tools.execution |
| D2.7 |
Intent triage / tool narrowing |
symfonic.agent.triage (IntentClassifier, narrow_tools_for_intent, estimate_dropped_tokens, DEFAULT_ALWAYS_INCLUDE) |
Capability |
symfonic.capabilities.tools.stages |
| D2.8 |
MCP client |
symfonic.tools.mcp (MCPToolProvider, JSONRPCMCPConnection, MCPServerConnection, MCPToolDefinition, MCPToolResult) |
Integration |
symfonic.tools.mcp |
| D2.9 |
Capabilities (fetch/search) |
symfonic.core.capabilities (FetchCapability, SearchCapability, validate_url, validate_query) |
Capability |
symfonic.core.capabilities |
D3 — Prompts, JIT and stratified context, caching, standing blocks, budgets
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D3.1 |
Prompt builder & sections |
symfonic.core.prompt (PromptBuilder, PromptSection, CacheBlock, CacheablePrompt) |
Capability |
symfonic.core.prompt |
| D3.2 |
Domain prompts & templates |
symfonic.agent.prompts (BRAIN_PROMPT_VERSION, DBPromptSection, HMSSystemPromptSection, MemoryExtractionSection), DomainTemplate |
Capability |
symfonic.capabilities.prompting.compiler |
| D3.3 |
Context managers (JIT / stratified HMS) |
symfonic.agent.context (ContextManager, JITContextManager, StratifiedHMSContextManager, make_context_manager, resolve_strategy_name) |
Capability |
symfonic.capabilities.prompting.strategies |
| D3.4 |
Stratigraphic caching |
CacheBlock/CacheablePrompt + examples/stratigraphic_cache_demo.py |
Capability |
symfonic.capabilities.prompting.cache |
| D3.5 |
Prompt-block layer (standing blocks) |
symfonic.core.prompt.blocks — 80 exports: resolver, injector, revisions, snapshots, tiers, scopes, render policy |
Capability |
symfonic.core.prompt.blocks |
| D3.6 |
Block source adapters |
symfonic.core.prompt.blocks.sources (StaticBlockSource, FileBlockSource, DatabaseBlockSource, ComputedBlockSource, + error types, content_revision) |
Capability |
symfonic.capabilities.prompting.sources |
| D3.7 |
Block boundaries & inheritance |
inheritable_blocks, block_isolation_key, check_scope_pairing, examples/block_boundaries |
Capability |
symfonic.capabilities.prompting.boundaries |
| D3.8 |
Context budgets |
ContextBudget (symfonic.memory.models), TokenBudgetTracker (symfonic.core.observability) |
Runtime service |
symfonic.services.budget |
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D4.1 |
Memory orchestrator |
symfonic.memory.MemoryOrchestrator, OrchestratorConfig |
Capability |
symfonic.capabilities.memory.bridge |
| D4.2 |
Five layers |
symfonic.memory.layers (WorkingLayer, EpisodicLayer, SemanticLayer, ProceduralLayer, ProspectiveLayer) |
Capability |
symfonic.capabilities.memory.layers |
| D4.3 |
Graph store & models |
GraphMemoryStore, MemoryNode, MemoryEdge, MemoryEntry, CandidateNode, MemoryOperation, WritePolicy, ScoringWeights, MemoryLayer |
Capability |
symfonic.capabilities.memory.records |
| D4.4 |
Retrieval & hydration |
retrieval package + HydratedMemory, AssembledContext, auto_hydrate config |
Capability |
symfonic.capabilities.memory.hydration |
| D4.5 |
Spreading activation |
FrameworkConfig.spreading_activation, ActivationEvent |
Capability |
symfonic.capabilities.memory.activation |
| D4.6 |
Extraction & consolidation |
memory/_internal/extraction, SleepConsolidator, InsightExtractor, LearnedInsight, ConsolidationReport, auto_consolidate |
Runtime service |
symfonic.capabilities.memory.consolidation |
| D4.7 |
Entity linking |
regex extractor in core; spaCy/LLM opt-in |
Capability |
symfonic.capabilities.memory.linking |
| D4.8 |
Promotion & scope blending |
orchestrator promotion paths, scope-blend rules (memory/scope_isolation.py) |
Capability |
symfonic.capabilities.memory.promotion |
| D4.9 |
Embeddings |
symfonic.memory.embeddings (EmbeddingProvider, make_embedding_provider, EmbeddingCache, maybe_embed, SUPPORTED_PROVIDER_IDENTIFIERS, DEFAULT_CACHE_CAP) |
Integration |
symfonic.memory.embeddings |
| D4.10 |
Working-memory summarization |
symfonic.memory.working (STMSummary, SummaryMode, summarize_entries) |
Capability |
symfonic.capabilities.memory.working |
| D4.11 |
Memory telemetry |
symfonic.memory.telemetry (episodic sinks: Jsonl, Logging, Null, resolve_episodic_sink) |
Integration |
symfonic.memory.telemetry |
| D4.12 |
Postgres backends |
symfonic.memory.backends (PostgresGraphBackend, PostgresVectorBackend, PostgresPoolManager) |
Integration |
symfonic.memory.backends |
D5 — Knowledge providers, documents, citations, attachments, OCR, multimodal
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D5.1 |
Knowledge provider protocol |
symfonic.knowledge (KnowledgeProvider, KnowledgeFragment) |
Capability |
symfonic.capabilities.knowledge.retrieval |
| D5.2 |
Document stores |
symfonic.core.documents.InMemoryDocumentStore + adapters |
Capability |
symfonic.capabilities.knowledge.documents |
| D5.3 |
Attachments & extraction |
symfonic.agent.attachments (extract_text[s], is_extractable, typed errors), Attachment type |
Capability |
symfonic.capabilities.knowledge.attachments |
| D5.4 |
OCR |
pytesseract path in attachments |
Capability |
symfonic.capabilities.knowledge.attachments |
| D5.5 |
Multimodal formatting |
ContentPart (symfonic.agent.engine) |
Capability |
symfonic.capabilities.knowledge.multimodal |
D6 — History, conversation strategies, sessions, transcripts, checkpoints
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D6.1 |
Conversation managers |
symfonic.agent (ConversationManager, Null…, SlidingWindow…, Summarizing…) |
Capability |
symfonic.services.conversation.history |
| D6.2 |
Sessions |
symfonic.agent.SessionManager (agent/sessions.py) |
Runtime service |
symfonic.services.conversation.session |
| D6.3 |
Transcripts |
SymfonicAgent.get_transcript (agent/transcript.py) |
Runtime service |
symfonic.services.conversation.transcript |
| D6.4 |
Checkpointer factories |
symfonic.agent.checkpointer (CheckpointerFactory, Memory…, Postgres…, Sqlite…, Mongo…) |
Runtime service |
symfonic.services.conversation.checkpoint |
| D6.5 |
Restart recovery |
durable checkpointer + resume flow |
Runtime service |
symfonic.services.conversation.recovery |
| D6.6 |
Structured output |
symfonic.agent.extract_structured_output, StructuredOutputError (agent/structured.py) |
Low-level core |
symfonic.kernel.adapters |
D7 — Sub-agents, delegation, inheritance, lockdown, snapshots
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D7.1 |
Sub-agent core |
symfonic.agent.subagents (SubAgent, SubAgentSpec, SubAgentRegistry) |
Capability |
symfonic.capabilities.delegation.declarations |
| D7.2 |
Delegation & response metadata |
delegation path in engine; delegated response metadata on AgentResponse |
Capability |
symfonic.capabilities.delegation.compiler |
| D7.3 |
Lockdown & self-edit denial |
assert_no_block_edit_surface, deny_child_self_edit (symfonic.agent.subagents) |
Capability |
symfonic.capabilities.delegation.lockdown |
| D7.4 |
Snapshots |
RunSnapshotSlot, capture_block_snapshot, open/close/ensure_run_snapshot, in_run_snapshot_scope (core/prompt/blocks) |
Capability |
symfonic.core.prompt.blocks |
| D7.5 |
Config inheritance |
FrameworkConfig.child() |
Agent API |
symfonic.capabilities.delegation.compiler |
D8 — ask_user, interrupts, pause tokens, replay resistance, resume
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D8.1 |
ask_user flow |
AskUserQuestionEvent/AnsweredEvent/ExpiredEvent (symfonic.core.contracts), elicitation nodes (core/nodes/elicitation.py) |
Capability |
symfonic.capabilities.human.registration |
| D8.2 |
Generic interrupts |
InterruptEvent/ResolvedEvent/ExpiredEvent, InterruptRegistration (core/contracts/interrupt.py, core/nodes/interrupt.py) |
Capability |
symfonic.capabilities.human.registration |
| D8.3 |
Pause tokens |
agent/middleware/pause_token.py, pause_token_store.py, interrupt_minter.py; POST /resume/{pause_token} |
Runtime service |
symfonic.capabilities.human.tokens |
| D8.4 |
Resume |
POST /resume/{pause_token} route + engine resume |
Platform |
symfonic.capabilities.human.resume |
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D9.1 |
Credential hygiene |
agent/hygiene.py + SymfonicAgent.validate_action |
Capability |
symfonic.capabilities.governance.stages |
| D9.2 |
Fabrication detection |
FabricationDetectedEvent (core/contracts), on_fabrication_detected hook |
Capability |
symfonic.capabilities.governance.stages |
| D9.3 |
Metacognitive middleware |
symfonic.agent.middleware (MetacognitiveMiddleware, ReflectionEvent, ReflectionVerdict, compute_confidence, detect_sensitive_hit) |
Capability |
symfonic.capabilities.governance.stages |
| D9.4 |
Preconditions / preflight |
agent/preflight_l1.py |
Capability |
symfonic.capabilities.governance.stages |
| D9.5 |
Budgets & governance |
BudgetStore, BudgetUsage, BudgetCheckResult, TokenBudgetTracker, get/set_budget_tracker (core/observability); agent/fastapi/budget_dep.py |
Runtime service |
symfonic.services.cost |
| D9.6 |
Audit logging |
AuditLogger, AuditLogEntry, InMemoryAuditLogger, emit_audit_event, get/set_audit_logger |
Platform |
symfonic.platform.audit |
D10 — Callbacks, typed events, streaming, OpenTelemetry, metrics, costs, traces
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D10.1 |
Callback system |
symfonic.core.callbacks (CallbackHandler protocol, BaseCallbackHandler, CallbackManager, NoOpCallbackHandler) |
Low-level core |
symfonic.services.observability.bridge |
| D10.2 |
Typed event contracts |
symfonic.core.contracts — 39 exports incl. all event dataclasses |
Low-level core |
symfonic.core.contracts |
| D10.3 |
Streaming |
symfonic.core.streaming (19 exports: deltas, tool events, usage, EventTranspiler, ExtractionFilter, TimestampedEvent) + StreamChunk |
Low-level core |
symfonic.kernel.streaming |
| D10.4 |
Streaming adapters |
symfonic.core.streaming.adapters (anthropic_adapter, openai_adapter) |
Integration |
symfonic.core.streaming.adapters |
| D10.5 |
OpenTelemetry exporter |
symfonic.observability.otel (OTelExporter, OTelExporterHandles) |
Integration |
symfonic.observability.otel |
| D10.6 |
Metrics & costs |
SymfonicAgent.metrics_collector, /metrics/* routes, UsageEvent |
Runtime service |
symfonic.services.observability.ports |
| D10.7 |
Traces |
symfonic.infra (ExecutionTrace, TraceEvent, TraceStoreProtocol, InMemoryTraceStore) |
Runtime service |
symfonic.infra.trace |
| D10.8 |
Diagnostics / HMS audit |
symfonic.diagnostics (audit_hms[_sync], AuditRunner, AuditReport, CheckResult, Severity) + 6 checks in diagnostics.checks |
Tooling |
symfonic.diagnostics |
| D10.9 |
Logging seam |
symfonic.core.logging (Logger, ConsoleLogger) |
Low-level core |
symfonic.core.logging |
| D10.10 |
Node observability |
observed_node, NodeName, NODE_NAMES, NODE_LABELS, human_label, NoOpObservabilityHook + lifecycle hook protocols |
Low-level core |
symfonic.core.observability |
D11 — Tenant scope, authentication, privacy, billing, FastAPI, SSE
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D11.1 |
Tenant scope |
TenantScope (symfonic.core / symfonic.memory), FrameworkTenantScope (symfonic.agent) |
Platform |
symfonic.platform.scope |
| D11.2 |
Agent HTTP API |
symfonic.agent.fastapi.router — chat, stream (SSE), typed stream, resume, chats, memories CRUD, procedures CRUD/approve/reject/toggle/dedupe, consolidate (25 routes) |
Platform |
symfonic.agent.fastapi.router |
| D11.3 |
Graph & maintenance API |
graph_router (7 routes), graph_maintenance_router (4 routes) |
Platform |
symfonic.agent.fastapi.graph_router |
| D11.4 |
Memory-create API |
memory_create_router (5 routes: semantic/episodic/procedural/working/prospective) |
Platform |
symfonic.agent.fastapi.memory_create_router |
| D11.5 |
Metrics API |
metrics_router (3 routes) |
Platform |
symfonic.agent.fastapi.metrics_router |
| D11.6 |
Privacy export/deletion |
tenant_privacy_router (GET /tenants/me/export, DELETE /tenants/me/data), tenant_privacy_export.py |
Platform |
symfonic.platform.privacy |
| D11.7 |
Auth & dependencies |
agent/fastapi/dependencies.py, budget_dep.py |
Platform |
symfonic.platform.ports |
| D11.8 |
Billing hooks |
budget/usage surface + scaffolded billing app (cli/templates/app/billing) |
Platform |
symfonic.platform.budget |
D12 — Plugins, schedulers, CLI, scaffolding, examples, testing utilities
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| D12.1 |
Plugin system |
symfonic.core.plugins (BaseDomainPlugin, PluginContribution, PluginPromptSection), SymfonicAgent.load_plugin |
Integration |
symfonic.capabilities.extensions.composition |
| D12.2 |
Schedulers |
symfonic.infra (TaskSchedulerProtocol, NullScheduler), FrameworkConfig.scheduler/task_scheduler |
Runtime service |
symfonic.infra.protocols |
| D12.3 |
CLI |
symfonic entry point → symfonic.agent.cli.main:app: guide, chat, migrate, init, examples list, examples add |
Tooling |
symfonic.agent.cli |
| D12.4 |
Scaffolding |
symfonic.cli.scaffold (cli/init.py, components.py) + cli/templates/** (FastAPI auth stack, webapp, alembic, tests) |
Tooling |
symfonic.cli |
| D12.5 |
Curated examples |
examples/ — 40 entries (see JSON examples); symfonic examples list/add |
Tooling |
symfonic.cli.examples |
| D12.6 |
Testing utilities |
symfonic.core.testing (MockChatModel, MockModelProvider), tests/doubles.py |
Tooling |
symfonic.core.testing |
| D12.7 |
Corpus scrubber |
symfonic.tools.corpus_scrub (CorpusScrubber, scrub_jsonl_file, PII/credential pattern sets) |
Tooling |
symfonic.tools.corpus_scrub |
| D12.8 |
Agent stores / skills / documents (in-memory) |
InMemoryAgentStore, InMemorySkillStore, InMemoryDocumentStore |
Integration |
symfonic.core.agents |
| D12.9 |
Graph runtime core |
symfonic.core (AgentGraph, AgentRuntime, GraphPreset, BaseAgentState, BaseAgentDeps, error types) |
Low-level core |
symfonic.kernel |
X — Packaging, environment, documentation, releases, test infrastructure
| # |
Feature |
Entry point today |
Layer |
Where the behaviour lives now |
| X.1 |
Distribution & extras |
pyproject.toml: 34 optional extras (full list in JSON), console script symfonic |
Platform |
pyproject.toml |
| X.2 |
Environment variables |
20 documented env vars (JSON environment_variables) incl. provider keys, EMBEDDING_PROVIDER, OTEL_EXPORTER_OTLP_PROTOCOL |
Agent API |
symfonic.agent.configuration |
| X.3 |
Documentation site |
docs/ (102 pages), mkdocs.yml, docs/gen_ref_pages.py (griffe API reference), docs/FEATURES.md, docs/llms.txt |
Tooling |
docs/ |
| X.4 |
Versioning & changelog |
CHANGELOG.md, docs/releases/, dual-line branching (main=9.x, 8.x) |
Tooling |
docs/CHANGELOG.md |
| X.5 |
Network guard & test infra |
tests/_network_guard.py, tests/_optional_deps.py, cassettes, _replay |
Tooling |
tests/ |
What preserved means here
Preservation is measured, not asserted. The catalogue behind this page was cross-checked against runtime behaviour through six independent channels — import tracing, test collection, route enumeration, entry-point metadata, wheel contents, and example discovery — and the drift ran in one direction only: the runtime has more than the catalogue records, never less. If you cannot find something you use, treat it as a defect in the migration and report it.